By Pater Noster Servings: 2 Prep Time: 10 mins Cook Time: 1-2 hrs Difficulty: Easy Trappist beer is a rich and pleasant beer traditionally brewed by monks.
Ingredients
Ale: Ale! The core of any good drink. Easily obtainable by fermenting oats in a barrel for a while. This will be the basis of our brew, giving it it's fruity taste and color! Holy water: This is what a makes a trappist a trappist and not a trapisst, the religion! Real easy to get if you are reading this where you are supposed to be reading this! If the chaplain can't bothered it's also easily harvestable from holymelons as long as you bother to separate it. Sugar: Sugar is what's gonna make it all come together sweetening the brew and mixing well with the ale from earlier. It's easy to obtain from grinding sugarcanes. Feel free to add liberally.
Preparation
1. Mix the ale and holy water together. 2. Add some sugar to the mix as you keep stirring it for 1 minute. 3. At this point you're free to just use it as is! But feel free to experiment by adding new flavours and really making it your own!
In the event of a singuloose, or a tesloose, crew should fling themselves out of the nearest airlock, in the hopes that their corpse is discovered in the future.
"
return ""
-//WS Begin
-/datum/controller/subsystem/ticker/proc/mouse_report()
- if(GLOB.mouse_food_eaten)
- var/list/parts = list()
- parts += "Mouse stats:"
- parts += "Mouse Born: [GLOB.mouse_spawned]"
- parts += "Mouse Killed: [GLOB.mouse_killed]"
- parts += "Trash Eaten: [GLOB.mouse_food_eaten]"
- return "
[parts.Join(" ")]
"
- return ""
-//WS End
+
/datum/controller/subsystem/ticker/proc/antag_report()
var/list/result = list()
var/list/all_teams = list()
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 8e9a1dbc9979..d6b048de4289 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -295,7 +295,7 @@ Turf and target are separate in case you want to teleport some distance from a t
return "[pick("!","@","#","$","%","^","&")][pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")]"
//Returns a list of all items of interest with their name
-/proc/getpois(mobs_only = FALSE, skip_mindless = FALSE, specify_dead_role = TRUE)
+/proc/getpois(mobs_only = FALSE, skip_mindless = FALSE, specify_dead_role = TRUE, only_realname = FALSE)
var/list/mobs = sortmobs()
var/list/namecounts = list()
var/list/pois = list()
@@ -305,7 +305,11 @@ Turf and target are separate in case you want to teleport some distance from a t
continue
if(M.client && M.client.holder && M.client.holder.fakekey) //stealthmins
continue
- var/name = avoid_assoc_duplicate_keys(M.name, namecounts) + M.get_realname_string()
+ var/name = ""
+ if(only_realname)
+ name = avoid_assoc_duplicate_keys(M.real_name, namecounts)
+ else
+ name = avoid_assoc_duplicate_keys(M.name, namecounts) + M.get_realname_string()
if(M.stat == DEAD && specify_dead_role)
if(isobserver(M))
@@ -321,6 +325,7 @@ Turf and target are separate in case you want to teleport some distance from a t
pois[avoid_assoc_duplicate_keys(A.name, namecounts)] = A
return pois
+
//Orders mobs by type then by name
/proc/sortmobs()
var/list/moblist = list()
@@ -1329,44 +1334,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
temp = ((temp + (temp>>3))&29127) % 63 //070707
return temp
-//same as do_mob except for movables and it allows both to drift and doesn't draw progressbar
-/proc/do_atom(atom/movable/user , atom/movable/target, time = 30, uninterruptible = 0,datum/callback/extra_checks = null)
- if(!user || !target)
- return TRUE
- var/user_loc = user.loc
-
- var/drifting = FALSE
- if(!user.Process_Spacemove(0) && user.inertia_dir)
- drifting = TRUE
-
- var/target_drifting = FALSE
- if(!target.Process_Spacemove(0) && target.inertia_dir)
- target_drifting = TRUE
-
- var/target_loc = target.loc
-
- var/endtime = world.time+time
- . = TRUE
- while (world.time < endtime)
- stoplag(1)
- if(QDELETED(user) || QDELETED(target))
- . = 0
- break
- if(uninterruptible)
- continue
-
- if(drifting && !user.inertia_dir)
- drifting = FALSE
- user_loc = user.loc
-
- if(target_drifting && !target.inertia_dir)
- target_drifting = FALSE
- target_loc = target.loc
-
- if((!drifting && user.loc != user_loc) || (!target_drifting && target.loc != target_loc) || (extra_checks && !extra_checks.Invoke()))
- . = FALSE
- break
-
//returns a GUID like identifier (using a mostly made up record format)
//guids are not on their own suitable for access or security tokens, as most of their bits are predictable.
// (But may make a nice salt to one)
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 406f0bb0b101..bbfb0d3a74c5 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -152,6 +152,7 @@ DEFINE_BITFIELD(item_flags, list(
"NOBLUDGEON" = NOBLUDGEON,
"NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION,
"SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND,
+ "NO_PIXEL_RANDOM_DROP" = NO_PIXEL_RANDOM_DROP,
))
DEFINE_BITFIELD(machine_stat, list(
@@ -190,6 +191,7 @@ DEFINE_BITFIELD(movement_type, list(
"GROUND" = GROUND,
"PHASING" = PHASING,
"VENTCRAWLING" = VENTCRAWLING,
+ "THROWN" = THROWN,
))
DEFINE_BITFIELD(obj_flags, list(
@@ -263,6 +265,14 @@ DEFINE_BITFIELD(zap_flags, list(
"ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE,
))
+
+DEFINE_BITFIELD(storage_flags, list(
+ "STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS,
+ "STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS,
+ "STORAGE_LIMIT_COMBINED_W_CLASS" = STORAGE_LIMIT_COMBINED_W_CLASS,
+ "STORAGE_LIMIT_VOLUME" = STORAGE_LIMIT_VOLUME,
+))
+
DEFINE_BITFIELD(bodytype, list(
"BODYTYPE_ORGANIC" = BODYTYPE_ORGANIC,
"BODYTYPE_ROBOTIC" = BODYTYPE_ROBOTIC,
diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm
index 479e43e34543..f9edbc500142 100644
--- a/code/_globalvars/lists/flavor_misc.dm
+++ b/code/_globalvars/lists/flavor_misc.dm
@@ -46,6 +46,7 @@ GLOBAL_LIST_EMPTY(spider_legs_list)
GLOBAL_LIST_EMPTY(spider_spinneret_list)
GLOBAL_LIST_EMPTY(kepori_feathers_list)
GLOBAL_LIST_EMPTY(kepori_body_feathers_list)
+GLOBAL_LIST_EMPTY(kepori_head_feathers_list)
GLOBAL_LIST_EMPTY(kepori_tail_feathers_list)
GLOBAL_LIST_EMPTY(vox_head_quills_list)
GLOBAL_LIST_EMPTY(vox_neck_quills_list)
@@ -189,6 +190,22 @@ GLOBAL_LIST_INIT(exowearlist, list(PREF_NOEXOWEAR, PREF_EXOWEAR, PREF_ALTEXOWEAR
#define UPLINK_PEN "Pen" //like a real spy!
GLOBAL_LIST_INIT(uplink_spawn_loc_list, list(UPLINK_PDA, UPLINK_RADIO, UPLINK_PEN))
+//favorite cigarette brand
+#define PREF_CIG_SPACE "Space Cigarettes"
+#define PREF_CIG_DROMEDARY "DromedaryCo Cigarettes"
+#define PREF_CIG_UPLIFT "Uplift Smooth Cigarettes"
+#define PREF_CIG_ROBUST "Robust Cigarettes"
+#define PREF_CIG_ROBUSTGOLD "Robust Gold Cigarettes"
+#define PREF_CIG_CARP "Carp Classic Cigarettes"
+#define PREF_CIG_MIDORI "Midori Taboko Rollies"
+#define PREF_CIGAR "Premium Cigars"
+#define PREF_CIGAR_SOLAR "Solarian Cigars"
+#define PREF_CIGAR_COHIBA "Cohiba Cigars"
+#define PREF_VAPE "Vape Pen"
+#define PREF_PIPE "Fancy Pipe"
+
+GLOBAL_LIST_INIT(valid_smoke_types, sortList(list(PREF_CIG_SPACE, PREF_CIG_DROMEDARY, PREF_CIG_UPLIFT, PREF_CIG_ROBUST, PREF_CIG_ROBUSTGOLD, PREF_CIG_CARP, PREF_CIG_MIDORI, PREF_CIGAR, PREF_CIGAR_SOLAR, PREF_CIGAR_COHIBA, PREF_VAPE, PREF_PIPE)))
+
//Female Uniforms
GLOBAL_LIST_EMPTY(female_clothing_icons)
//Alternate species icons
diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm
index 0091b88fa15f..532ed3f888d7 100644
--- a/code/_globalvars/lists/maintenance_loot.dm
+++ b/code/_globalvars/lists/maintenance_loot.dm
@@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(common_loot, list( //common: basic items
) = 1,
list(//misc
- /obj/item/radio/off = 1,
+ /obj/item/radio = 1,
/obj/item/extinguisher = 1,
/obj/item/tank/internals/emergency_oxygen = 1,
/obj/item/bodybag = 1,
@@ -212,7 +212,7 @@ GLOBAL_LIST_INIT(uncommon_loot, list(//uncommon: useful items
) = 1,
list(//drinks
/obj/item/reagent_containers/food/drinks/bottle/vodka = 1,
- /obj/item/reagent_containers/food/drinks/soda_cans/grey_bull = 1,
+ /obj/item/reagent_containers/food/drinks/soda_cans/crosstalk = 1,
) = 1,
list(//sprayers
/obj/item/reagent_containers/spray = 1,
diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm
index ecc1acb6f0e1..fe657d56284d 100644
--- a/code/_globalvars/lists/names.dm
+++ b/code/_globalvars/lists/names.dm
@@ -11,11 +11,10 @@ GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female
GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt"))
GLOBAL_LIST_INIT(lizard_names_male, world.file2list("strings/names/lizard_male.txt"))
GLOBAL_LIST_INIT(lizard_names_female, world.file2list("strings/names/lizard_female.txt"))
+GLOBAL_LIST_INIT(kepori_names, world.file2list("strings/names/kepori_names.txt"))
GLOBAL_LIST_INIT(clown_names, world.file2list("strings/names/clown.txt"))
GLOBAL_LIST_INIT(mime_names, world.file2list("strings/names/mime.txt"))
GLOBAL_LIST_INIT(carp_names, world.file2list("strings/names/carp.txt"))
-GLOBAL_LIST_INIT(moth_first, world.file2list("strings/names/moth_first.txt"))
-GLOBAL_LIST_INIT(moth_last, world.file2list("strings/names/moth_last.txt"))
GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt"))
GLOBAL_LIST_INIT(squid_names, world.file2list("strings/names/squid.txt"))
GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt"))
@@ -27,6 +26,8 @@ GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
GLOBAL_LIST_INIT(ing_verbs, world.file2list("strings/names/ing_verbs.txt"))
GLOBAL_LIST_INIT(adverbs, world.file2list("strings/names/adverbs.txt"))
GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt"))
+GLOBAL_LIST_INIT(preference_adjectives, world.file2list("strings/preference_adjectives.txt"))
+GLOBAL_LIST_INIT(ipc_preference_adjectives, world.file2list("strings/ipc_preference_adjectives.txt"))
GLOBAL_LIST_INIT(dream_strings, world.file2list("strings/dreamstrings.txt"))
//loaded on startup because of "
//would include in rsc if ' was used
@@ -41,11 +42,6 @@ List of configurable names in preferences and their metadata
),
*/
GLOBAL_LIST_INIT(preferences_custom_names, list(
- "human" = list("pref_name" = "Backup Human", "qdesc" = "backup human name, used in the event you are assigned a command role as another species", "group" = "backup_human", "allow_null" = FALSE),
- "clown" = list("pref_name" = "Clown" , "qdesc" = "clown name", "group" = "fun", "allow_null" = FALSE),
- "mime" = list("pref_name" = "Mime", "qdesc" = "mime name" , "group" = "fun", "allow_null" = FALSE),
"cyborg" = list("pref_name" = "Cyborg", "qdesc" = "cyborg name (Leave empty to use default naming scheme)", "group" = "silicons", "allow_null" = TRUE),
"ai" = list("pref_name" = "AI", "qdesc" = "ai name", "group" = "silicons", "allow_null" = FALSE),
- "religion" = list("pref_name" = "Chaplain religion", "qdesc" = "religion" , "group" = "chaplain", "allow_null" = FALSE),
- "deity" = list("pref_name" = "Chaplain deity", "qdesc" = "deity", "group" = "chaplain", "allow_null" = FALSE)
- ))
+))
diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm
index 3386e9952eeb..d6c720380f46 100644
--- a/code/_globalvars/misc.dm
+++ b/code/_globalvars/misc.dm
@@ -11,6 +11,9 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new)
GLOBAL_VAR_INIT(CELLRATE, 0.002) // conversion ratio between a watt-tick and kilojoule
GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
+GLOBAL_VAR_INIT(total_merits_exchanged, 0)
+GLOBAL_VAR_INIT(hydrogen_stored, 0) // can be -/+, + meaning surplus
+
GLOBAL_LIST_EMPTY(powernets)
GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes
diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm
index dbc3607129f4..5f5c26731d15 100644
--- a/code/_globalvars/traits.dm
+++ b/code/_globalvars/traits.dm
@@ -125,8 +125,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_NIGHT_VISION" = TRAIT_NIGHT_VISION,
"TRAIT_LIGHT_STEP" = TRAIT_LIGHT_STEP,
"TRAIT_SPIRITUAL" = TRAIT_SPIRITUAL,
- "TRAIT_FAN_CLOWN" = TRAIT_FAN_CLOWN,
- "TRAIT_FAN_MIME" = TRAIT_FAN_MIME,
"TRAIT_VORACIOUS" = TRAIT_VORACIOUS,
"TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE,
"TRAIT_FREERUNNING" = TRAIT_FREERUNNING,
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 81ce3ceec1eb..a6f81d8ca4f1 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -356,7 +356,6 @@
/**
* Control+Shift click
- * Unused except for AI
*/
/mob/proc/CtrlShiftClickOn(atom/A)
A.CtrlShiftClick(src)
@@ -367,7 +366,7 @@
return
/atom/proc/CtrlShiftClick(mob/user)
- SEND_SIGNAL(src, COMSIG_CLICK_CTRL_SHIFT)
+ SEND_SIGNAL(src, COMSIG_CLICK_CTRL_SHIFT, user)
return
/*
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 8615b9a9aa6d..ef1f614809fe 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -241,20 +241,20 @@
user.swap_hand(held_index)
return TRUE
-/atom/movable/screen/close
- name = "close"
- layer = ABOVE_HUD_LAYER
- plane = ABOVE_HUD_PLANE
- icon_state = "backpack_close"
+// /atom/movable/screen/close
+// name = "close"
+// layer = ABOVE_HUD_LAYER
+// plane = ABOVE_HUD_PLANE
+// icon_state = "backpack_close"
-/atom/movable/screen/close/Initialize(mapload, new_master)
- . = ..()
- master = new_master
+// /atom/movable/screen/close/Initialize(mapload, new_master)
+// . = ..()
+// master = new_master
-/atom/movable/screen/close/Click()
- var/datum/component/storage/S = master
- S.hide_from(usr)
- return TRUE
+// /atom/movable/screen/close/Click()
+// var/datum/component/storage/S = master
+// S.hide_from(usr)
+// return TRUE
/atom/movable/screen/drop
name = "drop"
@@ -437,30 +437,6 @@
icon_state = "[base_icon_state][user.resting ? 0 : null]"
return ..()
-/atom/movable/screen/storage
- name = "storage"
- icon_state = "block"
- screen_loc = "7,7 to 10,8"
- layer = HUD_LAYER
- plane = HUD_PLANE
-
-/atom/movable/screen/storage/Initialize(mapload, new_master)
- . = ..()
- master = new_master
-
-/atom/movable/screen/storage/Click(location, control, params)
- if(world.time <= usr.next_move)
- return TRUE
- if(usr.incapacitated())
- return TRUE
- if (ismecha(usr.loc)) // stops inventory actions in a mech
- return TRUE
- if(master)
- var/obj/item/I = usr.get_active_held_item()
- if(I)
- master.attackby(null, I, usr, params)
- return TRUE
-
/atom/movable/screen/throw_catch
name = "throw/catch"
icon = 'icons/hud/screen_midnight.dmi'
diff --git a/code/_onclick/hud/storage.dm b/code/_onclick/hud/storage.dm
new file mode 100644
index 000000000000..c10375df4e8b
--- /dev/null
+++ b/code/_onclick/hud/storage.dm
@@ -0,0 +1,198 @@
+/atom/movable/screen/storage
+ name = "storage"
+ var/insertion_click = FALSE
+
+/atom/movable/screen/storage/Initialize(mapload, new_master)
+ . = ..()
+ master = new_master
+
+/atom/movable/screen/storage/Click(location, control, params)
+ if(!insertion_click)
+ return ..()
+ if(hud?.mymob && (hud.mymob != usr))
+ return
+ // just redirect clicks
+ if(master)
+ var/obj/item/I = usr.get_active_held_item()
+ if(I)
+ master.attackby(null, I, usr, params)
+ return TRUE
+
+/atom/movable/screen/storage/boxes
+ name = "storage"
+ icon_state = "block"
+ screen_loc = "7,7 to 10,8"
+ layer = HUD_LAYER
+ plane = HUD_PLANE
+ insertion_click = TRUE
+
+/atom/movable/screen/storage/close
+ name = "close"
+ layer = ABOVE_HUD_LAYER
+ plane = ABOVE_HUD_PLANE
+ icon_state = "backpack_close"
+
+/atom/movable/screen/storage/close/Click()
+ var/datum/component/storage/S = master
+ S.close(usr)
+ return TRUE
+
+/atom/movable/screen/storage/left
+ icon_state = "storage_start"
+ insertion_click = TRUE
+
+/atom/movable/screen/storage/right
+ icon_state = "storage_end"
+ insertion_click = TRUE
+
+/atom/movable/screen/storage/continuous
+ icon_state = "storage_continue"
+ insertion_click = TRUE
+
+/atom/movable/screen/storage/volumetric_box
+ icon_state = "stored_continue"
+ layer = VOLUMETRIC_STORAGE_BOX_LAYER
+ plane = VOLUMETRIC_STORAGE_BOX_PLANE
+ var/obj/item/our_item
+
+/atom/movable/screen/storage/volumetric_box/Initialize(mapload, new_master, obj/item/our_item)
+ src.our_item = our_item
+ RegisterSignal(our_item, COMSIG_ITEM_MOUSE_ENTER, PROC_REF(on_item_mouse_enter))
+ RegisterSignal(our_item, COMSIG_ITEM_MOUSE_EXIT, PROC_REF(on_item_mouse_exit))
+ return ..()
+
+/atom/movable/screen/storage/volumetric_box/Destroy()
+ makeItemInactive()
+ our_item = null
+ return ..()
+
+/atom/movable/screen/storage/volumetric_box/Click(location, control, params)
+ return our_item.Click(location, control, params)
+
+/atom/movable/screen/storage/volumetric_box/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
+ return our_item.MouseDrop(over, src_location, over_location, src_control, over_control, params)
+
+/atom/movable/screen/storage/volumetric_box/MouseExited(location, control, params)
+ makeItemInactive()
+
+/atom/movable/screen/storage/volumetric_box/MouseEntered(location, control, params)
+ . = ..()
+ makeItemActive()
+
+/atom/movable/screen/storage/volumetric_box/proc/on_item_mouse_enter()
+ makeItemActive()
+
+/atom/movable/screen/storage/volumetric_box/proc/on_item_mouse_exit()
+ makeItemInactive()
+
+/atom/movable/screen/storage/volumetric_box/proc/makeItemInactive()
+ return
+
+/atom/movable/screen/storage/volumetric_box/proc/makeItemActive()
+ return
+
+/atom/movable/screen/storage/volumetric_box/center
+ icon_state = "stored_continue"
+ var/atom/movable/screen/storage/volumetric_edge/stored_left/left
+ var/atom/movable/screen/storage/volumetric_edge/stored_right/right
+ var/atom/movable/screen/storage/item_holder/holder
+ var/pixel_size
+
+/atom/movable/screen/storage/volumetric_box/center/Initialize(mapload, new_master, our_item)
+ left = new(null, src, our_item)
+ right = new(null, src, our_item)
+ return ..()
+
+/atom/movable/screen/storage/volumetric_box/center/Destroy()
+ QDEL_NULL(left)
+ QDEL_NULL(right)
+ vis_contents.Cut()
+ if(holder)
+ QDEL_NULL(holder)
+ return ..()
+
+/atom/movable/screen/storage/volumetric_box/center/proc/on_screen_objects()
+ return list(src)
+
+
+//Sets the size of this box screen object and regenerates its left/right borders. This includes the actual border's size!
+/atom/movable/screen/storage/volumetric_box/center/proc/set_pixel_size(pixels)
+ if(pixel_size == pixels)
+ return
+ pixel_size = pixels
+ cut_overlays()
+ vis_contents.Cut()
+ //our icon size is 32 pixels.
+ var/multiplier = (pixels - (VOLUMETRIC_STORAGE_BOX_BORDER_SIZE * 2)) / VOLUMETRIC_STORAGE_BOX_ICON_SIZE
+ transform = matrix(multiplier, 0, 0, 0, 1, 0)
+ if(our_item)
+ if(holder)
+ qdel(holder)
+ holder = new(null, src, our_item)
+ holder.transform = matrix(1 / multiplier, 0, 0, 0, 1, 0)
+ holder.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ holder.appearance_flags &= ~RESET_TRANSFORM
+ makeItemInactive()
+ vis_contents += holder
+ left.pixel_x = -((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) - VOLUMETRIC_STORAGE_BOX_BORDER_SIZE
+ right.pixel_x = ((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) + VOLUMETRIC_STORAGE_BOX_BORDER_SIZE
+ add_overlay(left)
+ add_overlay(right)
+
+/atom/movable/screen/storage/volumetric_box/center/makeItemInactive()
+ if(!holder)
+ return
+ holder.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
+ holder.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
+
+/atom/movable/screen/storage/volumetric_box/center/makeItemActive()
+ if(!holder)
+ return
+ holder.our_item.layer = VOLUMETRIC_STORAGE_ACTIVE_ITEM_LAYER //make sure we display infront of the others!
+ holder.our_item.plane = VOLUMETRIC_STORAGE_ACTIVE_ITEM_PLANE
+
+/atom/movable/screen/storage/volumetric_edge
+ layer = VOLUMETRIC_STORAGE_BOX_LAYER
+ plane = VOLUMETRIC_STORAGE_BOX_PLANE
+
+/atom/movable/screen/storage/volumetric_edge/Initialize(mapload, master, our_item)
+ src.master = master
+ return ..()
+
+/atom/movable/screen/storage/volumetric_edge/Click(location, control, params)
+ return master.Click(location, control, params)
+
+/atom/movable/screen/storage/volumetric_edge/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
+ return master.MouseDrop(over, src_location, over_location, src_control, over_control, params)
+
+/atom/movable/screen/storage/volumetric_edge/MouseExited(location, control, params)
+ return master.MouseExited(location, control, params)
+
+/atom/movable/screen/storage/volumetric_edge/MouseEntered(location, control, params)
+ . = ..()
+ return master.MouseEntered(location, control, params)
+
+/atom/movable/screen/storage/volumetric_edge/stored_left
+ icon_state = "stored_start"
+ appearance_flags = APPEARANCE_UI | KEEP_APART | RESET_TRANSFORM // Yes I know RESET_TRANSFORM is in APPEARANCE_UI but we're hard-asserting this incase someone changes it.
+
+/atom/movable/screen/storage/volumetric_edge/stored_right
+ icon_state = "stored_end"
+ appearance_flags = APPEARANCE_UI | KEEP_APART | RESET_TRANSFORM
+
+/atom/movable/screen/storage/item_holder
+ var/obj/item/our_item
+ vis_flags = NONE
+
+/atom/movable/screen/storage/item_holder/Initialize(mapload, new_master, obj/item/I)
+ . = ..()
+ our_item = I
+ vis_contents += I
+
+/atom/movable/screen/storage/item_holder/Destroy()
+ vis_contents.Cut()
+ our_item = null
+ return ..()
+
+/atom/movable/screen/storage/item_holder/Click(location, control, params)
+ return our_item.Click(location, control, params)
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 1cf0585c0ed4..58b9604e585a 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -153,7 +153,7 @@
var/armor_value = run_armor_check(attack_flag = "melee", armour_penetration = I.armour_penetration) //WS Edit - Simplemobs can have armor
send_item_attack_message(I, user)
if(I.force)
- apply_damage(I.force, I.damtype, break_modifier = I.force, blocked = armor_value) //Bone break modifier = item force
+ apply_damage(I.force, I.damtype, break_modifier = I.force, blocked = armor_value, sharpness = I.get_sharpness()) //Bone break modifier = item force
if(I.damtype == BRUTE)
if(prob(33))
I.add_mob_blood(src)
diff --git a/code/controllers/subsystem/blackmarket.dm b/code/controllers/subsystem/blackmarket.dm
index 6014259278d7..cbd07fcd8fda 100644
--- a/code/controllers/subsystem/blackmarket.dm
+++ b/code/controllers/subsystem/blackmarket.dm
@@ -5,8 +5,8 @@ SUBSYSTEM_DEF(blackmarket)
/// Descriptions for each shipping methods.
var/shipping_method_descriptions = list(
- SHIPPING_METHOD_LAUNCH="Launches the item at your coordinates from across deep space, cheap but you might not recieve your item at all.",
- SHIPPING_METHOD_LTSRBT="Long-To-Short-Range-Bluespace-Transceiver, a machine that prepares items at a remote storage location and then teleports them to the location of the uplink."
+ SHIPPING_METHOD_LAUNCH="Launches the item at your coordinates from across deep space. Cheap, but you might not recieve your item at all. We recommend being stationary in space, away from any large structures, for best results.",
+ SHIPPING_METHOD_LTSRBT="Long-To-Short-Range-Bluespace-Transceiver, a machine that prepares items at a remote storage location and then teleports them to the location of the LTRSBT."
)
/// List of all existing markets.
@@ -29,7 +29,8 @@ SUBSYSTEM_DEF(blackmarket)
if(!markets[M])
stack_trace("SSblackmarket: Item [I] available in market that does not exist.")
continue
- markets[M].add_item(item)
+ markets[M].add_item(item, FALSE)
+
qdel(I)
. = ..()
@@ -47,22 +48,10 @@ SUBSYSTEM_DEF(blackmarket)
switch(purchase.method)
// Find a ltsrbt pad and make it handle the shipping.
if(SHIPPING_METHOD_LTSRBT)
- if(!telepads.len)
- continue
- // Prioritize pads that don't have a cooldown active.
- var/free_pad_found = FALSE
- for(var/obj/machinery/ltsrbt/pad in telepads)
- if(pad.recharge_cooldown)
- continue
- pad.add_to_queue(purchase)
- queued_purchases -= purchase
- free_pad_found = TRUE
- break
-
- if(free_pad_found)
+ if(!purchase.uplink.target)
continue
- var/obj/machinery/ltsrbt/pad = pick(telepads)
+ var/obj/machinery/ltsrbt/pad = purchase.uplink.target
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), "[purchase.uplink] flashes a message noting that the order is being processed by [pad].")
@@ -76,7 +65,7 @@ SUBSYSTEM_DEF(blackmarket)
var/pickedloc = vlevel.get_side_turf(startSide)
var/atom/movable/item = purchase.entry.spawn_item(pickedloc)
- item.throw_at(purchase.uplink, 3, 3, spin = FALSE)
+ item.safe_throw_at(purchase.uplink, 3, 3, spin = FALSE)
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), "[purchase.uplink] flashes a message noting the order is being launched at your coordinates from [dir2text(startSide)].")
@@ -96,7 +85,7 @@ SUBSYSTEM_DEF(blackmarket)
/// Used to add /datum/blackmarket_purchase to queued_purchases var. Returns TRUE when queued.
/datum/controller/subsystem/blackmarket/proc/queue_item(datum/blackmarket_purchase/P)
- if(P.method == SHIPPING_METHOD_LTSRBT && !telepads.len)
+ if(P.method == SHIPPING_METHOD_LTSRBT && !P.uplink.target)
return FALSE
queued_purchases += P
return TRUE
diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm
index 32f404c936a6..dc55c7ca0755 100644
--- a/code/controllers/subsystem/events.dm
+++ b/code/controllers/subsystem/events.dm
@@ -102,7 +102,7 @@ SUBSYSTEM_DEF(events)
// Why the heck is this here! Took me so damn long to find!
/client/proc/forceEvent()
set name = "Trigger Event"
- set category = "Admin.Events"
+ set category = "Event"
if(!holder ||!check_rights(R_FUN))
return
diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm
index f163553f5f9b..3e044a441c0a 100644
--- a/code/controllers/subsystem/explosions.dm
+++ b/code/controllers/subsystem/explosions.dm
@@ -164,7 +164,7 @@ SUBSYSTEM_DEF(explosions)
// 5 explosion power is a (0, 1, 3) explosion.
// 1 explosion power is a (0, 0, 1) explosion.
-/proc/explosion(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0, silent = FALSE, smoke = FALSE)
+/proc/explosion(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0, silent = FALSE, smoke = FALSE, gentle = FALSE)
. = SSexplosions.explode(arglist(args))
#define CREAK_DELAY 5 SECONDS //Time taken for the creak to play after explosion, if applicable.
@@ -177,7 +177,7 @@ SUBSYSTEM_DEF(explosions)
#define FREQ_UPPER 40 //The upper limit for the randomly selected frequency.
#define FREQ_LOWER 25 //The lower of the above.
-/datum/controller/subsystem/explosions/proc/explode(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke)
+/datum/controller/subsystem/explosions/proc/explode(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke, gentle)
epicenter = get_turf(epicenter)
if(!epicenter)
return
@@ -550,6 +550,8 @@ SUBSYSTEM_DEF(explosions)
var/throw_dir = L[2]
var/max_range = L[3]
for(var/atom/movable/A in T)
+ if(QDELETED(A))
+ continue
if(!A.anchored && A.move_resist != INFINITY)
var/atom_throw_range = rand(throw_range, max_range)
var/turf/throw_at = get_ranged_target_turf(A, throw_dir, atom_throw_range)
diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm
index 4440d1c17b33..e8285abafde1 100644
--- a/code/controllers/subsystem/machines.dm
+++ b/code/controllers/subsystem/machines.dm
@@ -47,10 +47,7 @@ SUBSYSTEM_DEF(machines)
while(currentrun.len)
var/obj/machinery/thing = currentrun[currentrun.len]
currentrun.len--
- if(!QDELETED(thing) && thing.process(seconds) != PROCESS_KILL)
- if(thing.use_power)
- thing.auto_use_power() //add back the power state
- else
+ if(QDELETED(thing) || thing.process(seconds) == PROCESS_KILL)
processing -= thing
if (!QDELETED(thing))
thing.datum_flags &= ~DF_ISPROCESSING
diff --git a/code/controllers/subsystem/overmap.dm b/code/controllers/subsystem/overmap.dm
index b96a4944c812..1304eeeb34ea 100644
--- a/code/controllers/subsystem/overmap.dm
+++ b/code/controllers/subsystem/overmap.dm
@@ -133,7 +133,7 @@ SUBSYSTEM_DEF(overmap)
spawn_ruin_levels()
spawn_outpost()
- spawn_initial_ships()
+ //spawn_initial_ships()
/**
* VERY Simple random generation for overmap events, spawns the event in a random turf and sometimes spreads it out similar to ores
@@ -212,6 +212,7 @@ SUBSYSTEM_DEF(overmap)
new found_type(location)
return
+/*
/datum/controller/subsystem/overmap/proc/spawn_initial_ships()
#ifndef UNIT_TESTS
var/datum/map_template/shuttle/selected_template = SSmapping.maplist[pick(SSmapping.maplist)]
@@ -224,10 +225,11 @@ SUBSYSTEM_DEF(overmap)
query_round_map_name.Execute()
qdel(query_round_map_name)
#endif
+*/
/**
* Spawns a controlled ship with the passed template at the template's preferred spawn location.
- * Inteded for ship purchases, etc.
+ * Intended for ship purchases, etc.
*/
/datum/controller/subsystem/overmap/proc/spawn_ship_at_start(datum/map_template/shuttle/template)
//Should never happen, but just in case. This'll delay the next spawn until the current one is done.
@@ -274,7 +276,7 @@ SUBSYSTEM_DEF(overmap)
var/datum/map_zone/mapzone = SSmapping.create_map_zone(encounter_name)
var/datum/virtual_level/vlevel = SSmapping.create_virtual_level(
encounter_name,
- list(ZTRAIT_MINING = TRUE, ZTRAIT_BASETURF = dynamic_datum.default_baseturf),
+ list(ZTRAIT_MINING = TRUE, ZTRAIT_BASETURF = dynamic_datum.default_baseturf, ZTRAIT_GRAVITY = dynamic_datum.gravity),
mapzone,
dynamic_datum.vlevel_width,
dynamic_datum.vlevel_height,
diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm
index 7c2bf71cad6a..b7ef35e63663 100644
--- a/code/controllers/subsystem/pai.dm
+++ b/code/controllers/subsystem/pai.dm
@@ -146,7 +146,7 @@ SUBSYSTEM_DEF(pai)
continue
if(!(ROLE_PAI in G.client.prefs.be_special))
continue
- to_chat(G, "[user] is requesting a pAI personality! Use the pAI button to submit yourself as one.")
+ to_chat(G, "[user.real_name] is requesting a pAI personality! Use the pAI button to submit yourself as one.")
addtimer(CALLBACK(src, PROC_REF(spam_again)), spam_delay)
var/list/available = list()
for(var/datum/paiCandidate/c in SSpai.candidates)
diff --git a/code/controllers/subsystem/processing/movable_physics.dm b/code/controllers/subsystem/processing/movable_physics.dm
new file mode 100644
index 000000000000..65015edbd668
--- /dev/null
+++ b/code/controllers/subsystem/processing/movable_physics.dm
@@ -0,0 +1,24 @@
+///Real fast ticking subsystem for moving movables via modifying pixel_x/y/z
+PROCESSING_SUBSYSTEM_DEF(movablephysics)
+ name = "Movable Physics"
+ wait = 0.05 SECONDS
+ stat_tag = "MP"
+ priority = FIRE_PRIORITY_MOVABLE_PHYSICS
+
+/datum/controller/subsystem/processing/movablephysics/fire(resumed = FALSE)
+ if (!resumed)
+ currentrun = processing.Copy()
+ //cache for sanic speed (lists are references anyways)
+ var/list/current_run = currentrun
+
+ while(current_run.len)
+ var/datum/component/thing = current_run[current_run.len]
+ current_run.len--
+ if(QDELETED(thing))
+ processing -= thing
+ else
+ if(thing.process(wait * 0.1) == PROCESS_KILL)
+ // fully stop so that a future START_PROCESSING will work
+ STOP_PROCESSING(src, thing)
+ if (MC_TICK_CHECK)
+ return
diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm
index 9dc117783af9..c6f9e4404c07 100644
--- a/code/controllers/subsystem/processing/quirks.dm
+++ b/code/controllers/subsystem/processing/quirks.dm
@@ -23,7 +23,6 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
list("Ageusia","Vegetarian","Deviant Tastes"), \
list("Ananas Affinity","Ananas Aversion"), \
list("Alcohol Tolerance","Light Drinker"), \
- list("Clown Fan","Mime Fan", "RILENA Super Fan"), \
list("Bad Touch", "Friendly"))
species_blacklist = list("Blood Deficiency" = list(SPECIES_IPC, SPECIES_JELLYPERSON, SPECIES_PLASMAMAN, SPECIES_VAMPIRE))
diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index 0260e952d10d..e8cd514eb48b 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -47,7 +47,7 @@ SUBSYSTEM_DEF(throwing)
/datum/thrownthing
var/atom/movable/thrownthing
- var/atom/target
+ var/datum/weakref/initial_target
var/turf/target_turf
var/target_zone
var/init_dir
@@ -71,12 +71,13 @@ SUBSYSTEM_DEF(throwing)
var/last_move = 0
-/datum/thrownthing/New(thrownthing, target, target_turf, init_dir, maxrange, speed, thrower, diagonals_first, force, gentle, callback, target_zone)
+/datum/thrownthing/New(thrownthing, target, init_dir, maxrange, speed, thrower, diagonals_first, force, gentle, callback, target_zone)
. = ..()
src.thrownthing = thrownthing
RegisterSignal(thrownthing, COMSIG_PARENT_QDELETING, PROC_REF(on_thrownthing_qdel))
- src.target = target
- src.target_turf = target_turf
+ src.target_turf = get_turf(target)
+ if(target_turf != target)
+ src.initial_target = WEAKREF(target)
src.init_dir = init_dir
src.maxrange = maxrange
src.speed = speed
@@ -87,14 +88,13 @@ SUBSYSTEM_DEF(throwing)
src.callback = callback
src.target_zone = target_zone
-
/datum/thrownthing/Destroy()
SSthrowing.processing -= thrownthing
SSthrowing.currentrun -= thrownthing
thrownthing.throwing = null
thrownthing = null
- target = null
thrower = null
+ initial_target = null
if(callback)
QDEL_NULL(callback) //It stores a reference to the thrownthing, its source. Let's clean that.
return ..()
@@ -109,6 +109,7 @@ SUBSYSTEM_DEF(throwing)
/datum/thrownthing/proc/tick()
var/atom/movable/AM = thrownthing
+ AM.setMovetype(AM.movement_type | THROWN)
if (!isturf(AM.loc) || !AM.throwing)
finalize()
return
@@ -117,9 +118,17 @@ SUBSYSTEM_DEF(throwing)
delayed_time += world.time - last_move
return
- if (dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept
- finalize()
- return
+ var/atom/movable/actual_target = initial_target?.resolve()
+
+ if(dist_travelled) //to catch sneaky things moving on our tile while we slept
+ for(var/atom/movable/obstacle as anything in get_turf(thrownthing))
+ if (obstacle == thrownthing || (obstacle == thrower && !ismob(thrownthing)))
+ continue
+ if(obstacle.pass_flags_self & LETPASSTHROW)
+ continue
+ if (obstacle == actual_target || (obstacle.density && !(obstacle.flags_1 & ON_BORDER_1)))
+ finalize(TRUE, obstacle)
+ return
var/atom/step
@@ -146,10 +155,15 @@ SUBSYSTEM_DEF(throwing)
finalize()
return
- AM.Move(step, get_dir(AM, step), DELAY_TO_GLIDE_SIZE(1 / speed))
+ if(!AM.Move(step, get_dir(AM, step), DELAY_TO_GLIDE_SIZE(1 / speed))) // we hit something during our move...
+ if(AM.throwing) // ...but finalize() wasn't called on Bump() because of a higher level definition that doesn't always call parent.
+ finalize()
+ return
- if (!AM.throwing) // we hit something during our move
- finalize(hit = TRUE)
+ dist_travelled++
+
+ if(actual_target && !(actual_target.pass_flags_self & LETPASSTHROW) && actual_target.loc == AM.loc) // we crossed a movable with no density (e.g. a mouse or APC) we intend to hit anyway.
+ finalize(TRUE, actual_target)
return
dist_travelled++
@@ -158,18 +172,19 @@ SUBSYSTEM_DEF(throwing)
finalize()
return
-/datum/thrownthing/proc/finalize(hit = FALSE, target=null)
+//If the target hasent been hit search for it in the turf we landed on.
+/datum/thrownthing/proc/finalize(hit = FALSE, target = null)
set waitfor = FALSE
//done throwing, either because it hit something or it finished moving
if(!thrownthing)
return
thrownthing.throwing = null
+ thrownthing.setMovetype(thrownthing.movement_type & ~THROWN)
if (!hit)
- for (var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on.
- var/atom/A = thing
- if (A == target)
+ for (var/atom/movable/obstacle as anything in get_turf(thrownthing)) //looking for our target on the turf we land on.
+ if (obstacle == target)
hit = TRUE
- thrownthing.throw_impact(A, src)
+ thrownthing.throw_impact(obstacle, src)
if(QDELETED(thrownthing)) //throw_impact can delete things, such as glasses smashing
return //deletion should already be handled by on_thrownthing_qdel()
break
@@ -195,15 +210,3 @@ SUBSYSTEM_DEF(throwing)
T.zFall(thrownthing)
qdel(src)
-
-/datum/thrownthing/proc/hit_atom(atom/A)
- finalize(hit=TRUE, target=A)
-
-/datum/thrownthing/proc/hitcheck()
- for (var/thing in get_turf(thrownthing))
- var/atom/movable/AM = thing
- if (AM == thrownthing || (AM == thrower && !ismob(thrownthing)))
- continue
- if (AM.density && !(AM.pass_flags_self & LETPASSTHROW) && !(AM.flags_1 & ON_BORDER_1))
- finalize(hit=TRUE, target=AM)
- return TRUE
diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm
index 1e697327c844..25ae750eb0d3 100644
--- a/code/controllers/subsystem/traumas.dm
+++ b/code/controllers/subsystem/traumas.dm
@@ -41,7 +41,7 @@ SUBSYSTEM_DEF(traumas)
"spiders" = typecacheof(list(/mob/living/simple_animal/hostile/poison/giant_spider)),
"security" = typecacheof(list(/mob/living/simple_animal/bot/secbot)),
"lizards" = typecacheof(list(/mob/living/simple_animal/hostile/lizard)),
- "skeletons" = typecacheof(list(/mob/living/simple_animal/hostile/skeleton)),
+ "skeletons" = typecacheof(list(/mob/living/simple_animal/hostile/human/skeleton)),
"snakes" = typecacheof(list(/mob/living/simple_animal/hostile/retaliate/poison/snake)),
"robots" = typecacheof(list(/mob/living/silicon/robot, /mob/living/silicon/ai,
/mob/living/simple_animal/drone, /mob/living/simple_animal/bot, /mob/living/simple_animal/hostile/swarmer)),
@@ -90,10 +90,10 @@ SUBSYSTEM_DEF(traumas)
/obj/item/clothing/under/rank/command/captain, /obj/item/clothing/under/rank/security/head_of_security,
/obj/item/clothing/under/rank/engineering/chief_engineer, /obj/item/clothing/under/rank/medical/chief_medical_officer,
/obj/item/clothing/under/rank/command/head_of_personnel, /obj/item/clothing/under/rank/rnd/research_director,
- /obj/item/clothing/under/rank/security/head_of_security/alt,//WS Edit - Better security jumpsuit sprites
+ /obj/item/clothing/under/rank/security/head_of_security/alt,
/obj/item/clothing/under/rank/rnd/research_director/alt, /obj/item/clothing/under/rank/rnd/research_director/turtleneck,
- /obj/item/clothing/under/rank/command/captain/parade, /obj/item/clothing/under/rank/security/head_of_security/parade,
- /obj/item/clothing/under/rank/security/head_of_security/parade/female, //WS Edit - Better Command Uniforms
+ /obj/item/clothing/under/rank/security/head_of_security/parade,
+ /obj/item/clothing/under/rank/security/head_of_security/parade/female,
/obj/item/clothing/head/helmet/abductor, /obj/item/clothing/suit/armor/abductor/vest, /obj/item/melee/baton/abductor,
/obj/item/storage/belt/military/abductor, /obj/item/gun/energy/alien, /obj/item/abductor/silencer,
/obj/item/abductor/gizmo, /obj/item/clothing/under/rank/centcom/official,
@@ -128,11 +128,10 @@ SUBSYSTEM_DEF(traumas)
/obj/item/melee/cultblade, /obj/item/cult_bastard,
/obj/item/restraints/legcuffs/bola/cult, /obj/item/clothing/suit/space/hardsuit/cult,
/obj/item/clothing/suit/hooded/cultrobes, /obj/item/clothing/head/hooded/cult_hoodie, /obj/effect/rune,
- /obj/item/stack/sheet/runed_metal, /obj/machinery/door/airlock/cult, /obj/singularity/narsie,
+ /obj/machinery/door/airlock/cult, /obj/singularity/narsie,
/obj/item/soulstone,
/obj/item/clothing/suit/wizrobe, /obj/item/clothing/head/wizard, /obj/item/spellbook, /obj/item/staff,
/obj/item/clothing/suit/space/hardsuit/shielded/wizard, /obj/item/clothing/suit/space/hardsuit/wizard,
- /obj/item/gun/magic/staff, /obj/item/gun/magic/wand,
/obj/item/nullrod, /obj/item/clothing/under/rank/civilian/chaplain)),
"aliens" = typecacheof(list(
@@ -149,8 +148,7 @@ SUBSYSTEM_DEF(traumas)
"birds" = typecacheof(list(
/obj/item/clothing/mask/gas/plaguedoctor, /obj/item/reagent_containers/food/snacks/cracker,
/obj/item/clothing/suit/chickensuit, /obj/item/clothing/head/chicken,
- /obj/item/clothing/suit/toggle/owlwings, /obj/item/clothing/under/costume/owl, /obj/item/clothing/mask/gas/owl_mask,
- /obj/item/clothing/head/helmet/space/freedom, /obj/item/clothing/suit/space/freedom)),
+ /obj/item/clothing/suit/toggle/owlwings, /obj/item/clothing/under/costume/owl, /obj/item/clothing/mask/gas/owl_mask)),
"anime" = typecacheof(list(
/obj/item/clothing/under/costume/schoolgirl, /obj/item/katana, /obj/item/reagent_containers/food/snacks/sashimi,
diff --git a/code/datums/achievements/boss_achievements.dm b/code/datums/achievements/boss_achievements.dm
index ca45d5939eec..39b355318f0c 100644
--- a/code/datums/achievements/boss_achievements.dm
+++ b/code/datums/achievements/boss_achievements.dm
@@ -2,10 +2,10 @@
category = "Bosses"
icon = "baseboss"
-/datum/award/achievement/boss/tendril_exterminator
- name = "Tendril Exterminator"
+/datum/award/achievement/boss/nest_exterminator
+ name = "Nest Exterminator"
desc = "Watch your step"
- database_id = BOSS_MEDAL_TENDRIL
+ database_id = BOSS_MEDAL_NEST
icon = "tendril"
/datum/award/achievement/boss/boss_killer
@@ -55,23 +55,11 @@
database_id = BOSS_MEDAL_LEGION
icon = "legion"
-/datum/award/achievement/boss/swarmer_beacon_kill
- name = "Swarm Beacon Killer"
- desc = "GET THEM OFF OF ME!"
- database_id = BOSS_MEDAL_SWARMERS
- icon = "swarmer"
-
/datum/award/achievement/boss/wendigo_kill
name = "Wendigo Killer"
desc = "You've now ruined years of mythical storytelling."
database_id = BOSS_MEDAL_WENDIGO
-/datum/award/achievement/boss/king_goat_kill
- name = "King Goat Killer"
- desc = "The king is dead, long live the king!"
- database_id = BOSS_MEDAL_KINGGOAT
- icon = "goatboss"
-
/datum/award/achievement/boss/blood_miner_crusher
name = "Blood-drunk Miner Crusher"
desc = "I guess he couldn't handle his drink that well."
@@ -112,18 +100,7 @@
desc = "We were many... now we are none."
database_id = BOSS_MEDAL_LEGION_CRUSHER
-/datum/award/achievement/boss/swarmer_beacon_crusher
- name = "Swarm Beacon Crusher"
- desc = "GET THEM OFF OF ME!"
- database_id = BOSS_MEDAL_SWARMERS_CRUSHER
-
/datum/award/achievement/boss/wendigo_crusher
name = "Wendigo Crusher"
desc = "You've now ruined years of mythical storytelling."
database_id = BOSS_MEDAL_WENDIGO_CRUSHER
-
-/datum/award/achievement/boss/king_goat_crusher
- name = "King Goat Crusher"
- desc = "The king is dead, long live the king!"
- database_id = BOSS_MEDAL_KINGGOAT_CRUSHER
- icon = "goatboss"
diff --git a/code/datums/achievements/boss_scores.dm b/code/datums/achievements/boss_scores.dm
index 7cf2fa886183..c0135e6c68a1 100644
--- a/code/datums/achievements/boss_scores.dm
+++ b/code/datums/achievements/boss_scores.dm
@@ -1,7 +1,7 @@
-/datum/award/score/tendril_score
- name = "Tendril Score"
+/datum/award/score/nest_score
+ name = "Nest Score"
desc = "Watch your step"
- database_id = TENDRIL_CLEAR_SCORE
+ database_id = NEST_CLEAR_SCORE
/datum/award/score/boss_score
name = "Bosses Killed"
@@ -43,11 +43,6 @@
desc = "You've killed HOW many?"
database_id = LEGION_SCORE
-/datum/award/score/swarmer_beacon_score
- name = "Swarmer Beacons Killed"
- desc = "You've killed HOW many?"
- database_id = SWARMER_BEACON_SCORE
-
/datum/award/score/wendigo_score
name = "Wendigos Killed"
desc = "You've killed HOW many?"
diff --git a/code/datums/action.dm b/code/datums/action.dm
index ff03b689085d..cdca8729984f 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -86,9 +86,10 @@
if(owner)
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
owner = null
- button.moved = FALSE //so the button appears in its normal position when given to another owner.
- button.locked = FALSE
- button.id = null
+ if(button)
+ button.moved = FALSE //so the button appears in its normal position when given to another owner.
+ button.locked = FALSE
+ button.id = null
/datum/action/proc/Trigger()
if(!IsAvailable())
@@ -207,6 +208,7 @@
/datum/action/item_action/toggle_firemode
name = "Toggle Firemode"
+ icon_icon = 'icons/mob/actions/actions_items.dmi'
/datum/action/item_action/rcl_col
name = "Change Cable Color"
diff --git a/code/datums/blood_type.dm b/code/datums/blood_type.dm
index 3fb4e4198566..847a7d0b55db 100644
--- a/code/datums/blood_type.dm
+++ b/code/datums/blood_type.dm
@@ -52,10 +52,10 @@
color = "#009696"
compatible_types = list(/datum/blood_type/lizard)
-/datum/blood_type/elzuosa
+/datum/blood_type/elzuose
name = "E"
color = "#7fff7f"
- compatible_types = list(/datum/blood_type/elzuosa)
+ compatible_types = list(/datum/blood_type/elzuose)
/datum/blood_type/synthetic //Blood for synthetic/robotic species
name = "Coolant"
diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm
index 069d89f0e7e7..9c10c6f1fd7d 100644
--- a/code/datums/brain_damage/mild.dm
+++ b/code/datums/brain_damage/mild.dm
@@ -50,8 +50,6 @@
owner.derpspeech = min(owner.derpspeech + 5, 25)
if(prob(3))
owner.emote("drool")
- else if(owner.stat == CONSCIOUS && prob(3))
- owner.say(pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage"), forced = "brain damage")
..()
/datum/brain_trauma/mild/dumbness/on_lose()
diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm
index c27e0bd1b7ae..60b4db1d1ce9 100644
--- a/code/datums/chatmessage.dm
+++ b/code/datums/chatmessage.dm
@@ -182,7 +182,7 @@
message.maptext = complete_text
// View the message
- LAZYADDASSOC(owned_by.seen_messages, message_loc, src)
+ LAZYADDASSOCLIST(owned_by.seen_messages, message_loc, src)
owned_by.images |= message
animate(message, alpha = 255, time = CHAT_MESSAGE_SPAWN_TIME)
diff --git a/code/datums/cogbar.dm b/code/datums/cogbar.dm
new file mode 100644
index 000000000000..c03daa33a6ab
--- /dev/null
+++ b/code/datums/cogbar.dm
@@ -0,0 +1,88 @@
+#define COGBAR_ANIMATION_TIME (0.5 SECONDS)
+
+/**
+ * ### Cogbar
+ * Represents that the user is busy doing something.
+ */
+/datum/cogbar
+ /// Who's doing the thing
+ var/mob/user
+ /// The user client
+ var/client/user_client
+ /// The visible element to other players
+ var/obj/effect/overlay/vis/cog
+ /// The blank image that overlaps the cog - hides it from the source user
+ var/image/blank
+ /// The offset of the icon
+ //var/offset_y
+
+
+/datum/cogbar/New(mob/user)
+ src.user = user
+ src.user_client = user.client
+
+//Porting oversized icon offsets later, they have too many other unported dependencies. sorry zephyr
+ //var/list/icon_offsets = user.get_oversized_icon_offsets()
+ //offset_y = icon_offsets["y"]
+
+ add_cog_to_user()
+
+ RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(on_user_delete))
+
+
+/datum/cogbar/Destroy()
+ if(user)
+ SSvis_overlays.remove_vis_overlay(user, user.managed_vis_overlays)
+ user_client?.images -= blank
+
+ user = null
+ user_client = null
+ cog = null
+ QDEL_NULL(blank)
+
+ return ..()
+
+
+/// Adds the cog to the user, visible by other players
+/datum/cogbar/proc/add_cog_to_user()
+ cog = SSvis_overlays.add_vis_overlay(user,
+ icon = 'icons/effects/progressbar.dmi',
+ iconstate = "cog",
+ plane = HIGH_GAME_PLANE,
+ add_appearance_flags = APPEARANCE_UI_IGNORE_ALPHA,
+ unique = TRUE,
+ alpha = 0,
+ )
+ cog.pixel_y = world.icon_size// + offset_y
+ animate(cog, alpha = 255, time = COGBAR_ANIMATION_TIME)
+
+ if(isnull(user_client))
+ return
+
+ blank = image('icons/blanks/32x32.dmi', cog, "nothing")
+ blank.plane = HIGH_GAME_PLANE
+ blank.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
+ blank.override = TRUE
+
+ user_client.images += blank
+
+
+/// Removes the cog from the user
+/datum/cogbar/proc/remove()
+ if(isnull(cog))
+ qdel(src)
+ return
+
+ animate(cog, alpha = 0, time = COGBAR_ANIMATION_TIME)
+
+ QDEL_IN(src, COGBAR_ANIMATION_TIME)
+
+
+/// When the user is deleted, remove the cog
+/datum/cogbar/proc/on_user_delete(datum/source)
+ SIGNAL_HANDLER
+
+ qdel(src)
+
+
+#undef COGBAR_ANIMATION_TIME
diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm
index 1d16391a18e1..d76504787b04 100644
--- a/code/datums/components/_component.dm
+++ b/code/datums/components/_component.dm
@@ -321,10 +321,12 @@
// all the objects that are receiving the signal get the signal this final time.
// AKA: No you can't cancel the signal reception of another object by doing an unregister in the same signal.
var/list/queued_calls = list()
- for(var/datum/listening_datum as anything in target)
- queued_calls[listening_datum] = listening_datum.signal_procs[src][sigtype]
- for(var/datum/listening_datum as anything in queued_calls)
- . |= call(listening_datum, queued_calls[listening_datum])(arglist(arguments))
+ // This should be faster than doing `var/datum/listening_datum as anything in target` as it does not implicitly copy the list
+ for(var/i in 1 to length(target))
+ var/datum/listening_datum = target[i]
+ queued_calls.Add(listening_datum, listening_datum.signal_procs[src][sigtype])
+ for(var/i in 1 to length(queued_calls) step 2)
+ . |= call(queued_calls[i], queued_calls[i + 1])(arglist(arguments))
// The type arg is casted so initial works, you shouldn't be passing a real instance into this
/**
diff --git a/code/datums/components/attachment.dm b/code/datums/components/attachment.dm
new file mode 100644
index 000000000000..01e3abedd80b
--- /dev/null
+++ b/code/datums/components/attachment.dm
@@ -0,0 +1,182 @@
+/datum/component/attachment
+ ///Slot the attachment goes on, also used in descriptions so should be player readable
+ var/slot
+ ///various yes no flags associated with attachments. See defines for these: [_DEFINES/guns.dm]
+ var/attach_features_flags
+ ///Unused so far, should probally handle it in the parent unless you have a specific reason
+ var/list/valid_parent_types
+ var/datum/callback/on_attach
+ var/datum/callback/on_detach
+ var/datum/callback/on_toggle
+ ///Called on the parents preattack
+ var/datum/callback/on_preattack
+ ///Unused...Also a little broken..
+ var/list/datum/action/actions
+ ///Generated if the attachment can toggle, sends COMSIG_ATTACHMENT_TOGGLE
+ var/datum/action/attachment/attachment_toggle_action
+
+/datum/component/attachment/Initialize(
+ slot = ATTACHMENT_SLOT_RAIL,
+ attach_features_flags = ATTACH_REMOVABLE_HAND,
+ valid_parent_types = list(/obj/item/gun),
+ datum/callback/on_attach = null,
+ datum/callback/on_detach = null,
+ datum/callback/on_toggle = null,
+ datum/callback/on_preattack = null,
+ list/signals = null
+ )
+
+ if(!isitem(parent))
+ return COMPONENT_INCOMPATIBLE
+
+ src.slot = slot
+ src.attach_features_flags = attach_features_flags
+ src.valid_parent_types = valid_parent_types
+ src.on_attach = on_attach
+ src.on_detach = on_detach
+ src.on_toggle = on_toggle
+ src.on_preattack = on_preattack
+
+ ADD_TRAIT(parent, TRAIT_ATTACHABLE, "attachable")
+ RegisterSignal(parent, COMSIG_ATTACHMENT_ATTACH, PROC_REF(try_attach))
+ RegisterSignal(parent, COMSIG_ATTACHMENT_DETACH, PROC_REF(try_detach))
+ RegisterSignal(parent, COMSIG_ATTACHMENT_EXAMINE, PROC_REF(handle_examine))
+ RegisterSignal(parent, COMSIG_ATTACHMENT_EXAMINE_MORE, PROC_REF(handle_examine_more))
+ if(attach_features_flags & ATTACH_TOGGLE)
+ RegisterSignal(parent, COMSIG_ATTACHMENT_TOGGLE, PROC_REF(try_toggle))
+ attachment_toggle_action = new /datum/action/attachment(parent)
+ RegisterSignal(parent, COMSIG_ATTACHMENT_PRE_ATTACK, PROC_REF(relay_pre_attack))
+ RegisterSignal(parent, COMSIG_ATTACHMENT_UPDATE_OVERLAY, PROC_REF(update_overlays))
+ RegisterSignal(parent, COMSIG_ATTACHMENT_GET_SLOT, PROC_REF(send_slot))
+
+ for(var/signal in signals)
+ RegisterSignal(parent, signal, signals[signal])
+
+/datum/component/attachment/Destroy(force, silent)
+ REMOVE_TRAIT(parent, TRAIT_ATTACHABLE, "attachable")
+ if(actions && length(actions))
+ var/obj/item/gun/parent = src.parent
+ parent.actions -= actions
+ QDEL_LIST(actions)
+ qdel(attachment_toggle_action)
+ return ..()
+
+/datum/component/attachment/proc/try_toggle(obj/item/parent, obj/item/holder, mob/user)
+ SIGNAL_HANDLER
+ if(attach_features_flags & ATTACH_TOGGLE)
+ INVOKE_ASYNC(src, PROC_REF(do_toggle), parent, holder, user)
+ holder.update_icon()
+ attachment_toggle_action.UpdateButtonIcon()
+
+/datum/component/attachment/proc/do_toggle(obj/item/parent, obj/item/holder, mob/user)
+ if(on_toggle)
+ on_toggle.Invoke(holder, user)
+ return TRUE
+
+ parent.attack_self(user)
+ return TRUE
+
+/datum/component/attachment/proc/update_overlays(obj/item/parent, list/overlays, list/offset)
+ if(!(attach_features_flags & ATTACH_NO_SPRITE))
+ overlays += mutable_appearance(parent.icon, "[parent.icon_state]-attached")
+
+/datum/component/attachment/proc/try_attach(obj/item/parent, obj/item/holder, mob/user, bypass_checks)
+ SIGNAL_HANDLER
+
+ if(!bypass_checks)
+ if(!parent.Adjacent(user) || (length(valid_parent_types) && (holder.type in valid_parent_types)))
+ return FALSE
+
+ if(on_attach && !on_attach.Invoke(holder, user))
+ return FALSE
+
+ parent.forceMove(holder)
+
+ if(attach_features_flags & ATTACH_TOGGLE)
+ holder.actions += list(attachment_toggle_action)
+ attachment_toggle_action.gun = holder
+ attachment_toggle_action.Grant(user)
+
+ return TRUE
+
+/datum/component/attachment/proc/try_detach(obj/item/parent, obj/item/holder, mob/user)
+ SIGNAL_HANDLER
+
+ if(!parent.Adjacent(user) || (valid_parent_types && (holder.type in valid_parent_types)))
+ return FALSE
+
+ if(on_attach && !on_detach.Invoke(holder, user))
+ return FALSE
+
+ if(attach_features_flags & ATTACH_TOGGLE)
+ holder.actions -= list(attachment_toggle_action)
+ attachment_toggle_action.gun = null
+ attachment_toggle_action.Remove(user)
+
+ if(user.can_put_in_hand(parent))
+ user.put_in_hand(parent)
+ return TRUE
+
+ parent.forceMove(holder.drop_location())
+ return TRUE
+
+/datum/component/attachment/proc/handle_examine(obj/item/parent, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+/datum/component/attachment/proc/handle_examine_more(obj/item/parent, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+/datum/component/attachment/proc/relay_pre_attack(obj/item/parent, obj/item/gun, atom/target_atom, mob/user, params)
+ SIGNAL_HANDLER_DOES_SLEEP
+
+ if(on_preattack)
+ return on_preattack.Invoke(gun, target_atom, user, params)
+
+/datum/component/attachment/proc/send_slot(obj/item/parent)
+ SIGNAL_HANDLER
+ return attachment_slot_to_bflag(slot)
+
+/datum/action/attachment
+ name = "Toggle Attachment"
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_CONSCIOUS
+ button_icon_state = null
+ ///Decides where we send our toggle signal for when pressed
+ var/obj/item/gun/gun = null
+
+/datum/action/attachment/New(Target)
+ ..()
+ name = "Toggle [target.name]"
+ button.name = name
+ icon_icon = target.icon
+ button_icon_state = target.icon_state
+
+/datum/action/attachment/Destroy()
+ . = ..()
+ gun = null
+
+/datum/action/attachment/Trigger()
+ ..()
+ SEND_SIGNAL(target, COMSIG_ATTACHMENT_TOGGLE, gun, owner)
+
+/datum/action/attachment/UpdateButtonIcon()
+ icon_icon = target.icon
+ button_icon_state = target.icon_state
+ ..()
+
+//Copied from item action..
+/datum/action/attachment/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force)
+ if(button_icon && button_icon_state)
+ // If set, use the custom icon that we set instead
+ // of the item appearence
+ ..()
+ else if((target && current_button.appearance_cache != target.appearance) || force) //replace with /ref comparison if this is not valid.
+ var/obj/item/I = target
+ var/old_layer = I.layer
+ var/old_plane = I.plane
+ I.layer = FLOAT_LAYER //AAAH
+ I.plane = FLOAT_PLANE //^ what that guy said
+ current_button.cut_overlays()
+ current_button.add_overlay(I)
+ I.layer = old_layer
+ I.plane = old_plane
+ current_button.appearance_cache = I.appearance
diff --git a/code/datums/components/attachment_holder.dm b/code/datums/components/attachment_holder.dm
new file mode 100644
index 000000000000..82968a17604b
--- /dev/null
+++ b/code/datums/components/attachment_holder.dm
@@ -0,0 +1,188 @@
+/datum/component/attachment_holder
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+
+ ///List of things you can attach to the parent
+ var/list/valid_types = null
+ ///How many slots a parent can hold of any one slot
+ var/list/slot_room = null
+ ///Icon offsets, should match the sprite itself so just find the position where it should attach
+ var/list/slot_offsets = null
+ var/list/obj/item/attachments = list()
+
+/datum/component/attachment_holder/Initialize(
+ list/slot_room = null,
+ list/valid_types = null,
+ list/slot_offsets = null,
+ list/default_attachments = null
+ )
+
+ if(!isgun(parent))
+ return COMPONENT_INCOMPATIBLE
+ var/obj/item/gun/parent_gun = parent
+
+ src.slot_room = slot_room
+ src.valid_types = valid_types
+ src.slot_offsets = slot_offsets
+
+ RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(handle_attack))
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(handle_examine))
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE_MORE, PROC_REF(handle_examine_more))
+ RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(handle_qdel))
+ RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(handle_item_pre_attack))
+ RegisterSignal(parent, COMSIG_CLICK_CTRL_SHIFT, PROC_REF(handle_ctrl_shift_click))
+ RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(handle_alt_click))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(handle_overlays))
+
+ if(length(default_attachments))
+ for(var/attachment in default_attachments)
+ var/obj/item/attachment/new_attachment = new attachment(parent_gun.loc)
+ INVOKE_ASYNC(src, PROC_REF(do_attach), new_attachment, null, TRUE)
+
+/datum/component/attachment_holder/proc/handle_overlays(obj/item/parent, list/overlays)
+ SIGNAL_HANDLER
+
+ for(var/obj/item/attachment/attach as anything in attachments)
+ var/slot = SEND_SIGNAL(attach, COMSIG_ATTACHMENT_GET_SLOT)
+ slot = attachment_slot_from_bflag(slot)
+ var/list/attach_overlays = list()
+ SEND_SIGNAL(attach, COMSIG_ATTACHMENT_UPDATE_OVERLAY, attach_overlays)
+ for(var/mutable_appearance/overlay as anything in attach_overlays)
+ if(slot_offsets && slot_offsets[slot])
+ var/matrix/overlay_matrix = new
+ overlay_matrix.Translate(slot_offsets[slot]["x"] - attach.pixel_shift_x, slot_offsets[slot]["y"] - attach.pixel_shift_y)
+ overlay.transform = overlay_matrix
+ overlays += overlay
+
+/datum/component/attachment_holder/proc/handle_qdel()
+ SIGNAL_HANDLER
+ qdel(src)
+
+/datum/component/attachment_holder/Destroy(force, silent)
+ QDEL_LIST(attachments)
+ attachments = null
+ return ..()
+
+/datum/component/attachment_holder/proc/attachments_to_list(only_toggles = FALSE)
+ . = list()
+ for(var/obj/item/attachment/attach as anything in attachments)
+ if(attach.name in .)
+ stack_trace("two attachments with same name; this shouldn't happen and will cause failures")
+ continue
+ if(only_toggles && !(attach.attach_features_flags & ATTACH_TOGGLE))
+ continue
+ .[attach.name] = attach
+
+/datum/component/attachment_holder/proc/handle_ctrl_shift_click(obj/item/parent, mob/user)
+ SIGNAL_HANDLER
+
+ INVOKE_ASYNC(src, PROC_REF(do_attachment_radial), parent, user)
+
+/datum/component/attachment_holder/proc/handle_alt_click(obj/item/parent, mob/user)
+ SIGNAL_HANDLER
+
+ INVOKE_ASYNC(src, PROC_REF(handle_detach), parent, user)
+
+/datum/component/attachment_holder/proc/do_attachment_radial(obj/item/parent, mob/user)
+ var/list/attachments_as_list = attachments_to_list(TRUE)
+ var/selection = show_radial_menu(user, parent, attachments_as_list)
+ var/obj/item/attach = attachments_as_list[selection]
+ if(!attach)
+ return
+ SEND_SIGNAL(attach, COMSIG_ATTACHMENT_TOGGLE, parent, user)
+
+/datum/component/attachment_holder/proc/handle_examine(obj/item/parent, mob/user, list/examine_list)
+ if(length(attachments))
+ examine_list += span_notice("It has [length(attachments)] attachment\s.")
+ for(var/obj/item/attach as anything in attachments)
+ SEND_SIGNAL(attach, COMSIG_ATTACHMENT_EXAMINE, user, examine_list)
+
+/datum/component/attachment_holder/proc/handle_examine_more(obj/item/parent, mob/user, list/examine_list)
+ for(var/key in slot_room)
+ if(slot_room[key])
+ examine_list += span_notice("It has [slot_room[key]] slot\s free for [key] attachments.")
+ if(length(attachments))
+ examine_list += span_notice("It has the following attachments:")
+ for(var/obj/item/attach as anything in attachments)
+ examine_list += span_notice("\t- [attach.name]")
+ if(length(valid_types))
+ examine_list += span_notice("It can accept:")
+ for(var/obj/attach_type as anything in valid_types)
+ examine_list += span_notice("\t- [initial(attach_type.name)]")
+ for(var/obj/item/attach as anything in attachments)
+ SEND_SIGNAL(attach, COMSIG_ATTACHMENT_EXAMINE_MORE, user, examine_list)
+
+/datum/component/attachment_holder/proc/do_attach(obj/item/attachment, mob/user, bypass_checks)
+ var/slot = SEND_SIGNAL(attachment, COMSIG_ATTACHMENT_GET_SLOT)
+ slot = attachment_slot_from_bflag(slot)
+ if(!(attachment.type in valid_types))
+ to_chat(user, span_notice("[attachment] is not a valid attachment for this [parent]!"))
+ return
+ if(!slot_room[slot])
+ to_chat(user, span_notice("[parent] does not contain room for [attachment]!"))
+ return
+ slot_room[slot]--
+ . = SEND_SIGNAL(attachment, COMSIG_ATTACHMENT_ATTACH, parent, user, bypass_checks)
+ if(.)
+ attachments += attachment
+ var/atom/parent = src.parent
+ parent.update_icon()
+
+/datum/component/attachment_holder/proc/do_detach(obj/item/attachment, mob/user)
+ var/slot = SEND_SIGNAL(attachment, COMSIG_ATTACHMENT_GET_SLOT)
+ slot = attachment_slot_from_bflag(slot)
+ if(slot in slot_room)
+ slot_room[slot]++
+ . = SEND_SIGNAL(attachment, COMSIG_ATTACHMENT_DETACH, parent, user)
+ if(.)
+ attachments -= attachment
+ var/atom/parent = src.parent
+ parent.update_icon()
+
+/datum/component/attachment_holder/proc/handle_detach(obj/item/parent, mob/user, obj/item/tool)
+ var/list/tool_list = list()
+ var/list/hand_list = list()
+ for(var/obj/item/attachment/attach as anything in attachments)
+ if(attach.attach_features_flags & ATTACH_REMOVABLE_TOOL)
+ tool_list[attach.name] = attach
+ if(attach.attach_features_flags & ATTACH_REMOVABLE_HAND)
+ hand_list[attach.name] = attach
+ if(tool)
+ if(!length(tool_list))
+ return
+ var/selected = tgui_input_list(user, "Select Attachment", "Detach", tool_list)
+ if(!parent.Adjacent(user) || !selected || !tool || !tool.use_tool(parent, user, 2 SECONDS * tool.toolspeed))
+ return
+ do_detach(tool_list[selected], user)
+ else
+ if(!length(hand_list))
+ return
+ var/selected = tgui_input_list(user, "Select Attachment", "Detach", hand_list)
+ if(do_after(user, 2 SECONDS, parent))
+ do_detach(hand_list[selected], user)
+
+
+/datum/component/attachment_holder/proc/handle_attack(obj/item/parent, obj/item/item, mob/user)
+ SIGNAL_HANDLER
+
+ if(!user.Adjacent(parent))
+ return
+
+ if(item.tool_behaviour == TOOL_CROWBAR && length(attachments))
+ INVOKE_ASYNC(src, PROC_REF(handle_detach), parent, user, item)
+ return TRUE
+
+ if(HAS_TRAIT(item, TRAIT_ATTACHABLE))
+ INVOKE_ASYNC(src, PROC_REF(do_attach), item, user)
+ return TRUE
+
+ for(var/obj/item/attach as anything in attachments)
+ if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_ATTACK, parent, item, user))
+ parent.update_icon()
+ return TRUE
+
+/datum/component/attachment_holder/proc/handle_item_pre_attack(obj/item/parent, atom/target_atom, mob/user, params)
+ SIGNAL_HANDLER
+
+ for(var/obj/item/attach as anything in attachments)
+ if(SEND_SIGNAL(attach, COMSIG_ATTACHMENT_PRE_ATTACK, parent, target_atom, user, params))
+ return TRUE
diff --git a/code/datums/components/bandage.dm b/code/datums/components/bandage.dm
new file mode 100644
index 000000000000..16f6a2f0b059
--- /dev/null
+++ b/code/datums/components/bandage.dm
@@ -0,0 +1,60 @@
+#define TREATMENT_DAMAGE_MOD 2
+
+/datum/component/bandage
+ /// How fast do we stop bleeding?
+ var/bleed_reduction = 0
+ /// How many healing ticks will this bandage apply? Reduced by incoming damage and current bleeding
+ var/lifespan = 300
+ var/bandage_name = "gauze"
+ /// The person this bandage is applied to
+ var/mob/living/mummy
+
+/datum/component/bandage/Initialize(_bleed_reduction, _lifespan, _bandage_name)
+ if(!istype(parent, /obj/item/bodypart))
+ return COMPONENT_INCOMPATIBLE
+ var/obj/item/bodypart/BP = parent
+ mummy = BP.owner
+ if(!mummy)
+ return COMPONENT_INCOMPATIBLE
+ if(_bleed_reduction)
+ bleed_reduction = _bleed_reduction
+ if(_lifespan)
+ lifespan = _lifespan
+ if(_bandage_name)
+ bandage_name = _bandage_name
+ RegisterSignal(mummy, COMSIG_MOB_APPLY_DAMGE, PROC_REF(check_damage))
+ RegisterSignal(mummy, COMSIG_MOB_LIFE, PROC_REF(bandage_effects))
+ RegisterSignal(parent, COMSIG_LIVING_DROP_LIMB, PROC_REF(drop_bandage))
+
+/// Checks if damage to the owner is applied to this limb and reduces lifespan (perforated bandages dont work as well)
+/datum/component/bandage/proc/check_damage(attacker, damage, damagetype = BRUTE, def_zone = null)
+ SIGNAL_HANDLER
+
+ if(parent != mummy.get_bodypart(check_zone(def_zone)))
+ return
+ lifespan -= damage / 100 * initial(lifespan) * TREATMENT_DAMAGE_MOD //take incoming damage as a % of durability
+ if(lifespan <= 0)
+ drop_bandage()
+
+/// Handles healing effects and passive lifespan usage
+/datum/component/bandage/proc/bandage_effects()
+ SIGNAL_HANDLER
+
+ var/obj/item/bodypart/heal_target = parent
+ lifespan -= 1 + heal_target.bleeding // particularly nasty bleeding can burn through dressing faster
+ heal_target.adjust_bleeding(-bleed_reduction)
+ if(lifespan <= 0 || !heal_target.bleeding) //remove treatment once it's no longer able to treat
+ drop_bandage(TRUE)
+
+/// Handles deleting the component when the bandage runs out of lifespan or finishes healing. Special = bandage didn't get torn off
+/datum/component/bandage/proc/drop_bandage(special = FALSE)
+ SIGNAL_HANDLER
+
+ var/obj/item/bodypart/BP = parent
+ if(special)
+ to_chat(mummy, span_notice("The [bandage_name] on your [parse_zone(BP.body_zone)] has [BP.bleeding ? "done what it can" : "stopped the bleeding"]."))
+ else
+ to_chat(mummy, span_warning("The [bandage_name] on your [parse_zone(BP.body_zone)] is damaged beyond use!"))
+ qdel(src)
+
+#undef TREATMENT_DAMAGE_MOD
diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm
index 6923760a7705..3032a98dc85c 100644
--- a/code/datums/components/butchering.dm
+++ b/code/datums/components/butchering.dm
@@ -51,10 +51,14 @@
/datum/component/butchering/proc/startButcher(obj/item/source, mob/living/M, mob/living/user)
to_chat(user, "You begin to butcher [M]...")
playsound(M.loc, butcher_sound, 50, TRUE, -1)
- if(do_mob(user, M, speed) && M.Adjacent(source))
+ if(do_after(user, speed, M) && M.Adjacent(source))
Butcher(user, M)
/datum/component/butchering/proc/startNeckSlice(obj/item/source, mob/living/carbon/human/H, mob/living/user)
+ if(DOING_INTERACTION_WITH_TARGET(user, H))
+ to_chat(user, "You're already interacting with [H]!")
+ return
+
user.visible_message("[user] is slitting [H]'s throat!", \
"You start slicing [H]'s throat!", \
"You hear a cutting noise!", ignored_mobs = H)
@@ -63,17 +67,23 @@
log_combat(user, H, "starts slicing the throat of")
playsound(H.loc, butcher_sound, 50, TRUE, -1)
- if(do_mob(user, H, clamp(500 / source.force, 30, 100)) && H.Adjacent(source))
+ if(do_after(user, clamp(500 / source.force, 30, 100), H) && H.Adjacent(source))
if(H.has_status_effect(/datum/status_effect/neck_slice))
user.show_message("[H]'s neck has already been already cut, you can't make the bleeding any worse!", MSG_VISUAL, \
"Their neck has already been already cut, you can't make the bleeding any worse!")
return
+ var/obj/item/bodypart/throat_in_question = H.get_bodypart(BODY_ZONE_HEAD)
+ if(!throat_in_question)
+ user.show_message("[H]... doesn't have a neck.", MSG_VISUAL, \
+ "They don't seem to have a neck to cut.")
+ return
+
H.visible_message("[user] slits [H]'s throat!", \
"[user] slits your throat...")
log_combat(user, H, "finishes slicing the throat of")
H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD)
- H.bleed_rate = clamp(H.bleed_rate + 20, 0, 30)
+ throat_in_question.adjust_bleeding(20)
H.apply_status_effect(/datum/status_effect/neck_slice)
/datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat)
diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm
index f18002a05bd3..728a3bd44b86 100644
--- a/code/datums/components/chasm.dm
+++ b/code/datums/components/chasm.dm
@@ -18,8 +18,6 @@
/obj/effect/hotspot,
/obj/effect/landmark,
/obj/effect/temp_visual,
- /obj/effect/light_emitter/tendril,
- /obj/effect/collapse,
/obj/effect/particle_effect/ion_trails,
/obj/effect/dummy/phased_mob,
/obj/effect/mapping_helpers,
diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm
index 9ec90bf09eac..95bbae56a904 100644
--- a/code/datums/components/crafting/recipes.dm
+++ b/code/datums/components/crafting/recipes.dm
@@ -16,6 +16,7 @@
if(!(result in reqs))
blacklist += result
+
/**
* Run custom pre-craft checks for this recipe
*
@@ -24,1112 +25,3 @@
*/
/datum/crafting_recipe/proc/check_requirements(mob/user, list/collected_requirements)
return TRUE
-
-/datum/crafting_recipe/IED
- name = "IED"
- result = /obj/item/grenade/iedcasing
- reqs = list(/datum/reagent/fuel = 50,
- /obj/item/stack/cable_coil = 1,
- /obj/item/assembly/igniter = 1,
- /obj/item/reagent_containers/food/drinks/soda_cans = 1)
- parts = list(/obj/item/reagent_containers/food/drinks/soda_cans = 1)
- time = 15
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/lance
- name = "Explosive Lance (Grenade)"
- result = /obj/item/spear/explosive
- reqs = list(/obj/item/spear = 1,
- /obj/item/grenade = 1)
- blacklist = list(/obj/item/spear/bonespear)
- parts = list(/obj/item/spear = 1,
- /obj/item/grenade = 1)
- time = 15
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/strobeshield
- name = "Strobe Shield"
- result = /obj/item/shield/riot/flash
- reqs = list(/obj/item/wallframe/flasher = 1,
- /obj/item/assembly/flash/handheld = 1,
- /obj/item/shield/riot = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/strobeshield/New()
- ..()
- blacklist |= subtypesof(/obj/item/shield/riot/)
-
-/datum/crafting_recipe/molotov
- name = "Molotov"
- result = /obj/item/reagent_containers/food/drinks/bottle/molotov
- reqs = list(/obj/item/reagent_containers/glass/rag = 1,
- /obj/item/reagent_containers/food/drinks/bottle = 1)
- parts = list(/obj/item/reagent_containers/food/drinks/bottle = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/stunprod
- name = "Stunprod"
- result = /obj/item/melee/baton/cattleprod
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/stack/rods = 1,
- /obj/item/assembly/igniter = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/teleprod
- name = "Teleprod"
- result = /obj/item/melee/baton/cattleprod/teleprod
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/stack/rods = 1,
- /obj/item/assembly/igniter = 1,
- /obj/item/stack/ore/bluespace_crystal = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/bola
- name = "Bola"
- result = /obj/item/restraints/legcuffs/bola
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/stack/sheet/metal = 6)
- time = 20//15 faster than crafting them by hand!
- category= CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/gonbola
- name = "Gonbola"
- result = /obj/item/restraints/legcuffs/bola/gonbola
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/stack/sheet/metal = 6,
- /obj/item/stack/sheet/animalhide/gondola = 1)
- time = 40
- category= CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/ed209
- name = "ED209"
- result = /mob/living/simple_animal/bot/secbot/ed209
- reqs = list(/obj/item/robot_suit = 1,
- /obj/item/clothing/head/helmet = 1,
- /obj/item/clothing/suit/armor/vest = 1,
- /obj/item/bodypart/leg/left/robot = 1,
- /obj/item/bodypart/leg/right/robot = 1,
- /obj/item/stack/sheet/metal = 1,
- /obj/item/stack/cable_coil = 1,
- /obj/item/gun/energy/disabler = 1,
- /obj/item/assembly/prox_sensor = 1)
- tools = list(TOOL_WELDER, TOOL_SCREWDRIVER)
- time = 60
- category = CAT_ROBOT
-
-/datum/crafting_recipe/secbot
- name = "Secbot"
- result = /mob/living/simple_animal/bot/secbot
- reqs = list(/obj/item/assembly/signaler = 1,
- /obj/item/clothing/head/helmet/sec = 1,
- /obj/item/melee/baton = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bodypart/r_arm/robot = 1)
- tools = list(TOOL_WELDER)
- time = 60
- category = CAT_ROBOT
-
-/datum/crafting_recipe/cleanbot
- name = "Cleanbot"
- result = /mob/living/simple_animal/bot/cleanbot
- reqs = list(/obj/item/reagent_containers/glass/bucket = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bodypart/r_arm/robot = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/floorbot
- name = "Floorbot"
- result = /mob/living/simple_animal/bot/floorbot
- reqs = list(/obj/item/storage/toolbox = 1,
- /obj/item/stack/tile/plasteel = 10,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bodypart/r_arm/robot = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/medbot
- name = "Medbot"
- result = /mob/living/simple_animal/bot/medbot
- reqs = list(/obj/item/healthanalyzer = 1,
- /obj/item/storage/firstaid = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bodypart/r_arm/robot = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/honkbot
- name = "Honkbot"
- result = /mob/living/simple_animal/bot/honkbot
- reqs = list(/obj/item/storage/box/clown = 1,
- /obj/item/bodypart/r_arm/robot = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bikehorn/ = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/Firebot
- name = "Firebot"
- result = /mob/living/simple_animal/bot/firebot
- reqs = list(/obj/item/extinguisher = 1,
- /obj/item/bodypart/r_arm/robot = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/clothing/head/hardhat/red = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/Vibebot
- name = "Vibebot"
- result = /mob/living/simple_animal/bot/vibebot
- reqs = list(/obj/item/light/bulb = 2,
- /obj/item/bodypart/head/robot = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/toy/crayon = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but
- name = "Pneumatic Cannon"
- result = /obj/item/pneumatic_cannon/ghetto
- tools = list(TOOL_WELDER, TOOL_WRENCH)
- reqs = list(/obj/item/stack/sheet/metal = 4,
- /obj/item/stack/packageWrap = 8,
- /obj/item/pipe = 2)
- time = 50
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/flamethrower
- name = "Flamethrower"
- result = /obj/item/flamethrower
- reqs = list(/obj/item/weldingtool = 1,
- /obj/item/assembly/igniter = 1,
- /obj/item/stack/rods = 1)
- parts = list(/obj/item/assembly/igniter = 1,
- /obj/item/weldingtool = 1)
- tools = list(TOOL_SCREWDRIVER)
- time = 10
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/meteorslug
- name = "Meteorslug Shell"
- result = /obj/item/ammo_casing/shotgun/meteorslug
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /obj/item/rcd_ammo = 1,
- /obj/item/stock_parts/manipulator = 2)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/pulseslug
- name = "Pulse Slug Shell"
- result = /obj/item/ammo_casing/shotgun/pulseslug
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /obj/item/stock_parts/capacitor/adv = 2,
- /obj/item/stock_parts/micro_laser/ultra = 1)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/dragonsbreath
- name = "Dragonsbreath Shell"
- result = /obj/item/ammo_casing/shotgun/dragonsbreath
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, /datum/reagent/phosphorus = 5)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/frag12
- name = "FRAG-12 Shell"
- result = /obj/item/ammo_casing/shotgun/frag12
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /datum/reagent/glycerol = 5,
- /datum/reagent/toxin/acid = 5,
- /datum/reagent/toxin/acid/fluacid = 5)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/ionslug
- name = "Ion Scatter Shell"
- result = /obj/item/ammo_casing/shotgun/ion
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /obj/item/stock_parts/micro_laser/ultra = 1,
- /obj/item/stock_parts/subspace/crystal = 1)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/improvisedslug
- name = "Improvised Shotgun Shell"
- result = /obj/item/ammo_casing/shotgun/improvised
- reqs = list(/obj/item/stack/sheet/metal = 2,
- /obj/item/stack/cable_coil = 1,
- /datum/reagent/fuel = 10)
- tools = list(TOOL_SCREWDRIVER)
- time = 12
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/laserscatter
- name = "Scatter Laser Shell"
- result = /obj/item/ammo_casing/shotgun/laserscatter
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /obj/item/stock_parts/capacitor/adv = 1,
- /obj/item/stock_parts/micro_laser/high = 1)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/ishotgun
- name = "Improvised Shotgun"
- result = /obj/item/gun/ballistic/shotgun/doublebarrel/improvised
- reqs = list(/obj/item/weaponcrafting/receiver = 1,
- /obj/item/pipe = 1,
- /obj/item/weaponcrafting/stock = 1,
- /obj/item/stack/packageWrap = 5)
- tools = list(TOOL_SCREWDRIVER)
- time = 100
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/chainsaw
- name = "Chainsaw"
- result = /obj/item/chainsaw
- reqs = list(/obj/item/circular_saw = 1,
- /obj/item/stack/cable_coil = 3,
- /obj/item/stack/sheet/plasteel = 5)
- tools = list(TOOL_WELDER)
- time = 50
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/spear
- name = "Spear"
- result = /obj/item/spear
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/shard = 1,
- /obj/item/stack/rods = 1)
- parts = list(/obj/item/shard = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/spooky_camera
- name = "Camera Obscura"
- result = /obj/item/camera/spooky
- time = 15
- reqs = list(/obj/item/camera = 1,
- /datum/reagent/water/holywater = 10)
- parts = list(/obj/item/camera = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/skateboard
- name = "Skateboard"
- result = /obj/vehicle/ridden/scooter/skateboard
- time = 60
- reqs = list(/obj/item/stack/sheet/metal = 5,
- /obj/item/stack/rods = 10)
- category = CAT_MISC
-
-/datum/crafting_recipe/scooter
- name = "Scooter"
- result = /obj/vehicle/ridden/scooter
- time = 65
- reqs = list(/obj/item/stack/sheet/metal = 5,
- /obj/item/stack/rods = 12)
- category = CAT_MISC
-
-/datum/crafting_recipe/wheelchair
- name = "Wheelchair"
- result = /obj/vehicle/ridden/wheelchair
- reqs = list(/obj/item/stack/sheet/metal = 4,
- /obj/item/stack/rods = 6)
- time = 100
- category = CAT_MISC
-
-/datum/crafting_recipe/motorized_wheelchair
- name = "Motorized Wheelchair"
- result = /obj/vehicle/ridden/wheelchair/motorized
- reqs = list(/obj/item/stack/sheet/metal = 10,
- /obj/item/stack/rods = 8,
- /obj/item/stock_parts/manipulator = 2,
- /obj/item/stock_parts/capacitor = 1)
- parts = list(/obj/item/stock_parts/manipulator = 2,
- /obj/item/stock_parts/capacitor = 1)
- tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
- time = 200
- category = CAT_MISC
-
-/datum/crafting_recipe/mousetrap
- name = "Mouse Trap"
- result = /obj/item/assembly/mousetrap
- time = 10
- reqs = list(/obj/item/stack/sheet/cardboard = 1,
- /obj/item/stack/rods = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/papersack
- name = "Paper Sack"
- result = /obj/item/storage/box/papersack
- time = 10
- reqs = list(/obj/item/paper = 5)
- category = CAT_MISC
-
-
-/datum/crafting_recipe/flashlight_eyes
- name = "Flashlight Eyes"
- result = /obj/item/organ/eyes/robotic/flashlight
- time = 10
- reqs = list(
- /obj/item/flashlight = 2,
- /obj/item/restraints/handcuffs/cable = 1
- )
- category = CAT_MISC
-
-/datum/crafting_recipe/paperframes
- name = "Paper Frames"
- result = /obj/item/stack/sheet/paperframes/five
- time = 10
- reqs = list(/obj/item/stack/sheet/mineral/wood = 5, /obj/item/paper = 20)
- category = CAT_MISC
-
-/datum/crafting_recipe/naturalpaper
- name = "Hand-Pressed Paper"
- time = 30
- reqs = list(/datum/reagent/water = 50, /obj/item/stack/sheet/mineral/wood = 1)
- tools = list(/obj/item/hatchet)
- result = /obj/item/paper_bin/bundlenatural
- category = CAT_MISC
-
-/datum/crafting_recipe/toysword
- name = "Toy Sword"
- reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
- result = /obj/item/toy/sword
- category = CAT_MISC
-
-/datum/crafting_recipe/blackcarpet
- name = "Black Carpet"
- reqs = list(/obj/item/stack/tile/carpet = 50, /obj/item/toy/crayon/black = 1)
- result = /obj/item/stack/tile/carpet/black/fifty
- category = CAT_MISC
-
-/datum/crafting_recipe/curtain
- name = "Curtains"
- reqs = list(/obj/item/stack/sheet/cotton/cloth = 4, /obj/item/stack/rods = 1)
- result = /obj/structure/curtain/cloth
- category = CAT_MISC
-
-/datum/crafting_recipe/showercurtain
- name = "Shower Curtains"
- reqs = list(/obj/item/stack/sheet/cotton/cloth = 2, /obj/item/stack/sheet/plastic = 2, /obj/item/stack/rods = 1)
- result = /obj/structure/curtain
- category = CAT_MISC
-
-/datum/crafting_recipe/extendohand
- name = "Extendo-Hand"
- reqs = list(/obj/item/bodypart/r_arm/robot = 1, /obj/item/clothing/gloves/boxing = 1)
- result = /obj/item/extendohand
- category = CAT_MISC
-
-/datum/crafting_recipe/chemical_payload
- name = "Chemical Payload (C4)"
- result = /obj/item/bombcore/chemical
- reqs = list(
- /obj/item/stock_parts/matter_bin = 1,
- /obj/item/grenade/c4 = 1,
- /obj/item/grenade/chem_grenade = 2
- )
- parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
- time = 30
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/chemical_payload2
- name = "Chemical Payload (Gibtonite)"
- result = /obj/item/bombcore/chemical
- reqs = list(
- /obj/item/stock_parts/matter_bin = 1,
- /obj/item/gibtonite = 1,
- /obj/item/grenade/chem_grenade = 2
- )
- parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
- time = 50
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/bonearmor
- name = "Bone Armor"
- result = /obj/item/clothing/suit/armor/bone
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 6)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonetalisman
- name = "Bone Talisman"
- result = /obj/item/clothing/accessory/talisman
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2,
- /obj/item/stack/sheet/sinew = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonenecklace
- name = "Hunter's Necklace"
- result = /obj/item/clothing/accessory/wolftalisman
- time = 35
- reqs = list(/obj/item/stack/sheet/bone = 2,
- /obj/item/stack/sheet/sinew = 3,
- /obj/item/crusher_trophy/wolf_ear = 2,
- /obj/item/crusher_trophy/fang = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonecodpiece
- name = "Skull Codpiece"
- result = /obj/item/clothing/accessory/skullcodpiece
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2,
- /obj/item/crusher_trophy/legion_skull = 1,
- /obj/item/stack/sheet/animalhide/goliath_hide = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonestaff
- name = "Legion Staff"
- result = /obj/item/legion_staff
- time = 35
- reqs = list(/obj/item/stack/sheet/bone = 2,
- /obj/item/crusher_trophy/legion_skull = 2,\
- /obj/item/crusher_trophy/dwarf_skull = 1,
- /obj/item/organ/regenerative_core/legion = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/skilt
- name = "Sinew Kilt"
- result = /obj/item/clothing/accessory/skilt
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 1,
- /obj/item/stack/sheet/sinew = 2)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bracers
- name = "Bone Bracers"
- result = /obj/item/clothing/gloves/bracer
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2,
- /obj/item/stack/sheet/sinew = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/skullhelm
- name = "Skull Helmet"
- result = /obj/item/clothing/head/helmet/skull
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 4)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/goliathcloak
- name = "Goliath Cloak"
- result = /obj/item/clothing/suit/hooded/cloak/goliath
- time = 50
- reqs = list(/obj/item/stack/sheet/leather = 2,
- /obj/item/stack/sheet/sinew = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 2) //it takes 4 goliaths to make 1 cloak if the plates are skinned
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/drakecloak
- name = "Ash Drake Armour"
- result = /obj/item/clothing/suit/hooded/cloak/drake
- time = 60
- reqs = list(/obj/item/stack/sheet/bone = 10,
- /obj/item/stack/sheet/sinew = 2,
- /obj/item/stack/sheet/animalhide/ashdrake = 5)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/firebrand
- name = "Firebrand"
- result = /obj/item/match/firebrand
- time = 100 //Long construction time. Making fire is hard work.
- reqs = list(/obj/item/stack/sheet/mineral/wood = 2)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/gold_horn
- name = "Golden Bike Horn"
- result = /obj/item/bikehorn/golden
- time = 20
- reqs = list(/obj/item/stack/sheet/mineral/bananium = 5,
- /obj/item/bikehorn = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/bonedagger
- name = "Bone Dagger"
- result = /obj/item/kitchen/knife/combat/bone
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonespear
- name = "Bone Spear"
- result = /obj/item/spear/bonespear
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 4,
- /obj/item/stack/sheet/sinew = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/boneaxe
- name = "Bone Axe"
- result = /obj/item/fireaxe/boneaxe
- time = 50
- reqs = list(/obj/item/stack/sheet/bone = 6,
- /obj/item/stack/sheet/sinew = 3)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonfire
- name = "Bonfire"
- time = 60
- reqs = list(/obj/item/grown/log = 5)
- parts = list(/obj/item/grown/log = 5)
- blacklist = list(/obj/item/grown/log/steel)
- result = /obj/structure/bonfire
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/rake //Category resorting incoming
- name = "Rake"
- time = 30
- reqs = list(/obj/item/stack/sheet/mineral/wood = 5)
- result = /obj/item/cultivator/rake
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/woodbucket
- name = "Wooden Bucket"
- time = 30
- reqs = list(/obj/item/stack/sheet/mineral/wood = 3)
- result = /obj/item/reagent_containers/glass/bucket/wooden
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/headpike
- name = "Spike Head (Glass Spear)"
- time = 65
- reqs = list(/obj/item/spear = 1,
- /obj/item/bodypart/head = 1)
- parts = list(/obj/item/bodypart/head = 1,
- /obj/item/spear = 1)
- blacklist = list(/obj/item/spear/explosive, /obj/item/spear/bonespear)
- result = /obj/structure/headpike
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/legionpike
- name = "Legion on a Spear"
- time = 55
- reqs = list(/obj/item/spear = 1,
- /obj/item/organ/regenerative_core = 1,
- /obj/item/crusher_trophy/legion_skull = 2)
- result = /obj/structure/legionpike
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/tribal_torch
- name = "Tribal Torch"
- result = /obj/item/candle/tribal_torch
- time = 30
- reqs = list(/obj/item/stack/sheet/mineral/wood = 4)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/headpikebone
- name = "Spike Head (Bone Spear)"
- time = 65
- reqs = list(/obj/item/spear/bonespear = 1,
- /obj/item/bodypart/head = 1)
- parts = list(/obj/item/bodypart/head = 1,
- /obj/item/spear/bonespear = 1)
- result = /obj/structure/headpike/bone
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/pressureplate
- name = "Pressure Plate"
- result = /obj/item/pressure_plate
- time = 5
- reqs = list(/obj/item/stack/sheet/metal = 1,
- /obj/item/stack/tile/plasteel = 1,
- /obj/item/stack/cable_coil = 2,
- /obj/item/assembly/igniter = 1)
- category = CAT_MISC
-
-
-/datum/crafting_recipe/rcl
- name = "Makeshift Rapid Pipe Cleaner Layer"
- result = /obj/item/rcl/ghetto
- time = 40
- tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
- reqs = list(/obj/item/stack/sheet/metal = 15)
- category = CAT_MISC
-
-/datum/crafting_recipe/mummy
- name = "Mummification Bandages (Mask)"
- result = /obj/item/clothing/mask/mummy
- time = 10
- tools = list(/obj/item/nullrod/egyptian)
- reqs = list(/obj/item/stack/sheet/cotton/cloth = 2)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/mummy/body
- name = "Mummification Bandages (Body)"
- result = /obj/item/clothing/under/costume/mummy
- reqs = list(/obj/item/stack/sheet/cotton/cloth = 5)
-
-/datum/crafting_recipe/chaplain_hood
- name = "Follower Hoodie"
- result = /obj/item/clothing/suit/hooded/chaplain_hoodie
- time = 10
- tools = list(/obj/item/clothing/suit/hooded/chaplain_hoodie, /obj/item/storage/book/bible)
- reqs = list(/obj/item/stack/sheet/cotton/cloth = 4)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/guillotine
- name = "Guillotine"
- result = /obj/structure/guillotine
- time = 150 // Building a functioning guillotine takes time
- reqs = list(/obj/item/stack/sheet/plasteel = 3,
- /obj/item/stack/sheet/mineral/wood = 20,
- /obj/item/stack/cable_coil = 10)
- tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
- category = CAT_MISC
-
-/datum/crafting_recipe/aitater
- name = "intelliTater"
- result = /obj/item/aicard/aitater
- time = 30
- tools = list(TOOL_WIRECUTTER)
- reqs = list(/obj/item/aicard = 1,
- /obj/item/reagent_containers/food/snacks/grown/potato = 1,
- /obj/item/stack/cable_coil = 5)
- category = CAT_MISC
-
-/datum/crafting_recipe/aitater/check_requirements(mob/user, list/collected_requirements)
- var/obj/item/aicard/aicard = collected_requirements[/obj/item/aicard][1]
- if(!aicard.AI)
- return TRUE
-
- to_chat(user, "You can't craft an intelliTater with an AI in the card!")
- return FALSE
-
-/datum/crafting_recipe/aispook
- name = "intelliLantern"
- result = /obj/item/aicard/aispook
- time = 30
- tools = list(TOOL_WIRECUTTER)
- reqs = list(/obj/item/aicard = 1,
- /obj/item/reagent_containers/food/snacks/grown/pumpkin = 1,
- /obj/item/stack/cable_coil = 5)
- category = CAT_MISC
-
-/datum/crafting_recipe/ghettojetpack
- name = "Improvised Jetpack"
- result = /obj/item/tank/jetpack/improvised
- time = 30
- reqs = list(/obj/item/tank/internals/oxygen = 2, /obj/item/extinguisher = 1, /obj/item/pipe = 3, /obj/item/stack/cable_coil = MAXCOIL)
- category = CAT_MISC
- tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER)
-
-/datum/crafting_recipe/multiduct
- name = "Multi-layer duct"
- result = /obj/machinery/duct/multilayered
- time = 5
- reqs = list(/obj/item/stack/ducts = 5)
- category = CAT_MISC
- tools = list(TOOL_WELDER)
-
-/datum/crafting_recipe/rib
- name = "Collosal Rib"
- always_availible = FALSE
- reqs = list(
- /obj/item/stack/sheet/bone = 10,
- /datum/reagent/fuel/oil = 5)
- result = /obj/structure/statue/bone/rib
- subcategory = CAT_PRIMAL
-
-/datum/crafting_recipe/skull
- name = "Skull Carving"
- always_availible = FALSE
- reqs = list(
- /obj/item/stack/sheet/bone = 6,
- /datum/reagent/fuel/oil = 5)
- result = /obj/structure/statue/bone/skull
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/halfskull
- name = "Cracked Skull Carving"
- always_availible = FALSE
- reqs = list(
- /obj/item/stack/sheet/bone = 3,
- /datum/reagent/fuel/oil = 5)
- result = /obj/structure/statue/bone/skull/half
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/boneshovel
- name = "Serrated Bone Shovel"
- always_availible = FALSE
- reqs = list(
- /obj/item/stack/sheet/bone = 4,
- /datum/reagent/fuel/oil = 5,
- /obj/item/shovel/spade = 1)
- result = /obj/item/shovel/serrated
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/lasso
- name = "Bone Lasso"
- reqs = list(
- /obj/item/stack/sheet/bone = 1,
- /obj/item/stack/sheet/sinew = 5)
- result = /obj/item/key/lasso
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/gripperoffbrand
- name = "Improvised Gripper Gloves"
- reqs = list(
- /obj/item/clothing/gloves/fingerless = 1,
- /obj/item/stack/tape = 1)
- result = /obj/item/clothing/gloves/tackler/offbrand
- category = CAT_CLOTHING
-
-/*WS edit - Normal BoH
-/datum/crafting_recipe/boh
- name = "Bag of Holding"
- reqs = list(
- /obj/item/bag_of_holding_inert = 1,
- /obj/item/assembly/signaler/anomaly/bluespace = 1)
- result = /obj/item/storage/backpack/holding
- category = CAT_CLOTHING
-*/
-
-/datum/crafting_recipe/ipickaxe
- name = "Improvised Pickaxe"
- reqs = list(
- /obj/item/crowbar = 1,
- /obj/item/kitchen/knife = 1,
- /obj/item/stack/tape = 1)
- result = /obj/item/pickaxe/improvised
- category = CAT_MISC
-
-/datum/crafting_recipe/chem_scanner
- name = "Reagent Scanner"
- time = 30
- tools = list(TOOL_WIRECUTTER, TOOL_SCREWDRIVER)
- reqs = list(
- /obj/item/healthanalyzer = 1,
- /obj/item/stack/cable_coil = 5,
- /obj/item/stock_parts/scanning_module = 1)
- result = /obj/item/reagent_scanner
- category = CAT_MISC
-
-/datum/crafting_recipe/filter
- name = "Seperatory Funnel"
- time = 40
- tools = list(TOOL_WELDER, TOOL_WIRECUTTER)
- reqs = list(
- /obj/item/stack/cable_coil = 1,
- /obj/item/reagent_containers/glass/beaker = 3)
- result = /obj/item/reagent_containers/glass/filter
- category = CAT_MISC
-
-/datum/crafting_recipe/dragonspear
- name = "Dragonslayer's Spear"
- result = /obj/item/spear/dragonspear
- time = 45
- reqs = list(/obj/item/crusher_trophy/ash_spike = 1,
- /obj/item/crusher_trophy/tail_spike = 2,
- /obj/item/stack/sheet/bone = 5,
- /obj/item/stack/sheet/sinew = 3)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/splint
- name = "Makeshift Splint"
- reqs = list(
- /obj/item/stack/rods = 2,
- /obj/item/stack/sheet/cotton/cloth = 4)
- result = /obj/item/stack/medical/splint/ghetto
- category = CAT_MISC
-
-/datum/crafting_recipe/cwzippo
- name = "Clockwork Zippo"
- reqs = list(
- /obj/item/lighter = 1,
- /obj/item/stack/tile/bronze = 5)
- result = /obj/item/lighter/clockwork
- category = CAT_MISC
-
-/datum/crafting_recipe/pipebow
- name = "Pipe Bow"
- result = /obj/item/gun/ballistic/bow/pipe
- reqs = list(/obj/item/pipe = 5,
- /obj/item/stack/sheet/plastic = 15,
- /obj/item/weaponcrafting/silkstring = 10)
- time = 450
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/arrow
- name = "Arrow"
- result = /obj/item/ammo_casing/caseless/arrow/wood
- time = 30
- reqs = list(/obj/item/stack/sheet/mineral/wood = 1,
- /obj/item/stack/sheet/silk = 1,
- /obj/item/stack/rods = 1) //1 metal sheet = 2 rods= 2 arrows
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/bone_arrow
- name = "Bone Arrow"
- result = /obj/item/ammo_casing/caseless/arrow/bone
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 1,
- /obj/item/stack/sheet/sinew = 1,
- /obj/item/ammo_casing/caseless/arrow/ash = 1)
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/ashen_arrow
- name = "Fire hardened arrow"
- result = /obj/item/ammo_casing/caseless/arrow/ash
- tools = list(TOOL_WELDER)
- time = 30
- reqs = list(/obj/item/ammo_casing/caseless/arrow/wood = 1)
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/bronze_arrow
- name = "Bronze arrow"
- result = /obj/item/ammo_casing/caseless/arrow/bronze
- time = 30
- reqs = list(/obj/item/stack/sheet/mineral/wood = 1,
- /obj/item/stack/tile/bronze = 1,
- /obj/item/stack/sheet/silk = 1)
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/heavybonearmor
- name = "Heavy Bone Armor"
- result = /obj/item/clothing/suit/hooded/cloak/bone
- time = 60
- reqs = list(/obj/item/stack/sheet/bone = 8,
- /obj/item/stack/sheet/sinew = 3)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/watcherbola
- name = "Watcher Bola"
- result = /obj/item/restraints/legcuffs/bola/watcher
- time = 30
- reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide = 2,
- /obj/item/restraints/handcuffs/cable/sinew = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/goliathshield
- name = "Goliath shield"
- result = /obj/item/shield/riot/goliath
- time = 60
- reqs = list(/obj/item/stack/sheet/bone = 4,
- /obj/item/stack/sheet/animalhide/goliath_hide = 3)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonesword
- name = "Bone Sword"
- result = /obj/item/claymore/bone
- time = 40
- reqs = list(/obj/item/stack/sheet/bone = 3,
- /obj/item/stack/sheet/sinew = 2)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/hunterbelt
- name = "Hunters Belt"
- result = /obj/item/storage/belt/mining/primitive
- time = 20
- reqs = list(/obj/item/stack/sheet/sinew = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 2)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/quiver
- name = "Quiver"
- result = /obj/item/storage/bag/quiver/empty
- time = 80
- reqs = list(/obj/item/stack/sheet/leather = 3,
- /obj/item/stack/sheet/sinew = 4)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bone_bow
- name = "Bone Bow"
- result = /obj/item/gun/ballistic/bow/ashen
- time = 200
- reqs = list(/obj/item/stack/sheet/bone = 8,
- /obj/item/stack/sheet/sinew = 4)
- category = CAT_PRIMAL
-/datum/crafting_recipe/boneclub
- name = "Bone Club"
- result = /obj/item/melee/baseball_bat/bone
- time = 40
- reqs = list(/obj/item/stack/sheet/bone = 6)
- category = CAT_PRIMAL
-/datum/crafting_recipe/polarbearcloak
- name = "Polar Cloak"
- result = /obj/item/clothing/suit/hooded/cloak/goliath/polar
- time = 50
- reqs = list(/obj/item/stack/sheet/leather = 2,
- /obj/item/stack/sheet/sinew = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 2)
- blacklist = list(/obj/item/stack/sheet/animalhide/goliath_hide)
- category = CAT_PRIMAL
-/datum/crafting_recipe/portableseedextractor
- name = "Portable seed extractor"
- reqs = list(
- /obj/item/storage/bag/plants = 1,
- /obj/item/plant_analyzer = 1,
- /obj/item/stock_parts/manipulator = 1,
- /obj/item/stack/cable_coil = 2)
- result = /obj/item/storage/bag/plants/portaseeder //this will probably mean that you can craft portable seed extractors into themselves, sending the other materials into the void, but we still don't have a solution for recipes involving radios stealing your headset, so this is officially not my problem. "no, Tills-The-Soil, adding more analyzers and micro-manipulators to your portable seed extractor does not make it make more seeds. in fact it does exactly nothing."
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- category = CAT_MISC
-
-/datum/crafting_recipe/zip_pistol
- name = "Zip Pistol"
- result = /obj/item/gun/ballistic/automatic/zip_pistol
- reqs = list(/obj/item/stack/rods = 4,
- /obj/item/pipe = 1,
- /obj/item/stack/cable_coil = 15,
- /obj/item/weaponcrafting/receiver = 1,
- /obj/item/floor_painter = 1,
- /obj/item/stack/packageWrap = 10)
- tools = list(TOOL_SCREWDRIVER)
- time = 100
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/scrap_armor
- name = "Scrap Armor"
- result = /obj/item/clothing/suit/armor/vest/scrap_armor
- time = 60
- reqs = list(
- /obj/item/stack/sheet/metal = 10,
- /obj/item/stack/cable_coil = 20,
- )
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/umbrellared
- name = "Red Drink Umbrella"
- result = /obj/item/garnish/umbrellared
- time = 1 SECONDS
- tools = list(/obj/item/toy/crayon/spraycan)
- reqs = list(
- /obj/item/paper = 1,
- /obj/item/stack/rods = 1)
- category = CAT_DRINK
-
-/datum/crafting_recipe/umbrellablue
- name = "Blue Drink Umbrella"
- result = /obj/item/garnish/umbrellablue
- time = 1 SECONDS
- tools = list(/obj/item/toy/crayon/spraycan)
- reqs = list(
- /obj/item/paper = 1,
- /obj/item/stack/rods = 1)
- category = CAT_DRINK
-
-/datum/crafting_recipe/umbrellagreen
- name = "Green Drink Umbrella"
- result = /obj/item/garnish/umbrellagreen
- time = 1 SECONDS
- tools = list(/obj/item/toy/crayon/spraycan)
- reqs = list(
- /obj/item/paper = 1,
- /obj/item/stack/rods = 1)
- category = CAT_DRINK
-
-/datum/crafting_recipe/ash_garnish
- name = "Ash Garnish"
- result = /obj/item/garnish/ash
- reqs = list(/datum/reagent/ash = 10)
- time = 5
- category = CAT_DRINK
-
-/datum/crafting_recipe/salt_garnish
- name = "Salt Garnish"
- result = /obj/item/garnish/salt
- reqs = list(/datum/reagent/consumable/sodiumchloride = 10)
- time = 5
- category = CAT_DRINK
-
-/datum/crafting_recipe/crystalamulet
- name = "Crystal Amulet"
- result = /obj/item/clothing/neck/crystal_amulet
- time = 4 SECONDS
- reqs = list(/obj/item/strange_crystal = 3)
- category = CAT_MISC
-
-/datum/crafting_recipe/crystalspear
- name = "Crystal Spear"
- result = /obj/item/spear/crystal
- time = 4 SECONDS
- reqs = list(/obj/item/strange_crystal = 2)
- category = CAT_MISC
-
-/datum/crafting_recipe/freezer
- name = "Freezer"
- result = /obj/structure/closet/crate/freezer
- time = 2 SECONDS
- reqs = list(/datum/reagent/consumable/ice = 25,
- /obj/item/stack/sheet/metal = 2)
- category = CAT_MISC
-
-/datum/crafting_recipe/aquarium
- name = "Aquarium"
- result = /obj/structure/aquarium
- time = 10 SECONDS
- reqs = list(/obj/item/stack/sheet/metal = 15,
- /obj/item/stack/sheet/glass = 10,
- /obj/item/aquarium_kit = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/mothplush
- name = "Moth Plushie"
- result = /obj/item/toy/plush/moth
- reqs = list(/obj/item/stack/sheet/animalhide/mothroach = 1,
- /obj/item/organ/heart = 1,
- /obj/item/stack/sheet/cotton/cloth = 3)
- category = CAT_MISC
-
-/datum/crafting_recipe/breakawayflask
- name = "Breakaway Flask"
- result = /obj/item/reagent_containers/food/drinks/breakawayflask
- time = 5 SECONDS
- reqs = list(/obj/item/stack/sheet/glass = 5,
- /obj/item/stack/sheet/mineral/plasma = 1)
- tools = list(TOOL_WELDER)
- category = CAT_DRINK
-
-/datum/crafting_recipe/fermenting_barrel
- name = "Wooden Barrel"
- result = /obj/structure/fermenting_barrel
- reqs = list(/obj/item/stack/sheet/mineral/wood = 8)
- time = 50
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/distiller
- name = "Distiller"
- result = /obj/structure/fermenting_barrel/distiller
- reqs = list(/obj/item/stack/sheet/mineral/wood = 8, /obj/item/stack/sheet/metal = 5, /datum/reagent/srm_bacteria = 30)
- time = 50
- category = CAT_PRIMAL
diff --git a/code/datums/components/crafting/tailoring.dm b/code/datums/components/crafting/recipes/clothing.dm
similarity index 69%
rename from code/datums/components/crafting/tailoring.dm
rename to code/datums/components/crafting/recipes/clothing.dm
index 4caaa55ded29..95b37502bcaf 100644
--- a/code/datums/components/crafting/tailoring.dm
+++ b/code/datums/components/crafting/recipes/clothing.dm
@@ -73,14 +73,6 @@
)
category = CAT_CLOTHING
-/datum/crafting_recipe/hudsunsecremoval
- name = "Security HUD removal"
- result = /obj/item/clothing/glasses/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses = 1)
- category = CAT_CLOTHING
-
/datum/crafting_recipe/hudsunmed
name = "Medical HUDsunglasses"
result = /obj/item/clothing/glasses/hud/health/sunglasses
@@ -93,14 +85,6 @@
)
category = CAT_CLOTHING
-/datum/crafting_recipe/hudsunmedremoval
- name = "Medical HUD removal"
- result = /obj/item/clothing/glasses/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/health/sunglasses = 1)
- category = CAT_CLOTHING
-
/datum/crafting_recipe/hudsundiag
name = "Diagnostic HUDsunglasses"
result = /obj/item/clothing/glasses/hud/diagnostic/sunglasses
@@ -113,14 +97,6 @@
)
category = CAT_CLOTHING
-/datum/crafting_recipe/hudsundiagremoval
- name = "Diagnostic HUD removal"
- result = /obj/item/clothing/glasses/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/diagnostic/sunglasses = 1)
- category = CAT_CLOTHING
-
/datum/crafting_recipe/sciencesunglasses
name = "Science Sunglasses"
result = /obj/item/clothing/glasses/sunglasses/chemical
@@ -133,14 +109,6 @@
)
category = CAT_CLOTHING
-/datum/crafting_recipe/sciencesunglassesremoval
- name = "Science Sunglasses Dissemble"
- result = /obj/item/clothing/glasses/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/sunglasses/reagent = 1)
- category = CAT_CLOTHING
-
/datum/crafting_recipe/medhudglasses // The prescription HUD glasses. This long to have them... #Lianvee
name = "MedicalHUD Prescription Glasses"
result = /obj/item/clothing/glasses/hud/health/prescription
@@ -153,14 +121,6 @@
)
category = CAT_CLOTHING
-/datum/crafting_recipe/medhudglassesremoval
- name = "MedicalHUD Prescription Glasses Disassembly"
- result = /obj/item/clothing/glasses/regular
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/health/prescription = 1)
- category = CAT_CLOTHING
-
/datum/crafting_recipe/sechudglasses
name = "SecurityHUD Prescription Glasses"
result = /obj/item/clothing/glasses/hud/security/prescription
@@ -173,14 +133,6 @@
)
category = CAT_CLOTHING
-/datum/crafting_recipe/sechudglassesremoval
- name = "SecurityHUD Prescription Glasses Disassembly"
- result = /obj/item/clothing/glasses/regular
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/security/prescription = 1)
- category = CAT_CLOTHING
-
/datum/crafting_recipe/mesonglasses
name = "Meson Prescription Glasses"
result = /obj/item/clothing/glasses/meson/prescription
@@ -193,14 +145,6 @@
)
category = CAT_CLOTHING
-/datum/crafting_recipe/mesonglassesremoval
- name = "Meson Prescription Glasses Disassembly"
- result = /obj/item/clothing/glasses/regular
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/meson/prescription = 1)
- category = CAT_CLOTHING
-
/datum/crafting_recipe/scienceglasses
name = "Science Prescription Glasses"
result = /obj/item/clothing/glasses/science/prescription
@@ -213,14 +157,6 @@
)
category = CAT_CLOTHING
-/datum/crafting_recipe/scienceglassesremoval
- name = "Science Prescription Glasses Disassembly"
- result = /obj/item/clothing/glasses/regular
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/science/prescription = 1)
- category = CAT_CLOTHING
-
// Misc.
/datum/crafting_recipe/ghostsheet
name = "Ghost Sheet"
@@ -236,3 +172,21 @@
reqs = list(/obj/item/stack/sheet/leather = 2)
time = 45
category = CAT_CLOTHING
+
+/datum/crafting_recipe/gripperoffbrand
+ name = "Improvised Gripper Gloves"
+ reqs = list(
+ /obj/item/clothing/gloves/fingerless = 1,
+ /obj/item/stack/tape = 1)
+ result = /obj/item/clothing/gloves/tackler/offbrand
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/scrap_armor
+ name = "Scrap Armor"
+ result = /obj/item/clothing/suit/armor/vest/scrap_armor
+ time = 60
+ reqs = list(
+ /obj/item/stack/sheet/metal = 10,
+ /obj/item/stack/cable_coil = 20,
+ )
+ category = CAT_CLOTHING
diff --git a/code/datums/components/crafting/recipes/drink.dm b/code/datums/components/crafting/recipes/drink.dm
new file mode 100644
index 000000000000..5ca6d14814c1
--- /dev/null
+++ b/code/datums/components/crafting/recipes/drink.dm
@@ -0,0 +1,52 @@
+/datum/crafting_recipe/umbrellared
+ name = "Red Drink Umbrella"
+ result = /obj/item/garnish/umbrellared
+ time = 1 SECONDS
+ tools = list(/obj/item/toy/crayon/spraycan)
+ reqs = list(
+ /obj/item/paper = 1,
+ /obj/item/stack/rods = 1)
+ category = CAT_DRINK
+
+/datum/crafting_recipe/umbrellablue
+ name = "Blue Drink Umbrella"
+ result = /obj/item/garnish/umbrellablue
+ time = 1 SECONDS
+ tools = list(/obj/item/toy/crayon/spraycan)
+ reqs = list(
+ /obj/item/paper = 1,
+ /obj/item/stack/rods = 1)
+ category = CAT_DRINK
+
+/datum/crafting_recipe/umbrellagreen
+ name = "Green Drink Umbrella"
+ result = /obj/item/garnish/umbrellagreen
+ time = 1 SECONDS
+ tools = list(/obj/item/toy/crayon/spraycan)
+ reqs = list(
+ /obj/item/paper = 1,
+ /obj/item/stack/rods = 1)
+ category = CAT_DRINK
+
+/datum/crafting_recipe/ash_garnish
+ name = "Ash Garnish"
+ result = /obj/item/garnish/ash
+ reqs = list(/datum/reagent/ash = 10)
+ time = 5
+ category = CAT_DRINK
+
+/datum/crafting_recipe/salt_garnish
+ name = "Salt Garnish"
+ result = /obj/item/garnish/salt
+ reqs = list(/datum/reagent/consumable/sodiumchloride = 10)
+ time = 5
+ category = CAT_DRINK
+
+/datum/crafting_recipe/breakawayflask
+ name = "Breakaway Flask"
+ result = /obj/item/reagent_containers/food/drinks/breakawayflask
+ time = 5 SECONDS
+ reqs = list(/obj/item/stack/sheet/glass = 5,
+ /obj/item/stack/sheet/mineral/plasma = 1)
+ tools = list(TOOL_WELDER)
+ category = CAT_DRINK
diff --git a/code/datums/components/crafting/recipes/misc.dm b/code/datums/components/crafting/recipes/misc.dm
new file mode 100644
index 000000000000..0ed4acb5be78
--- /dev/null
+++ b/code/datums/components/crafting/recipes/misc.dm
@@ -0,0 +1,220 @@
+/datum/crafting_recipe/skateboard
+ name = "Skateboard"
+ result = /obj/vehicle/ridden/scooter/skateboard
+ time = 60
+ reqs = list(/obj/item/stack/sheet/metal = 5,
+ /obj/item/stack/rods = 10)
+ category = CAT_MISC
+
+/datum/crafting_recipe/scooter
+ name = "Scooter"
+ result = /obj/vehicle/ridden/scooter
+ time = 65
+ reqs = list(/obj/item/stack/sheet/metal = 5,
+ /obj/item/stack/rods = 12)
+ category = CAT_MISC
+
+/datum/crafting_recipe/wheelchair
+ name = "Wheelchair"
+ result = /obj/vehicle/ridden/wheelchair
+ reqs = list(/obj/item/stack/sheet/metal = 4,
+ /obj/item/stack/rods = 6)
+ time = 100
+ category = CAT_MISC
+
+/datum/crafting_recipe/motorized_wheelchair
+ name = "Motorized Wheelchair"
+ result = /obj/vehicle/ridden/wheelchair/motorized
+ reqs = list(/obj/item/stack/sheet/metal = 10,
+ /obj/item/stack/rods = 8,
+ /obj/item/stock_parts/manipulator = 2,
+ /obj/item/stock_parts/capacitor = 1)
+ parts = list(/obj/item/stock_parts/manipulator = 2,
+ /obj/item/stock_parts/capacitor = 1)
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
+ time = 200
+ category = CAT_MISC
+
+/datum/crafting_recipe/mousetrap
+ name = "Mouse Trap"
+ result = /obj/item/assembly/mousetrap
+ time = 10
+ reqs = list(/obj/item/stack/sheet/cardboard = 1,
+ /obj/item/stack/rods = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/papersack
+ name = "Paper Sack"
+ result = /obj/item/storage/box/papersack
+ time = 10
+ reqs = list(/obj/item/paper = 5)
+ category = CAT_MISC
+
+/datum/crafting_recipe/flashlight_eyes
+ name = "Flashlight Eyes"
+ result = /obj/item/organ/eyes/robotic/flashlight
+ time = 10
+ reqs = list(
+ /obj/item/flashlight = 2,
+ /obj/item/restraints/handcuffs/cable = 1
+ )
+ category = CAT_MISC
+
+/datum/crafting_recipe/paperframes
+ name = "Paper Frames"
+ result = /obj/item/stack/sheet/paperframes/five
+ time = 10
+ reqs = list(/obj/item/stack/sheet/mineral/wood = 5, /obj/item/paper = 20)
+ category = CAT_MISC
+
+/datum/crafting_recipe/naturalpaper
+ name = "Hand-Pressed Paper"
+ time = 30
+ reqs = list(/datum/reagent/water = 50, /obj/item/stack/sheet/mineral/wood = 1)
+ tools = list(/obj/item/hatchet)
+ result = /obj/item/paper_bin/bundlenatural
+ category = CAT_MISC
+
+/datum/crafting_recipe/curtain
+ name = "Curtains"
+ reqs = list(/obj/item/stack/sheet/cotton/cloth = 4, /obj/item/stack/rods = 1)
+ result = /obj/structure/curtain/cloth
+ category = CAT_MISC
+
+/datum/crafting_recipe/showercurtain
+ name = "Shower Curtains"
+ reqs = list(/obj/item/stack/sheet/cotton/cloth = 2, /obj/item/stack/sheet/plastic = 2, /obj/item/stack/rods = 1)
+ result = /obj/structure/curtain
+ category = CAT_MISC
+
+/datum/crafting_recipe/extendohand
+ name = "Extendo-Hand"
+ reqs = list(/obj/item/bodypart/r_arm/robot = 1, /obj/item/clothing/gloves/boxing = 1)
+ result = /obj/item/extendohand
+ category = CAT_MISC
+
+/datum/crafting_recipe/pressureplate
+ name = "Pressure Plate"
+ result = /obj/item/pressure_plate
+ time = 5
+ reqs = list(/obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/tile/plasteel = 1,
+ /obj/item/stack/cable_coil = 2,
+ /obj/item/assembly/igniter = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/rcl
+ name = "Makeshift Rapid Pipe Cleaner Layer"
+ result = /obj/item/rcl/ghetto
+ time = 40
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
+ reqs = list(/obj/item/stack/sheet/metal = 15)
+ category = CAT_MISC
+
+/datum/crafting_recipe/guillotine
+ name = "Guillotine"
+ result = /obj/structure/guillotine
+ time = 150 // Building a functioning guillotine takes time
+ reqs = list(/obj/item/stack/sheet/plasteel = 3,
+ /obj/item/stack/sheet/mineral/wood = 20,
+ /obj/item/stack/cable_coil = 10)
+ tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
+ category = CAT_MISC
+
+/datum/crafting_recipe/ghettojetpack
+ name = "Improvised Jetpack"
+ result = /obj/item/tank/jetpack/improvised
+ time = 30
+ reqs = list(/obj/item/tank/internals/oxygen = 2, /obj/item/extinguisher = 1, /obj/item/pipe = 3, /obj/item/stack/cable_coil = MAXCOIL)
+ category = CAT_MISC
+ tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER)
+
+/datum/crafting_recipe/multiduct
+ name = "Multi-layer duct"
+ result = /obj/machinery/duct/multilayered
+ time = 5
+ reqs = list(/obj/item/stack/ducts = 5)
+ category = CAT_MISC
+ tools = list(TOOL_WELDER)
+
+/datum/crafting_recipe/ipickaxe
+ name = "Improvised Pickaxe"
+ reqs = list(
+ /obj/item/crowbar = 1,
+ /obj/item/kitchen/knife = 1,
+ /obj/item/stack/tape = 1)
+ result = /obj/item/pickaxe/improvised
+ category = CAT_MISC
+
+/datum/crafting_recipe/chem_scanner
+ name = "Reagent Scanner"
+ time = 30
+ tools = list(TOOL_WIRECUTTER, TOOL_SCREWDRIVER)
+ reqs = list(
+ /obj/item/healthanalyzer = 1,
+ /obj/item/stack/cable_coil = 5,
+ /obj/item/stock_parts/scanning_module = 1)
+ result = /obj/item/reagent_scanner
+ category = CAT_MISC
+
+/datum/crafting_recipe/filter
+ name = "Seperatory Funnel"
+ time = 40
+ tools = list(TOOL_WELDER, TOOL_WIRECUTTER)
+ reqs = list(
+ /obj/item/stack/cable_coil = 1,
+ /obj/item/reagent_containers/glass/beaker = 3)
+ result = /obj/item/reagent_containers/glass/filter
+ category = CAT_MISC
+
+/datum/crafting_recipe/splint
+ name = "Makeshift Splint"
+ reqs = list(
+ /obj/item/stack/rods = 2,
+ /obj/item/stack/sheet/cotton/cloth = 4)
+ result = /obj/item/stack/medical/splint/ghetto
+ category = CAT_MISC
+
+/datum/crafting_recipe/portableseedextractor
+ name = "Portable seed extractor"
+ reqs = list(
+ /obj/item/storage/bag/plants = 1,
+ /obj/item/plant_analyzer = 1,
+ /obj/item/stock_parts/manipulator = 1,
+ /obj/item/stack/cable_coil = 2)
+ result = /obj/item/storage/bag/plants/portaseeder //this will probably mean that you can craft portable seed extractors into themselves, sending the other materials into the void, but we still don't have a solution for recipes involving radios stealing your headset, so this is officially not my problem. "no, Tills-The-Soil, adding more analyzers and micro-manipulators to your portable seed extractor does not make it make more seeds. in fact it does exactly nothing."
+ time = 20
+ tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ category = CAT_MISC
+
+/datum/crafting_recipe/freezer
+ name = "Freezer"
+ result = /obj/structure/closet/crate/freezer
+ time = 2 SECONDS
+ reqs = list(/datum/reagent/consumable/ice = 25,
+ /obj/item/stack/sheet/metal = 2)
+ category = CAT_MISC
+
+/datum/crafting_recipe/aquarium
+ name = "Aquarium"
+ result = /obj/structure/aquarium
+ time = 10 SECONDS
+ reqs = list(/obj/item/stack/sheet/metal = 15,
+ /obj/item/stack/sheet/glass = 10,
+ /obj/item/aquarium_kit = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/mothplush
+ name = "Moth Plushie"
+ result = /obj/item/toy/plush/moth
+ reqs = list(/obj/item/stack/sheet/animalhide/mothroach = 1,
+ /obj/item/organ/heart = 1,
+ /obj/item/stack/sheet/cotton/cloth = 3)
+ category = CAT_MISC
+
+/datum/crafting_recipe/candorupgrade
+ name = "Candor Upgrade"
+ result = /obj/item/gun/ballistic/automatic/pistol/candor/phenex
+ reqs = list(/obj/item/stack/sheet/mineral/hidden = 4,
+ /obj/item/gun/ballistic/automatic/pistol/candor = 1)
+ category = CAT_MISC
diff --git a/code/datums/components/crafting/recipes/robot.dm b/code/datums/components/crafting/recipes/robot.dm
new file mode 100644
index 000000000000..a5558682e86b
--- /dev/null
+++ b/code/datums/components/crafting/recipes/robot.dm
@@ -0,0 +1,86 @@
+/datum/crafting_recipe/ed209
+ name = "ED209"
+ result = /mob/living/simple_animal/bot/secbot/ed209
+ reqs = list(/obj/item/robot_suit = 1,
+ /obj/item/clothing/head/helmet = 1,
+ /obj/item/clothing/suit/armor/vest = 1,
+ /obj/item/bodypart/leg/left/robot = 1,
+ /obj/item/bodypart/leg/right/robot = 1,
+ /obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/cable_coil = 1,
+ /obj/item/gun/energy/disabler = 1,
+ /obj/item/assembly/prox_sensor = 1)
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER)
+ time = 60
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/secbot
+ name = "Secbot"
+ result = /mob/living/simple_animal/bot/secbot
+ reqs = list(/obj/item/assembly/signaler = 1,
+ /obj/item/clothing/head/helmet/sec = 1,
+ /obj/item/melee/baton = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bodypart/r_arm/robot = 1)
+ tools = list(TOOL_WELDER)
+ time = 60
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/cleanbot
+ name = "Cleanbot"
+ result = /mob/living/simple_animal/bot/cleanbot
+ reqs = list(/obj/item/reagent_containers/glass/bucket = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bodypart/r_arm/robot = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/floorbot
+ name = "Floorbot"
+ result = /mob/living/simple_animal/bot/floorbot
+ reqs = list(/obj/item/storage/toolbox = 1,
+ /obj/item/stack/tile/plasteel = 10,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bodypart/r_arm/robot = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/medbot
+ name = "Medbot"
+ result = /mob/living/simple_animal/bot/medbot
+ reqs = list(/obj/item/healthanalyzer = 1,
+ /obj/item/storage/firstaid = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bodypart/r_arm/robot = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/honkbot
+ name = "Honkbot"
+ result = /mob/living/simple_animal/bot/honkbot
+ reqs = list(/obj/item/storage/box/clown = 1,
+ /obj/item/bodypart/r_arm/robot = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bikehorn/ = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/Firebot
+ name = "Firebot"
+ result = /mob/living/simple_animal/bot/firebot
+ reqs = list(/obj/item/extinguisher = 1,
+ /obj/item/bodypart/r_arm/robot = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/clothing/head/hardhat/red = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/Vibebot
+ name = "Vibebot"
+ result = /mob/living/simple_animal/bot/vibebot
+ reqs = list(/obj/item/light/bulb = 2,
+ /obj/item/bodypart/head/robot = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/toy/crayon = 1)
+ time = 40
+ category = CAT_ROBOT
diff --git a/code/datums/components/crafting/recipes/tribal.dm b/code/datums/components/crafting/recipes/tribal.dm
new file mode 100644
index 000000000000..c831b85d7878
--- /dev/null
+++ b/code/datums/components/crafting/recipes/tribal.dm
@@ -0,0 +1,234 @@
+/datum/crafting_recipe/bonearmlet
+ name = "Bone Armlet"
+ result = /obj/item/clothing/accessory/bonearmlet
+ time = 20
+ reqs = list(/obj/item/stack/sheet/bone = 2,
+ /obj/item/stack/sheet/sinew = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/fangnecklace
+ name = "Wolf Fang Necklace"
+ result = /obj/item/clothing/neck/fangnecklace
+ time = 20
+ reqs = list(/obj/item/stack/sheet/sinew = 2,
+ /obj/item/mob_trophy/fang = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonecodpiece
+ name = "Skull Codpiece"
+ result = /obj/item/clothing/accessory/skullcodpiece
+ time = 20
+ reqs = list(/obj/item/stack/sheet/bone = 2,
+ /obj/item/mob_trophy/legion_skull = 1,
+ /obj/item/stack/sheet/animalhide/goliath_hide = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/skilt
+ name = "Sinew Kilt"
+ result = /obj/item/clothing/accessory/skilt
+ time = 20
+ reqs = list(/obj/item/stack/sheet/bone = 1,
+ /obj/item/stack/sheet/sinew = 2)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bracers
+ name = "Bone Bracers"
+ result = /obj/item/clothing/gloves/bracer
+ time = 20
+ reqs = list(/obj/item/stack/sheet/bone = 2,
+ /obj/item/stack/sheet/sinew = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/goliathcloak
+ name = "Goliath Cloak"
+ result = /obj/item/clothing/suit/hooded/cloak/goliath
+ time = 50
+ reqs = list(/obj/item/stack/sheet/leather = 2,
+ /obj/item/stack/sheet/sinew = 2,
+ /obj/item/stack/sheet/animalhide/goliath_hide = 2) //it takes 4 goliaths to make 1 cloak if the plates are skinned
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/drakecloak
+ name = "Ash Drake Armour"
+ result = /obj/item/clothing/suit/hooded/cloak/drake
+ time = 60
+ reqs = list(/obj/item/stack/sheet/bone = 10,
+ /obj/item/stack/sheet/sinew = 2,
+ /obj/item/stack/sheet/animalhide/ashdrake = 5)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonespear
+ name = "Bone Spear"
+ result = /obj/item/spear/bonespear
+ time = 30
+ reqs = list(/obj/item/stack/sheet/bone = 4,
+ /obj/item/stack/sheet/sinew = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/boneaxe
+ name = "Bone Axe"
+ result = /obj/item/fireaxe/boneaxe
+ time = 50
+ reqs = list(/obj/item/stack/sheet/bone = 6,
+ /obj/item/stack/sheet/sinew = 3)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonfire
+ name = "Bonfire"
+ time = 60
+ reqs = list(/obj/item/grown/log = 5)
+ parts = list(/obj/item/grown/log = 5)
+ blacklist = list(/obj/item/grown/log/steel)
+ result = /obj/structure/bonfire
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/headpike
+ name = "Spike Head (Glass Spear)"
+ time = 65
+ reqs = list(/obj/item/spear = 1,
+ /obj/item/bodypart/head = 1)
+ parts = list(/obj/item/bodypart/head = 1,
+ /obj/item/spear = 1)
+ blacklist = list(/obj/item/spear/explosive, /obj/item/spear/bonespear)
+ result = /obj/structure/headpike
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/headpikebone
+ name = "Spike Head (Bone Spear)"
+ time = 65
+ reqs = list(/obj/item/spear/bonespear = 1,
+ /obj/item/bodypart/head = 1)
+ parts = list(/obj/item/bodypart/head = 1,
+ /obj/item/spear/bonespear = 1)
+ result = /obj/structure/headpike/bone
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/lasso
+ name = "Bone Lasso"
+ reqs = list(
+ /obj/item/stack/sheet/bone = 1,
+ /obj/item/stack/sheet/sinew = 5)
+ result = /obj/item/key/lasso
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/heavybonearmor
+ name = "Heavy Bone Armor"
+ result = /obj/item/clothing/suit/hooded/cloak/bone
+ time = 60
+ reqs = list(/obj/item/stack/sheet/bone = 8,
+ /obj/item/stack/sheet/sinew = 3)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/watcherbola
+ name = "Watcher Bola"
+ result = /obj/item/restraints/legcuffs/bola/watcher
+ time = 30
+ reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide = 2,
+ /obj/item/restraints/handcuffs/cable/sinew = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/goliathshield
+ name = "Goliath shield"
+ result = /obj/item/shield/riot/goliath
+ time = 60
+ reqs = list(/obj/item/stack/sheet/bone = 4,
+ /obj/item/stack/sheet/animalhide/goliath_hide = 3)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonesword
+ name = "Bone Sword"
+ result = /obj/item/claymore/bone
+ time = 40
+ reqs = list(/obj/item/stack/sheet/bone = 3,
+ /obj/item/stack/sheet/sinew = 2)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/hunterbelt
+ name = "Hunters Belt"
+ result = /obj/item/storage/belt/mining/primitive
+ time = 20
+ reqs = list(/obj/item/stack/sheet/sinew = 2,
+ /obj/item/stack/sheet/animalhide/goliath_hide = 2)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/quiver
+ name = "Quiver"
+ result = /obj/item/storage/bag/quiver/empty
+ time = 80
+ reqs = list(/obj/item/stack/sheet/leather = 3,
+ /obj/item/stack/sheet/sinew = 4)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bone_bow
+ name = "Bone Bow"
+ result = /obj/item/gun/ballistic/bow/ashen
+ time = 200
+ reqs = list(/obj/item/stack/sheet/bone = 8,
+ /obj/item/stack/sheet/sinew = 4)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/polarbearcloak
+ name = "Polar Cloak"
+ result = /obj/item/clothing/suit/hooded/cloak/goliath/polar
+ time = 50
+ reqs = list(/obj/item/stack/sheet/leather = 2,
+ /obj/item/stack/sheet/sinew = 2,
+ /obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 2)
+ blacklist = list(/obj/item/stack/sheet/animalhide/goliath_hide)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/distiller
+ name = "Distiller"
+ result = /obj/structure/fermenting_barrel/distiller
+ reqs = list(/obj/item/stack/sheet/mineral/wood = 8, /obj/item/stack/sheet/metal = 5, /datum/reagent/srm_bacteria = 30)
+ time = 50
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/crystalamulet
+ name = "Crystal Amulet"
+ result = /obj/item/clothing/neck/crystal_amulet
+ time = 4 SECONDS
+ reqs = list(/obj/item/strange_crystal = 3)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/crystalspear
+ name = "Crystal Spear"
+ result = /obj/item/spear/crystal
+ time = 4 SECONDS
+ reqs = list(/obj/item/strange_crystal = 2)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/mushroom_bowl
+ name = "Mushroom Bowl"
+ result = /obj/item/reagent_containers/glass/bowl/mushroom_bowl
+ reqs = list(/obj/item/reagent_containers/food/snacks/grown/ash_flora/shavings = 5)
+ time = 30
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/charcoal_stylus
+ name = "Charcoal Stylus"
+ result = /obj/item/pen/charcoal
+ reqs = list(/obj/item/stack/sheet/mineral/wood = 1, /datum/reagent/ash = 30)
+ time = 30
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/mushroom_mortar
+ name = "Mushroom Mortar"
+ result = /obj/item/reagent_containers/glass/mortar/mushroom
+ reqs = list(/obj/item/reagent_containers/food/snacks/grown/ash_flora/shavings = 5)
+ time = 30
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/oar
+ name = "Goliath Bone Oar"
+ result = /obj/item/oar
+ reqs = list(/obj/item/stack/sheet/bone = 2)
+ time = 15
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/boat
+ name = "Goliath Hide Boat"
+ result = /obj/vehicle/ridden/lavaboat
+ reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide = 3)
+ time = 50
+ category = CAT_PRIMAL
diff --git a/code/datums/components/crafting/recipes/weapon.dm b/code/datums/components/crafting/recipes/weapon.dm
new file mode 100644
index 000000000000..c1dde04b3650
--- /dev/null
+++ b/code/datums/components/crafting/recipes/weapon.dm
@@ -0,0 +1,317 @@
+/datum/crafting_recipe/IED
+ name = "IED"
+ result = /obj/item/grenade/iedcasing
+ reqs = list(/datum/reagent/fuel = 50,
+ /obj/item/stack/cable_coil = 1,
+ /obj/item/assembly/igniter = 1,
+ /obj/item/reagent_containers/food/drinks/soda_cans = 1)
+ parts = list(/obj/item/reagent_containers/food/drinks/soda_cans = 1)
+ time = 15
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/lance
+ name = "Explosive Lance (Grenade)"
+ result = /obj/item/spear/explosive
+ reqs = list(/obj/item/spear = 1,
+ /obj/item/grenade = 1)
+ blacklist = list(/obj/item/spear/bonespear)
+ parts = list(/obj/item/spear = 1,
+ /obj/item/grenade = 1)
+ time = 15
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/strobeshield
+ name = "Strobe Shield"
+ result = /obj/item/shield/riot/flash
+ reqs = list(/obj/item/wallframe/flasher = 1,
+ /obj/item/assembly/flash/handheld = 1,
+ /obj/item/shield/riot = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/strobeshield/New()
+ ..()
+ blacklist |= subtypesof(/obj/item/shield/riot/)
+
+/datum/crafting_recipe/molotov
+ name = "Molotov"
+ result = /obj/item/reagent_containers/food/drinks/bottle/molotov
+ reqs = list(/obj/item/reagent_containers/glass/rag = 1,
+ /obj/item/reagent_containers/food/drinks/bottle = 1)
+ parts = list(/obj/item/reagent_containers/food/drinks/bottle = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/stunprod
+ name = "Stunprod"
+ result = /obj/item/melee/baton/cattleprod
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/stack/rods = 1,
+ /obj/item/assembly/igniter = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/teleprod
+ name = "Teleprod"
+ result = /obj/item/melee/baton/cattleprod/teleprod
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/stack/rods = 1,
+ /obj/item/assembly/igniter = 1,
+ /obj/item/stack/ore/bluespace_crystal = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/bola
+ name = "Bola"
+ result = /obj/item/restraints/legcuffs/bola
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/stack/sheet/metal = 6)
+ time = 20//15 faster than crafting them by hand!
+ category= CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/gonbola
+ name = "Gonbola"
+ result = /obj/item/restraints/legcuffs/bola/gonbola
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/stack/sheet/metal = 6,
+ /obj/item/stack/sheet/animalhide/gondola = 1)
+ time = 40
+ category= CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but
+ name = "Pneumatic Cannon"
+ result = /obj/item/pneumatic_cannon/ghetto
+ tools = list(TOOL_WELDER, TOOL_WRENCH)
+ reqs = list(/obj/item/stack/sheet/metal = 4,
+ /obj/item/stack/packageWrap = 8,
+ /obj/item/pipe = 2)
+ time = 50
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/flamethrower
+ name = "Flamethrower"
+ result = /obj/item/flamethrower
+ reqs = list(/obj/item/weldingtool = 1,
+ /obj/item/assembly/igniter = 1,
+ /obj/item/stack/rods = 1)
+ parts = list(/obj/item/assembly/igniter = 1,
+ /obj/item/weldingtool = 1)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 10
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/meteorslug
+ name = "Meteorslug Shell"
+ result = /obj/item/ammo_casing/shotgun/meteorslug
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /obj/item/rcd_ammo = 1,
+ /obj/item/stock_parts/manipulator = 2)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/pulseslug
+ name = "Pulse Slug Shell"
+ result = /obj/item/ammo_casing/shotgun/pulseslug
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /obj/item/stock_parts/capacitor = 3,
+ /obj/item/stock_parts/micro_laser = 1,
+ /obj/item/stock_parts/cell = 1,
+ /datum/reagent/lithium = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/dragonsbreath
+ name = "Dragonsbreath Shell"
+ result = /obj/item/ammo_casing/shotgun/dragonsbreath
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, /datum/reagent/phosphorus = 10)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/frag12
+ name = "FRAG-12 Shell"
+ result = /obj/item/ammo_casing/shotgun/frag12
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /datum/reagent/glycerol = 5,
+ /datum/reagent/toxin/acid = 5,
+ /datum/reagent/toxin/acid/fluacid = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/ionslug
+ name = "Ion Scatter Shell"
+ result = /obj/item/ammo_casing/shotgun/ion
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /obj/item/stock_parts/micro_laser = 2,
+ /obj/item/stock_parts/capacitor = 2,
+ /obj/item/stock_parts/scanning_module = 1,
+ /datum/reagent/iron = 5,
+ /datum/reagent/uranium = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/improvisedslug
+ name = "Improvised Shotgun Shell"
+ result = /obj/item/ammo_casing/shotgun/improvised
+ reqs = list(/obj/item/stack/sheet/metal = 2,
+ /obj/item/stack/cable_coil = 1,
+ /datum/reagent/fuel = 10)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 12
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/laserscatter
+ name = "Scatter Laser Shell"
+ result = /obj/item/ammo_casing/shotgun/laserscatter
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /obj/item/stock_parts/capacitor = 1,
+ /obj/item/stock_parts/micro_laser = 3,
+ /obj/item/stock_parts/cell = 1,
+ /datum/reagent/lithium = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/ishotgun
+ name = "Improvised Shotgun"
+ result = /obj/item/gun/ballistic/shotgun/doublebarrel/improvised
+ reqs = list(/obj/item/weaponcrafting/receiver = 1,
+ /obj/item/pipe = 1,
+ /obj/item/weaponcrafting/stock = 1,
+ /obj/item/stack/packageWrap = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 100
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/chainsaw
+ name = "Chainsaw"
+ result = /obj/item/chainsaw
+ reqs = list(/obj/item/circular_saw = 1,
+ /obj/item/stack/cable_coil = 3,
+ /obj/item/stack/sheet/plasteel = 5)
+ tools = list(TOOL_WELDER)
+ time = 50
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/spear
+ name = "Spear"
+ result = /obj/item/spear
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/shard = 1,
+ /obj/item/stack/rods = 1)
+ parts = list(/obj/item/shard = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/chemical_payload
+ name = "Chemical Payload (C4)"
+ result = /obj/item/bombcore/chemical
+ reqs = list(
+ /obj/item/stock_parts/matter_bin = 1,
+ /obj/item/grenade/c4 = 1,
+ /obj/item/grenade/chem_grenade = 2
+ )
+ parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
+ time = 30
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/chemical_payload2
+ name = "Chemical Payload (Gibtonite)"
+ result = /obj/item/bombcore/chemical
+ reqs = list(
+ /obj/item/stock_parts/matter_bin = 1,
+ /obj/item/gibtonite = 1,
+ /obj/item/grenade/chem_grenade = 2
+ )
+ parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
+ time = 50
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/pipebow
+ name = "Pipe Bow"
+ result = /obj/item/gun/ballistic/bow/pipe
+ reqs = list(/obj/item/pipe = 5,
+ /obj/item/stack/sheet/plastic = 15,
+ /obj/item/weaponcrafting/silkstring = 10)
+ time = 450
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/arrow
+ name = "Arrow"
+ result = /obj/item/ammo_casing/caseless/arrow/wood
+ time = 30
+ reqs = list(/obj/item/stack/sheet/mineral/wood = 1,
+ /obj/item/stack/sheet/silk = 1,
+ /obj/item/stack/rods = 1) //1 metal sheet = 2 rods= 2 arrows
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/bone_arrow
+ name = "Bone Arrow"
+ result = /obj/item/ammo_casing/caseless/arrow/bone
+ time = 30
+ reqs = list(/obj/item/stack/sheet/bone = 1,
+ /obj/item/stack/sheet/sinew = 1,
+ /obj/item/ammo_casing/caseless/arrow/ash = 1)
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/ashen_arrow
+ name = "Fire hardened arrow"
+ result = /obj/item/ammo_casing/caseless/arrow/ash
+ tools = list(TOOL_WELDER)
+ time = 30
+ reqs = list(/obj/item/ammo_casing/caseless/arrow/wood = 1)
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/bronze_arrow
+ name = "Bronze arrow"
+ result = /obj/item/ammo_casing/caseless/arrow/bronze
+ time = 30
+ reqs = list(/obj/item/stack/sheet/mineral/wood = 1,
+ /obj/item/stack/tile/bronze = 1,
+ /obj/item/stack/sheet/silk = 1)
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/zip_pistol
+ name = "Zip Pistol"
+ result = /obj/item/gun/ballistic/automatic/zip_pistol
+ reqs = list(/obj/item/stack/rods = 4,
+ /obj/item/pipe = 1,
+ /obj/item/stack/cable_coil = 15,
+ /obj/item/weaponcrafting/receiver = 1,
+ /obj/item/floor_painter = 1,
+ /obj/item/stack/packageWrap = 10)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 100
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
diff --git a/code/datums/components/edible.dm b/code/datums/components/edible.dm
index 3a047d082868..b65a2d8b7e32 100644
--- a/code/datums/components/edible.dm
+++ b/code/datums/components/edible.dm
@@ -33,8 +33,10 @@ Behavior that's still missing from this component that original food items had t
var/datum/callback/after_eat
///Last time we checked for food likes
var/last_check_time
+ ///Color we use when stuffed in things
+ var/filling_color = "#FFFFFF"
-/datum/component/edible/Initialize(list/initial_reagents, food_flags = NONE, foodtypes = NONE, volume = 50, eat_time = 30, list/tastes, list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"), bite_consumption = 2, datum/callback/after_eat)
+/datum/component/edible/Initialize(list/initial_reagents, food_flags = NONE, foodtypes = NONE, volume = 50, eat_time = 30, list/tastes, list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"), bite_consumption = 2, filling_color = "#FFFFFF", datum/callback/after_eat)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
@@ -52,6 +54,7 @@ Behavior that's still missing from this component that original food items had t
src.eatverbs = eatverbs
src.junkiness = junkiness
src.after_eat = after_eat
+ src.filling_color = filling_color
var/atom/owner = parent
@@ -115,7 +118,7 @@ Behavior that's still missing from this component that original food items had t
. = COMPONENT_ITEM_NO_ATTACK //Point of no return I suppose
if(eater == feeder)//If you're eating it yourself.
- if(!do_mob(feeder, eater, eat_time)) //Gotta pass the minimal eat time
+ if(!do_after(feeder, eat_time, eater)) //Gotta pass the minimal eat time
return
var/eatverb = pick(eatverbs)
if(junkiness && eater.satiety < -150 && eater.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(eater, TRAIT_VORACIOUS))
@@ -143,7 +146,7 @@ Behavior that's still missing from this component that original food items had t
eater.visible_message("[feeder] cannot force any more of [parent] down [eater]'s throat!", \
"[feeder] cannot force any more of [parent] down your throat!")
return
- if(!do_mob(feeder, eater)) //Wait 3 seconds before you can feed
+ if(!do_after(feeder, target = eater)) //Wait 3 seconds before you can feed
return
log_combat(feeder, eater, "fed", owner.reagents.log_list())
diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm
index ec1ee58735f9..8cabee42d21c 100644
--- a/code/datums/components/fantasy/suffixes.dm
+++ b/code/datums/components/fantasy/suffixes.dm
@@ -131,11 +131,7 @@
/obj/projectile/bullet/honker = 15,
/obj/projectile/temp = 15,
/obj/projectile/ion = 15,
- /obj/projectile/magic/door = 15,
- /obj/projectile/magic/locker = 15,
- /obj/projectile/magic/fetch = 15,
/obj/projectile/beam/emitter = 15,
- /obj/projectile/magic/flying = 15,
/obj/projectile/energy/net = 15,
/obj/projectile/bullet/incendiary/c9mm = 15,
/obj/projectile/temp/hot = 15,
diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm
index 3c006073304c..6f2a34e50ea5 100644
--- a/code/datums/components/forensics.dm
+++ b/code/datums/components/forensics.dm
@@ -192,4 +192,4 @@
return
if(isitem(parent))
var/obj/item/I = parent
- I.AddElement(/datum/element/decal/blood, initial(I.icon) || I.icon, initial(I.icon_state) || I.icon_state, _color = get_blood_dna_color(blood_DNA))
+ I.AddElement(/datum/element/decal/blood, I.icon, I.icon_state, _color = get_blood_dna_color(blood_DNA))
diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm
index 177093a49fef..f3050c7ab76c 100644
--- a/code/datums/components/fullauto.dm
+++ b/code/datums/components/fullauto.dm
@@ -8,7 +8,7 @@
var/turf/target_loc //For dealing with locking on targets due to BYOND engine limitations (the mouse input only happening when mouse moves).
var/autofire_stat = AUTOFIRE_STAT_IDLE
var/mouse_parameters
- var/autofire_shot_delay = 0.3 SECONDS //Time between individual shots.
+ var/autofire_shot_delay = 0.1 SECONDS //Time between individual shots.
var/mouse_status = AUTOFIRE_MOUSEUP //This seems hacky but there can be two MouseDown() without a MouseUp() in between if the user holds click and uses alt+tab, printscreen or similar.
var/enabled = TRUE
@@ -22,6 +22,7 @@
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(wake_up))
RegisterSignal(parent, COMSIG_GUN_DISABLE_AUTOFIRE, PROC_REF(disable_autofire))
RegisterSignal(parent, COMSIG_GUN_ENABLE_AUTOFIRE, PROC_REF(enable_autofire))
+ RegisterSignal(parent, COMSIG_GUN_SET_AUTOFIRE_SPEED, PROC_REF(set_autofire_speed))
if(_autofire_shot_delay)
autofire_shot_delay = _autofire_shot_delay
if(autofire_stat == AUTOFIRE_STAT_IDLE && ismob(gun.loc))
@@ -161,7 +162,7 @@
if(isgun(parent))
var/obj/item/gun/shoota = parent
- if(!shoota.on_autofire_start(shooter)) //This is needed because the minigun has a do_after before firing and signals are async.
+ if(!shoota.on_autofire_start(shooter=shooter)) //This is needed because the minigun has a do_after before firing and signals are async.
stop_autofiring()
return
if(autofire_stat != AUTOFIRE_STAT_FIRING)
@@ -242,12 +243,12 @@
// Gun procs.
-/obj/item/gun/proc/on_autofire_start(mob/living/shooter)
- if(semicd || shooter.stat || !can_trigger_gun(shooter))
- return FALSE
- if(!can_shoot())
- shoot_with_empty_chamber(shooter)
+/obj/item/gun/proc/on_autofire_start(datum/source, atom/target, mob/living/shooter, params)
+ if(current_cooldown || shooter.stat)
return FALSE
+ if(!can_shoot()) //we call pre_fire so bolts/slides work correctly
+ INVOKE_ASYNC(src, PROC_REF(do_autofire_shot), source, target, shooter, params)
+ return NONE
if(weapon_weight == WEAPON_HEAVY && (!wielded))
to_chat(shooter, "You need a more secure grip to fire [src]!")
return FALSE
@@ -262,32 +263,29 @@
/obj/item/gun/proc/do_autofire(datum/source, atom/target, mob/living/shooter, params)
SIGNAL_HANDLER
- if(semicd || shooter.incapacitated())
+ if(current_cooldown || shooter.incapacitated())
return NONE
if(weapon_weight == WEAPON_HEAVY && (!wielded))
to_chat(shooter, "You need a more secure grip to fire [src]!")
return NONE
- if(!can_shoot())
- shoot_with_empty_chamber(shooter)
+ if(!can_shoot()) //we stop if we cant shoot but also calling pre_fire so the bolt works correctly if it's a weird open bolt weapon.
+ INVOKE_ASYNC(src, PROC_REF(do_autofire_shot), source, target, shooter, params)
return NONE
INVOKE_ASYNC(src, PROC_REF(do_autofire_shot), source, target, shooter, params)
return COMPONENT_AUTOFIRE_SHOT_SUCCESS //All is well, we can continue shooting.
/obj/item/gun/proc/do_autofire_shot(datum/source, atom/target, mob/living/shooter, params)
- var/obj/item/gun/akimbo_gun = shooter.get_inactive_held_item()
- var/bonus_spread = 0
- if(istype(akimbo_gun) && weapon_weight < WEAPON_MEDIUM)
- if(akimbo_gun.weapon_weight < WEAPON_MEDIUM && akimbo_gun.can_trigger_gun(shooter))
- bonus_spread = dual_wield_spread
- addtimer(CALLBACK(akimbo_gun, TYPE_PROC_REF(/obj/item/gun, process_fire), target, shooter, TRUE, params, null, bonus_spread), 1)
- process_fire(target, shooter, TRUE, params, null, bonus_spread)
-
-/datum/component/automatic_fire/proc/disable_autofire()
+ pre_fire(target, shooter, TRUE, params, null) //dual wielding is handled here
+
+/datum/component/automatic_fire/proc/disable_autofire(datum/source)
enabled = FALSE
-/datum/component/automatic_fire/proc/enable_autofire()
+/datum/component/automatic_fire/proc/enable_autofire(datum/source)
enabled = TRUE
+/datum/component/automatic_fire/proc/set_autofire_speed(datum/source, newspeed)
+ autofire_shot_delay = newspeed
+
#undef AUTOFIRE_MOUSEUP
#undef AUTOFIRE_MOUSEDOWN
diff --git a/code/datums/components/gunpoint.dm b/code/datums/components/gunpoint.dm
index 2865865c98ab..85701e9c7626 100644
--- a/code/datums/components/gunpoint.dm
+++ b/code/datums/components/gunpoint.dm
@@ -40,7 +40,7 @@
if(istype(weapon, /obj/item/gun/ballistic/rocketlauncher) && weapon.chambered)
shooter.client.give_award(/datum/award/achievement/misc/rocket_holdup, shooter)
- target.do_alert_animation(target)
+ target.do_alert_animation()
target.playsound_local(target.loc, 'sound/machines/chime.ogg', 50, TRUE)
SEND_SIGNAL(target, COMSIG_ADD_MOOD_EVENT, "gunpoint", /datum/mood_event/gunpoint)
@@ -126,10 +126,7 @@
if(weapon.chambered && weapon.chambered.BB)
weapon.chambered.BB.damage *= damage_mult
- if(weapon.check_botched(shooter))
- return
-
- weapon.process_fire(target, shooter)
+ weapon.pre_fire(target, shooter)
qdel(src)
/datum/component/gunpoint/proc/cancel()
diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm
index de334598f141..3434c741dba8 100644
--- a/code/datums/components/mood.dm
+++ b/code/datums/components/mood.dm
@@ -321,7 +321,7 @@
/datum/component/mood/proc/HandleNutrition()
var/mob/living/L = parent
- if(isethereal(L))
+ if(iselzuose(L))
HandleCharge(L)
if(HAS_TRAIT(L, TRAIT_NOHUNGER))
return FALSE //no mood events for nutrition
@@ -338,19 +338,19 @@
add_event(null, "nutrition", /datum/mood_event/starving)
/datum/component/mood/proc/HandleCharge(mob/living/carbon/human/H)
- var/datum/species/ethereal/E = H.dna.species
+ var/datum/species/elzuose/E = H.dna.species
switch(E.get_charge(H))
- if(ETHEREAL_CHARGE_NONE to ETHEREAL_CHARGE_LOWPOWER)
+ if(ELZUOSE_CHARGE_NONE to ELZUOSE_CHARGE_LOWPOWER)
add_event(null, "charge", /datum/mood_event/decharged)
- if(ETHEREAL_CHARGE_LOWPOWER to ETHEREAL_CHARGE_NORMAL)
+ if(ELZUOSE_CHARGE_LOWPOWER to ELZUOSE_CHARGE_NORMAL)
add_event(null, "charge", /datum/mood_event/lowpower)
- if(ETHEREAL_CHARGE_NORMAL to ETHEREAL_CHARGE_ALMOSTFULL)
+ if(ELZUOSE_CHARGE_NORMAL to ELZUOSE_CHARGE_ALMOSTFULL)
clear_event(null, "charge")
- if(ETHEREAL_CHARGE_ALMOSTFULL to ETHEREAL_CHARGE_FULL)
+ if(ELZUOSE_CHARGE_ALMOSTFULL to ELZUOSE_CHARGE_FULL)
add_event(null, "charge", /datum/mood_event/charged)
- if(ETHEREAL_CHARGE_FULL to ETHEREAL_CHARGE_OVERLOAD)
+ if(ELZUOSE_CHARGE_FULL to ELZUOSE_CHARGE_OVERLOAD)
add_event(null, "charge", /datum/mood_event/overcharged)
- if(ETHEREAL_CHARGE_OVERLOAD to ETHEREAL_CHARGE_DANGEROUS)
+ if(ELZUOSE_CHARGE_OVERLOAD to ELZUOSE_CHARGE_DANGEROUS)
add_event(null, "charge", /datum/mood_event/supercharged)
/datum/component/mood/proc/check_area_mood(datum/source, area/A)
diff --git a/code/datums/components/movable_physics.dm b/code/datums/components/movable_physics.dm
new file mode 100644
index 000000000000..114cac29f24b
--- /dev/null
+++ b/code/datums/components/movable_physics.dm
@@ -0,0 +1,151 @@
+#define PHYSICS_GRAV_STANDARD 9.80665
+
+///Remove the component as soon as there's zero velocity, useful for movables that will no longer move after being initially moved (blood splatters)
+#define QDEL_WHEN_NO_MOVEMENT (1<<0)
+
+///Stores information related to the movable's physics and keeping track of relevant signals to trigger movement
+/datum/component/movable_physics
+ ///Modifies the pixel_x/pixel_y of an object every process()
+ var/horizontal_velocity
+ ///Modifies the pixel_z of an object every process(), movables aren't Move()'d into another turf if pixel_z exceeds 16, so try not to supply a super high vertical value if you don't want the movable to clip through multiple turfs
+ var/vertical_velocity
+ ///The horizontal_velocity is reduced by this every process(), this doesn't take into account the object being in the air vs gravity pushing it against the ground
+ var/horizontal_friction
+ ///The vertical_velocity is reduced by this every process()
+ var/z_gravity
+ ///The pixel_z that the object will no longer be influenced by gravity for a 32x32 turf, keep this value between -16 to 0 so it's visuals matches up with it physically being in the turf
+ var/z_floor
+ ///The angle of the path the object takes on the x/y plane
+ var/angle_of_movement
+ ///Flags for turning on certain physic properties, see the top of the file for more information on flags
+ var/physic_flags
+ ///The cached animate_movement of the parent; any kind of gliding when doing Move() makes the physics look derpy, so we'll just make Move() be instant
+ var/cached_animate_movement
+ ///The sound effect to play when bouncing off of something
+ var/bounce_sound
+
+ var/numbounce = 1
+
+/datum/component/movable_physics/Initialize(_horizontal_velocity = 0, _vertical_velocity = 0, _horizontal_friction = 0, _z_gravity = 0, _z_floor = 0, _angle_of_movement = 0, _physic_flags = 0, _bounce_sound)
+ . = ..()
+ if(!ismovable(parent))
+ return COMPONENT_INCOMPATIBLE
+ RegisterSignal(parent, COMSIG_MOVABLE_IMPACT, PROC_REF(throw_impact_ricochet), override = TRUE)
+ horizontal_velocity = _horizontal_velocity
+ vertical_velocity = _vertical_velocity
+ horizontal_friction = _horizontal_friction
+ z_gravity = _z_gravity
+ z_floor = _z_floor
+ angle_of_movement = _angle_of_movement
+ physic_flags = _physic_flags
+ bounce_sound = _bounce_sound
+ if(vertical_velocity || horizontal_velocity)
+ start_movement()
+
+///Let's get moving
+/datum/component/movable_physics/proc/start_movement()
+ var/atom/movable/moving_atom = parent
+ cached_animate_movement = moving_atom.animate_movement
+ moving_atom.animate_movement = NO_STEPS
+ START_PROCESSING(SSmovablephysics, src)
+ moving_atom.SpinAnimation(speed = 1 SECONDS, loops = 1)
+
+///Alright it's time to stop
+/datum/component/movable_physics/proc/stop_movement()
+ var/atom/movable/moving_atom = parent
+ moving_atom.animate_movement = cached_animate_movement
+ STOP_PROCESSING(SSmovablephysics, src)
+ if(physic_flags & QDEL_WHEN_NO_MOVEMENT)
+ qdel(src)
+
+/datum/component/movable_physics/UnregisterFromParent()
+ UnregisterSignal(parent, COMSIG_MOVABLE_IMPACT)
+
+/datum/component/movable_physics/proc/throw_impact_ricochet(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum)
+ SIGNAL_HANDLER
+ var/atom/movable/atom_source = source
+ ricochet(atom_source, Get_Angle(atom_source, throwingdatum.target_turf))
+
+/datum/component/movable_physics/proc/z_floor_bounce(atom/movable/moving_atom)
+ angle_of_movement += rand(-3000, 3000) / 100
+ var/turf/a_turf = get_turf(moving_atom)
+ if(istype(moving_atom, /obj/item/ammo_casing) && !bounce_sound)
+ playsound(moving_atom, a_turf.bullet_bounce_sound, 50, TRUE)
+ else
+ playsound(moving_atom, bounce_sound, 50, TRUE)
+ moving_atom.SpinAnimation(speed = 1 SECONDS / numbounce, loops = 1)
+ moving_atom.pixel_z = z_floor
+ horizontal_velocity = max(0, horizontal_velocity + (vertical_velocity * -0.8))
+ vertical_velocity = max(0, ((vertical_velocity * -0.8) - 0.2))
+ numbounce += 0.5
+
+/datum/component/movable_physics/proc/ricochet(atom/movable/moving_atom, bounce_angle)
+ angle_of_movement = ((180 - bounce_angle) - angle_of_movement)
+ if(angle_of_movement < 0)
+ angle_of_movement += 360
+ //var/turf/a_turf = get_turf(moving_atom)
+ //playsound(src, a_turf.bullet_bounce_sound, 50, TRUE)
+
+/datum/component/movable_physics/proc/fix_angle(angle, atom/moving_atom)//fixes an angle below 0 or above 360
+ if(!(angle_of_movement > 360) && !(angle_of_movement < 0))
+ return angle //early return if it doesn't need to change
+ var/new_angle
+ if(angle_of_movement > 360)
+ new_angle = angle_of_movement - 360
+ if(angle_of_movement < 0)
+ new_angle = angle_of_movement + 360
+ return new_angle
+
+/datum/component/movable_physics/process(delta_time)
+ var/atom/movable/moving_atom = parent
+ var/turf/location = get_turf(moving_atom)
+
+ angle_of_movement = fix_angle(angle_of_movement, moving_atom)
+ if(horizontal_velocity <= 0 && moving_atom.pixel_z == 0)
+ horizontal_velocity = 0
+ stop_movement()
+ return
+
+ moving_atom.pixel_x += (horizontal_velocity * (sin(angle_of_movement)))
+ moving_atom.pixel_y += (horizontal_velocity * (cos(angle_of_movement)))
+
+ horizontal_velocity = max(0, horizontal_velocity - horizontal_friction)
+
+ moving_atom.pixel_z = max(z_floor, moving_atom.pixel_z + vertical_velocity)
+ if(moving_atom.pixel_z > z_floor)
+ vertical_velocity -= (z_gravity * 0.05)
+
+ if(moving_atom.pixel_z <= z_floor && (vertical_velocity != 0) && moving_atom.has_gravity(location)) //z bounce
+ z_floor_bounce(moving_atom)
+
+ if(moving_atom.pixel_x > 16)
+ if(moving_atom.Move(get_step(moving_atom, EAST)))
+ moving_atom.pixel_x = -16
+ else
+ moving_atom.pixel_x = 16
+ ricochet(moving_atom, 0)
+ return
+
+ if(moving_atom.pixel_x < -16)
+ if(moving_atom.Move(get_step(moving_atom, WEST)))
+ moving_atom.pixel_x = 16
+ else
+ moving_atom.pixel_x = -16
+ ricochet(moving_atom, 0)
+ return
+
+ if(moving_atom.pixel_y > 16)
+ if(moving_atom.Move(get_step(moving_atom, NORTH)))
+ moving_atom.pixel_y = -16
+ else
+ moving_atom.pixel_y = 16
+ ricochet(moving_atom, 180)
+ return
+
+ if(moving_atom.pixel_y < -16)
+ if(moving_atom.Move(get_step(moving_atom, SOUTH)))
+ moving_atom.pixel_y = 16
+ else
+ moving_atom.pixel_y = -16
+ ricochet(moving_atom, 180)
+
diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm
index e7f5174c9102..19b1e2094993 100644
--- a/code/datums/components/pellet_cloud.dm
+++ b/code/datums/components/pellet_cloud.dm
@@ -1,20 +1,19 @@
-/*
- * This component is used when you want to create a bunch of shrapnel or projectiles (say, shrapnel from a fragmentation grenade, or buckshot from a shotgun) from a central point,
- * without necessarily printing a separate message for every single impact. This component should be instantiated right when you need it (like the moment of firing), then activated
- * by signal.
- *
- * Pellet cloud currently works on two classes of sources: directed (ammo casings), and circular (grenades, landmines).
- * -Directed: This means you're shooting multiple pellets, like buckshot. If an ammo casing is defined as having multiple pellets, it will automatically create a pellet cloud
- * and call COMSIG_PELLET_CLOUD_INIT (see [/obj/item/ammo_casing/proc/fire_casing]). Thus, the only projectiles fired will be the ones fired here.
- * The magnitude var controls how many pellets are created.
- * -Circular: This results in a big spray of shrapnel flying all around the detonation point when the grenade fires COMSIG_GRENADE_PRIME or landmine triggers COMSIG_MINE_TRIGGERED.
- * The magnitude var controls how big the detonation radius is (the bigger the magnitude, the more shrapnel is created). Grenades can be covered with bodies to reduce shrapnel output.
- *
- * Once all of the fired projectiles either hit a target or disappear due to ranging out/whatever else, we resolve the list of all the things we hit and print aggregate messages so we get
- * one "You're hit by 6 buckshot pellets" vs 6x "You're hit by the buckshot blah blah" messages.
- *
- * Note that this is how all guns handle shooting ammo casings with multiple pellets, in case such a thing comes up.
-*/
+
+ //This component is used when you want to create a bunch of shrapnel or projectiles (say, shrapnel from a fragmentation grenade, or buckshot from a shotgun) from a central point,
+ //without necessarily printing a separate message for every single impact. This component should be instantiated right when you need it (like the moment of firing), then activated
+ //by signal.
+
+ //Pellet cloud currently works on two classes of sources: directed (ammo casings), and circular (grenades, landmines).
+ //Directed: This means you're shooting multiple pellets, like buckshot. If an ammo casing is defined as having multiple pellets, it will automatically create a pellet cloud
+ //and call COMSIG_PELLET_CLOUD_INIT (see [/obj/item/ammo_casing/proc/fire_casing]). Thus, the only projectiles fired will be the ones fired here.
+ //The magnitude var controls how many pellets are created.
+ //Circular: This results in a big spray of shrapnel flying all around the detonation point when the grenade fires COMSIG_GRENADE_PRIME or landmine triggers COMSIG_MINE_TRIGGERED.
+ //The magnitude var controls how big the detonation radius is (the bigger the magnitude, the more shrapnel is created). Grenades can be covered with bodies to reduce shrapnel output.
+
+ //Once all of the fired projectiles either hit a target or disappear due to ranging out/whatever else, we resolve the list of all the things we hit and print aggregate messages so we get
+ //one "You're hit by 6 buckshot pellets" vs 6x "You're hit by the buckshot blah blah" messages.
+
+ //Note that this is how all guns handle shooting ammo casings with multiple pellets, in case such a thing comes up.
/datum/component/pellet_cloud
/// What's the projectile path of the shrapnel we're shooting?
@@ -83,12 +82,13 @@
/datum/component/pellet_cloud/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_PARENT_PREQDELETED, COMSIG_PELLET_CLOUD_INIT, COMSIG_GRENADE_PRIME, COMSIG_GRENADE_ARMED, COMSIG_MOVABLE_MOVED, COMSIG_MINE_TRIGGERED, COMSIG_ITEM_DROPPED))
-/**
- * create_casing_pellets() is for directed pellet clouds for ammo casings that have multiple pellets (buckshot and scatter lasers for instance)
- *
- * Honestly this is mostly just a rehash of [/obj/item/ammo_casing/proc/fire_casing()] for pellet counts > 1, except this lets us tamper with the pellets and hook onto them for tracking purposes.
- * The arguments really don't matter, this proc is triggered by COMSIG_PELLET_CLOUD_INIT which is only for this really, it's just a big mess of the state vars we need for doing the stuff over here.
- */
+
+//create_casing_pellets() is for directed pellet clouds for ammo casings that have multiple pellets (buckshot and scatter lasers for instance)
+//
+//Honestly this is mostly just a rehash of [/obj/item/ammo_casing/proc/fire_casing()] for pellet counts > 1, except this lets us tamper with the pellets and hook onto them for tracking purposes.
+//The arguments really don't matter, this proc is triggered by COMSIG_PELLET_CLOUD_INIT which is only for this really, it's just a big mess of the state vars we need for doing the stuff over here.
+
+
/datum/component/pellet_cloud/proc/create_casing_pellets(obj/item/ammo_casing/shell, atom/target, mob/living/user, fired_from, randomspread, spread, zone_override, params, distro)
shooter = user
var/targloc = get_turf(target)
@@ -111,16 +111,27 @@
if(i != num_pellets)
shell.newshot()
-/**
- * create_blast_pellets() is for when we have a central point we want to shred the surroundings of with a ring of shrapnel, namely frag grenades and landmines.
- *
- * Note that grenades have extra handling for someone throwing themselves/being thrown on top of it, while landmines do not (obviously, it's a landmine!). See [/datum/component/pellet_cloud/proc/handle_martyrs()]
- */
-/datum/component/pellet_cloud/proc/create_blast_pellets(obj/O, mob/living/lanced_by)
+//create_blast_pellets() is for when we have a central point we want to shred the surroundings of with a ring of shrapnel, namely frag grenades and landmines.
+
+//Note that grenades have extra handling for someone throwing themselves/being thrown on top of it, see [/datum/component/pellet_cloud/proc/handle_martyrs]
+//Landmines just have a small check for [/obj/item/mine/pressure/explosive/shrapnel/var/shred_triggerer], and spawn extra shrapnel for them if so
+
+//Arguments:
+////O- Our parent, the thing making the shrapnel obviously (grenade or landmine)
+////punishable_triggerer- For grenade lances or people who step on the landmines (if we shred the triggerer), we spawn extra shrapnel for them in addition to the normal spread
+//
+/datum/component/pellet_cloud/proc/create_blast_pellets(obj/O, mob/living/punishable_triggerer)
var/atom/A = parent
if(isgrenade(parent)) // handle_martyrs can reduce the radius and thus the number of pellets we produce if someone dives on top of a frag grenade
- handle_martyrs(lanced_by) // note that we can modify radius in this proc
+ handle_martyrs(punishable_triggerer) // note that we can modify radius in this proc
+ else if(istype(parent, /obj/item/mine/pressure/explosive))
+ var/obj/item/mine/pressure/explosive/triggered_mine = parent
+ if(triggered_mine.shred_triggerer && istype(punishable_triggerer)) // free shrapnel for the idiot who stepped on it if we're a mine that shreds the triggerer
+ pellet_delta += radius // so they don't count against the later total
+ if(punishable_triggerer.loc == triggered_mine.loc)//only trigger this if they're actually on the tile
+ for(var/i in 1 to radius)
+ pew(punishable_triggerer, TRUE)
if(radius < 1)
return
@@ -132,27 +143,27 @@
var/turf/shootat_turf = T
pew(shootat_turf)
-/**
- * handle_martyrs() is used for grenades that shoot shrapnel to check if anyone threw themselves/were thrown on top of the grenade, thus absorbing a good chunk of the shrapnel
- *
- * Between the time the grenade is armed and the actual detonation, we set var/list/bodies to the list of mobs currently on the new tile, as if the grenade landed on top of them, tracking if any of them move off the tile and removing them from the "under" list
- * Once the grenade detonates, handle_martyrs() is called and gets all the new mobs on the tile, and add the ones not in var/list/bodies to var/list/martyrs
- * We then iterate through the martyrs and reduce the shrapnel magnitude for each mob on top of it, shredding each of them with some of the shrapnel they helped absorb. This can snuff out all of the shrapnel if there's enough bodies
- *
- * Note we track anyone who's alive and client'd when they get shredded in var/list/purple_hearts, for achievement checking later
- */
-/datum/component/pellet_cloud/proc/handle_martyrs(mob/living/lanced_by)
+
+// handle_martyrs() is used for grenades that shoot shrapnel to check if anyone threw themselves/were thrown on top of the grenade, thus absorbing a good chunk of the shrapnel
+//
+// Between the time the grenade is armed and the actual detonation, we set var/list/bodies to the list of mobs currently on the new tile, as if the grenade landed on top of them, tracking if any of them move off the tile and removing them from the "under" list
+// Once the grenade detonates, handle_martyrs() is called and gets all the new mobs on the tile, and add the ones not in var/list/bodies to var/list/martyrs
+// We then iterate through the martyrs and reduce the shrapnel magnitude for each mob on top of it, shredding each of them with some of the shrapnel they helped absorb. This can snuff out all of the shrapnel if there's enough bodies
+
+// Note we track anyone who's alive and client'd when they get shredded in var/list/purple_hearts, for achievement checking later
+
+/datum/component/pellet_cloud/proc/handle_martyrs(mob/living/punishable_triggerer)
var/magnitude_absorbed
var/list/martyrs = list()
var/self_harm_radius_mult = 3
- if(lanced_by && prob(60))
- to_chat(lanced_by, "Your plan to whack someone with a grenade on a stick backfires on you, literally!")
+ if(punishable_triggerer && prob(60))
+ to_chat(punishable_triggerer, "Your plan to whack someone with a grenade on a stick backfires on you, literally!")
self_harm_radius_mult = 1 // we'll still give the guy who got hit some extra shredding, but not 3*radius
pellet_delta += radius
for(var/i in 1 to radius)
- pew(lanced_by) // thought you could be tricky and lance someone with no ill effects!!
+ pew(punishable_triggerer) // thought you could be tricky and lance someone with no ill effects!!
for(var/mob/living/body in get_turf(parent))
if(body == shooter)
@@ -209,11 +220,11 @@
finalize()
/// Minor convenience function for creating each shrapnel piece with circle explosions, mostly stolen from the MIRV component
-/datum/component/pellet_cloud/proc/pew(atom/target, spread=0)
+/datum/component/pellet_cloud/proc/pew(atom/target, landmine_victim)
var/obj/projectile/P = new projectile_type(get_turf(parent))
//Shooting Code:
- P.spread = spread
+ P.spread = 0
P.original = target
P.fired_from = parent
P.firer = parent // don't hit ourself that would be really annoying
@@ -224,6 +235,8 @@
RegisterSignal(P, list(COMSIG_PROJECTILE_RANGE_OUT, COMSIG_PARENT_QDELETING), PROC_REF(pellet_range))
pellets += P
P.fire()
+ if(landmine_victim)
+ P.process_hit(get_turf(target), target)
///All of our pellets are accounted for, time to go target by target and tell them how many things they got hit by.
/datum/component/pellet_cloud/proc/finalize()
@@ -286,7 +299,9 @@
/// Someone who was originally "under" the grenade has moved off the tile and is now eligible for being a martyr and "covering" it
/datum/component/pellet_cloud/proc/on_target_qdel(atom/target)
+ SIGNAL_HANDLER
+
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
targets_hit -= target
LAZYREMOVE(bodies, target)
- purple_hearts -= target
+ LAZYREMOVE(purple_hearts, target)
diff --git a/code/datums/components/remote_materials.dm b/code/datums/components/remote_materials.dm
index de61c13ae295..2f3aa79749b2 100644
--- a/code/datums/components/remote_materials.dm
+++ b/code/datums/components/remote_materials.dm
@@ -52,7 +52,7 @@ handles linking back and forth.
/datum/material/diamond,
/datum/material/plasma,
/datum/material/uranium,
- /datum/material/bananium,
+ /datum/material/hellstone,
/datum/material/titanium,
/datum/material/bluespace,
/datum/material/plastic,
diff --git a/code/datums/components/sitcomlaughter.dm b/code/datums/components/sitcomlaughter.dm
index 8dfef21b749d..8a5c32d2e2d1 100644
--- a/code/datums/components/sitcomlaughter.dm
+++ b/code/datums/components/sitcomlaughter.dm
@@ -1,6 +1,6 @@
/datum/component/wearertargeting/sitcomlaughter
valid_slots = list(ITEM_SLOT_HANDS, ITEM_SLOT_BELT, ITEM_SLOT_ID, ITEM_SLOT_LPOCKET, ITEM_SLOT_RPOCKET, ITEM_SLOT_SUITSTORE, ITEM_SLOT_DEX_STORAGE)
- signals = list(COMSIG_MOB_CREAMED, COMSIG_ON_CARBON_SLIP, COMSIG_ON_VENDOR_CRUSH, COMSIG_MOB_CLUMSY_SHOOT_FOOT)
+ signals = list(COMSIG_MOB_CREAMED, COMSIG_ON_CARBON_SLIP, COMSIG_ON_VENDOR_CRUSH)
proctype = PROC_REF(EngageInComedy)
mobtype = /mob/living
///Sounds used for when user has a sitcom action occur
diff --git a/code/datums/components/storage/concrete/_concrete.dm b/code/datums/components/storage/concrete/_concrete.dm
index c0a9bd162209..160b72fa9566 100644
--- a/code/datums/components/storage/concrete/_concrete.dm
+++ b/code/datums/components/storage/concrete/_concrete.dm
@@ -57,7 +57,7 @@
_contents_limbo = null
if(_user_limbo)
for(var/i in _user_limbo)
- show_to(i)
+ ui_show(i)
_user_limbo = null
/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE)
diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm
index bd0a59f85f42..32a74c843b01 100644
--- a/code/datums/components/storage/concrete/pockets.dm
+++ b/code/datums/components/storage/concrete/pockets.dm
@@ -83,10 +83,16 @@
/datum/component/storage/concrete/pockets/helmet/Initialize()
. = ..()
set_holdable(list(
- /obj/item/reagent_containers/food/drinks/bottle/vodka,
- /obj/item/reagent_containers/food/drinks/bottle/molotov,
- /obj/item/reagent_containers/food/drinks/drinkingglass,
- /obj/item/ammo_box/magazine/illestren_a850r
+ /obj/item/clothing/glasses/cold,
+ /obj/item/clothing/glasses/heat,
+ /obj/item/clothing/glasses/welding,
+ /obj/item/clothing/glasses/thermal,
+ /obj/item/clothing/glasses/night,
+ /obj/item/clothing/glasses/hud/health/night,
+ /obj/item/clothing/glasses/hud/security/night,
+ /obj/item/clothing/glasses/hud/security/sunglasses/inteq,
+ /obj/item/ammo_casing,
+ /obj/item/ammo_box/magazine/illestren_a850r,
))
/datum/component/storage/concrete/pockets/holster
@@ -137,7 +143,7 @@
original_parent = parent
. = ..()
can_hold = typecacheof(list(
- /obj/item/gun/ballistic/automatic/pistol,
+ /obj/item/gun/ballistic/automatic/pistol/syndicate,
/obj/item/gun/ballistic/revolver,
/obj/item/gun/energy/e_gun/mini,
/obj/item/gun/energy/disabler,
diff --git a/code/datums/components/storage/concrete/rped.dm b/code/datums/components/storage/concrete/rped.dm
index 455eb985f090..58a520d3a7bd 100644
--- a/code/datums/components/storage/concrete/rped.dm
+++ b/code/datums/components/storage/concrete/rped.dm
@@ -6,6 +6,7 @@
max_w_class = WEIGHT_CLASS_NORMAL
max_combined_w_class = 100
max_items = 50
+ storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
display_numerical_stacking = TRUE
/datum/component/storage/concrete/rped/can_be_inserted(obj/item/I, stop_messages, mob/M)
diff --git a/code/datums/components/storage/concrete/stack.dm b/code/datums/components/storage/concrete/stack.dm
index 319d1d4b3d41..19ea4fa58584 100644
--- a/code/datums/components/storage/concrete/stack.dm
+++ b/code/datums/components/storage/concrete/stack.dm
@@ -1,6 +1,7 @@
//Stack-only storage.
/datum/component/storage/concrete/stack
display_numerical_stacking = TRUE
+ storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
var/max_combined_stack_amount = 300
max_w_class = WEIGHT_CLASS_NORMAL
max_combined_w_class = WEIGHT_CLASS_NORMAL * 14
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
index ced0b0e79ff7..89831dafab72 100644
--- a/code/datums/components/storage/storage.dm
+++ b/code/datums/components/storage/storage.dm
@@ -26,9 +26,16 @@
var/locked = FALSE //when locked nothing can see inside or use it.
var/locked_flavor = "locked" //prevents tochat messages related to locked from sending
- var/max_w_class = WEIGHT_CLASS_SMALL //max size of objects that will fit.
- var/max_combined_w_class = 14 //max combined sizes of objects that will fit.
- var/max_items = 7 //max number of objects that will fit.
+ /// Storage flags, including what kinds of limiters we use for how many items we can hold
+ var/storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
+ /// Max w_class we can hold. Applies to [STORAGE_LIMIT_COMBINED_W_CLASS] and [STORAGE_LIMIT_VOLUME]
+ var/max_w_class = WEIGHT_CLASS_SMALL
+ /// Max combined w_class. Applies to [STORAGE_LIMIT_COMBINED_W_CLASS]
+ var/max_combined_w_class = WEIGHT_CLASS_SMALL * 7
+ /// Max items we can hold. Applies to [STORAGE_LIMIT_MAX_ITEMS]
+ var/max_items = 7
+ /// Max volume we can hold. Applies to [STORAGE_LIMIT_VOLUME]. Auto scaled on New() if unset.
+ var/max_volume
var/emp_shielded = FALSE
@@ -44,8 +51,8 @@
var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number.
- var/atom/movable/screen/storage/boxes //storage display object
- var/atom/movable/screen/close/closer //close button object
+ /// Ui objects by person. mob = list(objects)
+ var/list/ui_by_mob = list()
var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
@@ -58,19 +65,20 @@
var/screen_max_columns = 7 //These two determine maximum screen sizes.
var/screen_max_rows = INFINITY
var/screen_pixel_x = 16 //These two are pixel values for screen loc of boxes and closer
- var/screen_pixel_y = 16
+ var/screen_pixel_y = 25
var/screen_start_x = 4 //These two are where the storage starts being rendered, screen_loc wise.
var/screen_start_y = 2
//End
+ var/limited_random_access = FALSE //Quick if statement in accessible_items to determine if we care at all about what people can access at once.
+ var/limited_random_access_stack_position = 0 //If >0, can only access top items
+ var/limited_random_access_stack_bottom_up = FALSE
+
/datum/component/storage/Initialize(datum/component/storage/concrete/master)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
if(master)
change_master(master)
- boxes = new(null, src)
- closer = new(null, src)
- orient2hud()
RegisterSignal(parent, COMSIG_CONTAINS_STORAGE, PROC_REF(on_check))
RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, PROC_REF(check_locked))
@@ -113,11 +121,16 @@
/datum/component/storage/Destroy()
close_all()
- QDEL_NULL(boxes)
- QDEL_NULL(closer)
+ wipe_ui_objects()
LAZYCLEARLIST(is_using)
return ..()
+/datum/component/storage/proc/wipe_ui_objects()
+ for(var/i in ui_by_mob)
+ var/list/objects = ui_by_mob[i]
+ QDEL_LIST(objects)
+ ui_by_mob.Cut()
+
/datum/component/storage/PreTransfer()
update_actions()
@@ -171,6 +184,19 @@
var/datum/component/storage/concrete/master = master()
return master? master.real_location() : null
+//What players can access
+//this proc can probably eat a refactor at some point.
+/datum/component/storage/proc/accessible_items(random_access = TRUE)
+ var/list/contents = contents()
+ if(contents)
+ if(limited_random_access && random_access)
+ if(limited_random_access_stack_position && (length(contents) > limited_random_access_stack_position))
+ if(limited_random_access_stack_bottom_up)
+ contents.Cut(1, limited_random_access_stack_position + 1)
+ else
+ contents.Cut(1, length(contents) - limited_random_access_stack_position + 1)
+ return contents
+
/datum/component/storage/proc/canreach_react(datum/source, list/next)
SIGNAL_HANDLER
@@ -189,7 +215,7 @@
var/atom/A = parent
for(var/mob/living/L in can_see_contents())
if(!L.CanReach(A))
- hide_from(L)
+ ui_hide(L)
/datum/component/storage/proc/attack_self(datum/source, mob/M)
SIGNAL_HANDLER
@@ -227,9 +253,12 @@
if(!len)
to_chat(M, "You failed to pick up anything with [parent]!")
return
+ if(I.anchored)
+ to_chat(M, "\The [I] is stuck to the ground and cannot be picked up by [parent]!")
+ return
var/datum/progressbar/progress = new(M, len, I.loc)
var/list/rejections = list()
- while(do_after(M, 10, TRUE, parent, FALSE, CALLBACK(src, PROC_REF(handle_mass_pickup), things, I.loc, rejections, progress)))
+ while(do_after(M, 10, parent, TRUE, FALSE, CALLBACK(src, PROC_REF(handle_mass_pickup), things, I.loc, rejections, progress)))
stoplag(1)
progress.end_progress()
to_chat(M, "You put everything you could [insert_preposition] [parent].")
@@ -287,7 +316,7 @@
var/turf/T = get_turf(A)
var/list/things = contents()
var/datum/progressbar/progress = new(M, length(things), T)
- while (do_after(M, 10, TRUE, T, FALSE, CALLBACK(src, PROC_REF(mass_remove_from_storage), T, things, progress)))
+ while (do_after(M, 1 SECONDS, T, NONE, FALSE, CALLBACK(src, PROC_REF(mass_remove_from_storage), T, things, progress)))
stoplag(1)
progress.end_progress()
@@ -312,7 +341,7 @@
if(!_target)
_target = get_turf(parent)
if(usr)
- hide_from(usr)
+ ui_hide(usr)
var/list/contents = contents()
var/atom/real_location = real_location()
for(var/obj/item/I in contents)
@@ -328,109 +357,12 @@
if(locked)
close_all()
-/datum/component/storage/proc/_process_numerical_display()
- . = list()
- var/atom/real_location = real_location()
- for(var/obj/item/I in real_location.contents)
- if(QDELETED(I))
- continue
- if(!.["[I.type]-[I.name]"])
- .["[I.type]-[I.name]"] = new /datum/numbered_display(I, 1)
- else
- var/datum/numbered_display/ND = .["[I.type]-[I.name]"]
- ND.number++
-
-//This proc determines the size of the inventory to be displayed. Please touch it only if you know what you're doing.
-/datum/component/storage/proc/orient2hud()
- var/atom/real_location = real_location()
- var/adjusted_contents = real_location.contents.len
-
- //Numbered contents display
- var/list/datum/numbered_display/numbered_contents
- if(display_numerical_stacking)
- numbered_contents = _process_numerical_display()
- adjusted_contents = numbered_contents.len
-
- var/columns = clamp(max_items, 1, screen_max_columns)
- var/rows = clamp(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows)
- standard_orient_objs(rows, columns, numbered_contents)
-
-//This proc draws out the inventory and places the items on it. It uses the standard position.
-/datum/component/storage/proc/standard_orient_objs(rows, cols, list/obj/item/numerical_display_contents)
- boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+cols-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
- var/cx = screen_start_x
- var/cy = screen_start_y
- if(islist(numerical_display_contents))
- for(var/type in numerical_display_contents)
- var/datum/numbered_display/ND = numerical_display_contents[type]
- ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
- ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
- ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]"
- ND.sample_object.layer = ABOVE_HUD_LAYER
- ND.sample_object.plane = ABOVE_HUD_PLANE
- cx++
- if(cx - screen_start_x >= cols)
- cx = screen_start_x
- cy++
- if(cy - screen_start_y >= rows)
- break
- else
- var/atom/real_location = real_location()
- for(var/obj/O in real_location)
- if(QDELETED(O))
- continue
- O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
- O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
- O.maptext = ""
- O.layer = ABOVE_HUD_LAYER
- O.plane = ABOVE_HUD_PLANE
- cx++
- if(cx - screen_start_x >= cols)
- cx = screen_start_x
- cy++
- if(cy - screen_start_y >= rows)
- break
- closer.screen_loc = "[screen_start_x + cols]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
-
-/datum/component/storage/proc/show_to(mob/M)
- if(!M.client)
- return FALSE
- var/atom/real_location = real_location()
- if(M.active_storage != src && (M.stat == CONSCIOUS))
- for(var/obj/item/I in real_location)
- if(I.on_found(M))
- return FALSE
- if(M.active_storage)
- M.active_storage.hide_from(M)
- orient2hud()
- M.client.screen |= boxes
- M.client.screen |= closer
- M.client.screen |= real_location.contents
- M.set_active_storage(src)
- LAZYOR(is_using, M)
- RegisterSignal(M, COMSIG_PARENT_QDELETING, PROC_REF(mob_deleted))
- return TRUE
-
/datum/component/storage/proc/mob_deleted(datum/source)
SIGNAL_HANDLER
- hide_from(source)
-
-/datum/component/storage/proc/hide_from(mob/M)
- if(M.active_storage == src)
- M.set_active_storage(null)
- LAZYREMOVE(is_using, M)
-
- UnregisterSignal(M, COMSIG_PARENT_QDELETING)
- if(!M.client)
- return TRUE
- var/atom/real_location = real_location()
- M.client.screen -= boxes
- M.client.screen -= closer
- M.client.screen -= real_location.contents
- return TRUE
+ ui_hide(source)
/datum/component/storage/proc/close(mob/M)
- hide_from(M)
+ ui_hide(M)
/datum/component/storage/proc/close_all()
SIGNAL_HANDLER
@@ -448,25 +380,6 @@
var/datum/component/storage/concrete/master = master()
master.emp_act(source, severity)
-//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
-//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
-/datum/component/storage/proc/orient_objs(tx, ty, mx, my)
- var/atom/real_location = real_location()
- var/cx = tx
- var/cy = ty
- boxes.screen_loc = "[tx]:,[ty] to [mx],[my]"
- for(var/obj/O in real_location)
- if(QDELETED(O))
- continue
- O.screen_loc = "[cx],[cy]"
- O.layer = ABOVE_HUD_LAYER
- O.plane = ABOVE_HUD_PLANE
- cx++
- if(cx > mx)
- cx = tx
- cy--
- closer.screen_loc = "[mx+1],[my]"
-
//Resets something that is being removed from storage.
/datum/component/storage/proc/_removal_reset(atom/movable/thing)
if(!istype(thing))
@@ -477,9 +390,7 @@
return master._removal_reset(thing)
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
- SIGNAL_HANDLER
-
- _removal_reset(thing)
+ _removal_reset(thing) // THIS NEEDS TO HAPPEN AFTER SO LAYERING DOESN'T BREAK!
refresh_mob_views()
//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted
@@ -496,7 +407,7 @@
var/list/seeing = can_see_contents()
for(var/i in seeing)
- show_to(i)
+ ui_show(i)
return TRUE
/datum/component/storage/proc/can_see_contents()
@@ -615,7 +526,7 @@
if(force || M.CanReach(parent, view_only = TRUE))
if(use_sound && !silent)
playsound(A, use_sound, 50, TRUE, -5)
- show_to(M)
+ ui_show(M)
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
SIGNAL_HANDLER
@@ -644,10 +555,6 @@
host.add_fingerprint(M)
to_chat(M, "[host] seems to be [locked_flavor]!")
return FALSE
- if(real_location.contents.len >= max_items)
- if(!stop_messages)
- to_chat(M, "[host] is full, make some space!")
- return FALSE //Storage item is full
if(length(can_hold))
if(!is_type_in_typecache(I, can_hold))
if(!stop_messages)
@@ -657,22 +564,34 @@
if(!stop_messages)
to_chat(M, "[host] cannot hold [I]!")
return FALSE
- if(I.w_class > max_w_class && !is_type_in_typecache(I, exception_hold))
- if(!stop_messages)
- to_chat(M, "[I] is too big for [host]!")
- return FALSE
- var/datum/component/storage/biggerfish = real_location.loc.GetComponent(/datum/component/storage)
- if(biggerfish && biggerfish.max_w_class < max_w_class)//return false if we are inside of another container, and that container has a smaller max_w_class than us (like if we're a bag in a box)
- if(!stop_messages)
- to_chat(M, "[I] can't fit in [host] while [real_location.loc] is in the way!")
- return FALSE
- var/sum_w_class = I.w_class
- for(var/obj/item/_I in real_location)
- sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it.
- if(sum_w_class > max_combined_w_class)
- if(!stop_messages)
- to_chat(M, "[I] won't fit in [host], make some space!")
- return FALSE
+ // STORAGE LIMITS
+ if(storage_flags & STORAGE_LIMIT_MAX_ITEMS)
+ if(real_location.contents.len >= max_items)
+ if(!stop_messages)
+ to_chat(M, "[host] has too much junk in it, make some space!")
+ return FALSE //Storage item is full
+ if(storage_flags & STORAGE_LIMIT_MAX_W_CLASS)
+ if(I.w_class > max_w_class)
+ if(!stop_messages)
+ to_chat(M, "[I] is much too long for [host]!")
+ return FALSE
+ if(storage_flags & STORAGE_LIMIT_COMBINED_W_CLASS)
+ var/sum_w_class = I.w_class
+ for(var/obj/item/_I in real_location)
+ sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it.
+ if(sum_w_class > max_combined_w_class)
+ if(!stop_messages)
+ to_chat(M, "[I] won't fit in [host], make some space!")
+ return FALSE
+ if(storage_flags & STORAGE_LIMIT_VOLUME)
+ var/sum_volume = I.get_w_volume()
+ for(var/obj/item/_I in real_location)
+ sum_volume += _I.get_w_volume()
+ if(sum_volume > get_max_volume())
+ if(!stop_messages)
+ to_chat(M, "[I] is too large to fit in [host], make some space!")
+ return FALSE
+ /////////////////
if(isitem(host))
var/obj/item/IP = host
var/datum/component/storage/STR_I = I.GetComponent(/datum/component/storage)
@@ -822,7 +741,7 @@
if(locked)
to_chat(user, "[parent] seems to be [locked_flavor]!")
else
- show_to(user)
+ ui_show(user)
if(use_sound)
playsound(A, use_sound, 50, TRUE, -5)
@@ -848,7 +767,7 @@
/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target)
SIGNAL_HANDLER
- return hide_from(target)
+ return ui_hide(target)
/datum/component/storage/proc/on_alt_click(datum/source, mob/user)
SIGNAL_HANDLER
@@ -893,3 +812,7 @@
to_chat(user, "[parent] now picks up all items in a tile at once.")
if(COLLECT_ONE)
to_chat(user, "[parent] now picks up one item at a time.")
+
+//Gets our max volume
+/datum/component/storage/proc/get_max_volume()
+ return max_volume || AUTO_SCALE_STORAGE_VOLUME(max_w_class, max_combined_w_class)
diff --git a/code/datums/components/storage/ui.dm b/code/datums/components/storage/ui.dm
new file mode 100644
index 000000000000..e3e4c126d730
--- /dev/null
+++ b/code/datums/components/storage/ui.dm
@@ -0,0 +1,253 @@
+// Generates a list of numbered_display datums for the numerical display system.
+/datum/component/storage/proc/_process_numerical_display()
+ . = list()
+ for(var/obj/item/I in accessible_items())
+ if(QDELETED(I))
+ continue
+ if(!.[I.type])
+ .[I.type] = new /datum/numbered_display(I, 1, src)
+ else
+ var/datum/numbered_display/ND = .[I.type]
+ ND.number++
+
+// Orients all objects in legacy mode, and returns the objects to show to the user.
+/datum/component/storage/proc/orient2hud_legacy(mob/user, maxcolumns)
+ . = list()
+ var/list/accessible_contents = accessible_items()
+ var/adjusted_contents = length(accessible_contents)
+ var/atom/movable/screen/storage/close/ui_close
+ var/atom/movable/screen/storage/boxes/ui_boxes
+
+ //Numbered contents display
+ var/list/datum/numbered_display/numbered_contents
+ if(display_numerical_stacking)
+ numbered_contents = _process_numerical_display()
+ adjusted_contents = numbered_contents.len
+
+ var/columns = limited_random_access_stack_position == 0 ? clamp(max_items, 1, maxcolumns ? maxcolumns : screen_max_columns) : clamp(limited_random_access_stack_position, 1, maxcolumns ? maxcolumns : screen_max_columns)
+ var/rows = clamp(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows)
+
+ // First, boxes.
+ ui_boxes = get_ui_boxes()
+ ui_boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+columns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
+ . += ui_boxes
+ // Then, closer.
+ ui_close = get_ui_close()
+ ui_close.screen_loc = "[screen_start_x + columns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
+ . += ui_close
+ // Then orient the actual items.
+ var/cx = screen_start_x
+ var/cy = screen_start_y
+ if(islist(numbered_contents))
+ for(var/type in numbered_contents)
+ var/datum/numbered_display/ND = numbered_contents[type]
+ ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
+ ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
+ ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]"
+ ND.sample_object.layer = ABOVE_HUD_LAYER
+ ND.sample_object.plane = ABOVE_HUD_PLANE
+ . += ND.sample_object
+ cx++
+ if(cx - screen_start_x >= columns)
+ cx = screen_start_x
+ cy++
+ if(cy - screen_start_y >= rows)
+ break
+ else
+ for(var/obj/O in accessible_items())
+ if(QDELETED(O))
+ continue
+ var/atom/movable/screen/storage/item_holder/D = new(null, src, O)
+ D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
+ D.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
+ O.maptext = ""
+ O.layer = ABOVE_HUD_LAYER
+ O.plane = ABOVE_HUD_PLANE
+ . += D
+ cx++
+ if(cx - screen_start_x >= columns)
+ cx = screen_start_x
+ cy++
+ if(cy - screen_start_y >= rows)
+ break
+
+// Orients all objects in .. volumetric mode. Does not support numerical display!
+/datum/component/storage/proc/orient2hud_volumetric(mob/user, maxcolumns)
+ . = list()
+ var/atom/movable/screen/storage/left/ui_left
+ var/atom/movable/screen/storage/continuous/ui_continuous
+ var/atom/movable/screen/storage/close/ui_close
+
+ // Generate ui_item_blocks for missing ones and render+orient.
+ var/list/atom/contents = accessible_items()
+ // our volume
+ var/our_volume = get_max_volume()
+ var/horizontal_pixels = (maxcolumns * world.icon_size) - (VOLUMETRIC_STORAGE_EDGE_PADDING * 2)
+ var/max_horizontal_pixels = horizontal_pixels * screen_max_rows
+ // sigh loopmania time
+ var/used = 0
+ // define outside for performance
+ var/volume
+ var/list/volume_by_item = list()
+ var/list/percentage_by_item = list()
+ for(var/obj/item/I in contents)
+ if(QDELETED(I))
+ continue
+ volume = I.get_w_volume()
+ used += volume
+ volume_by_item[I] = volume
+ percentage_by_item[I] = volume / get_max_volume()
+ var/padding_pixels = ((length(percentage_by_item) - 1) * VOLUMETRIC_STORAGE_ITEM_PADDING) + VOLUMETRIC_STORAGE_EDGE_PADDING * 2
+ var/min_pixels = (MINIMUM_PIXELS_PER_ITEM * length(percentage_by_item)) + padding_pixels
+ // do the check for fallback for when someone has too much gamer gear
+ if((min_pixels) > (max_horizontal_pixels + 4)) // 4 pixel grace zone
+ to_chat(user, "[parent] was showed to you in legacy mode due to your items overrunning the three row limit! Consider not carrying too much or bugging a maintainer to raise this limit!")
+ return orient2hud_legacy(user, maxcolumns)
+ // after this point we are sure we can somehow fit all items into our max number of rows.
+
+ // determine rows
+ var/rows = clamp(CEILING(min_pixels / horizontal_pixels, 1), 1, screen_max_rows)
+
+ var/overrun = FALSE
+ if(used > our_volume)
+ // congratulations we are now in overrun mode. everything will be crammed to minimum storage pixels.
+ to_chat(user, "[parent] rendered in overrun mode due to more items inside than the maximum volume supports.")
+ overrun = TRUE
+
+ // how much we are using
+ var/using_horizontal_pixels = horizontal_pixels * rows
+
+ // item padding
+ using_horizontal_pixels -= padding_pixels
+
+ // define outside for marginal performance boost
+ var/obj/item/I
+ // start at this pixel from screen_start_x.
+ var/current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING
+ var/first = TRUE
+ var/row = 1
+
+ for(var/i in percentage_by_item)
+ I = i
+ var/percent = percentage_by_item[I]
+ var/atom/movable/screen/storage/volumetric_box/center/B = new /atom/movable/screen/storage/volumetric_box/center(null, src, I)
+ // SNOWFLAKE: force it to icon until we unfuck storage/click passing
+ I.mouse_opacity = MOUSE_OPACITY_ICON
+ var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM)
+ var/addrow = FALSE
+ if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1))
+ pixels_to_use = horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING
+ addrow = TRUE
+
+ // now that we have pixels_to_use, place our thing and add it to the returned list.
+ B.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING), 1)],[screen_start_y+row-1]:[screen_pixel_y]"
+ // add the used pixels to pixel after we place the object
+ current_pixel += pixels_to_use + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING)
+ first = FALSE //apply padding to everything after this
+
+ // set various things
+ B.set_pixel_size(pixels_to_use)
+ B.name = I.name
+
+ // finally add our things.
+ . += B.on_screen_objects()
+
+ // go up a row if needed
+ if(addrow)
+ row++
+ first = TRUE //first in the row, don't apply between-item padding.
+ current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING
+
+ // Then, continuous section.
+ ui_continuous = get_ui_continuous()
+ ui_continuous.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+maxcolumns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
+ . += ui_continuous
+ // Then, left.
+ ui_left = get_ui_left()
+ ui_left.screen_loc = "[screen_start_x]:[screen_pixel_x - 2],[screen_start_y]:[screen_pixel_y] to [screen_start_x]:[screen_pixel_x - 2],[screen_start_y+rows-1]:[screen_pixel_y]"
+ . += ui_left
+ // Then, closer, which is also our right element.
+ ui_close = get_ui_close()
+ ui_close.screen_loc = "[screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y + row - 1]:[screen_pixel_y]"
+ . += ui_close
+
+
+// Shows our UI to a mob.
+/datum/component/storage/proc/ui_show(mob/M)
+ if(!M.client)
+ return FALSE
+ if(ui_by_mob[M] || LAZYFIND(is_using, M))
+ // something went horribly wrong
+ // hide first
+ ui_hide(M)
+ var/list/cview = getviewsize(M.client.view)
+ // in tiles
+ var/maxallowedscreensize = cview[1]-8
+ // we got screen size, register signal
+ RegisterSignal(M, COMSIG_PARENT_QDELETING, PROC_REF(on_logout), override = TRUE)
+ if(M.active_storage != src)
+ if(M.active_storage)
+ M.active_storage.ui_hide(M)
+ M.active_storage = src
+ LAZYOR(is_using, M)
+ if(volumetric_ui())
+ //new volumetric ui bay-style
+ var/list/objects = orient2hud_volumetric(M, maxallowedscreensize)
+ M.client.screen |= objects
+ ui_by_mob[M] = objects
+ else
+ //old ui
+ var/list/objects = orient2hud_legacy(M, maxallowedscreensize)
+ M.client.screen |= objects
+ ui_by_mob[M] = objects
+ return TRUE
+
+// VV hooked to ensure no lingering screen objects.
+/datum/component/storage/vv_edit_var(var_name, var_value)
+ var/list/old
+ if(var_name == NAMEOF(src, storage_flags))
+ old = is_using.Copy()
+ for(var/i in is_using)
+ ui_hide(i)
+ . = ..()
+ if(old)
+ for(var/i in old)
+ ui_show(i)
+
+// Proc triggered by signal to ensure logging out clients don't linger.
+/datum/component/storage/proc/on_logout(datum/source, client/C)
+ ui_hide(source)
+
+// Hides our UI from a mob
+/datum/component/storage/proc/ui_hide(mob/M)
+ if(!M.client)
+ return TRUE
+ UnregisterSignal(M, list(COMSIG_PARENT_QDELETING))
+ M.client.screen -= ui_by_mob[M]
+ var/list/objects = ui_by_mob[M]
+ QDEL_LIST(objects)
+ if(M.active_storage == src)
+ M.active_storage = null
+ LAZYREMOVE(is_using, M)
+ return TRUE
+
+// Returns TRUE if we are using volumetric UI instead of box UI
+/datum/component/storage/proc/volumetric_ui()
+ var/atom/real_location = real_location()
+ return (storage_flags & STORAGE_LIMIT_VOLUME) && (length(real_location.contents) <= MAXIMUM_VOLUMETRIC_ITEMS) && !display_numerical_stacking
+
+// Gets our ui_boxes, making it if it doesn't exist.
+/datum/component/storage/proc/get_ui_boxes()
+ return new /atom/movable/screen/storage/boxes(null, src)
+
+// Gets our ui_left, making it if it doesn't exist.
+/datum/component/storage/proc/get_ui_left()
+ return new /atom/movable/screen/storage/left(null, src)
+
+// Gets our ui_close, making it if it doesn't exist.
+/datum/component/storage/proc/get_ui_close()
+ return new /atom/movable/screen/storage/close(null, src)
+
+// Gets our ui_continuous, making it if it doesn't exist.
+/datum/component/storage/proc/get_ui_continuous()
+ return new /atom/movable/screen/storage/continuous(null, src)
diff --git a/code/datums/diseases/advance/presets.dm b/code/datums/diseases/advance/presets.dm
index da8ad0d69a59..1924d92428e4 100644
--- a/code/datums/diseases/advance/presets.dm
+++ b/code/datums/diseases/advance/presets.dm
@@ -16,14 +16,6 @@
symptoms = list(new/datum/symptom/cough)
..()
-/datum/disease/advance/necropolis
- copy_type = /datum/disease/advance
-
-/datum/disease/advance/necropolis/New()
- name = "Necropolis Seed"
- symptoms = list(new/datum/symptom/necroseed)
- ..()
-
//Randomly generated Disease, for virus crates and events
/datum/disease/advance/random
name = "Experimental Disease"
diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm
index f6cd5698d73d..5f18f6c78a91 100644
--- a/code/datums/diseases/advance/symptoms/flesh_eating.dm
+++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm
@@ -63,7 +63,7 @@ Bonus
if(bleed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
- H.bleed_rate += 5 * power
+ H.cause_bleeding(5 * power)
return 1
/*
diff --git a/code/datums/diseases/advance/symptoms/necropolis.dm b/code/datums/diseases/advance/symptoms/necropolis.dm
deleted file mode 100644
index 9626b944124d..000000000000
--- a/code/datums/diseases/advance/symptoms/necropolis.dm
+++ /dev/null
@@ -1,113 +0,0 @@
-/datum/symptom/necroseed
- name = "Necropolis Seed"
- desc = "An infantile form of the root of Lavaland's tendrils. Forms a symbiotic bond with the host, making them stronger and hardier, at the cost of speed. Should the disease be cured, the host will be severely weakened."
- stealth = 0
- resistance = 3
- stage_speed = -10
- transmittable = -3
- level = 9
- base_message_chance = 3
- severity = 0
- symptom_delay_min = 1
- symptom_delay_max = 1
- var/color = "#302f20"
- var/tendrils = FALSE
- var/chest = FALSE
- var/fireproof = FALSE
- threshold_descs = list(
- "Resistance 15" = "The area near the host roils with paralyzing tendrils.",
- "Resistance 20" = "Host becomes immune to heat, ash, and lava. Removes movespeed debuff. Hail to the necropolis!",
- )
- var/list/cached_tentacle_turfs
- var/turf/last_location
- var/tentacle_recheck_cooldown = 100
-
-/datum/symptom/necroseed/Start(datum/disease/advance/A)
- . = ..()
- if(!.)
- return
- if(A.totalResistance() >= 15)
- tendrils = TRUE
- if(A.totalResistance() >= 20)
- fireproof = TRUE
-
-/datum/symptom/necroseed/Activate(datum/disease/advance/A)
- . = ..()
- if(!.)
- return
- var/mob/living/carbon/M = A.affected_mob
- switch(A.stage)
- if(1, 2)
- if(tendrils)
- tendril(A)
- if(prob(base_message_chance))
- to_chat(M, "Your skin feels scaly.")
- if(3, 4)
- if(tendrils)
- tendril(A)
- if(prob(base_message_chance))
- to_chat(M, "[pick("Your skin is hard.", "You feel stronger.", "You feel powerful.", "You feel your muscles growing stiff.", "You feel warm.")]")
- if(5)
- if(tendrils)
- tendril(A)
- M.dna.species.punchdamagelow = 15
- M.dna.species.punchdamagehigh = 20
- M.dna.species.punchstunthreshold = 18
- M.dna.species.brutemod = 0.6
- M.dna.species.burnmod = 0.6
- M.dna.species.heatmod = 0.6
- M.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
- M.add_movespeed_modifier(/datum/movespeed_modifier/necropolis, update=TRUE)
- ADD_TRAIT(M, TRAIT_PIERCEIMMUNE, DISEASE_TRAIT)
- if(fireproof)
- to_chat(M, "[pick("You taste primordial ash.", "The necropolis whispers sweet nothings to you.", "You feel like a god.")]")
- ADD_TRAIT(M, TRAIT_RESISTHEAT, DISEASE_TRAIT)
- ADD_TRAIT(M, TRAIT_RESISTHIGHPRESSURE, DISEASE_TRAIT)
- M.weather_immunities |= "ash"
- M.weather_immunities |= "lava"
- M.remove_movespeed_modifier(/datum/movespeed_modifier/necropolis)
- else
- if(prob(base_message_chance))
- to_chat(M, "[pick("Your skin has become a hardened carapace.", "Your strength is superhuman.", "You feel invincible.")]")
- if(tendrils)
- tendril(A)
- return
-
-/datum/symptom/necroseed/proc/tendril(datum/disease/advance/A)
- . = A.affected_mob
- var/mob/living/loc = A.affected_mob.loc
- if(isturf(loc))
- if(!LAZYLEN(cached_tentacle_turfs) || loc != last_location || tentacle_recheck_cooldown <= world.time)
- LAZYCLEARLIST(cached_tentacle_turfs)
- last_location = loc
- tentacle_recheck_cooldown = world.time + initial(tentacle_recheck_cooldown)
- for(var/turf/open/T in orange(4, loc))
- LAZYADD(cached_tentacle_turfs, T)
- for(var/t in cached_tentacle_turfs)
- if(isopenturf(t))
- if(prob(10))
- new /obj/effect/temp_visual/goliath_tentacle(t, .)
- else
- cached_tentacle_turfs -= t
-
-/datum/symptom/necroseed/End(datum/disease/advance/A)
- . = ..()
- if(!.)
- return
- var/mob/living/carbon/M = A.affected_mob
- to_chat(M, "You feel weakened as the necropolis' blessing leaves your body.")
- M.remove_movespeed_modifier(/datum/movespeed_modifier/necropolis)
- M.dna.species.punchdamagelow = initial(M.dna.species.punchdamagelow)
- M.dna.species.punchdamagehigh = initial(M.dna.species.punchdamagehigh)
- M.dna.species.punchstunthreshold = initial(M.dna.species.punchstunthreshold)
- M.remove_atom_colour(color, FIXED_COLOUR_PRIORITY)
- M.dna.species.brutemod /= 0.6
- M.dna.species.burnmod /= 0.6
- M.dna.species.heatmod /= 0.6
- REMOVE_TRAIT(M, TRAIT_PIERCEIMMUNE, DISEASE_TRAIT)
- if(fireproof)
- REMOVE_TRAIT(M, TRAIT_RESISTHIGHPRESSURE, DISEASE_TRAIT)
- REMOVE_TRAIT(M, TRAIT_RESISTHEAT, DISEASE_TRAIT)
- M.weather_immunities -= "ash"
- M.weather_immunities -= "lava"
-
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index 6d3959753a9e..1fc6d09cb2cb 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -226,43 +226,3 @@
new_form = /mob/living/simple_animal/hostile/morph
infectable_biotypes = MOB_ORGANIC|MOB_MINERAL|MOB_UNDEAD //magic!
transformed_antag_datum = /datum/antagonist/morph
-
-/datum/disease/transformation/gondola
- name = "Gondola Transformation"
- cure_text = "Condensed Capsaicin, ingested or injected." //getting pepper sprayed doesn't help
- cures = list(/datum/reagent/consumable/condensedcapsaicin) //beats the hippie crap right out of your system
- cure_chance = 80
- stage_prob = 5
- agent = "Tranquility"
- desc = "Consuming the flesh of a Gondola comes at a terrible price."
- severity = DISEASE_SEVERITY_BIOHAZARD
- visibility_flags = 0
- stage1 = list("You seem a little lighter in your step.")
- stage2 = list("You catch yourself smiling for no reason.")
- stage3 = list("A cruel sense of calm overcomes you.", "You can't feel your arms!", "You let go of the urge to hurt clowns.")
- stage4 = list("You can't feel your arms. It does not bother you anymore.", "You forgive the clown for hurting you.")
- stage5 = list("You have become a Gondola.")
- new_form = /mob/living/simple_animal/pet/gondola
-
-/datum/disease/transformation/gondola/stage_act()
- ..()
- switch(stage)
- if(2)
- if (prob(5))
- affected_mob.emote("smile")
- if (prob(20))
- affected_mob.reagents.add_reagent_list(list(/datum/reagent/pax = 5))
- if(3)
- if (prob(5))
- affected_mob.emote("smile")
- if (prob(20))
- affected_mob.reagents.add_reagent_list(list(/datum/reagent/pax = 5))
- if(4)
- if (prob(5))
- affected_mob.emote("smile")
- if (prob(20))
- affected_mob.reagents.add_reagent_list(list(/datum/reagent/pax = 5))
- if (prob(2))
- to_chat(affected_mob, "You let go of what you were holding.")
- var/obj/item/I = affected_mob.get_active_held_item()
- affected_mob.dropItemToGround(I)
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index dde90dd5dbe8..abd20fd29212 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -659,8 +659,6 @@
O.Remove(src)
visible_message("[src] vomits up their [O.name]!", "You vomit up your [O.name]") //no "vomit up your the heart"
O.forceMove(drop_location())
- if(prob(20))
- O.animate_atom_living()
if(9 to 10)
ForceContractDisease(new/datum/disease/gastrolosis())
to_chat(src, "Oh, I actually feel quite alright!")
diff --git a/code/datums/elements/decals/blood.dm b/code/datums/elements/decals/blood.dm
index 85f75bef2416..0a3ca8ce59a3 100644
--- a/code/datums/elements/decals/blood.dm
+++ b/code/datums/elements/decals/blood.dm
@@ -6,9 +6,11 @@
. = ..()
RegisterSignal(target, COMSIG_ATOM_GET_EXAMINE_NAME, PROC_REF(get_examine_name), TRUE)
+ RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), PROC_REF(redraw), TRUE)
/datum/element/decal/blood/Detach(atom/source, force)
UnregisterSignal(source, COMSIG_ATOM_GET_EXAMINE_NAME)
+ UnregisterSignal(source, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
return ..()
/datum/element/decal/blood/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha, source)
@@ -30,3 +32,11 @@
override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
override[EXAMINE_POSITION_BEFORE] = " blood-stained "
return COMPONENT_EXNAME_CHANGED
+
+///this is probably quite bad, let me know if you have a better solution for this -S
+/datum/element/decal/blood/proc/redraw(datum/source, mob/user)
+ SIGNAL_HANDLER
+
+ var/atom/bloodsource = source
+ Detach(source)
+ bloodsource.AddElement(/datum/element/decal/blood, bloodsource.icon, bloodsource.icon_state, _color = get_blood_dna_color(bloodsource.return_blood_DNA()))
diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm
index 9b427b6b80c5..11072c771bab 100644
--- a/code/datums/elements/embed.dm
+++ b/code/datums/elements/embed.dm
@@ -176,23 +176,20 @@
* If we hit a valid target (carbon or closed turf), we create the shrapnel_type object and immediately call tryEmbed() on it, targeting what we impacted. That will lead
* it to call tryForceEmbed() on its own embed element (it's out of our hands here, our projectile is done), where it will run through all the checks it needs to.
*/
-/datum/element/embed/proc/checkEmbedProjectile(obj/projectile/P, atom/movable/firer, atom/hit)
+/datum/element/embed/proc/checkEmbedProjectile(obj/projectile/P, atom/movable/firer, atom/hit, angle, hit_zone)
SIGNAL_HANDLER
- if(!iscarbon(hit) && !isclosedturf(hit))
+ if(!iscarbon(hit))
Detach(P)
return // we don't care
var/obj/item/payload = new payload_type(get_turf(hit))
- var/did_embed
- if(iscarbon(hit))
- var/mob/living/carbon/C = hit
- var/obj/item/bodypart/limb = C.get_bodypart(C.check_limb_hit(P.def_zone))
- did_embed = payload.tryEmbed(limb)
- else
- did_embed = payload.tryEmbed(hit)
+ var/mob/living/carbon/C = hit
+ var/obj/item/bodypart/limb = C.get_bodypart(hit_zone)
+ if(!limb)
+ limb = C.get_bodypart()
- if(!did_embed)
+ if(!payload.tryEmbed(limb))
payload.failedEmbed()
Detach(P)
@@ -213,7 +210,6 @@
var/obj/item/bodypart/limb
var/mob/living/carbon/C
- var/turf/closed/T
if(!forced && !prob(embed_chance))
return
@@ -225,11 +221,8 @@
hit_zone = limb.body_zone
else if(isbodypart(target))
limb = target
+ hit_zone = limb.body_zone
C = limb.owner
- else if(isclosedturf(target))
- T = target
if(C)
return checkEmbedMob(I, C, hit_zone, forced=TRUE)
- else if(T)
- return checkEmbedOther(I, T, forced=TRUE)
diff --git a/code/datums/elements/world_icon.dm b/code/datums/elements/world_icon.dm
new file mode 100644
index 000000000000..bcb0129c6c68
--- /dev/null
+++ b/code/datums/elements/world_icon.dm
@@ -0,0 +1,121 @@
+/////////////////////////////////////////////////////////////
+////////// WORLD ICON ELEMENT DIRECTORY //////////
+/////////////////////////////////////////////////////////////
+//PORTED FROM MOJAVE SUN//
+
+// Slap onto something to give it a world icon that differs from the inventory one (allows for realistically sized objects and all that) //
+// To fix 25/06/2021 : Blood Decals, Mutable Overlays and other baked in bitch ass overlays that need to be remade when the icon changes //
+// Fixed 07/05/2022: Now you can deal with the above by handling everything with attached_proc instead
+// Fixed 12/04/2023: Icon states, Needs major tuning up by someone who can properly make it work
+
+/datum/element/world_icon
+ id_arg_index = 2
+ element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH
+ //If we want COMPLEX world icon behavior, this proc will handle icon updating when the item is NOT in the inventory.
+ //I just assumed that the default update_icon is for inventory sprites because ss13 basically focuses on how the sprites
+ //look on your hand, not how they realistically look in the world.
+ var/attached_proc
+ /// Only used if attached_proc doesn't exist, simply changes the icon of target to this when it's in the inventory
+ var/inventory_icon
+ /// Only used if attached_proc doesn't exist, simply changes the icon of target to this when it's NOT in the inventory
+ var/world_icon
+ /// Only used when inventory state icon is different from original
+ var/inventory_icon_state
+ /// Only used when world state icon is different from original, pretty much just the original "icon_state" but if you for some reason need to flip the standard icon states for this element around you can use this
+ var/world_icon_state
+
+/datum/element/world_icon/Attach(obj/item/target, attached_proc, world_icon, inventory_icon, world_icon_state, inventory_icon_state)
+ . = ..()
+ if(!istype(target))
+ return ELEMENT_INCOMPATIBLE
+
+ src.attached_proc = attached_proc
+ src.world_icon = world_icon
+ src.world_icon_state = world_icon_state
+ src.inventory_icon = inventory_icon
+ src.inventory_icon_state = inventory_icon_state
+ RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON, PROC_REF(update_icon))
+ RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(update_icon_state))
+ RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_STORAGE_ENTERED, COMSIG_ITEM_DROPPED, COMSIG_STORAGE_EXITED), PROC_REF(inventory_updated))
+ target.update_appearance(UPDATE_ICON)
+ target.update_appearance(UPDATE_ICON_STATE)
+
+/datum/element/world_icon/Detach(obj/item/source)
+ . = ..()
+ UnregisterSignal(source, COMSIG_ATOM_UPDATE_ICON)
+ UnregisterSignal(source, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(update_icon_state))
+ UnregisterSignal(source, list(COMSIG_ITEM_EQUIPPED, COMSIG_STORAGE_ENTERED, COMSIG_ITEM_DROPPED, COMSIG_STORAGE_EXITED))
+ source.update_appearance(UPDATE_ICON)
+ source.update_appearance(UPDATE_ICON_STATE)
+
+/datum/element/world_icon/proc/update_icon(obj/item/source, updates)
+ SIGNAL_HANDLER
+
+ if((source.item_flags & IN_INVENTORY) || (source.loc && SEND_SIGNAL(source.loc, COMSIG_CONTAINS_STORAGE)))
+ if(attached_proc)
+ return
+ return default_inventory_icon(source)
+
+ if(attached_proc)
+ return call(source, attached_proc)(updates)
+ else
+ return default_world_icon(source)
+
+/datum/element/world_icon/proc/update_icon_state(obj/item/source, updates)
+ SIGNAL_HANDLER
+
+ if((source.item_flags & IN_INVENTORY) || (source.loc && SEND_SIGNAL(source.loc, COMSIG_CONTAINS_STORAGE)))
+ if(attached_proc)
+ return
+ return default_inventory_icon_state(source)
+
+ if(attached_proc)
+ return call(source, attached_proc)(updates)
+ else
+ return default_world_icon_state(source)
+
+/datum/element/world_icon/proc/inventory_updated(obj/item/source)
+ SIGNAL_HANDLER
+
+ source.update_appearance(UPDATE_ICON)
+ source.update_appearance(UPDATE_ICON_STATE)
+
+/datum/element/world_icon/proc/default_inventory_icon(obj/item/source)
+ SIGNAL_HANDLER
+
+ source.icon = inventory_icon
+
+/datum/element/world_icon/proc/default_world_icon(obj/item/source)
+ SIGNAL_HANDLER
+
+ source.icon = world_icon
+
+/datum/element/world_icon/proc/default_inventory_icon_state(obj/item/source)
+ SIGNAL_HANDLER
+
+ if(!inventory_icon_state)
+ source.icon_state = source.icon_state
+ return
+
+ INVOKE_ASYNC(src, PROC_REF(check_inventory_state), source)
+
+/datum/element/world_icon/proc/default_world_icon_state(obj/item/source)
+ SIGNAL_HANDLER
+
+ if(!world_icon_state)
+ source.icon_state = source.icon_state
+ return
+
+ INVOKE_ASYNC(src, PROC_REF(check_world_icon_state), source)
+
+/datum/element/world_icon/proc/check_inventory_state(obj/item/source)
+ SIGNAL_HANDLER
+
+ inventory_icon_state = source.inventory_state
+ source.icon_state = inventory_icon_state
+
+/datum/element/world_icon/proc/check_world_icon_state(obj/item/source)
+ SIGNAL_HANDLER
+
+ world_icon_state = source.world_state
+ source.icon_state = world_icon_state
diff --git a/code/datums/ert.dm b/code/datums/ert.dm
index ff11057704c4..0c5227e41074 100644
--- a/code/datums/ert.dm
+++ b/code/datums/ert.dm
@@ -257,10 +257,16 @@
/datum/ert/frontier/assault
leader_role = /datum/antagonist/ert/frontier/leader
- roles = list(/datum/antagonist/ert/frontier, /datum/antagonist/ert/frontier/medic, /datum/antagonist/ert/frontier/engineer)
+ roles = list(/datum/antagonist/ert/frontier/better, /datum/antagonist/ert/frontier/medic, /datum/antagonist/ert/frontier/engineer)
rename_team = "Assault Frontiersmen Team"
polldesc = "a well armed squad of pirates"
+/datum/ert/frontier/unarmed //use for finer control of pirate's armaments
+ leader_role = /datum/antagonist/ert/frontier/leader/unnarmed
+ roles = list(/datum/antagonist/ert/frontier/unnarmed)
+ rename_team = "Unnarmed Frontiersmen Team"
+ polldesc = "a custom squad of pirates"
+
/datum/ert/independent
teamsize = 3
opendoors = FALSE
diff --git a/code/datums/guestbook.dm b/code/datums/guestbook.dm
new file mode 100644
index 000000000000..99104f09d715
--- /dev/null
+++ b/code/datums/guestbook.dm
@@ -0,0 +1,148 @@
+/**
+ * THE GUESTBOOK DATUM // ripped straight from mojave.
+ *
+ * Essentially, this datum handles the people that a given human knows,
+ * to handle getting the correct names on examine and saycode.
+ */
+/datum/guestbook
+ /// Associative list of known guests, real_name = known_name
+ var/list/known_names
+
+/datum/guestbook/Destroy(force)
+ known_names = null
+ return ..()
+
+/datum/guestbook/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "Guestbook", "[user.real_name]'s Guestbook")
+ ui.set_autoupdate(FALSE)
+ ui.open()
+
+/datum/guestbook/ui_state(mob/user)
+ return GLOB.always_state
+
+/datum/guestbook/ui_data(mob/user)
+ var/list/data = list()
+ var/list/names = list()
+ for(var/real_name in known_names)
+ var/given_name = LAZYACCESS(known_names, real_name)
+ names += list(list("real_name" = real_name, "given_name" = given_name))
+ data["names"] = names
+ return data
+
+/datum/guestbook/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+ if(.)
+ return .
+ switch(action)
+ if("rename_guest")
+ var/real_name = params["real_name"]
+ var/new_name = params["new_name"]
+ new_name = reject_bad_name(new_name, max_length = 42)
+ if(!new_name)
+ to_chat(usr, span_warning("That's a pretty terrible name. You can do better."))
+ return FALSE
+ if(!rename_guest(usr, null, real_name, new_name, silent = FALSE))
+ return FALSE
+ return TRUE
+ if("delete_guest")
+ var/real_name = params["real_name"]
+ if(!remove_guest(usr, null, real_name, silent = FALSE))
+ return FALSE
+ return TRUE
+
+/datum/guestbook/proc/try_add_guest(mob/user, mob/living/carbon/human/guest, silent = FALSE)
+ if(user == guest)
+ if(!silent)
+ to_chat(user, span_warning("That's you! You already know yourself plenty."))
+ return FALSE
+ if(!visibility_checks(user, guest, silent))
+ return FALSE
+ var/given_name = input(user, "What name do you want to give to [guest]?", "Guestbook Name", guest.get_visible_name())
+ if(!given_name)
+ if(!silent)
+ to_chat(user, span_warning("Nevermind."))
+ return FALSE
+ given_name = reject_bad_name(given_name)
+ if(!given_name)
+ if(!silent)
+ to_chat(user, span_warning("That's a pretty terrible name. You can do better."))
+ return FALSE
+ if(!visibility_checks(user, guest, silent))
+ return FALSE
+ var/face_name = guest.get_face_name("ForgetMeNot")
+ if(LAZYACCESS(known_names, face_name))
+ if(!rename_guest(user, guest, face_name, given_name, silent))
+ return FALSE
+ else
+ if(!add_guest(user, guest, face_name, given_name, silent))
+ return FALSE
+ return TRUE
+
+/datum/guestbook/proc/add_guest(mob/user, mob/living/carbon/guest, real_name, given_name, silent = TRUE)
+ //Already exists, should be handled by rename_guest()
+ var/existing_name = LAZYACCESS(known_names, real_name)
+ if(existing_name)
+ if(!silent)
+ to_chat(user, span_warning("You already know them as \"[existing_name]\"."))
+ return FALSE
+ LAZYADDASSOC(known_names, real_name, given_name)
+ if(!silent)
+ to_chat(user, span_notice("You memorize the face of [guest] as \"[given_name]\"."))
+ return TRUE
+
+/datum/guestbook/proc/rename_guest(mob/user, mob/living/carbon/guest, real_name, given_name, silent = TRUE)
+ var/old_name = LAZYACCESS(known_names, real_name)
+ if(!old_name)
+ return FALSE
+ known_names[real_name] = given_name
+ if(!silent)
+ to_chat(user, span_notice("You re-memorize the face of \"[old_name]\" as \"[given_name]\"."))
+ return TRUE
+
+/datum/guestbook/proc/try_remove_guest(mob/user, mob/living/carbon/human/guest, silent = FALSE)
+ if(user == guest)
+ if(!silent)
+ to_chat(user, span_warning("That's you! You'll never forget yourself."))
+ return
+ if(!visibility_checks(user, guest, silent))
+ return FALSE
+ var/face_name = guest.get_face_name("ForgetMeNot")
+ if(!remove_guest(user, guest, face_name, silent))
+ return FALSE
+ return TRUE
+
+/datum/guestbook/proc/remove_guest(mob/user, mob/living/carbon/guest, real_name, silent = TRUE)
+ //Already exists, should be handled by rename_guest()
+ var/existing_name = LAZYACCESS(known_names, real_name)
+ if(!existing_name)
+ if(!silent)
+ to_chat(user, span_warning("You don't know them in the first place."))
+ return FALSE
+ LAZYREMOVE(known_names, real_name)
+ if(!silent)
+ to_chat(user, span_notice("You forget the face of \"[existing_name]\"."))
+ return TRUE
+
+/datum/guestbook/proc/get_known_name(mob/user, mob/living/carbon/guest, real_name)
+ if(user == guest || isAdminObserver(user))
+ return real_name
+ return LAZYACCESS(known_names, real_name)
+
+/datum/guestbook/proc/visibility_checks(mob/user, mob/living/carbon/human/guest, silent = FALSE)
+ if(QDELETED(guest))
+ if(!silent)
+ to_chat(user, span_warning("What?"))
+ return FALSE
+ var/visible_name = guest.get_visible_name("")
+ var/face_name = guest.get_face_name("")
+ if(!visible_name || !face_name)
+ if(!silent)
+ to_chat(user, span_warning("You can't see their face very well!"))
+ return FALSE
+ if(get_dist(user, guest) > 4)
+ if(!silent)
+ to_chat(user, span_warning("You need to take a closer look at them!"))
+ return FALSE
+ return TRUE
diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm
index 721444281653..c5f907f9c31d 100644
--- a/code/datums/holocall.dm
+++ b/code/datums/holocall.dm
@@ -462,303 +462,3 @@
NAME Blackbox Automated Message
SAY Connection lost. Dumping audio logs to disk.
DELAY 50"}
-
-/obj/item/disk/holodisk/rube/disk1
- name = "Gustus Amort on how to be a successful Engineer 1: Overview"
- desc = "A guide by Gustus Amort on running the Rube Goldberg Class Vessel. This seems to be disk 1."
- preset_image_type = /datum/preset_holoimage/engineer/ce
- preset_record_text = {"
- NAME Gustus Amort
- SAY Hello and welcome to your new-ish Rube Goldberg-class space faring vessel!
- DELAY 30
- NAME Mary Polish
- PRESET /datum/preset_holoimage/engineer/atmos
- SAY Oh are you going to tell them about how to set up the atmos on this?
- DELAY 2
- NAME Gustus Amort
- PRESET /datum/preset_holoimage/engineer/ce
- SAY Yes, we'll get to that. I'm doing the intro.
- SOUND explosion
- SOUND sparks
- DELAY 30
- SAY God Dammit! Who the hell was watching the burn mix?!
- SOUND spark
- DELAY 30
- NAME Mary Polish
- PRESET /datum/preset_holoimage/engineer/atmos
- SAY That was Jamie, they were testing out that Supermatter we had in the back.
- DELAY 30
- NAME Gustus Amort
- PRESET /datum/preset_holoimage/engineer/ce
- SAY GOD DAMMIT I SAID TO WAIT. Tell him to turn it the fuck off.
- DELAY 30
- NAME Mary Polish
- PRESET /datum/preset_holoimage/engineer/atmos
- SAY On it Sir.
- DELAY 30
- NAME Gustus Amort
- PRESET /datum/preset_holoimage/engineer/ce
- SAY Alright. I have to go cleanup. Disk 2 is general operation.
- DELAY 30
- SAY Disk 3 is Atmos Setup
- DELAY 30
- SAY Disk 4 is Burnmix Setup
- DELAY 30
- SAY Disk 5 is TEG Setup
- DELAY 30
- SAY And Disk 6 is everything else.
-
- "}
-
-/obj/item/disk/holodisk/rube/disk2
- name = "Gustus Amort on how to be a successful Engineer 2: General Operations"
- desc = "A guide by Gustus Amort on general operations of the Rube Goldberg Class Vessel. This seems to be disk 2."
- preset_image_type = /datum/preset_holoimage/engineer/ce
- preset_record_text = {"
- NAME Gustus Amort
- SAY Alright welcome to disk 2-
- SOUND explosion
- DELAY 15
- SAY Anyway, general operations. You'll need to run a tight shift to keep this puppy floating.
- DELAY 30
- SAY This ship is equipped with a lot of equipment, almost anything you could want or need as an Engineer.
- SOUND spark
- DELAY 30
- SAY Sadly the budget did not allow for a good handful of this equipment to be installed properly.
- DELAY 30
- SAY To start you'll want to set up your atmospherics system. Air and burn mix primarily. You'll learn that on Disk 3 and 4.
- DELAY 30
- SAY After you-
- SOUND spark
- DELAY 30
- SAY You'll want to make sure your power is good. You'll need to set up the TEG in the back. Disk 5 for that.
- DELAY 30
- SAY Once that's all out of the way, you'll ned to make sure this puppy can move around right?
- DELAY 30
- SAY That's simple turning on the thrusters. Eh- You'll learn that in disk 6.
- DELAY 30
- SAY Finally, once the ship is operational, that's where we get the fun. You'll find a good number of circuits in storage.
- DELAY 30
- SAY Your miners will need you to build their equipment, their vendor and Ore redemption. You do want them to be able to work right?
- DELAY 30
- SAY This will be continued in-
- SOUND explosion
- DELAY 30
- SAY Ok... Yeah Disk 3.
- DELAY 30
-
- "}
-
-/obj/item/disk/holodisk/rube/disk3
- name = "Gustus Amort on how to be a successful Engineer 3: Atmos"
- desc = "A guide by Gustus Amort on setting up Atmos in the Rube Goldberg Class Vessel. This seems to be disk 3."
- preset_image_type = /datum/preset_holoimage/engineer/ce
- preset_record_text = {"
- NAME Gustus Amort
- SAY Alright, now that you know what you have to do, here's how to get started!
- SOUND spark
- DELAY 10
- SAY I'll be handing this one off to our Atmos Tech, Ms. Polish.
- DELAY 30
- NAME Mary Polish
- PRESET /datum/preset_holoimage/engineer/atmos
- SAY Hello! This is Mary! So your Chief Engineer just told you to set up atmos huh?
- DELAY 30
- SAY Well I'm sure you're well acquainted with the ins and out sof fluid dynamics. But just in case!
- DELAY 30
- SAY To start you'll want to get your gas supplies ready. It's the same procoess for all of them.
- DELAY 30
- SAY You'll need to put on your hardsuit and get an oxygen tank, so suit up!
- DELAY 30
- SAY Then you'll go into each chamber and do the following:
- DELAY 30
- SAY 1: Wrench the portable canister into the connector.
- DELAY 30
- SAY 2: Turn on the pump, and max the pressure.
- DELAY 30
- SAY 3: Open the portable canister, no need to touch the pressure control.
- DELAY 30
- SAY Once that's all done your chambers should be ready to go! That is, all but the mix chamber.
- DELAY 30
- SAY For the ship air, simply turn on the pump labeled Air Mix to Air Supply. Don't mess with the pressure.
- DELAY 30
- SAY For everything else, you can adjust the pumps coming from each chamber to move it out.
- DELAY 30
- SAY See you on disk-
- SOUND explosion
- DELAY 30
- SAY 4- IT WASN'T MY FAULT.
- "}
-
-/obj/item/disk/holodisk/rube/disk4
- name = "Gustus Amort on how to be a successful Engineer 4: Plasma and Burn Mix"
- desc = "A guide by Gustus Amort on plasma and burn mixes. This seems to be disk 4."
- preset_image_type = /datum/preset_holoimage/engineer/ce
- preset_record_text = {"
- NAME Gustus Amort
- SAY Thank you Mary, go clean up that mess with Jamie and I'll take it from here.
- DELAY 30
- SAY Now that you've set up oxygen and made your gases accessible to the mixer, it's time to get to work.
- DELAY 30
- SAY You'll need to pump your plasma out of the chamber at max volume, set the pump accordingly. Same for O2.
- DELAY 30
- SAY Before you start the burn mix, you'll want to supply your thrusters. Simply turn on the pump labeled Plasma to Thrusters.
- DELAY 30
- SAY You may wish to alter the output pressure here, but I find 1 or 200 kpa is just fine.
- DELAY 30
- SAY You'll want to set up your thrusters properly later. To do so you'll want to go to the north thruster room.
- DELAY 30
- SAY You'll notice there are pumps in leading to the plasma thrusters. Simply turn them on and adjust pressure to max.
- DELAY 30
- SAY Thrusters can wait for later however, time for the burn mix.
- DELAY 30
- SAY The O2 and Plasma pipes lead to a gas mixer preset to a 30 70 mix.
- DELAY 30
- SAY A proper burn mix can range from 60 percent plasma to 80 percent plasma, with the rest as oxygen.
- DELAY 30
- SAY If you want a different setup than a simple burnmix, you'll need to redo the piping in atmos.
- DELAY 30
- SAY Once you set your mixer to on it'll go to the mix chamber. Turn the pump labeled Gas Mix to Gas Chamber to max pressure and on.
- DELAY 30
- SAY Then you'll want to turn the mix tank scrubber to siphoning mode on extended range via the air alarm. You'll need an ID for this.
- DELAY 30
- SAY The mix chamber scrubber is typically Scrubber 1 on the console in atmos. But double check before adjusting. It should be the only one off by default.
- DELAY 30
- SAY Once your mix chamber is full of the burn mix, set the pump labeled Mix Chamber to Engine to 2000 KPA and on. Then you're done!
- DELAY 30
- SAY But that's standard stuff re-
- SOUND explosion
- SOUND explosion
- DELAY 30
- SAY Is it ove-
- SOUND explosion
- DELAY 30
- SAY Of course. Disk 5 is next.
-
- "}
-
-/obj/item/disk/holodisk/rube/disk5
- name = "Gustus Amort on how to be a successful Engineer 5: TEG"
- desc = "A guide by Gustus Amort on operation the Rube Goldberg TEG. This seems to be disk 5."
- preset_image_type = /datum/preset_holoimage/engineer/ce
- preset_record_text = {"
- NAME Gustus Amort
- SAY Alright we're finally handing it off to- JAMIE WHAT THE FUCK DID YOU DO?
- SOUND explosion
- SOUND spark
- DELAY 30
- SAY God dammit Jamie, alright just fucking turn the pipe off and vent it. Start from square one come on.
- DELAY 30
- SAY We've done this a hundred times now. Why do you always turn your shit on early?
- DELAY 30
- NAME Jamie Coldwell
- PRESET /datum/preset_holoimage/engineer
- SAY Well Chief, you see, I was trying to see if I could set it up with some plasma from the tanks in the shed, and the SM-
- DELAY 30
- NAME Gustus Amort
- PRESET /datum/preset_holoimage/engineer/ce
- SAY GOOD LORD YOU TRIED TO WHAT? No no no no no no no no. Just. Let me set it up. We'll fuck with the SM when we get planetside.
- DELAY 30
- SAY Alright so if you happen to have a not too bright engineer working your TEG-
- NAME Jamie Coldwell
- PRESET /datum/preset_holoimage/engineer
- DELAY 30
- SAY Hey!
- NAME Gustus Amort
- PRESET /datum/preset_holoimage/engineer/ce
- DELAY 30
- SAY Shut up Jamie. Anyway, you'll want to vent your chamber. That button is next to the service door behind the TEG.
- DELAY 30
- SAY Check the gas monitoring computer see when the chamber hits 0 KPA. Then shut the emergency hatch.
- DELAY 30
- SAY You'll need to make sure your TEG circulators are correctly set. Incoming is the cold loop, outgoing is the hot loop.
- DELAY 30
- SAY To change them you'll want to open the hatches with a scredriver and hit them with a multitool.
- DELAY 30
- SAY When you're all done, screw them back up and wrench the centerpiece, the thermoelectric generator.
- DELAY 30
- SAY Next you'll want to set the pump pressures. Do this before you turn them on.
- DELAY 30
- SAY Turn the pump labeled Engine Mix to Engine to 1000 KPA.
- DELAY 30
- SAY Turn the next pump after that to 610 KPA. It'll be placed directly in front of the cold loop going into the chamber.
- DELAY 30
- SAY Turn the next pump leading into the hot loop ciruclator to 710 KPA. And the TEG Waste Disposals Pump to max KPA.
- DELAY 30
- SAY Now you need to flood the chamber. Turn on Engine Mix to Engine, and the connected to the cold loop.
- DELAY 30
- SAY once the chamber filled up to a few thousand KPA, which you can check on the computer, you'll need to ignite it.
- DELAY 30
- SAY The igniters don't work very well, their button is behind the tables but in case that doesn't work...
- DELAY 30
- SAY Turn a welder on, there are a few on the table, and throw it in the disposals unit. Make sure to flush!
- DELAY 30
- SAY finally you have a burn mix roaring and ready! Turn on the remaining two pumps and you should be good to go!
- DELAY 30
- SAY Congratulations, you've set up the TEG! See! That wasn't so hard Jamie! Make sure to set your SMES's!
- DELAY 30
-
- "}
-
-
-/obj/item/disk/holodisk/rube/disk6
- name = "Gustus Amort on how to be a successful Engineer 6: What now?"
- desc = "A guide by Gustus Amort on what to do next! This seems to be disk 6."
- preset_image_type = /datum/preset_holoimage/engineer/ce
- preset_record_text = {"
- NAME Gustus Amort
- SAY Now that you've got your ship working like a well oiled pile of congregated circuits, you're probably wondering what to do next!
- DELAY 30
- SAY Lucky for you, there's a whole storage unit of things to do! You'll have materials waiting at your disposal.
- DELAY 30
- SAY Primarily speaking, you'll be set to land on a planet of your choice and set up shop.
- DELAY 30
- SAY You have a wire running out through storage and up to the dock doors.
- DELAY 30
- SAY My recommendation is to use this wire to run power out to your new colony, beachhouse, or factory whatever.
- DELAY 30
- SAY Other than that, you'll need to upgrade your machines, communicate with other ships for research components, and keep your bloodthirsty miner happy.
- DELAY 30
- SAY Good Luck! This is Gustus Amort signi- IS THAT A FUCKING BUBBLEGUM?
- SOUND explosion
-
- "}
-
-
-
-
-/obj/item/disk/holodisk/rube/disk7
- name = "Larry Triangles guide on how to be the last man standing."
- desc = "Gustus Amort didn't mention a disk 7? Maybe someone else made this one?"
- preset_image_type = /datum/preset_holoimage/miner
- preset_record_text = {"
- NAME Larry Triangles
- SAY Hey guys it is absolutely wonderful to hit you up today. Today we'll be going over how to not die in the horrid wastes of space.
- DELAY 30
- SAY Sadly, you got strande do this shithole ship with barely any supplies. How terrible for you!
- DELAY 30
- SAY No weapons, no KA, no nothing. Not even a drill! Just your wits and your basic tools.
- DELAY 30
- SAY Lucky for you, there are a few things around the ship that'll help you.
- DELAY 30
- SAY First is medicine. If you can't find your way to medbay, then you're a dead motherfucker anyway.
- DELAY 30
- SAY There's a wall nanomed in there, as well as some blood bags. Best to be prepared!
- DELAY 30
- SAY Next is a melee weapon. And you got the best one available, the Fire Axe! It's just up at the end of atmos.
- DELAY 30
- SAY Now finally the piece of resistance. Your boss has a very special item in their locker. A gun.
- DELAY 30
- SAY But not just any gun! A fucking lever action action 38 cal hunting rifle! They also have ammo and a design disk.
- DELAY 30
- SAY Now you'll either need to kiss ass or break in. I prefer breaking in while the boss is distracted.
- DELAY 30
- SAY Engineers aren't the only ones with the tools to break open lockers you know.
- DELAY 30
- SAY Your boss left you emitters, plasma, tools, portable generators, and a spare power source to bust that shit open!
- DELAY 30
- SAY Once you got all that it's time to bitch and moan until they build you your ore redemption machine and supply vendor!
- DELAY 30
- SAY Now excuse me, I'm gonna go punk my captain with a bubblegum I found outside.
-
- "}
diff --git a/code/datums/keybinding/client.dm b/code/datums/keybinding/client.dm
index e4b940c7f722..3e78c4ac4c23 100644
--- a/code/datums/keybinding/client.dm
+++ b/code/datums/keybinding/client.dm
@@ -45,3 +45,39 @@
return
user.mob.button_pressed_F12()
return TRUE
+
+/client
+ var/fullscreen = FALSE
+/datum/keybinding/client/t_fullscreen
+ hotkey_keys = list("F11")
+ name = "change_fullscreen"
+ full_name = "Toggle Fullscreen"
+ description = "Change window to Fullscreen or back"
+ keybind_signal = COMSIG_KB_CLIENT_FULLSCREEN_DOWN
+
+/datum/keybinding/client/t_fullscreen/down(client/C)
+ . = ..()
+ C.toggle_fullscreen()
+
+
+/client/verb/toggle_fullscreen()
+ set name = "Toggle Fullscreen"
+ set category = "OOC"
+
+ fullscreen = !fullscreen
+
+ if (fullscreen)
+ winset(usr, "mainwindow", "on-size=")
+ winset(usr, "mainwindow", "titlebar=false")
+ winset(usr, "mainwindow", "can-resize=false")
+ winset(usr, "mainwindow", "menu=")
+ winset(usr, "mainwindow", "is-maximized=false")
+ winset(usr, "mainwindow", "is-maximized=true")
+ else
+ winset(usr, "mainwindow", "titlebar=true")
+ winset(usr, "mainwindow", "can-resize=true")
+ winset(usr, "mainwindow", "menu=menu")
+ winset(usr, "mainwindow", "is-maximized=false")
+ winset(usr, "mainwindow", "on-size=fitviewport")
+
+ fit_viewport()
diff --git a/code/datums/mapgen/planetary/AsteroidGenerator.dm b/code/datums/mapgen/planetary/AsteroidGenerator.dm
index c2f7a5340097..dc5c27ac79e7 100644
--- a/code/datums/mapgen/planetary/AsteroidGenerator.dm
+++ b/code/datums/mapgen/planetary/AsteroidGenerator.dm
@@ -111,10 +111,11 @@
)
feature_spawn_list = list(
+ /obj/structure/spawner/burrow/asteroid = 3,
/obj/structure/geyser/random = 1,
- /obj/structure/spawner/mining/goliath = 1,
- /obj/structure/spawner/mining = 1,
- /obj/structure/spawner/mining/hivelord = 1
+ /obj/structure/vein/asteroid = 5,
+ /obj/structure/vein/classtwo/asteroid = 10,
+ /obj/structure/vein/classthree/asteroid = 5
)
mob_spawn_list = list(
@@ -157,8 +158,11 @@
)
feature_spawn_list = list(
- /obj/structure/geyser/random = 1,
- /obj/structure/spawner/mining/carp = 1
+ /obj/structure/geyser/random = 5,
+ /obj/structure/spawner/carp = 5,
+ /obj/structure/vein/asteroid = 10,
+ /obj/structure/vein/classtwo/asteroid = 15,
+ /obj/structure/vein/classthree/asteroid = 12
)
mob_spawn_list = list(
diff --git a/code/datums/mapgen/planetary/JungleGenerator.dm b/code/datums/mapgen/planetary/JungleGenerator.dm
index 45ae4a7120cc..077065c8e44e 100644
--- a/code/datums/mapgen/planetary/JungleGenerator.dm
+++ b/code/datums/mapgen/planetary/JungleGenerator.dm
@@ -180,7 +180,7 @@
feature_spawn_chance = 0.5
feature_spawn_list = list(
/obj/item/pickaxe/rusted = 1,
- /obj/structure/spawner/ice_moon = 1,
+ /obj/structure/spawner/burrow/jungle_planet = 1,
/obj/effect/spawner/lootdrop/anomaly/jungle = 1
)
diff --git a/code/datums/mapgen/planetary/LavaGenerator.dm b/code/datums/mapgen/planetary/LavaGenerator.dm
index c244f3ef2560..bca54d019397 100644
--- a/code/datums/mapgen/planetary/LavaGenerator.dm
+++ b/code/datums/mapgen/planetary/LavaGenerator.dm
@@ -84,7 +84,7 @@
/datum/biome/lavaland
open_turf_types = list(
- /turf/open/floor/plating/asteroid/basalt/lava_land_surface/lit = 1
+ /turf/open/floor/plating/asteroid/basalt/lava_land_surface/lit = 1,
)
flora_spawn_chance = 1
flora_spawn_list = list(
@@ -93,17 +93,22 @@
/obj/structure/flora/ash/fern = 5,
/obj/structure/flora/ash/fireblossom = 1,
/obj/structure/flora/ash/puce = 5,
+ /obj/item/mine/pressure/explosive/rusty/live = 1,
)
feature_spawn_chance = 0.3
feature_spawn_list = list(
+ /obj/structure/flora/rock/hell = 20,
+ /obj/structure/elite_tumor = 4,
+ /obj/structure/geyser/random = 4,
+ /obj/effect/spawner/lootdrop/anomaly/lava = 2,
/obj/structure/flora/rock/hell = 14,
/obj/structure/vein = 5,
/obj/structure/vein/classtwo = 2,
/obj/structure/elite_tumor = 2,
/obj/structure/geyser/random = 2,
/obj/structure/vein/classthree = 1,
+ /obj/effect/spawner/minefield = 1,
/obj/effect/spawner/lootdrop/anomaly/lava = 1,
-
)
mob_spawn_chance = 4
mob_spawn_list = list(
@@ -115,9 +120,7 @@
/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/crystal = 1,
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/forgotten = 1,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/crystal = 1,
- /obj/structure/spawner/lavaland/low_threat = 8,
- /obj/structure/spawner/lavaland/medium_threat = 3,
- /obj/structure/spawner/lavaland/high_threat = 1,
+ /obj/structure/spawner/burrow/lava_planet = 10
)
/datum/biome/lavaland/forest
@@ -237,10 +240,7 @@
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 10,
- /obj/structure/spawner/lavaland/low_threat = 8,
- /obj/structure/spawner/lavaland/medium_threat = 3,
- /obj/structure/spawner/lavaland/high_threat = 2,
- /obj/structure/spawner/lavaland/extreme_threat = 1
+ /obj/structure/spawner/burrow/lava_planet = 10
)
flora_spawn_chance = 1
flora_spawn_list = list(
@@ -250,14 +250,17 @@
/obj/structure/flora/ash/cacti = 1,
/obj/structure/flora/ash/tall_shroom = 2,
/obj/structure/flora/ash/fern = 2,
- /obj/structure/flora/ash/puce = 2
+ /obj/structure/flora/ash/puce = 2,
+ /obj/item/mine/proximity/explosive/live = 1,
+ /obj/item/mine/pressure/explosive/rusty/live = 1
)
/datum/biome/cave/lavaland/rocky
open_turf_types = list(/turf/open/floor/plating/asteroid/purple = 1)
flora_spawn_list = list(
- /obj/structure/flora/rock/pile/lava = 1,
- /obj/structure/flora/rock/lava = 1
+ /obj/structure/flora/rock/pile/lava = 3,
+ /obj/structure/flora/rock/lava = 3,
+ /obj/item/mine/pressure/explosive/rusty/live = 1
)
flora_spawn_chance = 5
@@ -271,6 +274,7 @@
/obj/structure/flora/ash/cap_shroom = 2,
/obj/structure/flora/ash/stem_shroom = 2,
/obj/structure/flora/ash/cacti = 1,
+ /obj/item/mine/pressure/explosive/rusty/live = 1,
/obj/structure/flora/ash/tall_shroom = 2
)
diff --git a/code/datums/mapgen/planetary/RockGenerator.dm b/code/datums/mapgen/planetary/RockGenerator.dm
index 95e1273bb9d7..30349a2ea53b 100644
--- a/code/datums/mapgen/planetary/RockGenerator.dm
+++ b/code/datums/mapgen/planetary/RockGenerator.dm
@@ -91,6 +91,7 @@
/obj/structure/vein/classtwo = 40,
/obj/effect/spawner/lootdrop/anomaly/rock = 10,
/obj/structure/vein/classthree = 10,
+ /obj/effect/spawner/minefield = 2,
/obj/effect/spawner/lootdrop/anomaly/big = 1 //get out of here stalker
)
@@ -98,10 +99,11 @@
mob_spawn_chance = 3
flora_spawn_list = list(
- /obj/structure/flora/rock/rockplanet = 3,
- /obj/structure/flora/tree/cactus = 4,
- /obj/structure/flora/ash/cacti = 1,
- /obj/structure/flora/ash/garden/arid = 1,
+ /obj/structure/flora/rock/rockplanet = 6,
+ /obj/structure/flora/tree/cactus = 8,
+ /obj/structure/flora/ash/cacti = 2,
+ /obj/structure/flora/ash/garden/arid = 2,
+ /obj/item/mine/pressure/explosive/rusty/live = 1
)
mob_spawn_list = list(
@@ -136,6 +138,7 @@
/obj/structure/flora/ash/cacti = 2,
/obj/structure/flora/grass/rockplanet/dead = 8,
/obj/structure/flora/ash/garden/arid = 1,
+ /obj/item/mine/pressure/explosive/rusty/live = 1
)
/datum/biome/cave/rock
@@ -143,10 +146,12 @@
open_turf_types = list(/turf/open/floor/plating/asteroid/rockplanet/cracked = 1)
flora_spawn_chance = 4
flora_spawn_list = list(
- /obj/structure/flora/rock/rockplanet = 4,
- /obj/structure/flora/rock/pile/rockplanet = 4,
- /obj/structure/flora/ash/fern = 2,
- /obj/structure/flora/ash/puce = 1,
+ /obj/structure/flora/rock/rockplanet = 8,
+ /obj/structure/flora/rock/pile/rockplanet = 8,
+ /obj/structure/flora/ash/fern = 4,
+ /obj/structure/flora/ash/puce = 2,
+ /obj/item/mine/pressure/explosive/rusty/live = 1,
+ /obj/item/mine/proximity/explosive/live = 1,
)
feature_spawn_chance = 0.5
feature_spawn_list = list(
@@ -155,7 +160,8 @@
/obj/structure/vein/classtwo = 2,
/obj/structure/elite_tumor = 1,
/obj/structure/vein/classthree = 1,
- /obj/structure/spawner/ice_moon/rockplanet = 4,
+ /obj/structure/spawner/burrow/rock_plant = 4,
+ /obj/effect/spawner/minefield = 1,
/obj/effect/spawner/lootdrop/anomaly/rock/cave = 1,
)
mob_spawn_chance = 6
@@ -172,11 +178,13 @@
open_turf_types = list(/turf/open/floor/plating/asteroid/rockplanet/cracked = 1)
flora_spawn_chance = 5
flora_spawn_list = list(
- /obj/structure/flora/rock/rockplanet = 4,
- /obj/structure/flora/rock/pile/rockplanet = 4,
- /obj/structure/flora/ash/fern = 4,
- /obj/structure/flora/ash/puce = 2,
- /obj/structure/flora/ash/garden/arid = 1,
+ /obj/structure/flora/rock/rockplanet = 8,
+ /obj/structure/flora/rock/pile/rockplanet = 8,
+ /obj/structure/flora/ash/fern = 6,
+ /obj/structure/flora/ash/puce = 4,
+ /obj/structure/flora/ash/garden/arid = 2,
+ /obj/item/mine/proximity/explosive/live = 1,
+ /obj/item/mine/pressure/explosive/rusty/live = 1
)
mob_spawn_list = list(
/mob/living/simple_animal/hostile/netherworld/asteroid = 30,
diff --git a/code/datums/mapgen/planetary/SandGenerator.dm b/code/datums/mapgen/planetary/SandGenerator.dm
index 442daa0c7705..1431ab53c6b9 100644
--- a/code/datums/mapgen/planetary/SandGenerator.dm
+++ b/code/datums/mapgen/planetary/SandGenerator.dm
@@ -103,7 +103,7 @@
/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 50,
/mob/living/simple_animal/hostile/asteroid/basilisk/whitesands = 40,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30,
- /mob/living/simple_animal/hostile/asteroid/whitesands/survivor/random = 25,
+ /mob/living/simple_animal/hostile/human/hermit/survivor/random = 25,
)
/datum/biome/sand/wasteland
@@ -135,7 +135,7 @@
)
mob_spawn_chance = 1
mob_spawn_list = list(
- /mob/living/simple_animal/hostile/asteroid/whitesands/survivor/random = 1,
+ /mob/living/simple_animal/hostile/human/hermit/survivor/random = 1,
)
/datum/biome/sand/grass/dead
@@ -169,7 +169,7 @@
/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 40,
/mob/living/simple_animal/hostile/asteroid/basilisk/whitesands = 30,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 20,
- /mob/living/simple_animal/hostile/asteroid/whitesands/survivor/random = 40,
+ /mob/living/simple_animal/hostile/human/hermit/survivor/random = 40,
)
/datum/biome/sand/acid //plains
@@ -217,9 +217,7 @@
/mob/living/simple_animal/hostile/asteroid/basilisk/whitesands = 40,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 20,
- /obj/structure/spawner/lavaland/sand_world/low_threat = 14,
- /obj/structure/spawner/lavaland/sand_world/medium_threat = 8,
- /obj/structure/spawner/lavaland/sand_world/high_threat = 2,
+ /obj/structure/spawner/burrow/sand_planet = 25
)
/datum/biome/cave/sand/volcanic
diff --git a/code/datums/mapgen/planetary/SnowGenerator.dm b/code/datums/mapgen/planetary/SnowGenerator.dm
index a066647a0e4d..7fddcd176c66 100644
--- a/code/datums/mapgen/planetary/SnowGenerator.dm
+++ b/code/datums/mapgen/planetary/SnowGenerator.dm
@@ -90,19 +90,19 @@
/turf/open/floor/plating/asteroid/snow/lit = 25
)
flora_spawn_list = list(
- /obj/structure/flora/tree/pine = 2,
- /obj/structure/flora/rock/icy = 2,
- /obj/structure/flora/rock/pile/icy = 2,
- /obj/structure/flora/grass/both = 6,
- /obj/structure/flora/ash/chilly = 2,
- /obj/structure/flora/ash/garden/frigid = 1,
+ /obj/structure/flora/tree/pine = 4,
+ /obj/structure/flora/rock/icy = 4,
+ /obj/structure/flora/rock/pile/icy = 4,
+ /obj/structure/flora/grass/both = 12,
+ /obj/structure/flora/ash/chilly = 4,
+ /obj/structure/flora/ash/garden/frigid = 2,
+ /obj/item/mine/pressure/explosive/rusty/live = 1
)
flora_spawn_chance = 10
mob_spawn_chance = 1
mob_spawn_list = list(
/mob/living/simple_animal/hostile/asteroid/wolf/random = 30,
- /obj/structure/spawner/ice_moon = 2,
- /obj/structure/spawner/ice_moon/polarbear = 2,
+ /obj/structure/spawner/burrow/ice_planet = 4,
/mob/living/simple_animal/hostile/asteroid/polarbear/random = 30,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 10,
@@ -114,10 +114,9 @@
feature_spawn_list = list(
/obj/effect/spawner/lootdrop/anomaly/ice = 12,
/obj/effect/spawner/lootdrop/anomaly/big = 1,
- /obj/structure/spawner/ice_moon/demonic_portal/low_threat = 25,
- /obj/structure/spawner/ice_moon/demonic_portal/medium_threat = 50,
- /obj/structure/spawner/ice_moon/demonic_portal/high_threat = 13,
+ /obj/structure/spawner/burrow/ice_planet = 80,
/obj/structure/vein/ice = 25,
+ /obj/effect/spawner/minefield = 2,
/obj/structure/vein/ice/classtwo = 50,
/obj/structure/vein/ice/classthree = 10,
)
@@ -148,9 +147,10 @@
/datum/biome/snow/forest
flora_spawn_chance = 15
flora_spawn_list = list(
- /obj/structure/flora/tree/pine = 10,
- /obj/structure/flora/tree/dead = 3,
- /obj/structure/flora/grass/both = 4
+ /obj/structure/flora/tree/pine = 20,
+ /obj/structure/flora/tree/dead = 6,
+ /obj/structure/flora/grass/both = 8,
+ /obj/item/mine/pressure/explosive/rusty/live = 1,
)
/datum/biome/snow/forest/dense
@@ -159,6 +159,7 @@
/obj/structure/flora/tree/pine = 20,
/obj/structure/flora/grass/both = 6,
/obj/structure/flora/tree/dead = 3,
+ /obj/item/mine/pressure/explosive/rusty/live = 1,
)
/datum/biome/arctic
@@ -167,8 +168,7 @@
)
feature_spawn_chance = 0.1
feature_spawn_list = list(
- /obj/structure/spawner/ice_moon = 2,
- /obj/structure/spawner/ice_moon/polarbear = 2,
+ /obj/structure/spawner/burrow/ice_planet = 4,
/obj/structure/statue/snow/snowman = 3,
/obj/structure/statue/snow/snowlegion = 1,
/obj/structure/vein/ice = 3,
@@ -177,8 +177,7 @@
)
mob_spawn_list = list(
/mob/living/simple_animal/hostile/asteroid/wolf/random = 30,
- /obj/structure/spawner/ice_moon = 2,
- /obj/structure/spawner/ice_moon/polarbear = 2,
+ /obj/structure/spawner/burrow/ice_planet = 2,
/mob/living/simple_animal/hostile/asteroid/polarbear/random = 30,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 10,
@@ -215,10 +214,7 @@
feature_spawn_list = list(
/obj/effect/spawner/lootdrop/anomaly/ice = 100,
/obj/effect/spawner/lootdrop/anomaly/big = 1,
- /obj/structure/spawner/ice_moon/demonic_portal/low_threat = 200,
- /obj/structure/spawner/ice_moon/demonic_portal/medium_threat = 400,
- /obj/structure/spawner/ice_moon/demonic_portal/high_threat = 40,
- /obj/structure/spawner/ice_moon/demonic_portal/extreme_threat = 1,
+ /obj/structure/spawner/burrow/ice_planet/hard = 600,
/obj/structure/vein/ice = 300,
/obj/structure/vein/ice/classtwo = 500,
/obj/structure/vein/ice/classthree = 50,
@@ -242,15 +238,17 @@
)
flora_spawn_chance = 6
flora_spawn_list = list(
- /obj/structure/flora/grass/both = 5,
- /obj/structure/flora/rock/pile/icy = 1,
- /obj/structure/flora/rock/icy = 1,
- /obj/structure/flora/ash/space = 1,
- /obj/structure/flora/ash/leaf_shroom = 1,
- /obj/structure/flora/ash/cap_shroom = 1,
- /obj/structure/flora/ash/stem_shroom = 1,
- /obj/structure/flora/ash/puce = 1,
- /obj/structure/flora/ash/garden/frigid = 1,
+ /obj/structure/flora/grass/both = 10,
+ /obj/structure/flora/rock/pile/icy = 2,
+ /obj/structure/flora/rock/icy = 2,
+ /obj/structure/flora/ash/space = 2,
+ /obj/structure/flora/ash/leaf_shroom = 2,
+ /obj/structure/flora/ash/cap_shroom = 2,
+ /obj/structure/flora/ash/stem_shroom = 2,
+ /obj/structure/flora/ash/puce = 2,
+ /obj/structure/flora/ash/garden/frigid = 2,
+ /obj/item/mine/proximity/explosive/live = 1,
+ /obj/item/mine/pressure/explosive/rusty/live = 1
)
closed_turf_types = list(
/turf/closed/mineral/random/snow = 1
@@ -258,8 +256,7 @@
mob_spawn_chance = 2
mob_spawn_list = list(
/mob/living/simple_animal/hostile/asteroid/wolf/random = 30,
- /obj/structure/spawner/ice_moon = 2,
- /obj/structure/spawner/ice_moon/polarbear = 2,
+ /obj/structure/spawner/burrow/ice_planet = 4,
/mob/living/simple_animal/hostile/asteroid/polarbear/random = 30,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 10,
@@ -269,16 +266,13 @@
)
feature_spawn_chance = 0.2
feature_spawn_list = list(
- /obj/structure/spawner/ice_moon/demonic_portal/low_threat = 20,
- /obj/structure/spawner/ice_moon/demonic_portal/medium_threat = 40,
- /obj/structure/spawner/ice_moon/demonic_portal/high_threat = 5,
- /obj/structure/spawner/ice_moon/demonic_portal/extreme_threat = 1,
- /obj/structure/spawner/ice_moon = 20,
- /obj/structure/spawner/ice_moon/polarbear = 20,
+ /obj/structure/spawner/burrow/ice_planet = 60,
+ /obj/structure/spawner/burrow/ice_planet = 40,
/obj/effect/spawner/lootdrop/anomaly/ice/cave = 10,
/obj/structure/vein/ice = 30,
/obj/structure/vein/ice/classtwo = 50,
/obj/structure/vein/ice/classthree = 6,
+ /obj/effect/spawner/minefield = 2,
)
/datum/biome/cave/snow/thawed
@@ -317,9 +311,10 @@
)
flora_spawn_chance = 3
flora_spawn_list = list(
- /obj/structure/flora/ash/leaf_shroom = 1,
- /obj/structure/flora/ash/cap_shroom = 1,
- /obj/structure/flora/ash/stem_shroom = 1,
+ /obj/structure/flora/ash/leaf_shroom = 3,
+ /obj/structure/flora/ash/cap_shroom = 3,
+ /obj/structure/flora/ash/stem_shroom = 3,
+ /obj/item/mine/pressure/explosive/fire/live = 1,
)
feature_spawn_chance = 0.2
diff --git a/code/datums/mapgen/planetary/WasteGenerator.dm b/code/datums/mapgen/planetary/WasteGenerator.dm
index d0243740bc3b..9b100412a391 100644
--- a/code/datums/mapgen/planetary/WasteGenerator.dm
+++ b/code/datums/mapgen/planetary/WasteGenerator.dm
@@ -125,7 +125,9 @@
//the illusive shrapnel plant
- /obj/effect/mine/shrapnel/human_only = 10
+ /obj/item/mine/pressure/explosive/shrapnel/live = 30,
+ /obj/effect/spawner/lootdrop/mine = 8,
+ /obj/effect/spawner/minefield = 2
)
feature_spawn_list = list(
@@ -202,7 +204,9 @@
/obj/effect/spawner/lootdrop/maintenance/four = 20,
/obj/structure/flora/ash/garden/waste = 300,
/obj/structure/flora/ash/glowshroom = 1800,
- /obj/effect/mine/shrapnel/human_only = 10
+ /obj/item/mine/pressure/explosive/shrapnel/live = 30,
+ /obj/effect/spawner/lootdrop/mine = 8,
+ /obj/effect/spawner/minefield = 2
)
/datum/biome/waste/tar_bed //tar colorings
@@ -246,7 +250,10 @@
/obj/structure/closet/crate/secure/loot = 30,
/obj/effect/spawner/lootdrop/waste/atmos_can = 180,
/obj/effect/spawner/lootdrop/waste/atmos_can/rare = 1,
- /obj/effect/spawner/lootdrop/waste/salvageable = 300
+ /obj/effect/spawner/lootdrop/waste/salvageable = 300,
+ /obj/item/mine/pressure/explosive/rad/live = 30,
+ /obj/effect/spawner/lootdrop/mine = 8,
+ /obj/effect/spawner/minefield = 2
)
mob_spawn_list = list( //nor organics, more biased towards hivebots though
/mob/living/simple_animal/hostile/hivebot/wasteplanet/strong = 80,
@@ -256,10 +263,7 @@
/mob/living/simple_animal/bot/secbot/ed209/rockplanet = 3,
/mob/living/simple_animal/hostile/abandoned_minebot = 15,
/mob/living/simple_animal/bot/floorbot/rockplanet = 15,
- /obj/structure/spawner/wasteplanet/hivebot/low_threat = 20,
- /obj/structure/spawner/wasteplanet/hivebot/medium_threat = 10,
- /obj/structure/spawner/wasteplanet/hivebot/high_threat = 5,
- /obj/structure/spawner/wasteplanet/hivebot/extreme_threat = 2
+ /obj/structure/spawner/hivebot = 35
)
/datum/biome/waste/metal/rust
@@ -308,7 +312,9 @@
/obj/effect/spawner/lootdrop/waste/salvageable = 400,
/obj/structure/flora/ash/garden/waste = 70,
/obj/structure/flora/ash/glowshroom = 400, //more common in caves
- /obj/effect/mine/shrapnel/human_only = 10
+ /obj/item/mine/pressure/explosive/rad/live = 10,
+ /obj/effect/spawner/lootdrop/mine = 8,
+ /obj/effect/spawner/minefield = 2
)
feature_spawn_list = list(
@@ -362,7 +368,10 @@
/obj/effect/spawner/lootdrop/maintenance/two = 50,
/obj/effect/spawner/lootdrop/maintenance/three = 100,
/obj/effect/spawner/lootdrop/maintenance/four = 200,
- /obj/structure/flora/ash/glowshroom = 1800
+ /obj/structure/flora/ash/glowshroom = 1800,
+ /obj/item/mine/pressure/explosive/rad/live = 30,
+ /obj/effect/spawner/lootdrop/mine = 8,
+ /obj/effect/spawner/minefield = 2
)
feature_spawn_chance = 12
@@ -397,6 +406,9 @@
/obj/effect/spawner/lootdrop/maintenance/three = 20,
/obj/effect/spawner/lootdrop/maintenance/four = 40,
/obj/effect/spawner/lootdrop/waste/salvageable = 80,
+ /obj/item/mine/proximity/spawner/manhack/live = 40,
+ /obj/effect/spawner/lootdrop/mine = 8,
+ /obj/effect/spawner/minefield/manhack = 2
)
mob_spawn_list = list( //nor organics, more biased towards hivebots though
/mob/living/simple_animal/hostile/hivebot/wasteplanet/strong = 80,
@@ -406,10 +418,7 @@
/mob/living/simple_animal/bot/secbot/ed209/rockplanet = 3,
/mob/living/simple_animal/hostile/abandoned_minebot = 15,
/mob/living/simple_animal/bot/floorbot/rockplanet = 15,
- /obj/structure/spawner/wasteplanet/hivebot/low_threat = 20,
- /obj/structure/spawner/wasteplanet/hivebot/medium_threat = 10,
- /obj/structure/spawner/wasteplanet/hivebot/high_threat = 5,
- /obj/structure/spawner/wasteplanet/hivebot/extreme_threat = 2
+ /obj/structure/spawner/hivebot = 20
)
/datum/biome/cave/waste/metal/hivebot
@@ -427,19 +436,17 @@
/obj/effect/spawner/lootdrop/maintenance/three = 10,
/obj/effect/spawner/lootdrop/maintenance/four = 20,
/obj/effect/spawner/lootdrop/waste/salvageable = 40,
- /obj/structure/foamedmetal = 100
+ /obj/structure/foamedmetal = 100,
+ /obj/item/mine/proximity/spawner/manhack/live = 20
)
mob_spawn_list = list( //Whoops! All hivebots!
/mob/living/simple_animal/hostile/hivebot/wasteplanet/strong = 80,
/mob/living/simple_animal/hostile/hivebot/wasteplanet/ranged = 50,
- /mob/living/simple_animal/hostile/hivebot/wasteplanet/ranged/rapid = 50,
-
+ /mob/living/simple_animal/hostile/hivebot/wasteplanet/ranged/rapid = 50
)
mob_spawn_chance = 30
feature_spawn_list = list(
- /obj/structure/spawner/wasteplanet/hivebot/low_threat = 20,
- /obj/structure/spawner/wasteplanet/hivebot/medium_threat = 10,
- /obj/structure/spawner/wasteplanet/hivebot/high_threat = 5,
- /obj/structure/spawner/wasteplanet/hivebot/extreme_threat = 2
+ /obj/structure/spawner/hivebot = 1,
+ /obj/effect/spawner/minefield/manhack = 2
)
feature_spawn_chance = 2 //hivebot biomes should have their dongles
diff --git a/code/datums/mapgen/single_biome/WasteplanetCaves.dm b/code/datums/mapgen/single_biome/WasteplanetCaves.dm
index 472a5cf4d54b..08f63ba3149a 100644
--- a/code/datums/mapgen/single_biome/WasteplanetCaves.dm
+++ b/code/datums/mapgen/single_biome/WasteplanetCaves.dm
@@ -39,10 +39,12 @@
/obj/structure/salvageable/circuit_imprinter = 8,
/obj/structure/salvageable/destructive_analyzer = 8,
/obj/structure/salvageable/server = 8,
+ /obj/item/mine/pressure/explosive/rusty/live = 30,
+ /obj/effect/spawner/lootdrop/mine = 8
)
feature_spawn_list = list(
/obj/structure/geyser/random = 1,
- /obj/effect/mine/shrapnel/human_only = 1
+ /obj/effect/spawner/minefield = 1
)
mob_spawn_list = list(
//hivebots, not too difficult
diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm
index 98db1541c953..ed8dd509ec3b 100644
--- a/code/datums/materials/basemats.dm
+++ b/code/datums/materials/basemats.dm
@@ -127,30 +127,6 @@ Unless you know what you're doing, only use the first three numbers. They're in
ore_type = /obj/item/stack/ore/bluespace_crystal
value_per_unit = 0.15
-///Honks and slips
-/datum/material/bananium
- name = "bananium"
- id = "bananium"
- desc = "Material with hilarious properties"
- color = "#ffff00" //obnoxiously bright yellow
- categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
- sheet_type = /obj/item/stack/sheet/mineral/bananium
- ore_type = /obj/item/stack/ore/bananium
- value_per_unit = 0.5
- beauty_modifier = 0.5
- armor_modifiers = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 0) //Clowns cant be blown away.
-
-/datum/material/bananium/on_applied(atom/source, amount, material_flags)
- . = ..()
- source.LoadComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50, falloff_exponent = 20)
- source.AddComponent(/datum/component/slippery, min(amount / 10, 80))
-
-
-/datum/material/bananium/on_removed(atom/source, amount, material_flags)
- . = ..()
- qdel(source.GetComponent(/datum/component/slippery))
- qdel(source.GetComponent(/datum/component/squeak))
-
///Mediocre force increase
/datum/material/titanium
@@ -166,18 +142,6 @@ Unless you know what you're doing, only use the first three numbers. They're in
beauty_modifier = 0.05
armor_modifiers = list("melee" = 1.35, "bullet" = 1.3, "laser" = 1.3, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1)
-/datum/material/runite
- name = "runite"
- id = "runite"
- desc = "Runite"
- color = "#3F9995"
- strength_modifier = 1.3
- categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
- sheet_type = /obj/item/stack/sheet/mineral/runite
- value_per_unit = 0.3
- beauty_modifier = 0.5
- armor_modifiers = list("melee" = 1.35, "bullet" = 2, "laser" = 0.5, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 1.4, "acid" = 1) //rune is weak against magic lasers but strong against bullets. This is the combat triangle.
-
///Force decrease
/datum/material/plastic
name = "plastic"
@@ -224,42 +188,20 @@ Unless you know what you're doing, only use the first three numbers. They're in
var/obj/wooden = source
wooden.resistance_flags &= ~FLAMMABLE
-///Stronk force increase
-/datum/material/adamantine
- name = "adamantine"
- id = "adamantine"
- desc = "A powerful material made out of magic, I mean science!"
- color = "#6d7e8e"
+//Remember when the theme used to be "Eerie" before 1.3? Good times.
+/datum/material/hellstone
+ name = "hellstone"
+ id = "hellstone"
+ desc = "A colloquialism given to millenia-old slag, heat-treated through the eons in deep magma."
+ color = "#ffaf5e"
strength_modifier = 1.5
categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
- sheet_type = /obj/item/stack/sheet/mineral/adamantine
+ sheet_type = /obj/item/stack/sheet/mineral/hidden/hellstone
+ ore_type = /obj/item/stack/ore/hellstone
value_per_unit = 0.25
beauty_modifier = 0.4
armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.3, "energy" = 1.3, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 2.5, "acid" = 1)
-///RPG Magic.
-/datum/material/mythril
- name = "mythril"
- id = "mythril"
- desc = "How this even exists is byond me"
- color = "#f2d5d7"
- categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
- sheet_type = /obj/item/stack/sheet/mineral/mythril
- value_per_unit = 0.75
- strength_modifier = 1.2
- armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.5, "energy" = 1.5, "bomb" = 1.5, "bio" = 1.5, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5)
- beauty_modifier = 0.5
-
-/datum/material/mythril/on_applied_obj(atom/source, amount, material_flags)
- . = ..()
- if(istype(source, /obj/item))
- source.AddComponent(/datum/component/fantasy)
-
-/datum/material/mythril/on_removed_obj(atom/source, material_flags)
- . = ..()
- if(istype(source, /obj/item))
- qdel(source.GetComponent(/datum/component/fantasy))
-
//formed when freon react with o2, emits a lot of plasma when heated
/datum/material/hot_ice
name = "hot ice"
@@ -323,18 +265,6 @@ Unless you know what you're doing, only use the first three numbers. They're in
turf_sound_override = FOOTSTEP_SAND
texture_layer_icon_state = "sand"
-/datum/material/runedmetal
- name = "runed metal"
- id = "runed metal"
- desc = "Mir'ntrath barhah Nar'sie."
- color = "#3C3434"
- categories = list(MAT_CATEGORY_RIGID = TRUE)
- sheet_type = /obj/item/stack/sheet/runed_metal
- value_per_unit = 0.75
- armor_modifiers = list("melee" = 1.2, "bullet" = 1.2, "laser" = 1, "energy" = 1, "bomb" = 1.2, "bio" = 1.2, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5)
- beauty_modifier = -0.15
- texture_layer_icon_state = "runed"
-
/datum/material/bronze
name = "bronze"
id = "bronze"
diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm
index aed6577a5af9..62479d90e0d3 100644
--- a/code/datums/materials/pizza.dm
+++ b/code/datums/materials/pizza.dm
@@ -28,4 +28,4 @@
/datum/material/pizza/proc/make_edible(atom/source, amount, material_flags)
var/nutriment_count = 3 * (amount / MINERAL_MATERIAL_AMOUNT)
var/oil_count = 2 * (amount / MINERAL_MATERIAL_AMOUNT)
- source.AddComponent(/datum/component/edible, list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/cooking_oil = oil_count), null, GRAIN | MEAT | DAIRY | VEGETABLES, null, 30, list("crust", "tomato", "cheese", "meat"))
+ source.AddComponent(/datum/component/edible, list(/datum/reagent/consumable/nutriment = nutriment_count, /datum/reagent/consumable/cooking_oil = oil_count), null, GRAIN | MEAT | DAIRY | VEGETABLES, null, 30, list("crust", "tomato", "cheese", "meat"), filling_color = COLOR_YELLOW)
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index fc91d2c71de1..96ca4b12d8b4 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -55,7 +55,6 @@
var/damnation_type = 0
var/datum/mind/soulOwner //who owns the soul. Under normal circumstances, this will point to src
var/hasSoul = TRUE // If false, renders the character unable to sell their soul.
- var/holy_role = NONE //is this person a chaplain or admin role allowed to use bibles, Any rank besides 'NONE' allows for this.
var/mob/living/enslaved_to //If this mind's master is another mob
var/datum/language_holder/language_holder
@@ -79,6 +78,9 @@
/// The index for our current scar slot, so we don't have to constantly check the savefile (unlike the slots themselves, this index is independent of selected char slot, and increments whenever a valid char is joined with)
var/current_scar_slot_index
+ /// Guestbook datum, in case we actually make use of the guestbook mechanics
+ var/datum/guestbook/guestbook
+
///Skill multiplier, adjusts how much xp you get/loose from adjust_xp. Dont override it directly, add your reason to experience_multiplier_reasons and use that as a key to put your value in there.
var/experience_multiplier = 1
///Skill multiplier list, just slap your multiplier change onto this with the type it is coming from as key.
@@ -95,6 +97,7 @@
key = _key
soulOwner = src
martial_art = default_martial_art
+ guestbook = new()
init_known_skills()
/datum/mind/Destroy()
@@ -102,6 +105,7 @@
if(islist(antag_datums))
QDEL_LIST(antag_datums)
QDEL_NULL(language_holder)
+ QDEL_NULL(guestbook)
set_current(null)
soulOwner = null
return ..()
diff --git a/code/datums/mood_events/drug_events.dm b/code/datums/mood_events/drug_events.dm
index 6af401e8b009..028973c5c839 100644
--- a/code/datums/mood_events/drug_events.dm
+++ b/code/datums/mood_events/drug_events.dm
@@ -4,12 +4,12 @@
/datum/mood_event/smoked
description = "I have had a smoke recently.\n"
- mood_change = 2
+ mood_change = 1
timeout = 6 MINUTES
/datum/mood_event/wrong_brand
- description = "I hate that brand of cigarettes.\n"
- mood_change = -2
+ description = "That brand of cigarette just doesn't hit right.\n"
+ mood_change = -1
timeout = 6 MINUTES
/datum/mood_event/overdose
diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index 84fca0443ca0..f5e51d1d59f4 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -292,3 +292,13 @@
description = "I was forced to eat cement...\n"
mood_change = -6
timeout = 4 MINUTES
+
+/datum/mood_event/joywire_emp
+ description = span_boldwarning("IT'S GONE!! IT'S GONE!!\n")
+ mood_change = -30
+ timeout = 5 MINUTES
+
+/datum/mood_event/mindscrew
+ description = span_boldwarning("It isn't ending... it isn't ending, come on...\n")
+ mood_change = -18
+ timeout = 3 MINUTES
diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm
index dbaac99c4296..f9e339c3c081 100644
--- a/code/datums/mood_events/generic_positive_events.dm
+++ b/code/datums/mood_events/generic_positive_events.dm
@@ -105,14 +105,6 @@
description = "My family heirloom is safe with me.\n"
mood_change = 1
-/datum/mood_event/fan_clown_pin
- description = "I love showing off my clown pin!\n"
- mood_change = 1
-
-/datum/mood_event/fan_mime_pin
- description = "I love showing off my mime pin!\n"
- mood_change = 1
-
/datum/mood_event/rilena_fan
description = "I love my RILENA merch!\n"
mood_change = 1
@@ -239,3 +231,13 @@
description = "Fishing is relaxing"
mood_change = 5
timeout = 3 MINUTES
+
+/datum/mood_event/joywire
+ description = span_boldnicegreen("I feel so joyous! Oh, so joyous!\n")
+ mood_change = 8
+ timeout = 10 SECONDS
+
+/datum/mood_event/root
+ description = span_nicegreen("I rooted recently, it feels good to charge naturally.\n")
+ mood_change = 5
+ timeout = 5 MINUTES
diff --git a/code/datums/mutations/actions.dm b/code/datums/mutations/actions.dm
index f2ffe7c25fd2..53080247b827 100644
--- a/code/datums/mutations/actions.dm
+++ b/code/datums/mutations/actions.dm
@@ -88,67 +88,6 @@
if(direction_text)
to_chat(user,"You consider [tracking_target]'s scent. The trail leads [direction_text].")
-/datum/mutation/human/firebreath
- name = "Fire Breath"
- desc = "An ancient mutation that gives lizards breath of fire."
- quality = POSITIVE
- difficulty = 12
- locked = TRUE
- text_gain_indication = "Your throat is burning!"
- text_lose_indication = "Your throat is cooling down."
- power = /obj/effect/proc_holder/spell/aimed/firebreath
- instability = 30
- energy_coeff = 1
- power_coeff = 1
-
-/datum/mutation/human/firebreath/modify()
- if(power)
- var/obj/effect/proc_holder/spell/aimed/firebreath/S = power
- S.strength = GET_MUTATION_POWER(src)
-
-/obj/effect/proc_holder/spell/aimed/firebreath
- name = "Fire Breath"
- desc = "You can breathe fire at a target."
- school = "evocation"
- charge_max = 600
- clothes_req = FALSE
- range = 20
- projectile_type = /obj/projectile/magic/aoe/fireball/firebreath
- base_icon_state = "fireball"
- action_icon_state = "fireball0"
- sound = 'sound/magic/demon_dies.ogg' //horrifying lizard noises
- active_msg = "You built up heat in your mouth."
- deactive_msg = "You swallow the flame."
- var/strength = 1
-
-/obj/effect/proc_holder/spell/aimed/firebreath/before_cast(list/targets)
- . = ..()
- if(iscarbon(usr))
- var/mob/living/carbon/C = usr
- if(C.is_mouth_covered())
- C.adjust_fire_stacks(2)
- C.IgniteMob()
- to_chat(C,"Something in front of your mouth caught fire!")
- return FALSE
-
-/obj/effect/proc_holder/spell/aimed/firebreath/ready_projectile(obj/projectile/P, atom/target, mob/user, iteration)
- if(!istype(P, /obj/projectile/magic/aoe/fireball))
- return
- var/obj/projectile/magic/aoe/fireball/F = P
- switch(strength)
- if(1 to 3)
- F.exp_light = strength-1
- if(4 to INFINITY)
- F.exp_heavy = strength-3
- F.exp_fire += strength
-
-/obj/projectile/magic/aoe/fireball/firebreath
- name = "fire breath"
- exp_heavy = 0
- exp_light = 0
- exp_flash = 0
- exp_fire= 4
-
/datum/mutation/human/void
name = "Void Magnet"
desc = "A rare genome that attracts odd forces not usually observed."
diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm
index 5545c4efde53..afd4e83cfe34 100644
--- a/code/datums/mutations/speech.dm
+++ b/code/datums/mutations/speech.dm
@@ -68,129 +68,6 @@
return
REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION)
-/datum/mutation/human/swedish
- name = "Swedish"
- desc = "A horrible mutation originating from the distant past. Thought to be eradicated after the incident in 2037."
- quality = MINOR_NEGATIVE
- text_gain_indication = "You feel Swedish, however that works."
- text_lose_indication = "The feeling of Swedishness passes."
-
-/datum/mutation/human/swedish/on_acquiring(mob/living/carbon/human/owner)
- if(..())
- return
- RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech))
-
-/datum/mutation/human/swedish/on_losing(mob/living/carbon/human/owner)
- if(..())
- return
- UnregisterSignal(owner, COMSIG_MOB_SAY)
-
-/datum/mutation/human/swedish/proc/handle_speech(datum/source, list/speech_args)
- SIGNAL_HANDLER
-
- var/message = speech_args[SPEECH_MESSAGE]
- if(message)
- message = replacetext(message,"w","v")
- message = replacetext(message,"j","y")
- message = replacetext(message,"a",pick("å","ä","æ","a"))
- message = replacetext(message,"bo","bjo")
- message = replacetext(message,"o",pick("ö","ø","o"))
- if(prob(30))
- message += " Bork[pick("",", bork",", bork, bork")]!"
- speech_args[SPEECH_MESSAGE] = trim(message)
-
-/datum/mutation/human/chav
- name = "Chav"
- desc = "Unknown"
- quality = MINOR_NEGATIVE
- text_gain_indication = "Ye feel like a reet prat like, innit?"
- text_lose_indication = "You no longer feel like being rude and sassy."
-
-/datum/mutation/human/chav/on_acquiring(mob/living/carbon/human/owner)
- if(..())
- return
- RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech))
-
-/datum/mutation/human/chav/on_losing(mob/living/carbon/human/owner)
- if(..())
- return
- UnregisterSignal(owner, COMSIG_MOB_SAY)
-
-/datum/mutation/human/chav/proc/handle_speech(datum/source, list/speech_args)
- var/message = speech_args[SPEECH_MESSAGE]
- if(message)
- message = " [message] "
- message = replacetext(message," looking at "," gawpin' at ")
- message = replacetext(message," great "," bangin' ")
- message = replacetext(message," man "," mate ")
- message = replacetext(message," friend ",pick(" mate "," bruv "," bledrin "))
- message = replacetext(message," what "," wot ")
- message = replacetext(message," drink "," wet ")
- message = replacetext(message," get "," giz ")
- message = replacetext(message," what "," wot ")
- message = replacetext(message," no thanks "," wuddent fukken do one ")
- message = replacetext(message," i don't know "," wot mate ")
- message = replacetext(message," no "," naw ")
- message = replacetext(message," robust "," chin ")
- message = replacetext(message," hi "," how what how ")
- message = replacetext(message," hello "," sup bruv ")
- message = replacetext(message," kill "," bang ")
- message = replacetext(message," murder "," bang ")
- message = replacetext(message," windows "," windies ")
- message = replacetext(message," window "," windy ")
- message = replacetext(message," break "," do ")
- message = replacetext(message," your "," yer ")
- message = replacetext(message," security "," coppers ")
- speech_args[SPEECH_MESSAGE] = trim(message)
-
-
-/datum/mutation/human/elvis
- name = "Elvis"
- desc = "A terrifying mutation named after its 'patient-zero'."
- quality = MINOR_NEGATIVE
- locked = TRUE
- text_gain_indication = "You feel pretty good, honeydoll."
- text_lose_indication = "You feel a little less conversation would be great."
-
-/datum/mutation/human/elvis/on_life()
- switch(pick(1,2))
- if(1)
- if(prob(15))
- var/list/dancetypes = list("swinging", "fancy", "stylish", "20'th century", "jivin'", "rock and roller", "cool", "salacious", "bashing", "smashing")
- var/dancemoves = pick(dancetypes)
- owner.visible_message("[owner] busts out some [dancemoves] moves!")
- if(2)
- if(prob(15))
- owner.visible_message("[owner] [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!")
-
-/datum/mutation/human/elvis/on_acquiring(mob/living/carbon/human/owner)
- if(..())
- return
- RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech))
-
-/datum/mutation/human/elvis/on_losing(mob/living/carbon/human/owner)
- if(..())
- return
- UnregisterSignal(owner, COMSIG_MOB_SAY)
-
-/datum/mutation/human/elvis/proc/handle_speech(datum/source, list/speech_args)
- SIGNAL_HANDLER
-
- var/message = speech_args[SPEECH_MESSAGE]
- if(message)
- message = " [message] "
- message = replacetext(message," i'm not "," I aint ")
- message = replacetext(message," girl ",pick(" honey "," baby "," baby doll "))
- message = replacetext(message," man ",pick(" son "," buddy "," brother"," pal "," friendo "))
- message = replacetext(message," out of "," outta ")
- message = replacetext(message," thank you "," thank you, thank you very much ")
- message = replacetext(message," thanks "," thank you, thank you very much ")
- message = replacetext(message," what are you "," whatcha ")
- message = replacetext(message," yes ",pick(" sure", "yea "))
- message = replacetext(message," muh valids "," my kicks ")
- speech_args[SPEECH_MESSAGE] = trim(message)
-
-
/datum/mutation/human/stoner
name = "Stoner"
desc = "A common mutation that severely decreases intelligence."
diff --git a/code/datums/numbered_display.dm b/code/datums/numbered_display.dm
index 9aa880aa75d9..b714be23fbbe 100644
--- a/code/datums/numbered_display.dm
+++ b/code/datums/numbered_display.dm
@@ -3,8 +3,8 @@
var/obj/item/sample_object
var/number
-/datum/numbered_display/New(obj/item/sample, _number = 1)
+/datum/numbered_display/New(obj/item/sample, _number = 1, datum/component/storage/parent)
if(!istype(sample))
qdel(src)
- sample_object = sample
+ sample_object = new /atom/movable/screen/storage/item_holder(null, parent, sample)
number = _number
diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm
index 964c269b5f43..15a580a89328 100644
--- a/code/datums/outfit.dm
+++ b/code/datums/outfit.dm
@@ -50,9 +50,13 @@
/// Type path of item to go in the glasses slot
var/glasses = null
+ var/wallet = null
+
/// Type path of item to go in the idcard slot
var/id = null
+ var/bank_card = null
+
/// Type path of item for left pocket slot
var/l_pocket = null
@@ -104,6 +108,9 @@
/// Set to FALSE if your outfit requires runtime parameters
var/can_be_admin_equipped = TRUE
+ // Used to determine if it should be ignored in unit tests due to being to dynamic to always spawn backpack contents right
+ var/random = FALSE
+
/**
* extra types for chameleon outfit changes, mostly guns
*
@@ -177,8 +184,13 @@
H.equip_to_slot_or_del(new ears(H),ITEM_SLOT_EARS, TRUE)
if(glasses)
H.equip_to_slot_or_del(new glasses(H),ITEM_SLOT_EYES, TRUE)
- if(id)
- H.equip_to_slot_or_del(new id(H),ITEM_SLOT_ID, TRUE)
+ if(!visualsOnly)
+ if(wallet)
+ H.equip_to_slot_or_del(new wallet(H),ITEM_SLOT_ID, TRUE)
+ if(id)
+ H.equip_to_slot_or_del(new id(H),ITEM_SLOT_ID, TRUE)
+ if(bank_card)
+ H.equip_to_slot_or_del(new bank_card(H),ITEM_SLOT_ID, TRUE)
if(suit_store)
H.equip_to_slot_or_del(new suit_store(H),ITEM_SLOT_SUITSTORE, TRUE)
diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm
index 5ffa3778edc6..7134d2e8ecef 100644
--- a/code/datums/progressbar.dm
+++ b/code/datums/progressbar.dm
@@ -32,12 +32,12 @@
return
goal = goal_number
bar_loc = target
- bar = image('icons/effects/progessbar.dmi', bar_loc, "prog_bar_0", HUD_LAYER)
+ bar = image('icons/effects/progressbar.dmi', bar_loc, "prog_bar_0", HUD_LAYER)
bar.plane = ABOVE_HUD_PLANE
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
user = User
- LAZYADDASSOC(user.progressbars, bar_loc, src)
+ LAZYADDASSOCLIST(user.progressbars, bar_loc, src)
var/list/bars = user.progressbars[bar_loc]
listindex = bars.len
diff --git a/code/datums/ruins/beachplanet.dm b/code/datums/ruins/beachplanet.dm
index dae334aefae1..b258ef45f0e8 100644
--- a/code/datums/ruins/beachplanet.dm
+++ b/code/datums/ruins/beachplanet.dm
@@ -2,8 +2,6 @@
/datum/map_template/ruin/beachplanet
prefix = "_maps/RandomRuins/BeachRuins/"
- allow_duplicates = FALSE
- cost = 5
ruin_type = RUINTYPE_BEACH
/datum/map_template/ruin/beachplanet/fishinghut
@@ -18,12 +16,6 @@
description = "As you draw near the ancient wall, a sense of foreboding overcomes you. You aren't sure why, but you feel this dusty structure may contain great dangers."
suffix = "beach_ancient_ruin.dmm"
-/datum/map_template/ruin/beachplanet/colony
- name = "Abandoned Beachside Colony"
- id = "beach_colony"
- description = "A abandoned colony. It seems that this colony was abandoned, for a reason or another"
- suffix = "beach_colony.dmm"
-
/datum/map_template/ruin/beachplanet/town
name = "Beachside Town"
id = "beach_town"
@@ -36,18 +28,6 @@
description = "A small pirate outpost formed from the remains of a wrecked shuttle."
suffix = "beach_pirate_crash.dmm"
-/datum/map_template/ruin/beachplanet/fallenstar
- name = "Crashed Starwalker"
- id = "crashed_star"
- description = "A Crashed Starwalker Class Pirate Ship. It's Crew is Long-Dead."
- suffix = "beach_crashed_starwalker.dmm"
-
-/datum/map_template/ruin/beachplanet/knight
- name = "Knight's Rest"
- id = "knights_rest"
- description = "An small castle holding the grave of a renowned warrior"
- suffix = "beach_knights_rest.dmm"
-
/datum/map_template/ruin/beachplanet/treasurecove
name = "Treasure Cove"
id = "beach_treasure_cove"
diff --git a/code/datums/ruins/icemoon.dm b/code/datums/ruins/icemoon.dm
index a447a5b6f465..60304e86f6f0 100644
--- a/code/datums/ruins/icemoon.dm
+++ b/code/datums/ruins/icemoon.dm
@@ -2,57 +2,20 @@
/datum/map_template/ruin/icemoon
prefix = "_maps/RandomRuins/IceRuins/"
- allow_duplicates = FALSE
- cost = 5
ruin_type = RUINTYPE_ICE
-// above ground only
-
-/datum/map_template/ruin/icemoon/engioutpost
- name = "Engineer Outpost"
- id = "engioutpost"
- description = "Blown up by an unfortunate accident."
- suffix = "icemoon_surface_engioutpost.dmm"
-
-
-/datum/map_template/ruin/icemoon/hydroponicslab //Shiptest edit
+/datum/map_template/ruin/icemoon/hydroponicslab
name = "Hydroponics Lab"
id = "hydroponicslab"
description = "An abandoned hydroponics research facility containing hostile plant fauna."
suffix = "icemoon_hydroponics_lab.dmm"
-// above and below ground together
-
-
-// below ground only
-
-/datum/map_template/ruin/icemoon
- name = "underground ruin"
-
/datum/map_template/ruin/icemoon/abandonedvillage
name = "Abandoned Village"
id = "abandonedvillage"
description = "Who knows what lies within?"
suffix = "icemoon_underground_abandoned_village.dmm"
-/datum/map_template/ruin/icemoon/corpreject
- name = "NT Security Solutions Site Gamma"
- id = "corpreject"
- description = "Nanotrasen Corporate Security Solutions vault site Gamma."
- suffix = "icemoon_surface_corporate_rejects.dmm"
-
-/datum/map_template/ruin/icemoon/syndicate_outpost
- name = "Abandoned Syndicate Outpost"
- id = "syndicate-outpost-icemoon"
- description = "A outpost that used to be a staging area for nuclear operatives. The Syndicate have moved to another location, but this still remains."
- suffix = "icemoon_underground_abandoned_newcops.dmm"
-
-/datum/map_template/ruin/icemoon/drakelair
- name = "Dragon's Lair"
- id = "drake-lair"
- description = "\"First the creature's Flame breathed from beneath the stone, Hot battle-fumes, and the earth rumbled.\""
- suffix = "icemoon_underground_drakelair.dmm"
-
/datum/map_template/ruin/icemoon/brazillian_lab
name = "Barricaded Compound"
id = "brazillian-lab"
diff --git a/code/datums/ruins/jungle.dm b/code/datums/ruins/jungle.dm
index 5642e7aadacd..f1e2e16bfec8 100644
--- a/code/datums/ruins/jungle.dm
+++ b/code/datums/ruins/jungle.dm
@@ -4,92 +4,12 @@
prefix = "_maps/RandomRuins/JungleRuins/"
ruin_type = RUINTYPE_JUNGLE
-/datum/map_template/ruin/jungle/jungle_botany_ruin
- id = "jungle_botany-ruin"
- suffix = "jungle_botany.dmm"
- name = "Ruined Botany Research Facility"
- description = "A research facility of great botany discoveries. Long since abandoned, willingly or not..."
-
-/datum/map_template/ruin/jungle/ai_ikea
- name = "Space Ikea AI Shipment"
- id = "ikea-ai"
- description = "A Space Ikea Brand AI Core and Necessities Crate, it seems to have missed its intended target."
- suffix = "jungle_surface_ikea_ai.dmm"
-
-/datum/map_template/ruin/jungle/coffinpirate
- name = "Coffin-Shaped Pirate Hut"
- id = "coffinpirate"
- description = "An odd coffin shaped pirate hut that the inhabitant of died in."
- suffix = "jungle_surface_coffinpirate.dmm"
-
-//far more tasteful than its predecessor...
-/datum/map_template/ruin/jungle/lessonintrickery
- name = "Bombmaker's Cabin"
- id = "bombmakers-cabin"
- description = "Playing with bombs again, are we?"
- suffix = "jungle_surface_bombmakers_cabin.dmm"
-
-/datum/map_template/ruin/jungle/weedshack
- name = "Stoner's Cabin"
- id = "weed-shack"
- description = "The Industrial Revolution and its consequences have been a disaster for the human race."
- suffix = "jungle_surface_weed_shack.dmm"
-
-//vae's jungle ruins from bungalowstation
-/datum/map_template/ruin/jungle/pizzawave
- name = "Jungle Pizzawave"
- id = "pizzawave"
- description = "Get some pizza my dude."
- suffix = "jungle_pizzawave.dmm"
-
-/datum/map_template/ruin/jungle/nest
- name = "Jungle Xenonest"
- id = "xenonestjungle"
- description = "A Xeno nest crammed into the Jungle."
- suffix = "jungle_nest.dmm"
-
-/datum/map_template/ruin/jungle/seedling
- name = "Seedling ruin"
- id = "seedling"
- description = "A rare seedling plant."
- suffix = "jungle_seedling.dmm"
-
-/datum/map_template/ruin/jungle/hangar
- name = "Abandoned Hangar"
- id = "hangar"
- description = "An abandoned hangar containing exosuits."
- suffix = "jungle_hangar.dmm"
-
-/datum/map_template/ruin/jungle/pirate
- name = "Jungle Pirates"
- id = "piratejungle"
- description = "A group of pirates on a small ship in the jungle."
- suffix = "jungle_pirate.dmm"
-
/datum/map_template/ruin/jungle/syndicate
name = "Jungle Syndicate Bunker"
id = "syndicatebunkerjungle"
description = "A small bunker owned by the Syndicate."
suffix = "jungle_syndicate.dmm"
-/datum/map_template/ruin/jungle/village
- name = "Monkey Village"
- id = "monkeyvillage"
- description = "A small village of monkeys."
- suffix = "jungle_village.dmm"
-
-/datum/map_template/ruin/jungle/roommates
- name = "Roommates"
- id = "roommates"
- description = "A shack once inhabited by a clown and a mime... and they were roommates."
- suffix = "jungle_surface_roommates.dmm"
-
-/datum/map_template/ruin/jungle/ninjashrine
- name = "Ninja Shrine"
- id = "ninjashrine"
- description = "A ninja shrine."
- suffix = "jungle_surface_ninjashrine.dmm"
-
/datum/map_template/ruin/jungle/interceptor
name = "Old Crashed Interceptor"
id = "crashedcondor"
diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm
index d5cd93f05e6c..816ffd685c14 100644
--- a/code/datums/ruins/lavaland.dm
+++ b/code/datums/ruins/lavaland.dm
@@ -4,75 +4,13 @@
prefix = "_maps/RandomRuins/LavaRuins/"
ruin_type = RUINTYPE_LAVA
-/datum/map_template/ruin/lavaland/biodome
- cost = 5
- allow_duplicates = FALSE
-
/datum/map_template/ruin/lavaland/biodome/winter
- name = "Biodome Winter"
+ name = "Solarian Winter Biodome"
id = "biodome-winter"
- description = "For those getaways where you want to get back to nature, but you don't want to leave the fortified military compound where you spend your days. \
- Includes a unique(*) laser pistol display case, and the recently introduced I.C.E(tm)."
+ description = "A Solarian frontier research facility created by the Pionierskompanien \
+ This one seems to simulate the wintery climate of the northern provinces, including a sauna!"
suffix = "lavaland_surface_biodome_winter.dmm"
-/datum/map_template/ruin/lavaland/sin
- cost = 10
- allow_duplicates = FALSE
-
-/datum/map_template/ruin/lavaland/sin/sloth
- name = "Ruin of Sloth"
- id = "sloth"
- description = "..."
- suffix = "lavaland_surface_sloth.dmm"
- // Generates nothing but atmos runtimes and salt
- cost = 0
-
-/datum/map_template/ruin/lavaland/hierophant
- name = "Hierophant's Arena"
- id = "hierophant"
- description = "A strange, square chunk of metal of massive size. Inside awaits only death and many, many squares."
- suffix = "lavaland_surface_hierophant.dmm"
- allow_duplicates = FALSE
-
-/datum/map_template/ruin/lavaland/xeno_nest
- name = "Xenomorph Nest"
- id = "xeno-nest"
- description = "These xenomorphs got bored of horrifically slaughtering people on space stations, and have settled down on a nice lava-filled hellscape to focus on what's really important in life. \
- Quality memes."
- suffix = "lavaland_surface_xeno_nest.dmm"
- cost = 20
-
-/datum/map_template/ruin/lavaland/survivalcapsule
- name = "Survival Capsule Ruins"
- id = "survivalcapsule"
- description = "What was once sanctuary to the common miner, is now their tomb."
- suffix = "lavaland_surface_survivalpod.dmm"
- cost = 5
-
-/datum/map_template/ruin/lavaland/pizza
- name = "Ruined Pizza Party"
- id = "pizza"
- description = "Little Timmy's birthday pizza bash took a turn for the worse when a bluespace anomaly passed by."
- suffix = "lavaland_surface_pizzaparty.dmm"
- allow_duplicates = FALSE
- cost = 5
-
-/datum/map_template/ruin/lavaland/hermit
- name = "Makeshift Shelter"
- id = "hermitcave"
- description = "A place of shelter for a lone hermit, scraping by to live another day."
- suffix = "lavaland_surface_hermit.dmm"
- allow_duplicates = FALSE
- cost = 10
-
-/datum/map_template/ruin/lavaland/miningripley
- name = "Ripley"
- id = "ripley"
- description = "A heavily-damaged mining ripley, property of a very unfortunate miner. You might have to do a bit of work to fix this thing up."
- suffix = "lavaland_surface_random_ripley.dmm"
- allow_duplicates = FALSE
- cost = 5
-
/datum/map_template/ruin/lavaland/elephant_graveyard
name = "Elephant Graveyard"
id = "Graveyard"
@@ -81,47 +19,26 @@
allow_duplicates = FALSE
cost = 10
-/datum/map_template/ruin/lavaland/comm_outpost
- name = "Syndicate Comm Outpost"
- id = "commoutpost"
- description = "A forgotten outpost home to only a tragic tale."
- suffix = "lavaland_surface_comm_outpost.dmm"
- allow_duplicates = FALSE
- cost = 5
-
-/datum/map_template/ruin/lavaland/dwarffortress
- name = "Legion infested Dwarf Fortress"
- id = "dwarffortress"
- description = "A forgotten fortress home to only a tragic tale and infested corpses."
- suffix = "lavaland_surface_dwarffortress.dmm"
- allow_duplicates = FALSE
-
-/datum/map_template/ruin/lavaland/ashwalker_shrine
- name = "Ashwalker shrine"
- id = "ashwalker_shrine"
- description = "A destroyed ashwalker village. What even happened here?"
- suffix = "lavaland_surface_ashwalker_shrine.dmm"
-
-/datum/map_template/ruin/lavaland/spookycrash
- name = "Spooky Crash"
- id = "spooky_crash"
- description = "A spooky looking crash."
- suffix = "lavaland_surface_SPOOKYCRASH.dmm"
-
-/datum/map_template/ruin/lavaland/crashedpinnance
- name = "Crashed Research Pinnance"
- id = "crashed_pinnance"
- description = "A crashed shuttlecraft, looks like the pilot didn't make it."
- suffix = "lavaland_surface_crashed_pinnance.dmm"
-
-/datum/map_template/ruin/lavaland/codelab
- name = "Nanotrasen Genetic Research Facility"
- id = "codelab"
- description = "A Nanotrasen genetic research facility, abandoned and ripe for looting. Whats that goo over there?"
- suffix = "lavaland_surface_codelab.dmm"
+/datum/map_template/ruin/lavaland/buried_shrine
+ name = "Buried Shrine"
+ id = "buried_shrine"
+ description = "An ancient temple belonging to some long-gone inhabitants, wrecked and buried by the volcanic activity of it's home planet."
+ suffix = "lavaland_surface_buried_shrine.dmm"
/datum/map_template/ruin/lavaland/lava_canyon
name = "Lava Canyon"
id = "lava_canyon"
description = "Tectonic activity has gouged a large fissure into the surface of the planet here. Tucked in the crevasse, the remains of an ashwalker village lay in ashes."
suffix = "lavaland_surface_lava_canyon.dmm"
+
+/datum/map_template/ruin/lavaland/wrecked_factory
+ name = "Wrecked Factory"
+ id = "wreck_factory"
+ description = "A Nanotrasen processing facility, assaulted by a pirate raid that has killed most of the staff. The offices however, remain unbreached for now."
+ suffix = "lavaland_surface_wrecked_factory.dmm"
+
+/datum/map_template/ruin/lavaland/fallenstar
+ name = "Crashed Starwalker"
+ id = "crashed_star"
+ description = "A crashed pirate ship. It would seem that it's crew died a while ago."
+ suffix = "lavaland_crashed_starwalker.dmm"
diff --git a/code/datums/ruins/rockplanet.dm b/code/datums/ruins/rockplanet.dm
index 0d47dd51d7da..f576f1a93464 100644
--- a/code/datums/ruins/rockplanet.dm
+++ b/code/datums/ruins/rockplanet.dm
@@ -2,64 +2,8 @@
/datum/map_template/ruin/rockplanet
prefix = "_maps/RandomRuins/RockRuins/"
- allow_duplicates = FALSE
- cost = 5
- ruin_type = RUINTYPE_ROCK
-
-/datum/map_template/ruin/rockplanet/heirophant
- name = "Ancient Heirophant"
- id = "rockheiro"
- description = "something dangerous"
- suffix = "rockplanet_heirophant.dmm"
-
-/* TODO: GREEBLE
-/datum/map_template/ruin/rockplanet/dangerpod
- name = "Dangerous pod"
- id = "dangerpod"
- description = "A pod holding a dangerous threat."
- suffix = "wasteplanet_dangerpod.dmm"
-*/
-
-/* //TODO: MAKE THIS A MINOR RUIN
-/datum/map_template/ruin/rockplanet/pioneer
- name = "Krusty Krab Pizza"
- id = "pioneer"
- description = "The pioneers used to ride these babies for miles!"
- suffix = "rockplanet_pioneer.dmm"
-*/
-
-/*greeble
-/datum/map_template/ruin/rockplanet/house
- name = "baracaded house"
- id = "house"
- description = "Some sort of house, baracaded in. It must be baracaded for a reason.."
- suffix = "rockplanet_house.dmm"
-*/
-
-/datum/map_template/ruin/rockplanet/mining_expedition
- name = "Mining Expedition"
- id = "expedition"
- description = "A mining operation gone wrong."
- suffix = "rockplanet_miningexpedition.dmm"
-
-/datum/map_template/ruin/rockplanet/boxsci
- name = "Abandoned science wing"
- id = "abandonedscience"
- description = "A chunk of a station that broke off.."
- suffix = "rockplanet_boxsci.dmm"
-
-/datum/map_template/ruin/rockplanet/crash_cult
- name = "Crashed Exploration Clipper"
- description = "A crashed exploration vessel. Hivebots are taking this ship apart for scrap."
- id = "crash_cult"
- suffix = "rockplanet_crash.dmm"
-
-/datum/map_template/ruin/rockplanet/saloon
- name = "Abandoned saloon"
- description = "For whatever reason, someone decided to make a colony with a indie style."
- id = "rockplanet_saloon"
- suffix = "rockplanet_saloon.dmm"
+ ruin_type = RUINTYPE_ROCK
/datum/map_template/ruin/rockplanet/harmfactory
name = "Harm Factory"
@@ -73,8 +17,15 @@
id = "rockplanet_budgetcuts"
suffix = "rockplanet_budgetcuts.dmm"
+/datum/map_template/ruin/rockplanet/shippingdock
+ name = "Abandoned Shipping Dock"
+ description = "An abandoned shipping dock used by small cargo freighters and smugglers alike. Some malicious group seems to have trapped the place to eliminate scavengers."
+ id = "rockplanet_shippingdock"
+ suffix = "rockplanet_shippingdock.dmm"
+
/datum/map_template/ruin/rockplanet/nomadcrash
name = "Nomad Crash"
description = "A Crashed Arrow & Axe Interceptor. A long forgotten Crew. They tried their best to survive..."
id = "rockplanet_nomadcrash"
suffix = "rockplanet_nomadcrash.dmm"
+
diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm
index 7872ba58a3a4..1aedb0b9be82 100644
--- a/code/datums/ruins/space.dm
+++ b/code/datums/ruins/space.dm
@@ -12,12 +12,6 @@
name = "Corporate Mining Module"
description = "An old and rusty mining facility, with big ore potential."
-/datum/map_template/ruin/space/excavator_DK
- id = "Excavator-DK"
- suffix = "excavator_DK.dmm"
- name = "Excavator DK Class"
- description = "A heavily damaged DK class excavator"
-
/datum/map_template/ruin/space/bigderelict1
id = "bigderelict1"
suffix = "bigderelict1.dmm"
@@ -31,65 +25,6 @@
name = "DK Excavator 453"
description = "Formerly a thriving planetary mining outpost, now a bit of an exploded mess. One has to wonder how it got here"
-/* shiptest: Replaced with dark_glade ruin
-/datum/map_template/ruin/space/way_home
- id = "way-home"
- suffix = "way_home.dmm"
- name = "Salvation"
- description = "In the darkest times, we will find our way home."
-*/
-
-/datum/map_template/ruin/space/djstation
- id = "djstation"
- suffix = "djstation.dmm"
- name = "DJ Station"
- description = "Until very recently this pirate radio station was used to harangue local space stations over a variety of perceived \"ethics violations\". \
- It seems like someone finally got sick of it, but the equipment still works."
-
-/datum/map_template/ruin/space/crashedship
- id = "crashedship"
- suffix = "crashedship.dmm"
- name = "Crashed Ship"
- description = "Among civilian vessels the most common cause of tragedy is lack of food. \
- This ship was outfitted with a multitude of food-generating features, then summarily ran into an asteroid shortly after takeoff."
-
-/datum/map_template/ruin/space/vaporwave
- id = "vaporwave"
- suffix = "vaporwave.dmm"
- name = "Aesthetic Outpost"
- description = "Pause and remember-- You are unique.You are special. Every mistake, trial, and hardship has helped to sculpt your real beauty. \
- Stop hating yourself and start appreciating and loving yourself!"
-
-/datum/map_template/ruin/space/hellfactory
- id = "hellfactory"
- suffix = "hellfactory.dmm"
- name = "Heck Brewery"
- description = "An abandoned warehouse and brewing facility, which has been recently rediscovered. Reports claim that the security system entered an ultra-hard lockdown, but these reports are inconclusive."
-
-/datum/map_template/ruin/space/cryocontainment
- id = "cryocontainment"
- suffix = "cryocontainment.dmm"
- name = "Cryogenic Containment Facility"
- description = "Some old facility where they stored something in a cryotube to experiement on, obviously it got out and now the only thing it contains is Space Carps."
-
-/datum/map_template/ruin/space/dangerous_research
- id = "dangerous_research"
- suffix = "dangerous_research.dmm"
- name = "Occult Research Station"
- description = "This station was deemed unsuitable for continued experiments, and quickly abandoned."
-
-/datum/map_template/ruin/space/macspace
- id = "fast_food"
- suffix = "Fast_Food.dmm"
- name = "Mac Space Restaurant"
- description = "A fast food reataurant in space."
-
-/datum/map_template/ruin/space/scav_mining
- id = "mining_asteroid"
- suffix = "scav_mining.dmm"
- name = "Mining asteroid"
- description = "An abandoned mining operation on an asteroid that now has new ocupants that is not happy to se you"
-
/datum/map_template/ruin/space/power_puzzle
id = "power_puzzle"
suffix = "power_puzzle.dmm"
@@ -97,42 +32,12 @@
description = "an abandoned secure storage location. there is no power left in the batteries and the former ocupants locked it pretty tight before leaving.\
You will have to power areas to raise the bolts on the doors. look out for secrets."
-/datum/map_template/ruin/space/transport18
- id = "transport18"
- suffix = "transport18.dmm"
- name = "Booze Cruise"
- description = "A freighter, damaged beyond repair and surrounded by a cloud of aluminium and... beer foam?"
-
-/datum/map_template/ruin/space/fueldepot
- id = "fueldepot"
- suffix = "fueldepot.dmm"
- name = "Fuel Depot"
- description = "An orbital refueling station with the remains of a ship lodged among the debris."
-
-/datum/map_template/ruin/space/ntfacility
- id = "ntfacility"
- suffix = "ntfacility.dmm"
- name = "Abandoned Facility"
- description = "A NT research station. Something has gone horribly wrong here."
-
/datum/map_template/ruin/space/astraeus
id = "astraeus"
suffix = "astraeus.dmm"
name = "Astraeus Ruin"
description = "This vessel served a lengthy period in the Nanotrasen fleet, before an accident in the munitions bay caused to to be destroyed while in active combat."
-/datum/map_template/ruin/space/glade
- id = "dark_glade"
- suffix = "dark_glade.dmm"
- name = "Dark Glade"
- description = "It's always dark in the ancient glade."
-
-/datum/map_template/ruin/space/syndicircle
- id = "provinggrounds"
- suffix = "provinggrounds.dmm"
- name = "Syndicate Battle Sphere"
- description = "The Syndicate Battle Sphere, complete with guns!"
-
/datum/map_template/ruin/space/singularitylab
id = "singularitylab"
suffix = "singularity_lab.dmm"
diff --git a/code/datums/ruins/wasteplanet.dm b/code/datums/ruins/wasteplanet.dm
index 80bf701526be..8083567a7c68 100644
--- a/code/datums/ruins/wasteplanet.dm
+++ b/code/datums/ruins/wasteplanet.dm
@@ -2,66 +2,26 @@
/datum/map_template/ruin/wasteplanet
prefix = "_maps/RandomRuins/WasteRuins/"
- allow_duplicates = FALSE
- cost = 5
ruin_type = RUINTYPE_WASTE
-/datum/map_template/ruin/wasteplanet/fortress
- name = "Fortress of Solitide"
- id = "solitude"
- description = "A fortress, although one you are probably more familiar with."
- suffix = "wasteplanet_fortress_of_solitide.dmm"
-
/datum/map_template/ruin/wasteplanet/weaponstest
name = "Weapons testing facility"
id = "guntested"
description = "A abandoned Nanotrasen weapons facility, presumably the place where the X-01 was manufactured."
suffix = "wasteplanet_lab.dmm"
-/datum/map_template/ruin/wasteplanet/oreprocess
- name = "Ore Processing Facility"
- id = "oreprocess"
- description = "A fortress, although one you are probably more familiar with.."
- suffix = "wasteplanet_ore_proccessing_facility.dmm"
-
/datum/map_template/ruin/wasteplanet/pandora
id = "pandora_arena"
suffix = "wasteplanet_pandora.dmm"
name = "Pandora Arena"
description = "Some... thing has settled here."
-/* Greeble
-/datum/map_template/ruin/wasteplanet/pod
- name = "Derelict pod"
- id = "oldpod"
- description = "A large, old pod."
- suffix = "wasteplanet_pod.dmm"
-*/
-
-/datum/map_template/ruin/wasteplanet/crash_kitchen
- name = "Crashed Kitchen"
- description = "A crashed part of some unlucky ship."
- id = "crash_kitchen"
- suffix = "wasteplanet_crash_kitchen.dmm"
-
/datum/map_template/ruin/wasteplanet/radiation
name = "Honorable deeds storage"
id = "wasteplanet_radiation"
description = "A dumping ground for nuclear waste."
suffix = "wasteplanet_unhonorable.dmm"
-/datum/map_template/ruin/wasteplanet/tradepost
- name = "Tradepost"
- id = "oldpod"
- description = "An abandoned tradepost."
- suffix = "wasteplanet_tradepost.dmm"
-
-/datum/map_template/ruin/wasteplanet/tarpit
- name = "Tar pit"
- id = "tarpit"
- description = "A facility once constructed over a asphalt deposit."
- suffix = "wasteplanet_tarpit.dmm"
-
/datum/map_template/ruin/wasteplanet/abandoned_mechbay
name = "Abandoned Mech Bay"
description = "A military base formerly used for staging 4 mechs and crew. God knows what's in it now."
diff --git a/code/datums/ruins/whitesands.dm b/code/datums/ruins/whitesands.dm
index 8e34f7cf379c..b3e0cb13adcc 100644
--- a/code/datums/ruins/whitesands.dm
+++ b/code/datums/ruins/whitesands.dm
@@ -4,43 +4,12 @@
prefix = "_maps/RandomRuins/SandRuins/"
ruin_type = RUINTYPE_SAND
-/datum/map_template/ruin/whitesands/starfury_crash
- name = "Starfury Crash"
- id = "starfurycrash"
- description = "The remains of an unidentified syndicate battleship has crashed here."
- suffix = "whitesands_surface_starfurycrash.dmm"
- allow_duplicates = FALSE
-
/datum/map_template/ruin/whitesands/medipen_plant
name = "Abandoned Medipen Factory"
id = "medipenplant"
description = "A once prosperous autoinjector manufacturing plant."
suffix = "whitesands_surface_medipen_plant.dmm"
-/datum/map_template/ruin/whitesands/assaultpodcrash
- name = "Crashed Syndicate Assault Drop Pod"
- id = "ws-assaultpodcrash"
- description = "The fauna of desert planets can be deadly even to equipped Syndicate Operatives."
- suffix = "whitesands_surface_assaultpodcrash.dmm"
-
-/datum/map_template/ruin/whitesands/conveniencestore
- name = "Conveniently Abandoned Convenience Store"
- id = "ws-conveniencestore"
- description = "Pretty convenient that they have a convenience store out here, huh?"
- suffix = "whitesands_surface_conveniencestore.dmm"
-
-/datum/map_template/ruin/whitesands/onlyaspoonful
- name = "Abandoned Spoon Factory"
- id = "ws-onlyaspoonful"
- description = "Literally a fucking spoon factory"
- suffix = "whitesands_surface_onlyaspoonful.dmm"
-
-/datum/map_template/ruin/whitesands/chokepoint
- name = "Chokepoint"
- id = "ws-chokepoint"
- description = "Some sort of survivors, brandishing old nanotrasen security gear."
- suffix = "whitesands_surface_chokepoint.dmm"
-
/datum/map_template/ruin/whitesands/pubbyslopcrash
name = "Pubby Slop Crash"
id = "ws-pubbyslopcrash"
@@ -48,19 +17,13 @@
suffix = "whitesands_surface_pubbyslopcrash.dmm"
//////////OUTSIDE SETTLEMENTS/RUINS//////////
-/datum/map_template/ruin/whitesands/survivors/drugstore
- name = "Abandoned Store"
- id = "ws-drugstore"
- description = "A store that once sold a variety of items and equipment."
- suffix = "whitesands_surface_camp_drugstore.dmm"
-
/datum/map_template/ruin/whitesands/survivors/saloon
name = "Hermit Saloon"
id = "ws-saloon"
description = "A western style saloon, most popular spot for the hermits to gather planetside"
suffix = "whitesands_surface_camp_saloon.dmm"
-/datum/map_template/ruin/whitesands/survivors/combination //combined extra large ruin of several other whitesands survivor ruins (excludes the drugstore)
+/datum/map_template/ruin/whitesands/survivors/combination //combined extra large ruin of several other whitesands survivor ruins
name = "Wasteland Survivor Village"
id = "ws-combination"
description = "A small encampment of nomadic survivors of the First Colony, and their descendants. By all accounts, feral and without allegance to anyone but themselves."
diff --git a/code/datums/shuttles.dm b/code/datums/shuttles.dm
index 84e21fd0633b..d7b60476d977 100644
--- a/code/datums/shuttles.dm
+++ b/code/datums/shuttles.dm
@@ -21,7 +21,8 @@
var/prefix = "ISV"
/// The full name of the ship's faction.
var/faction_name = "Independent"
- var/unique_ship_access = FALSE
+ /// Whether or not players from other ships can open airlocks.
+ var/unique_ship_access = TRUE
/// Set by config JSON. If true, the template's ships' "default" spawn location (when bought by a player or loaded at roundstart)
/// will be in the middle of space, instead of at an outpost.
var/space_spawn = FALSE
@@ -400,3 +401,8 @@
file_name = "pgf_nail"
name = "Nail-class Boarding Vessel"
prefix = "PGF"
+
+/datum/map_template/shuttle/subshuttles/brawler
+ file_name = "frontiersmen_brawler"
+ name = "Brawler-class Dropship"
+ prefix = "SV"
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 52087f03174c..02b96c1b81de 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -334,7 +334,8 @@
/datum/status_effect/neck_slice/tick()
var/mob/living/carbon/human/H = owner
- if(H.stat == DEAD || H.bleed_rate <= 8)
+ var/obj/item/bodypart/throat_in_question = H.get_bodypart(BODY_ZONE_HEAD)
+ if(H.stat == DEAD || throat_in_question?.bleeding <= 8)
H.remove_status_effect(/datum/status_effect/neck_slice)
if(prob(10))
H.emote(pick("gasp", "gag", "choke"))
diff --git a/code/datums/status_effects/gas.dm b/code/datums/status_effects/gas.dm
index 11037374b9b3..cc6a91b2f267 100644
--- a/code/datums/status_effects/gas.dm
+++ b/code/datums/status_effects/gas.dm
@@ -38,7 +38,7 @@
/datum/status_effect/freon/proc/do_resist()
to_chat(owner, "You start breaking out of the ice cube...")
- if(do_mob(owner, owner, 40))
+ if(do_after(owner, 40))
if(!QDELETED(src))
to_chat(owner, "You break out of the ice cube!")
owner.remove_status_effect(/datum/status_effect/freon)
diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm
index 76a33319631f..c7765ff772ac 100644
--- a/code/datums/status_effects/neutral.dm
+++ b/code/datums/status_effects/neutral.dm
@@ -275,3 +275,29 @@
/atom/movable/screen/alert/status_effect/surrender/Click(location, control, params)
. = ..()
owner.emote("surrender")
+
+/datum/status_effect/rooted
+ id = "rooted"
+ alert_type = /atom/movable/screen/alert/status_effect/rooted
+
+/datum/status_effect/rooted/on_apply()
+ . = ..()
+ ADD_TRAIT(owner,TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
+ ADD_TRAIT(owner,TRAIT_PUSHIMMUNE, TRAIT_STATUS_EFFECT(id))
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "root", /datum/mood_event/root)
+
+/datum/status_effect/rooted/on_remove()
+ . = ..()
+ REMOVE_TRAIT(owner,TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
+ REMOVE_TRAIT(owner,TRAIT_PUSHIMMUNE, TRAIT_STATUS_EFFECT(id))
+
+/atom/movable/screen/alert/status_effect/rooted
+ name = "Rooted"
+ desc = "You're currently rooted into the ground and can't move. Click here to start digging yourself out."
+ icon_state = "dig_out"
+
+/atom/movable/screen/alert/status_effect/rooted/Click(location, control, params)
+ . = ..()
+ to_chat(owner, span_notice("You begin digging yourself free."))
+ SEND_SIGNAL(owner,COMSIG_DIGOUT)
+
diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm
index 52ee20e23c27..574c35f60beb 100644
--- a/code/datums/traits/good.dm
+++ b/code/datums/traits/good.dm
@@ -62,26 +62,6 @@
lose_text = "You feel isolated from others."
medical_record_text = "Patient is highly perceptive of and sensitive to social cues, or may possibly have ESP. Further testing needed."
-/datum/quirk/fan_clown
- name = "Clown Fan"
- desc = "You enjoy clown antics and get a mood boost from wearing your clown pin."
- value = 1
- mob_traits = list(TRAIT_FAN_CLOWN)
- gain_text = "You are a big fan of clowns."
- lose_text = "The clown doesn't seem so great."
- medical_record_text = "Patient reports being a big fan of clowns."
-
-/datum/quirk/fan_clown/on_spawn()
- var/mob/living/carbon/human/H = quirk_holder
- var/obj/item/clothing/accessory/fan_clown_pin/B = new(get_turf(H))
- var/list/slots = list (
- "backpack" = ITEM_SLOT_BACKPACK,
- "hands" = ITEM_SLOT_HANDS,
- )
- H.equip_in_one_of_slots(B, slots , qdel_on_fail = TRUE)
- var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
- fan.add_hud_to(H)
-
/datum/quirk/fan_rilena
name = "RILENA Super Fan"
desc = "You are a major fan of the popular webseries RILENA: LMR. You get a mood boost from plushies of your favorite characters, and wearing your Xader pin."
@@ -102,26 +82,6 @@
var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
fan.add_hud_to(H)
-/datum/quirk/fan_mime
- name = "Mime Fan"
- desc = "You enjoy mime antics and get a mood boost from wearing your mime pin."
- value = 1
- mob_traits = list(TRAIT_FAN_MIME)
- gain_text = "You are a big fan of the Mime."
- lose_text = "The mime doesn't seem so great."
- medical_record_text = "Patient reports being a big fan of mimes."
-
-/datum/quirk/fan_mime/on_spawn()
- var/mob/living/carbon/human/H = quirk_holder
- var/obj/item/clothing/accessory/fan_mime_pin/B = new(get_turf(H))
- var/list/slots = list (
- "backpack" = ITEM_SLOT_BACKPACK,
- "hands" = ITEM_SLOT_HANDS,
- )
- H.equip_in_one_of_slots(B, slots , qdel_on_fail = TRUE)
- var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
- fan.add_hud_to(H)
-
/datum/quirk/freerunning
name = "Freerunning"
desc = "You're great at quick moves! You can climb tables more quickly."
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index 4b0afce14b47..d1a8fd6acaa5 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -430,11 +430,6 @@
/datum/quirk/insanity/proc/madness()
quirk_holder.hallucination += rand(10, 25)
-/datum/quirk/insanity/post_add() //I don't /think/ we'll need this but for newbies who think "roleplay as insane" = "license to kill" it's probably a good thing to have
- if(!quirk_holder.mind || quirk_holder.mind.special_role)
- return
- to_chat(quirk_holder, "Please note that your dissociation syndrome does NOT give you the right to attack people or otherwise cause any interference to \
- the round. You are not an antagonist, and the rules will treat you the same as other crewmembers.")
/datum/quirk/social_anxiety
name = "Social Anxiety"
@@ -589,24 +584,57 @@
reagent_type = /datum/reagent/drug/nicotine
accessory_type = /obj/item/lighter/greyscale
+//I fucking hate prefscode
+
/datum/quirk/junkie/smoker/on_spawn()
- drug_container_type = pick(/obj/item/storage/fancy/cigarettes,
- /obj/item/storage/fancy/cigarettes/cigpack_midori,
- /obj/item/storage/fancy/cigarettes/cigpack_uplift,
- /obj/item/storage/fancy/cigarettes/cigpack_robust,
- /obj/item/storage/fancy/cigarettes/cigpack_robustgold,
- /obj/item/storage/fancy/cigarettes/cigpack_carp)
+ var/mob/living/carbon/human/H = quirk_holder
+ switch (H.client?.prefs.preferred_smoke_brand)
+ if (PREF_CIG_SPACE)
+ drug_container_type = /obj/item/storage/fancy/cigarettes
+ if (PREF_CIG_DROMEDARY)
+ drug_container_type = /obj/item/storage/fancy/cigarettes/dromedaryco
+ if (PREF_CIG_UPLIFT)
+ drug_container_type = /obj/item/storage/fancy/cigarettes/cigpack_uplift
+ if (PREF_CIG_ROBUST)
+ drug_container_type = /obj/item/storage/fancy/cigarettes/cigpack_robust
+ if (PREF_CIG_ROBUSTGOLD)
+ drug_container_type = /obj/item/storage/fancy/cigarettes/cigpack_robustgold
+ if (PREF_CIG_CARP)
+ drug_container_type= /obj/item/storage/fancy/cigarettes/cigpack_carp
+ if (PREF_CIG_MIDORI)
+ drug_container_type = /obj/item/storage/fancy/cigarettes/cigpack_midori
+ if (PREF_CIGAR)
+ drug_container_type = /obj/item/storage/fancy/cigarettes/cigars
+ accessory_type = /obj/item/storage/box/matches
+ if (PREF_CIGAR_SOLAR)
+ drug_container_type = /obj/item/storage/fancy/cigarettes/cigars/havana
+ accessory_type = /obj/item/storage/box/matches
+ if (PREF_CIGAR_COHIBA)
+ drug_container_type = /obj/item/storage/fancy/cigarettes/cigars/cohiba
+ accessory_type = /obj/item/storage/box/matches
+ if (PREF_VAPE)
+ drug_container_type = /obj/item/clothing/mask/vape
+ accessory_type = null
+ if (PREF_PIPE)
+ drug_container_type = /obj/item/clothing/mask/cigarette/pipe
+ accessory_type = /obj/item/storage/box/matches
+ else
+ CRASH("Someone had an improper cigarette pref on loading")
. = ..()
/datum/quirk/junkie/smoker/announce_drugs()
- to_chat(quirk_holder, "There is a [initial(drug_container_type.name)] [where_drug], and a lighter [where_accessory]. Make sure you get your favorite brand when you run out.")
-
+ if(accessory_type == null)
+ to_chat(quirk_holder, "There is a [initial(drug_container_type.name)] [where_drug], Make sure you get a refill soon.")
+ return
+ to_chat(quirk_holder, "There is a [initial(drug_container_type.name)] [where_drug], and a [initial(accessory_type.name)] [where_accessory]. Make sure you get your favorite brand when you run out.")
/datum/quirk/junkie/smoker/on_process()
. = ..()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/I = H.get_item_by_slot(ITEM_SLOT_MASK)
if (istype(I, /obj/item/clothing/mask/cigarette))
+ if(I == drug_container_type)
+ return
var/obj/item/storage/fancy/cigarettes/C = drug_container_type
if(istype(I, initial(C.spawn_type)))
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "wrong_cigs")
diff --git a/code/datums/wires/mines.dm b/code/datums/wires/mines.dm
new file mode 100644
index 000000000000..91e0ac816189
--- /dev/null
+++ b/code/datums/wires/mines.dm
@@ -0,0 +1,82 @@
+/datum/wires/mine
+ holder_type = /obj/item/mine/pressure
+ randomize = TRUE
+
+/datum/wires/mine/New(atom/holder)
+ wires = list(
+ WIRE_BOOM, WIRE_DELAYBOOM, WIRE_PIN, WIRE_RESET
+ )
+ ..()
+
+/datum/wires/mine/interactable(mob/user)
+ var/obj/item/mine/pressure/ourmine = holder
+ if(ourmine.open_panel)
+ return TRUE
+
+//are you feelin lucky, punk?
+/datum/wires/mine/on_pulse(wire)
+ var/obj/item/mine/pressure/ourmine = holder
+ switch(wire)
+ if(WIRE_BOOM)//oopsies
+ holder.visible_message(span_userdanger("[icon2html(ourmine, viewers(holder))] \The [ourmine] makes a shrill noise! It's go-"))
+ ourmine.trigger_mine()
+ if(WIRE_DELAYBOOM)//oopsies but you get to run
+ ourmine.blast_delay = clamp(ourmine.blast_delay * 5, 8, 50)
+ holder.visible_message(span_userdanger("[icon2html(ourmine, viewers(holder))] \The [ourmine] makes a shrill noise! It's go-"))
+ ourmine.trigger_mine()
+ //Resets the detonation pin, allowing someone to step off the mine. Minor success.
+ if(WIRE_PIN)
+ if(ourmine.clicked == TRUE)
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] You hear something inside \the [ourmine] click softly."))
+ playsound(ourmine, SOUND_EMPTY_MAG, 30, TRUE)
+ ourmine.clicked = FALSE
+ else
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] \The [ourmine]'s detonation pad shifts slightly. Nothing happens."))
+ if(WIRE_RESET)//Disarms the mine, allowing it to be picked up. Major success.
+ if(ourmine.armed && ourmine.anchored)
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] \The [ourmine]'s arming lights fade, and the securing bolts loosen. "))
+ playsound(ourmine, 'sound/machines/click.ogg', 100, TRUE)
+ ourmine.disarm()
+ else if(ourmine.anchored)
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] \The [ourmine]'s yellow arming light flickers."))
+ else
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] \The [ourmine]'s securing bolt shifts. Nothing happens."))
+
+/datum/wires/mine/on_cut(wire, mend)
+ var/obj/item/mine/pressure/ourmine = holder
+ switch(wire)
+ if(WIRE_BOOM)
+ if(!mend)
+ holder.visible_message(span_userdanger("[icon2html(ourmine, viewers(holder))] \The [ourmine] makes a shrill noise! It's go-"))
+ ourmine.trigger_mine()
+ if(WIRE_DELAYBOOM)
+ if(!mend)
+ ourmine.blast_delay = clamp(ourmine.blast_delay * 5, 8, 50)
+ holder.visible_message(span_userdanger("[icon2html(ourmine, viewers(holder))] \The [ourmine] makes a shrill noise! It's go-"))
+ ourmine.trigger_mine()
+ //Disables the detonation pin. Nothing will happen when the mine is triggered.
+ //Mine can still be exploded by cutting wires & damage.
+ if(WIRE_PIN)
+ if(!mend)
+ ourmine.dud = TRUE
+ if(ourmine.clicked == TRUE)
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] You hear something inside \the [ourmine] shift out of place."))
+ playsound(ourmine, SOUND_EMPTY_MAG, 30, TRUE)
+ ourmine.clicked = FALSE
+ else
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] \The [ourmine]'s detonation pad goes loose."))
+ ourmine.foot_on_mine = null
+ else
+ ourmine.dud = FALSE
+ ourmine.clicked = FALSE
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] You hear something inside \the [ourmine] shift back into place."))
+ if(WIRE_RESET)
+ if(!mend)
+ if(ourmine.armed && ourmine.anchored)
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] \The [ourmine]'s arming lights fade, and the securing bolts loosen. Disarmed. "))
+ playsound(ourmine, 'sound/machines/click.ogg', 100, TRUE)
+ ourmine.disarm()
+ else if(ourmine.anchored)
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] \The [ourmine]'s yellow arming light flickers."))
+ else
+ holder.visible_message(span_notice("[icon2html(ourmine, viewers(holder))] \The [ourmine]'s securing bolt shifts. Nothing happens."))
diff --git a/code/game/MapData/shuttles/srm_elder.dm b/code/game/MapData/shuttles/srm_elder.dm
index db6561b6550c..97805731ec2f 100644
--- a/code/game/MapData/shuttles/srm_elder.dm
+++ b/code/game/MapData/shuttles/srm_elder.dm
@@ -20,15 +20,38 @@
name = "shadow's locker"
desc = "The closet of equipment and attire for the aspiring shadow."
icon_state = "cabinet"
+ open_sound = 'sound/machines/wooden_closet_open.ogg'
+ close_sound = 'sound/machines/wooden_closet_close.ogg'
+
+/obj/structure/closet/secure_closet/flamebearer
+ name = "flamebearer's locker"
+ desc = "The closet of equipment an ascetic Flamebearer would require."
+ icon_state = "cabinet"
+ open_sound = 'sound/machines/wooden_closet_open.ogg'
+ close_sound = 'sound/machines/wooden_closet_close.ogg'
/obj/structure/closet/secure_closet/hunter
name = "hunter's locker"
desc = "Everything a hunter will need, held in one secure closet."
icon_state = "cabinet"
req_access = list(ACCESS_SECURITY)
+ open_sound = 'sound/machines/wooden_closet_open.ogg'
+ close_sound = 'sound/machines/wooden_closet_close.ogg'
+
+/obj/structure/closet/secure_closet/machinist
+ name = "machinist's Locker"
+ desc = "The personal closet with tools of a Machinist."
+ req_access = list(ACCESS_ENGINE)
+ icon_state = "eng_secure"
+
+/obj/structure/closet/secure_closet/collignes
+ name = "\proper hunter colligne's locker"
+ desc = "The posessions of the Hunter Colligne aboard the vessel."
+ req_access = list(ACCESS_HOP)
+ icon_state = "hop"
/obj/structure/closet/secure_closet/montagnes
- name = "\proper Hunter Montagnes Locker"
+ name = "\proper hunter montagne's locker"
desc = "The posessions of the owning Hunter Montagnes."
req_access = list(ACCESS_HOS)
icon_state = "hos"
diff --git a/code/game/area/areas/ruins/beachplanet.dm b/code/game/area/areas/ruins/beachplanet.dm
index 919d2602a3d3..d33825e0087e 100644
--- a/code/game/area/areas/ruins/beachplanet.dm
+++ b/code/game/area/areas/ruins/beachplanet.dm
@@ -1,4 +1,3 @@
-
//tropical ruins here
//Beachside Town
@@ -24,12 +23,6 @@
/area/ruin/beach/oceantown/house
-//Knight's Rest
-
-/area/ruin/beachplanet/knight
- name = "Knight's Rest"
- icon_state = "dkyellow"
-
//Ancient Complex
/area/ruin/beach/complex //seems quite simple to me
@@ -58,12 +51,6 @@
/area/ruin/beach/piratecrash/storage
name = "Scrap Hut"
-//beach_crashed_starwalker
-
-/area/ruin/beach/starwalker
- name = "Crashed Pirate Ship"
- icon_state = "green"
-
//beach_treasure_cove, the beeginning
/area/ruin/beach/treasure_cove
diff --git a/code/game/area/areas/ruins/icemoon.dm b/code/game/area/areas/ruins/icemoon.dm
index d2c8d1ca61f6..8e614c8a0e79 100644
--- a/code/game/area/areas/ruins/icemoon.dm
+++ b/code/game/area/areas/ruins/icemoon.dm
@@ -1,21 +1,5 @@
// Icemoon Ruins
-//Buried Library
-
-/area/ruin/unpowered/buried_library
- name = "Buried Library"
- icon_state = "dk_yellow"
-
-//Bathhouse
-
-/area/ruin/powered/bathhouse
- name = "Bath House"
- icon_state = "dk_yellow"
- mood_bonus = 10
- mood_message = "I wish I could stay here forever.\n"
-
-//corporate rejects
-
//Corporate Rejects
/area/ruin/unpowered/corprejectrooms
diff --git a/code/game/area/areas/ruins/jungle.dm b/code/game/area/areas/ruins/jungle.dm
index 09d0e95f2f36..2d2fc76f97b1 100644
--- a/code/game/area/areas/ruins/jungle.dm
+++ b/code/game/area/areas/ruins/jungle.dm
@@ -1,10 +1,3 @@
-//Thneed Factory
-
-/area/ruin/jungle/onceler/main
- requires_power = FALSE
- name = "Thneed Factory"
- icon_state = "engine"
-
//Interceptor Crash Site
/area/ruin/jungle/interceptor/crashsite
@@ -89,10 +82,6 @@
name = "cargo dump"
icon_state = "dk_yellow"
-/area/ruin/jungle/roommates/shack
- name = "clown and mime hideout"
- icon_state = "crew_quarters"
-
// Bombed Syndicate Starport
/area/ruin/jungle/starport
name = "Bombed Air Base"
diff --git a/code/game/area/areas/ruins/lavaland.dm b/code/game/area/areas/ruins/lavaland.dm
index 3722fcb09356..f7cbb414bc00 100644
--- a/code/game/area/areas/ruins/lavaland.dm
+++ b/code/game/area/areas/ruins/lavaland.dm
@@ -1,25 +1,25 @@
//Lavaland Ruins
-// Beach
+// Winter Biodome
-/area/ruin/powered/beach
- icon_state = "dk_yellow"
+/area/ruin/unpowered/winter_biodome
+ icon_state = "bluenew"
+ name = "Biodome Main Area"
-// Snow Biodome
+/area/ruin/unpowered/winter_biodome/entrance
+ name = "Biodome Entrance"
-/area/ruin/powered/snow_biodome
- icon_state = "dk_yellow"
+/area/ruin/unpowered/winter_biodome/living_quarters
+ name = "Biodome Living Quarters"
-//Gluttony
+/area/ruin/unpowered/winter_biodome/cabin
+ name = "Biodome Cabin"
-/area/ruin/powered/gluttony
- icon_state = "dk_yellow"
+/area/ruin/unpowered/winter_biodome/engineering
+ name = "Biodome Engineering"
-//Golem Ship
-
-/area/ruin/powered/golem_ship
- name = "Free Golem Ship"
- icon_state = "dk_yellow"
+/area/ruin/unpowered/winter_biodome/sauna
+ name = "Biodome Sauna"
//Hierophant Arena
@@ -38,61 +38,50 @@
name = "Elephant Graveyard"
icon_state = "green"
-//Syndicate Comms Outpost
+//Lava Canyon
-/area/ruin/unpowered/syndicate_outpost
- name = "Syndicate Comm Outpost"
- icon_state = "dk_yellow"
-
-
-//Xeno Nest
-
-/area/ruin/unpowered/xenonest
- name = "The Hive"
- always_unpowered = TRUE
- power_environ = FALSE
- power_equip = FALSE
- power_light = FALSE
- poweralm = FALSE
-
-// Crashed Pinnance
+/area/ruin/unpowered/scorched_hut
+ name = "Scorched Hut"
+ icon_state = "red"
-/area/ruin/unpowered/crashsite
- name = "Crash Site"
- icon_state = "green"
+// Wrecked Factory
-/area/ruin/unpowered/crashsite/pinnance
- name = "Pinnace Wreckage"
- icon_state = "dk_yellow"
- always_unpowered = TRUE
+/area/ruin/lavaland/factory/warehouse
+ name = "Factory Warehouse"
+ icon_state = "cargo_warehouse"
+ requires_power = FALSE
-/area/ruin/unpowered/codelab
- name = "Nanotrasen Genetic Research Facility"
- icon_state = "bluenew"
+/area/ruin/lavaland/factory/foreman_office
+ name = "Foreman's Office"
+ icon_state = "purple"
+ requires_power = FALSE
-/area/ruin/unpowered/codelab/exterior
- name = "Nanotrasen Genetic Research Facility Exterior"
+/area/ruin/lavaland/factory/adminstrative
+ name = "Adminstrative Wing"
+ icon_state = "bridge_hallway"
+ requires_power = FALSE
-/area/ruin/unpowered/codelab/reception
- name = "Nanotrasen Genetic Research Reception"
- icon_state = "green"
+/area/ruin/lavaland/factory/manager_office
+ name ="Manager's Office"
+ icon_state = "bridge"
+ requires_power = FALSE
-/area/ruin/unpowered/codelab/subjectrooms
- name = "Nanotrasen Genetic Research Test Subject Storage"
- icon_state = "Sleep"
+/area/ruin/lavaland/factory/lobby
+ name ="Lobby"
+ icon_state = "hallC"
+ requires_power = FALSE
-/area/ruin/unpowered/codelab/storage
- name = "Nanotrasen Genetic Research Storage"
- icon_state = "cargo_bay"
+/area/ruin/lavaland/factory/dorms
+ name ="Dormitory"
+ icon_state = "crew_quarters"
+ requires_power = FALSE
+//Buried Shrine
-/area/ruin/unpowered/codelab/laboratory
- name = "Nanotrasen Genetic Research Laboratory"
- icon_state = "bridge"
+/area/ruin/unpowered/buried_shrine
+ name = "Buried Shrine"
+ icon_state = "red"
-/area/ruin/unpowered/codelab/maintenance
- name = "Nanotrasen Genetic Research Maintenance"
- icon_state = "dk_yellow"
+//Crashed Starwalker
-/area/ruin/unpowered/scorched_hut
- name = "Scorched Hut"
- icon_state = "red"
+/area/ruin/unpowered/crashed_starwalker
+ name = "Crashed Pirate Ship"
diff --git a/code/game/area/areas/ruins/rockplanet.dm b/code/game/area/areas/ruins/rockplanet.dm
index a89969566196..43516a72376a 100644
--- a/code/game/area/areas/ruins/rockplanet.dm
+++ b/code/game/area/areas/ruins/rockplanet.dm
@@ -1,15 +1,31 @@
/**********************Rock Planet Areas**************************/
-
-//syndicate
-/area/ruin/rockplanet/syndicate
- name = "Abandoned Syndicate Mining Facility"
- icon_state = "green"
+/area/ruin/rockplanet
+ icon_state = "red"
//budgetcuts
/area/ruin/rockplanet/nanotrasen
name = "Abandoned Research Facility"
always_unpowered = FALSE
- icon_state = "green"
+
+//shippingdock
+/area/ruin/rockplanet/shippingdockoffice
+ name = "Employee Office"
+ icon_state = "crew_quarters"
+
+/area/ruin/rockplanet/shippingdockcustoms
+ name = "Cargo Checkpoint"
+ icon_state = "security"
+
+/area/ruin/rockplanet/shippingdockwarehouse
+ name = "Warehouse"
+ icon_state = "storage"
+
+/area/ruin/rockplanet/shippingdocksecure
+ name = "Warehouse Secure Storage"
+ icon_state = "armory"
+
+/area/ruin/rockplanet/shippingdock
+ name = "Abandoned Shipping Dock"
//nomad
/area/ruin/rockplanet/nomad
diff --git a/code/game/area/areas/ruins/space.dm b/code/game/area/areas/ruins/space.dm
index e6034e412198..45a9113d86ba 100644
--- a/code/game/area/areas/ruins/space.dm
+++ b/code/game/area/areas/ruins/space.dm
@@ -11,29 +11,12 @@
requires_power = FALSE
/////////////
-
-/area/ruin/space/way_home
- name = "\improper Salvation"
- icon_state = "away"
- always_unpowered = FALSE
-
// Onehalf Ruin
/area/ruin/space/has_grav/onehalf
name = "Station Fragment"
icon_state = "away"
-//Dinner For Two
-
-/area/ruin/space/has_grav/powered/dinner_for_two
- name = "Dinner for Two"
-
-//Aesthetic
-
-/area/ruin/space/has_grav/powered/aesthetic
- name = "Aesthetic"
- ambientsounds = list('sound/ambience/ambivapor1.ogg')
-
//Ruin of Derelict Oupost
/area/ruin/space/has_grav/derelictoutpost
@@ -56,222 +39,6 @@
name = "Derelict Outpost Docked Ship"
icon_state = "red"
-//Ruin of Deep Storage
-
-/area/ruin/space/has_grav/deepstorage
- name = "Deep Storage"
- icon_state = "storage"
-
-/area/ruin/space/has_grav/deepstorage/airlock
- name = "Deep Storage Airlock"
- icon_state = "quart"
-
-/area/ruin/space/has_grav/deepstorage/power
- name = "Deep Storage Power and Atmospherics Room"
- icon_state = "engi_storage"
-
-/area/ruin/space/has_grav/deepstorage/hydroponics
- name = "Deep Storage Hydroponics"
- icon_state = "garden"
-
-/area/ruin/space/has_grav/deepstorage/armory
- name = "Deep Storage Secure Storage"
- icon_state = "armory"
-
-/area/ruin/space/has_grav/deepstorage/storage
- name = "Deep Storage Storage"
- icon_state = "storage_wing"
-
-/area/ruin/space/has_grav/deepstorage/dorm
- name = "Deep Storage Dormitory"
- icon_state = "crew_quarters"
-
-/area/ruin/space/has_grav/deepstorage/kitchen
- name = "Deep Storage Kitchen"
- icon_state = "kitchen"
-
-/area/ruin/space/has_grav/deepstorage/crusher
- name = "Deep Storage Recycler"
- icon_state = "storage"
-
-//DERELICT
-
-/area/ruin/space/derelict
- name = "Derelict Station"
- icon_state = "storage"
-
-/area/ruin/space/derelict/hallway/primary
- name = "Derelict Primary Hallway"
- icon_state = "hallP"
-
-/area/ruin/space/derelict/hallway/secondary
- name = "Derelict Secondary Hallway"
- icon_state = "hallS"
-
-/area/ruin/space/derelict/hallway/primary/port
- name = "Derelict Port Hallway"
- icon_state = "hallFP"
-
-/area/ruin/space/derelict/arrival
- name = "Derelict Arrival Centre"
- icon_state = "yellow"
-
-/area/ruin/space/derelict/storage/equipment
- name = "Derelict Equipment Storage"
-
-/area/ruin/space/derelict/bridge
- name = "Derelict Control Room"
- icon_state = "bridge"
-
-/area/ruin/space/derelict/bridge/access
- name = "Derelict Control Room Access"
- icon_state = "auxstorage"
-
-/area/ruin/space/derelict/bridge/ai_upload
- name = "Derelict Computer Core"
- icon_state = "ai"
-
-/area/ruin/space/derelict/solar_control
- name = "Derelict Solar Control"
- icon_state = "engine"
-
-/area/ruin/space/derelict/se_solar
- name = "South East Solars"
- icon_state = "engine"
-
-/area/ruin/space/derelict/medical
- name = "Derelict Medbay"
- icon_state = "medbay"
-
-/area/ruin/space/derelict/medical/chapel
- name = "Derelict Chapel"
- icon_state = "chapel"
-
-/area/solar/derelict_starboard
- name = "Derelict Starboard Solar Array"
- icon_state = "panelsS"
-
-/area/solar/derelict_aft
- name = "Derelict Aft Solar Array"
- icon_state = "yellow"
-
-/area/ruin/space/derelict/singularity_engine
- name = "Derelict Singularity Engine"
- icon_state = "engine"
-
-/area/ruin/space/derelict/gravity_generator
- name = "Derelict Gravity Generator Room"
- icon_state = "red"
-
-/area/ruin/space/derelict/atmospherics
- name = "Derelict Atmospherics"
- icon_state = "red"
-
-//DJSTATION
-
-/area/ruin/space/djstation
- name = "Ruskie DJ Station"
- icon_state = "DJ"
- has_gravity = STANDARD_GRAVITY
-
-/area/ruin/space/djstation/solars
- name = "DJ Station Solars"
- icon_state = "DJ"
- has_gravity = STANDARD_GRAVITY
-
-//OLD AI SAT
-
-/area/tcommsat/oldaisat
- name = "Abandoned Satellite"
- icon_state = "tcomsatcham"
-
-//ABANDONED BOX WHITESHIP
-
-/area/ruin/space/has_grav/whiteship/box
-
- name = "Abandoned Ship"
- icon_state = "red"
-
-
-//SYNDICATE LISTENING POST STATION
-
-/area/ruin/space/has_grav/listeningstation
- name = "Listening Post"
- icon_state = "yellow"
-
-/area/ruin/space/has_grav/powered/ancient_shuttle
- name = "Ancient Shuttle"
- icon_state = "yellow"
-
-//HELL'S FACTORY OPERATING FACILITY
-
-/area/ruin/space/has_grav/hellfactory
- name = "Hell Factory"
- icon_state = "yellow"
-
-/area/ruin/space/has_grav/hellfactoryoffice
- name = "Hell Factory Office"
- icon_state = "red"
- area_flags = VALID_TERRITORY | BLOBS_ALLOWED | NOTELEPORT
-
-//Ruin of Transport 18
-
-/area/ruin/space/has_grav/transport18fore
- name = "Booze Cruise Fore"
- icon_state = "crew_quarters"
-
-/area/ruin/space/has_grav/transport18mid
- name = "Booze Cruise Hold"
- icon_state = "cargo_bay"
-
-/area/ruin/space/transport18aft
- name = "Booze Cruise Aft"
- icon_state = "engine"
-
-//Ruin of the rad ship. It's pretty rad.
-
-/area/ruin/space/has_grav/radship/Cargo1
- name = "Cargo Bay 1"
- icon_state = "cargo_bay"
-
-/area/ruin/space/has_grav/radship/Cargo2
- name = "Cargo Bay 2"
- icon_state = "cargo_bay"
-
-/area/ruin/space/has_grav/radship/Cargo3
- name = "Cargo Bay 3"
- icon_state = "cargo_bay"
-
-/area/ruin/space/has_grav/radship/Cargo4
- name = "Cargo Bay 4"
- icon_state = "cargo_bay"
-
-/area/ruin/space/has_grav/radship/EngineRoom
- name = "Engine Room"
- icon_state = "yellow"
-
-/area/ruin/space/has_grav/radship/Engineering
- name = "Engineering"
- icon_state = "engine"
-
-/area/ruin/space/has_grav/radship/MethLab
- name = "Storage"
- icon_state = "red"
-
-/area/ruin/space/has_grav/radship/CrewQuarters
- name = "Crew Quarters"
- icon_state = "green"
-
-/area/ruin/space/has_grav/radship/Hallway
- name = "Hallway"
- icon_state = "away"
-
-//MACSPACE
-
-/area/ruin/space/has_grav/powered/macspace
- name = "Mac Space Restaurant"
- icon_state = "yellow"
-
//POWER PUZZLE
/area/ruin/space/has_grav/powerpuzzle
@@ -286,20 +53,6 @@
name = "Engineering Wing"
icon_state = "yellow"
-//scav_mining
-
-/area/ruin/space/has_grav/scav_mining/entrance
- name = "Asteroid mine entrance"
- icon_state = "red"
-
-/area/ruin/space/has_grav/scav_mining/core
- name = "Asteroid mine core"
- icon_state = "yellow"
-
-/area/ruin/space/has_grav/scav_mining/dorm
- name = "Asteroid mine dorm"
- icon_state = "blue"
-
//astraeus
/area/ruin/space/has_grav/astraeus/hallway
@@ -326,44 +79,6 @@
name = "Custodial Closet"
icon_state = "green"
-/area/ruin/space/has_grav/glade
- name = "\improper Dark Glade"
- icon_state = "away"
- always_unpowered = FALSE
-
-//Syndie battle sphere
-
-/area/ruin/space/has_grav/syndicircle/halls
- name = "Syndicate Battle Sphere Primary Hallway"
- icon_state = "dk_yellow"
- color = "#a5131388"
-
-/area/ruin/space/has_grav/syndicircle/spacewalk
- name = "Syndicate Battle Sphere Shuttle Launch Site"
- icon_state = "dk_yellow"
- color = "#663cb488"
-
-/area/ruin/space/has_grav/syndicircle/research
- name = "Syndicate Battle Sphere Laboratory"
- icon_state = "dk_yellow"
- color = "#228a2b88"
-
-/area/ruin/space/has_grav/syndicircle/escape
- name = "Syndicate Battle Sphere Escape Shuttle"
- icon_state = "dk_yellow"
- color = "#92bb3388"
-
-/area/ruin/space/has_grav/syndicircle/winter
- name = "Syndicate Battle Sphere Snow Outpost"
- icon_state = "dk_yellow"
- color = "#4341c488"
-
-/area/ruin/space/has_grav/syndicircle/training
- name = "Syndicate Battle Sphere Training Grounds"
- icon_state = "dk_yellow"
- color = "#26773a88"
-
-
//Singularity Lab
/area/ruin/space/has_grav/singularitylab
diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm
index a9d7220bd3ca..6060367ca51b 100644
--- a/code/game/area/areas/shuttles.dm
+++ b/code/game/area/areas/shuttles.dm
@@ -189,27 +189,3 @@
/area/shuttle/syndicate_scout
name = "Syndicate Scout"
-
-/area/shuttle/caravan
- requires_power = TRUE
-
-/area/shuttle/caravan/syndicate1
- name = "Syndicate Fighter"
-
-/area/shuttle/caravan/syndicate2
- name = "Syndicate Fighter"
-
-/area/shuttle/caravan/syndicate3
- name = "Syndicate Drop Ship"
-
-/area/shuttle/caravan/pirate
- name = "Pirate Cutter"
-
-/area/shuttle/caravan/freighter1
- name = "Small Freighter"
-
-/area/shuttle/caravan/freighter2
- name = "Tiny Freighter"
-
-/area/shuttle/caravan/freighter3
- name = "Tiny Freighter"
diff --git a/code/game/area/ship_areas.dm b/code/game/area/ship_areas.dm
index abf40f900af5..9732893523b7 100644
--- a/code/game/area/ship_areas.dm
+++ b/code/game/area/ship_areas.dm
@@ -68,7 +68,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ship
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
- has_gravity = STANDARD_GRAVITY
always_unpowered = FALSE
area_flags = VALID_TERRITORY | BLOBS_ALLOWED // Loading the same shuttle map at a different time will produce distinct area instances.
icon_state = "shuttle"
@@ -172,10 +171,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/ship/crew/dorm/dormfive
name = "Dormitory 5"
+/area/ship/crew/dorm/captain
+ name = "Captain's Quarters"
+
/area/ship/crew/toilet
name = "Restroom"
icon_state = "toilet"
+/area/ship/crew/toilet/two
+ name = "Restroom 2"
+
+/area/ship/crew/toilet/three
+ name = "Restroom 3"
+
/area/ship/crew/canteen
name = "Canteen"
icon_state = "cafeteria"
@@ -199,6 +207,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Chapel Office"
icon_state = "chapeloffice"
sound_environment = SOUND_AREA_SMALL_SOFTFLOOR
+
/area/ship/crew/library
name = "Library"
icon_state = "library"
@@ -221,6 +230,13 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "vacant_office"
sound_environment = SOUND_AREA_WOODFLOOR
+/area/ship/crew/office/lobby
+ name = "Lobby"
+
+/area/ship/crew/ccommons
+ name = "Commons"
+ icon_state = "vacant_office"
+
/area/ship/crew/janitor
name = "Custodial Closet"
icon_state = "janitor"
@@ -245,6 +261,9 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "morgue"
ambientsounds = SPOOKY
+/area/ship/medical/psych
+ name = "Psych's Office"
+
/// Science Lab ///
/area/ship/science
name = "Science Lab"
@@ -445,6 +464,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "storage"
sound_environment = SOUND_AREA_STANDARD_STATION
+/area/ship/storage/port
+ name = "Port Storage Bay"
+
+/area/ship/storage/starboard
+ name = "Starboard Storage Bay"
+
/area/ship/storage/eva
name = "EVA Storage"
icon_state = "eva"
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 6c6849724bde..6d9f0df9f2ec 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -84,9 +84,6 @@
var/list/alternate_appearances
- ///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy()
- var/list/targeted_by
-
/// Last appearance of the atom for demo saving purposes
var/image/demo_last_appearance
@@ -160,6 +157,7 @@
var/hitsound_type = PROJECTILE_HITSOUND_NON_LIVING
///volume wanted for being hit
var/hitsound_volume = 50
+
/**
* Called when an atom is created in byond (built in engine proc)
*
@@ -309,11 +307,6 @@
LAZYCLEARLIST(overlays)
LAZYCLEARLIST(managed_overlays)
- for(var/i in targeted_by)
- var/mob/M = i
- LAZYREMOVE(M.do_afters, src)
-
- targeted_by = null
QDEL_NULL(light)
if(smoothing_flags & SMOOTH_QUEUED)
@@ -975,15 +968,12 @@
var/list/things = src_object.contents()
var/datum/progressbar/progress = new(user, things.len, src)
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(STR, TYPE_PROC_REF(/datum/component/storage, handle_mass_item_insertion), things, src_object, user, progress)))
+ while (do_after(user, 1 SECONDS, src, NONE, FALSE, CALLBACK(STR, TYPE_PROC_REF(/datum/component/storage, handle_mass_item_insertion), things, src_object, user, progress)))
stoplag(1)
progress.end_progress()
to_chat(user, "You dump as much of [src_object.parent]'s contents [STR.insert_preposition]to [src] as you can.")
- STR.orient2hud(user)
- src_object.orient2hud(user)
if(user.active_storage) //refresh the HUD to show the transfered contents
- user.active_storage.close(user)
- user.active_storage.show_to(user)
+ user.active_storage.ui_show(user)
return TRUE
///Get the best place to dump the items contained in the source storage item?
@@ -1555,6 +1545,7 @@
* * No gravity if this atom is in is a space turf
* * Gravity if the area it's in always has gravity
* * Gravity if there's a gravity generator on the z level
+ * * Gravity if there is a ship gravity generator in a ship
* * Gravity if the Z level has an SSMappingTrait for ZTRAIT_GRAVITY
* * otherwise no gravity
*/
@@ -1587,12 +1578,31 @@
else
// See if there's a gravity generator on our map zone
var/datum/map_zone/mapzone = T.get_map_zone()
+ var/max_grav = T.virtual_level_trait(ZTRAIT_GRAVITY)
if(mapzone?.gravity_generators.len)
- var/max_grav = 0
for(var/obj/machinery/gravity_generator/main/G as anything in mapzone.gravity_generators)
max_grav = max(G.setting,max_grav)
- return max_grav
- return T.virtual_level_trait(ZTRAIT_GRAVITY)
+ // Check for ship-based gravity
+ var/area/ship/ship = A
+ if(istype(ship))
+ var/obj/docking_port/mobile/shuttle = ship.mobile_port
+ if(shuttle)
+ if(istype(shuttle.docked, /obj/docking_port/stationary))
+ var/obj/docking_port/stationary/shipfinder = shuttle.docked
+ if(shipfinder.owner_ship)
+ for(var/datum/weakref/weakref as anything in shipfinder.owner_ship.gravgen_list)
+ var/obj/machinery/power/ship_gravity/SG = weakref.resolve()
+ if(!SG)
+ shipfinder.owner_ship.gravgen_list -= weakref
+ continue
+ max_grav = max(SG.active,max_grav)
+ for(var/datum/weakref/weakref as anything in shuttle.gravgen_list)
+ var/obj/machinery/power/ship_gravity/SG = weakref.resolve()
+ if(!SG)
+ shuttle.gravgen_list -= weakref
+ continue
+ max_grav = max(SG.active,max_grav)
+ return max_grav
/**
* Called when a mob examines (shift click or verb) this atom twice (or more) within EXAMINE_MORE_TIME (default 1.5 seconds)
@@ -1673,7 +1683,11 @@
active_hud.screentip_text.maptext = ""
else
//We inline a MAPTEXT() here, because there's no good way to statically add to a string like this
- active_hud.screentip_text.maptext = "[name]"
+ active_hud.screentip_text.maptext = "[get_screentip_name(client)]"
+
+/// Returns the atom name that should be used on screentip
+/atom/proc/get_screentip_name(client/hovering_client)
+ return name
///Called whenever a player is spawned on the same turf as this atom.
/atom/proc/join_player_here(mob/M)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 7dd3d612ae81..beb7cef2718f 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -560,7 +560,7 @@
if(!client)
return
if(new_virtual_z)
- LAZYADDASSOC(SSmobs.players_by_virtual_z, "[new_virtual_z]", src)
+ LAZYADDASSOCLIST(SSmobs.players_by_virtual_z, "[new_virtual_z]", src)
SSidlenpcpool.try_wakeup_virtual_z(new_virtual_z)
/mob/dead/on_virtual_z_change(new_virtual_z, previous_virtual_z)
@@ -570,7 +570,7 @@
if(!client)
return
if(new_virtual_z)
- LAZYADDASSOC(SSmobs.dead_players_by_virtual_z, "[new_virtual_z]", src)
+ LAZYADDASSOCLIST(SSmobs.dead_players_by_virtual_z, "[new_virtual_z]", src)
// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly.
// You probably want CanPass()
@@ -624,7 +624,7 @@
SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
. = ..()
if(!QDELETED(throwing))
- throwing.hit_atom(A)
+ throwing.finalize(hit = TRUE, target = A)
. = TRUE
if(QDELETED(A))
return
@@ -821,7 +821,9 @@
var/impact_signal = SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
if(impact_signal & COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH)
hitpush = FALSE // hacky, tie this to something else or a proper workaround later
-
+ if(isturf(loc))
+ var/turf/T = loc
+ T.Entered(src)
if(impact_signal & ~COMPONENT_MOVABLE_IMPACT_NEVERMIND) // in case a signal interceptor broke or deleted the thing before we could process our hit
return hit_atom.hitby(src, throwingdatum=throwingdatum, hitpush=hitpush)
@@ -883,7 +885,7 @@
else
target_zone = thrower.zone_selected
- var/datum/thrownthing/TT = new(src, target, get_turf(target), get_dir(src, target), range, speed, thrower, diagonals_first, force, gentle, callback, target_zone)
+ var/datum/thrownthing/TT = new(src, target, get_dir(src, target), range, speed, thrower, diagonals_first, force, gentle, callback, target_zone)
var/dist_x = abs(target.x - src.x)
var/dist_y = abs(target.y - src.y)
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 1dee49da7f54..4020895f29bd 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -216,24 +216,6 @@ Medical HUD! Basic mode needs suit sensors on.
holder.icon_state = "hudhealthy"
-/***********************************************
-FAN HUDs! For identifying other fans on-sight.
-************************************************/
-
-//HOOKS
-
-/mob/living/carbon/human/proc/fan_hud_set_fandom()
- var/image/holder = hud_list[FAN_HUD]
- var/icon/I = icon(icon, icon_state, dir)
- holder.pixel_y = I.Height() - world.icon_size
- holder.icon_state = "hudfan_no"
- var/obj/item/clothing/under/U = get_item_by_slot(ITEM_SLOT_ICLOTHING)
- if(U)
- if(istype(U.attached_accessory, /obj/item/clothing/accessory/fan_mime_pin))
- holder.icon_state = "fan_mime_pin"
- else if(istype(U.attached_accessory, /obj/item/clothing/accessory/fan_clown_pin))
- holder.icon_state = "fan_clown_pin"
-
/***********************************************
Security HUDs! Basic mode shows only the job.
************************************************/
diff --git a/code/game/gamemodes/clown_ops/clown_ops.dm b/code/game/gamemodes/clown_ops/clown_ops.dm
index 9025f6ec2dcb..74e391ef5510 100644
--- a/code/game/gamemodes/clown_ops/clown_ops.dm
+++ b/code/game/gamemodes/clown_ops/clown_ops.dm
@@ -40,7 +40,6 @@
backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\
/obj/item/kitchen/knife/combat/survival,
/obj/item/dnainjector/clumsymut, //in case you want to be clumsy for the memes
- /obj/item/storage/box/syndie_kit/clownpins, //for any guns that you get your grubby little clown op mitts on
/obj/item/reagent_containers/spray/waterflower/lube)
implants = list(/obj/item/implant/sad_trombone)
diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm
index fe95ea3c5988..3064a52a48ad 100644
--- a/code/game/gamemodes/clown_ops/clown_weapons.dm
+++ b/code/game/gamemodes/clown_ops/clown_weapons.dm
@@ -40,14 +40,14 @@
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/Initialize()
. = ..()
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
- bananium.insert_amount_mat(max_recharge, /datum/material/bananium)
+ bananium.insert_amount_mat(max_recharge, /datum/material/hellstone)
START_PROCESSING(SSobj, src)
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/process()
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
- var/bananium_amount = bananium.get_material_amount(/datum/material/bananium)
+ var/bananium_amount = bananium.get_material_amount(/datum/material/hellstone)
if(bananium_amount < max_recharge)
- bananium.insert_amount_mat(min(recharge_rate, max_recharge - bananium_amount), /datum/material/bananium)
+ bananium.insert_amount_mat(min(recharge_rate, max_recharge - bananium_amount), /datum/material/hellstone)
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/attack_self(mob/user)
ui_action_click(user)
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index e6f4f882a401..f7ce7b036eb5 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -16,8 +16,6 @@
if(!istype(M))
return FALSE
if(M.mind)
- if(ishuman(M) && (M.mind.holy_role))
- return FALSE
if(specific_cult && specific_cult.is_sacrifice_target(M.mind))
return FALSE
if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to))
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 992f97ba700b..85ab6ee64a14 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -118,7 +118,7 @@
ears = /obj/item/radio/headset/syndicate/alt
l_pocket = /obj/item/modular_computer/tablet/nukeops
id = /obj/item/card/id/syndicate
- belt = /obj/item/gun/ballistic/automatic/pistol
+ belt = /obj/item/gun/ballistic/automatic/pistol/syndicate
backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\
/obj/item/kitchen/knife/combat/survival)
@@ -168,7 +168,7 @@
r_hand = /obj/item/gun/ballistic/shotgun/bulldog
backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\
/obj/item/tank/jetpack/oxygen/harness=1,\
- /obj/item/gun/ballistic/automatic/pistol=1,\
+ /obj/item/gun/ballistic/automatic/pistol/syndicate=1,\
/obj/item/kitchen/knife/combat/survival)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 82735ff9d522..65e161f2176b 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -883,31 +883,6 @@ GLOBAL_LIST_EMPTY(possible_items_special)
explanation_text = "Steal at least five guns!"
wanted_items = list(/obj/item/gun)
-/datum/objective/steal_five_of_type/summon_magic
- name = "steal magic"
- explanation_text = "Steal at least five magical artefacts!"
- wanted_items = list()
-
-/datum/objective/steal_five_of_type/summon_magic/New()
- wanted_items = GLOB.summoned_magic_objectives
- ..()
-
-/datum/objective/steal_five_of_type/summon_magic/check_completion()
- var/list/datum/mind/owners = get_owners()
- var/stolen_count = 0
- for(var/datum/mind/M in owners)
- if(!isliving(M.current))
- continue
- var/list/all_items = M.current.GetAllContents() //this should get things in cheesewheels, books, etc.
- for(var/obj/I in all_items) //Check for wanted items
- if(istype(I, /obj/item/book/granter/spell))
- var/obj/item/book/granter/spell/spellbook = I
- if(!spellbook.used || !spellbook.oneuse) //if the book still has powers...
- stolen_count++ //it counts. nice.
- else if(is_type_in_typecache(I, wanted_items))
- stolen_count++
- return stolen_count >= 5
-
//Created by admin tools
/datum/objective/custom
name = "custom"
diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm
index e9906a6a0089..b423b28ce4d2 100644
--- a/code/game/machinery/PDApainter.dm
+++ b/code/game/machinery/PDApainter.dm
@@ -5,6 +5,8 @@
icon_state = "pdapainter"
base_icon_state = "pdapainter"
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_MINIMAL
max_integrity = 200
var/obj/item/pda/storedpda = null
var/list/colorlist = list()
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index a17b9c705dc1..3e3939620f3c 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -21,7 +21,7 @@ Class Variables:
power_channel (num)
What channel to draw from when drawing power for power mode
Possible Values:
- AREA_USAGE_EQUIP:0 -- Equipment Channel
+ AREA_USAGE_EQUIP:1 -- Equipment Channel
AREA_USAGE_LIGHT:2 -- Lighting Channel
AREA_USAGE_ENVIRON:3 -- Environment Channel
@@ -44,7 +44,7 @@ Class Procs:
auto_use_power() 'game/machinery/machine.dm'
This proc determines how power mode power is deducted by the machine.
'auto_use_power()' is called by the 'master_controller' game_controller every
- tick.
+ tick. (not anymore)
Return Value:
return:1 -- if object is powered
@@ -102,6 +102,7 @@ Class Procs:
//0 = dont run the auto
//1 = run auto, use idle
//2 = run auto, use active
+ var/use_static_power = NO_POWER_USE
var/idle_power_usage = 0
var/active_power_usage = 0
var/power_channel = AREA_USAGE_EQUIP
@@ -151,7 +152,11 @@ Class Procs:
if(occupant_typecache)
occupant_typecache = typecacheof(occupant_typecache)
-
+ switch(use_power)
+ if(IDLE_POWER_USE)
+ set_idle_power()
+ if(ACTIVE_POWER_USE)
+ set_active_power()
return INITIALIZE_HINT_LATELOAD
/// Helper proc for telling a machine to start processing with the subsystem type that is located in its `subsystem_type` var.
@@ -168,7 +173,16 @@ Class Procs:
. = ..()
power_change()
become_area_sensitive(ROUNDSTART_TRAIT)
- RegisterSignal(src, COMSIG_ENTER_AREA, PROC_REF(power_change))
+ RegisterSignal(src, COMSIG_ENTER_AREA, PROC_REF(enter_area))
+ RegisterSignal(src, COMSIG_EXIT_AREA, PROC_REF(exit_area))
+
+/obj/machinery/proc/enter_area(datum/source, area/A)
+ SIGNAL_HANDLER
+ power_change(A)
+
+/obj/machinery/proc/exit_area(datum/source, area/A)
+ SIGNAL_HANDLER
+ set_no_power(A)
/obj/machinery/Destroy()
GLOB.machines.Remove(src)
@@ -177,6 +191,7 @@ Class Procs:
lose_area_sensitivity(ROUNDSTART_TRAIT)
QDEL_NULL(circuit)
QDEL_LIST(component_parts)
+ set_no_power()
return ..()
/obj/machinery/proc/locate_machinery()
@@ -273,8 +288,8 @@ Class Procs:
target.forceMove(src)
updateUsrDialog()
update_appearance()
-
-/obj/machinery/proc/auto_use_power()
+/*
+/obj/machinery/proc/auto_use_power() //obsolete, tick controller doesn't call this anymore because machines use addStaticPower now.
if(!powered(power_channel))
return 0
if(use_power == 1)
@@ -282,7 +297,7 @@ Class Procs:
else if(use_power >= 2)
use_power(active_power_usage,power_channel)
return 1
-
+*/
///Called when we want to change the value of the `is_operational` variable. Boolean.
/obj/machinery/proc/set_is_operational(new_value)
@@ -421,6 +436,7 @@ Class Procs:
for(var/obj/item/I in component_parts)
I.forceMove(loc)
component_parts.Cut()
+ SEND_SIGNAL(src, COMSIG_OBJ_DECONSTRUCT, disassembled)
qdel(src)
/**
@@ -618,6 +634,7 @@ Class Procs:
//called on deconstruction before the final deletion
/obj/machinery/proc/on_deconstruction()
+ set_no_power()
return
/obj/machinery/proc/can_be_overridden()
diff --git a/code/game/machinery/airlock_cycle_control.dm b/code/game/machinery/airlock_cycle_control.dm
index 76094e803cd3..7ba391fae782 100644
--- a/code/game/machinery/airlock_cycle_control.dm
+++ b/code/game/machinery/airlock_cycle_control.dm
@@ -67,8 +67,8 @@
icon = 'icons/obj/monitors.dmi'
icon_state = "aac"
use_power = IDLE_POWER_USE
- idle_power_usage = 4
- active_power_usage = 8
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
power_channel = AREA_USAGE_ENVIRON
req_access = list(ACCESS_ATMOSPHERICS)
max_integrity = 250
diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm
index f275d234fca7..d4057603957d 100644
--- a/code/game/machinery/announcement_system.dm
+++ b/code/game/machinery/announcement_system.dm
@@ -12,8 +12,8 @@ GLOBAL_LIST_EMPTY(announcement_systems)
verb_ask = "queries"
verb_exclaim = "alarms"
- idle_power_usage = 20
- active_power_usage = 50
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = IDLE_DRAW_LOW
circuit = /obj/item/circuitboard/machine/announcement_system
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index d83831f2c634..e63b3f75fb2b 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -9,8 +9,9 @@
icon_state = "autolathe"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 10
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_HIGH
+ power_channel = AREA_USAGE_EQUIP
circuit = /obj/item/circuitboard/machine/autolathe
layer = BELOW_OBJ_LAYER
@@ -50,7 +51,7 @@
)
/obj/machinery/autolathe/Initialize()
- AddComponent(/datum/component/material_container,list(/datum/material/iron, /datum/material/glass, /datum/material/plastic, /datum/material/silver, /datum/material/gold, /datum/material/plasma, /datum/material/uranium, /datum/material/titanium), 0, TRUE, null, null, CALLBACK(src, PROC_REF(AfterMaterialInsert)))
+ AddComponent(/datum/component/material_container,list(/datum/material/iron, /datum/material/glass, /datum/material/plastic, /datum/material/silver, /datum/material/gold, /datum/material/plasma, /datum/material/uranium, /datum/material/titanium, /datum/material/hellstone), 0, TRUE, null, null, CALLBACK(src, PROC_REF(AfterMaterialInsert)))
. = ..()
wires = new /datum/wires/autolathe(src)
@@ -223,7 +224,7 @@
for(var/MAT in being_built.materials)
total_amount += being_built.materials[MAT]
- var/power = max(active_power_usage, (total_amount)*multiplier/5) //Change this to use all materials
+ var/power = max(active_power_usage, total_amount) //Change this to use all materials
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
@@ -252,6 +253,7 @@
use_power(power)
icon_state = "autolathe_n"
var/time = is_stack ? 32 : (32 * coeff * multiplier) ** 0.8
+ set_active_power()
addtimer(CALLBACK(src, PROC_REF(make_item), power, materials_used, custom_materials, multiplier, coeff, is_stack, usr), time)
. = TRUE
else
@@ -326,12 +328,13 @@
else
flick("autolathe_o", src) //plays metal insertion animation
- use_power(min(1000, amount_inserted / 100))
+ use_power(min(active_power_usage, amount_inserted))
/obj/machinery/autolathe/proc/make_item(power, list/materials_used, list/picked_materials, multiplier, coeff, is_stack, mob/user)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/atom/A = drop_location()
use_power(power)
+ set_idle_power()
materials.use_materials(materials_used)
diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm
index 2e93cd179ed5..83f3e366e8a3 100644
--- a/code/game/machinery/bank_machine.dm
+++ b/code/game/machinery/bank_machine.dm
@@ -3,7 +3,7 @@
desc = "A machine used to deposit and withdraw funds."
icon_screen = "vault"
icon_keyboard = "security_key"
- idle_power_usage = 100
+ idle_power_usage = IDLE_DRAW_LOW
var/siphoning = FALSE
var/next_warning = 0
diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/beacon.dm
similarity index 100%
rename from code/game/machinery/Beacon.dm
rename to code/game/machinery/beacon.dm
diff --git a/code/game/machinery/bounty_board.dm b/code/game/machinery/bounty_board.dm
index b0991110e80d..4cc3413fe9d9 100644
--- a/code/game/machinery/bounty_board.dm
+++ b/code/game/machinery/bounty_board.dm
@@ -33,8 +33,8 @@ GLOBAL_LIST_EMPTY(request_list)
/obj/machinery/bounty_board/attackby(obj/item/I, mob/living/user, params)
. = ..()
- if(istype(I,/obj/item/card/id))
- var/obj/item/card/id/current_card = I
+ if(istype(I,/obj/item/card/bank))
+ var/obj/item/card/bank/current_card = I
if(current_card.registered_account)
current_user = current_card.registered_account
return TRUE
@@ -72,9 +72,9 @@ GLOBAL_LIST_EMPTY(request_list)
if(request.applicants)
for(var/datum/bank_account/j in request.applicants)
formatted_applicants += list(list("name" = j.account_holder, "request_id" = request.owner_account.account_id, "requestee_id" = j.account_id))
- var/obj/item/card/id/id_card = user.get_idcard()
- if(id_card?.registered_account)
- current_user = id_card.registered_account
+ var/obj/item/card/bank/bank_card = user.get_bankcard()
+ if(bank_card?.registered_account)
+ current_user = bank_card.registered_account
if(current_user)
data["accountName"] = current_user.account_holder
data["requests"] = formatted_requests
diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm
index 1a89a2b011cc..f6c004ddca71 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -12,7 +12,7 @@
var/initialized_button = 0
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 70)
use_power = IDLE_POWER_USE
- idle_power_usage = 2
+ idle_power_usage = IDLE_DRAW_MINIMAL
resistance_flags = LAVA_PROOF | FIRE_PROOF
/obj/machinery/button/indestructible
@@ -68,34 +68,40 @@
default_deconstruction_screwdriver(user, "button-open", "[skin]",W)
update_appearance()
else
- to_chat(user, "Maintenance Access Denied.")
+ to_chat(user, span_alert("Maintenance Access Denied."))
flick("[skin]-denied", src)
return
if(panel_open)
if(!device && istype(W, /obj/item/assembly))
if(!user.transferItemToLoc(W, src))
- to_chat(user, "\The [W] is stuck to you!")
+ to_chat(user, span_warning("\The [W] is stuck to you!"))
return
device = W
- to_chat(user, "You add [W] to the button.")
+ to_chat(user, span_notice("You add [W] to the button."))
if(!board && istype(W, /obj/item/electronics/airlock))
if(!user.transferItemToLoc(W, src))
- to_chat(user, "\The [W] is stuck to you!")
+ to_chat(user, span_warning("\The [W] is stuck to you!"))
return
board = W
if(board.one_access)
req_one_access = board.accesses
else
req_access = board.accesses
- to_chat(user, "You add [W] to the button.")
+ to_chat(user, span_notice("You add [W] to the button."))
+
+ if(device && W.tool_behaviour == TOOL_MULTITOOL)
+ var/obj/item/multitool/multi = W
+ if(istype(device, /obj/item/assembly/control))
+ multi.buffer = device
+ to_chat(user, span_notice("You copy the [device] to your multitool's buffer."))
if(!device && !board && W.tool_behaviour == TOOL_WRENCH)
- to_chat(user, "You start unsecuring the button frame...")
+ to_chat(user, span_notice("You start unsecuring the button frame..."))
W.play_tool_sound(src)
if(W.use_tool(src, user, 40))
- to_chat(user, "You unsecure the button frame.")
+ to_chat(user, span_notice("You unsecure the button frame."))
transfer_fingerprints_to(new /obj/item/wallframe/button(get_turf(src)))
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
qdel(src)
@@ -153,14 +159,14 @@
req_one_access = list()
board = null
update_appearance()
- to_chat(user, "You remove electronics from the button frame.")
+ to_chat(user, span_notice("You remove electronics from the button frame."))
else
if(skin == "doorctrl")
skin = "launcher"
else
skin = "doorctrl"
- to_chat(user, "You change the button frame's front panel.")
+ to_chat(user, span_notice("You change the button frame's front panel."))
return
if((machine_stat & (NOPOWER|BROKEN)))
@@ -170,7 +176,7 @@
return
if(!allowed(user))
- to_chat(user, "Access Denied.")
+ to_chat(user, span_alert("Access Denied."))
flick("[skin]-denied", src)
return
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index c1cca432efd4..fda41eab7789 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -9,8 +9,8 @@
icon_state = "camera" //mapping icon to represent upgrade states. if you want a different base icon, update default_camera_icon as well as this.
light_color = "#CDDDFF"
use_power = ACTIVE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 10
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = IDLE_DRAW_MINIMAL*2
layer = WALL_OBJ_LAYER
resistance_flags = FIRE_PROOF
damage_deflection = 12
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index 8f57ad09203a..d5f7e618c637 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -56,18 +56,11 @@
/obj/machinery/camera/autoname/LateInitialize()
. = ..()
- number = 1
- var/area/A = get_area(src)
- if(A)
- for(var/obj/machinery/camera/autoname/C in GLOB.machines)
- if(C == src)
- continue
- var/area/CA = get_area(C)
- if(CA.type == A.type)
- if(C.number)
- number = max(number, C.number+1)
- c_tag = "[A.name] #[number]"
-
+ var/static/list/autonames_in_areas = list()
+ var/area/camera_area = get_area(src)
+ number = autonames_in_areas[camera_area] + 1
+ autonames_in_areas[camera_area] = number
+ c_tag = "[format_text(camera_area.name)] #[number]"
// UPGRADE PROCS
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index e1be8d8e4453..85d2d5651203 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -4,8 +4,8 @@
icon = 'icons/obj/power.dmi'
icon_state = "ccharger"
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 60
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_LOW
power_channel = AREA_USAGE_EQUIP
circuit = /obj/item/circuitboard/machine/cell_charger
pass_flags = PASSTABLE
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index c71e94a0948a..ad4cd3834f06 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -16,6 +16,8 @@
density = TRUE
icon = 'icons/obj/machines/cloning.dmi'
icon_state = "pod_0"
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
req_access = list(ACCESS_CLONING) //FOR PREMATURE UNLOCKING.
verb_say = "states"
circuit = /obj/item/circuitboard/machine/clonepod
diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm
index bdbadf79a943..3a36603c5070 100644
--- a/code/game/machinery/computer/_computer.dm
+++ b/code/game/machinery/computer/_computer.dm
@@ -4,8 +4,8 @@
icon_state = "computer"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 300
- active_power_usage = 300
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_LOW
max_integrity = 200
integrity_failure = 0.5
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 20)
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 571d5b090da9..d7f80fc45680 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -93,7 +93,6 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
visible_message("[src] dispenses.. woah, a gun! Way past cool.", "You hear a chime and a shot.")
user.client.give_award(/datum/award/achievement/misc/pulse, user)
return
-
var/prizeselect
if(prize_override)
prizeselect = pickweight(prize_override)
@@ -868,7 +867,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
say("WEEWOO! WEEWOO! Spaceport security en route!")
playsound(src, 'sound/items/weeoo1.ogg', 100, FALSE)
for(var/i, i<=3, i++)
- var/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion(get_turf(src))
+ var/mob/living/simple_animal/hostile/human/syndicate/ranged/smg/orion/O = new/mob/living/simple_animal/hostile/human/syndicate/ranged/smg/orion(get_turf(src))
O.target = usr
@@ -1243,7 +1242,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
newgame()
obj_flags |= EMAGGED
-/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion
+/mob/living/simple_animal/hostile/human/syndicate/ranged/smg/orion
name = "spaceport security"
desc = "Premier corporate security forces for all spaceports found along the Orion Trail."
faction = list("orion")
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 0fe059653d5c..3916ad0d4b00 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -534,9 +534,7 @@
if(ishuman(mob_occupant))
dna = C.has_dna()
- var/obj/item/card/id/I = C.get_idcard(TRUE)
- if(I)
- has_bank_account = I.registered_account
+ has_bank_account = C.get_bank_account()
if(isbrain(mob_occupant))
dna = B.stored_dna
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index f875defd6044..c1a1171e57cc 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -6,8 +6,8 @@
icon_screen = "crew"
icon_keyboard = "med_key"
use_power = IDLE_POWER_USE
- idle_power_usage = 250
- active_power_usage = 500
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_MEDIUM
circuit = /obj/item/circuitboard/computer/crew
light_color = LIGHT_COLOR_BLUE
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index ffeabbdc4e0a..815e2496d41b 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -43,8 +43,8 @@
circuit = /obj/item/circuitboard/computer/scan_consolenew
use_power = IDLE_POWER_USE
- idle_power_usage = 10
- active_power_usage = 400
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_MEDIUM
light_color = LIGHT_COLOR_BLUE
/// Link to the techweb's stored research. Used to retrieve stored mutations
diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm
index 20c3d66e8585..8419ee80ce1e 100644
--- a/code/game/machinery/dance_machine.dm
+++ b/code/game/machinery/dance_machine.dm
@@ -5,6 +5,8 @@
icon_state = "jukebox-"
verb_say = "states"
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_MINIMAL
var/active = FALSE
var/list/rangers = list()
var/stop = 0
diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm
index f3fa616032d3..645e8eee762f 100644
--- a/code/game/machinery/defibrillator_mount.dm
+++ b/code/game/machinery/defibrillator_mount.dm
@@ -165,7 +165,7 @@
name = "PENLITE defibrillator mount"
desc = "Holds defibrillators. You can grab the paddles if one is mounted. This PENLITE variant also allows for slow, passive recharging of the defibrillator."
icon_state = "penlite_mount"
- idle_power_usage = 1
+ idle_power_usage = 0
wallframe_type = /obj/item/wallframe/defib_mount/charging
diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm
index baf3d6ae2cc1..740ea5c935fa 100644
--- a/code/game/machinery/dish_drive.dm
+++ b/code/game/machinery/dish_drive.dm
@@ -5,8 +5,8 @@
Or you can just drop your plates on the floor, like civilized folk."
icon = 'icons/obj/kitchen.dmi'
icon_state = "synthesizer"
- idle_power_usage = 8 //5 with default parts
- active_power_usage = 13 //10 with default parts
+ idle_power_usage = IDLE_DRAW_MINIMAL //lower
+ active_power_usage = ACTIVE_DRAW_MINIMAL //lower ingame because stockparts
density = FALSE
circuit = /obj/item/circuitboard/machine/dish_drive
pass_flags = PASSTABLE
diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm
index 7f61dde6ef79..a45aaa474438 100644
--- a/code/game/machinery/dna_scanner.dm
+++ b/code/game/machinery/dna_scanner.dm
@@ -6,8 +6,8 @@
base_icon_state = "scanner"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 50
- active_power_usage = 300
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
occupant_typecache = list(/mob/living, /obj/item/bodypart/head, /obj/item/organ/brain)
circuit = /obj/item/circuitboard/machine/dnascanner
var/locked = FALSE
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 6bb5a4bab561..121c93a07353 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -958,7 +958,7 @@
to_chat(user, "You need at least 2 metal sheets to reinforce [src].")
return
to_chat(user, "You start reinforcing [src].")
- if(do_after(user, 20, TRUE, src))
+ if(do_after(user, 20, src))
if(!panel_open || !S.use(2))
return
user.visible_message("[user] reinforces \the [src] with metal.",
@@ -972,7 +972,7 @@
to_chat(user, "You need at least 2 plasteel sheets to reinforce [src].")
return
to_chat(user, "You start reinforcing [src].")
- if(do_after(user, 20, TRUE, src))
+ if(do_after(user, 20, src))
if(!panel_open || !S.use(2))
return
user.visible_message("[user] reinforces \the [src] with plasteel.",
@@ -1226,7 +1226,7 @@
var/time_to_open = 50
playsound(src, pry_sound, 100, TRUE, mono_adj = TRUE) //is it aliens or just the CE being a dick?
prying_so_hard = TRUE
- if(do_after(user, time_to_open, TRUE, src))
+ if(do_after(user, time_to_open, src))
open(2)
if(density && !open(2))
to_chat(user, "Despite your attempts, [src] refuses to open.")
@@ -1414,7 +1414,7 @@
playsound(src, 'sound/machines/creaking.ogg', 100, TRUE, mono_adj = TRUE)
- if(do_after(user, time_to_open, TRUE, src))
+ if(do_after(user, time_to_open, src))
if(density && !open(2)) //The airlock is still closed, but something prevented it opening. (Another player noticed and bolted/welded the airlock in time!)
to_chat(user, "Despite your efforts, [src] managed to resist your attempts to open it!")
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index 8e0ed982b501..492ce30f6ac4 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -264,17 +264,7 @@
opacity = FALSE
glass = TRUE
-/obj/machinery/door/airlock/bananium
- name = "bananium airlock"
- desc = "Honkhonkhonk"
- icon = 'icons/obj/doors/airlocks/station/bananium.dmi'
- assemblytype = /obj/structure/door_assembly/door_assembly_bananium
- doorOpen = 'sound/items/bikehorn.ogg'
- has_hatch = FALSE
-/obj/machinery/door/airlock/bananium/glass
- opacity = FALSE
- glass = TRUE
/obj/machinery/door/airlock/sandstone
name = "sandstone airlock"
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 81cb1908ce89..1ab88896accb 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -104,7 +104,7 @@
if(!welded && !operating && !(machine_stat & NOPOWER) && (!density || allow_hand_open(user)))
user.visible_message("[user] tries to open \the [src] manually.",
"You operate the manual lever on \the [src].")
- if (!do_after(user, 30, TRUE, src))
+ if (!do_after(user, 30, src))
return FALSE
add_fingerprint(user)
if(density)
@@ -174,7 +174,7 @@
if(is_holding_pressure())
// tell the user that this is a bad idea, and have a do_after as well
to_chat(user, "As you begin crowbarring \the [src] a gush of air blows in your face... maybe you should reconsider?")
- if(!do_after(user, 20, TRUE, src)) // give them a few seconds to reconsider their decision.
+ if(!do_after(user, 20, src)) // give them a few seconds to reconsider their decision.
return
log_game("[key_name(user)] has opened a firelock with a pressure difference at [AREACOORD(loc)]")
user.log_message("has opened a firelock with a pressure difference at [AREACOORD(loc)]", LOG_ATTACK)
diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index 4e846c26f14a..7e3febcc482c 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -23,26 +23,32 @@
/obj/machinery/door/poddoor/attackby(obj/item/W, mob/user, params)
. = ..()
if((resistance_flags & INDESTRUCTIBLE) && W.tool_behaviour == TOOL_SCREWDRIVER) // This makes it so ERT members cannot cheese by opening their blast doors.
- to_chat(user, "You can't find the panel!")
+ to_chat(user, span_warning("You can't find the panel!"))
return
if(W.tool_behaviour == TOOL_SCREWDRIVER)
if(density)
- to_chat(user, "You need to open [src] to access the maintenance panel!")
+ to_chat(user, span_warning("You need to open [src] to access the maintenance panel"))
return
else if(default_deconstruction_screwdriver(user, icon_state, icon_state, W))
- to_chat(user, "You [panel_open ? "open" : "close"] the maintenance hatch of [src].")
+ to_chat(user, span_notice("You [panel_open ? "open" : "close"] the maintenance hatch of [src]."))
return TRUE
if(panel_open && !density)
if(W.tool_behaviour == TOOL_MULTITOOL)
- var/change_id = input("Set [src]'s ID. It must be a number between 1 and 100.", "ID", id) as num|null
- if(change_id)
- id = clamp(round(change_id, 1), 1, 100)
- to_chat(user, "You change the ID to [id].")
+ var/obj/item/multitool/multi = W
+ if (istype(multi.buffer,/obj/item/assembly/control))
+ var/obj/item/assembly/control/controller = multi.buffer
+ id = controller.id
+ to_chat(user, span_notice("You copy the ID in your multitool's buffer into the [src]."))
+ else
+ var/change_id = input("Set [src]'s ID. It must be a number between 1 and 100.", "ID", id) as num|null
+ if(change_id)
+ id = clamp(round(change_id, 1), 1, 100)
+ to_chat(user, span_notice("You change the ID to [id]."))
if(W.tool_behaviour == TOOL_CROWBAR)
- to_chat(user, "You start to remove the airlock electronics.")
+ to_chat(user, span_notice("You start to remove the airlock electronics."))
if(!(machine_stat & NOPOWER))
do_sparks(5, TRUE, src)
electrocute_mob(user, get_area(src), src, 1, TRUE) //fuck this fella
@@ -52,9 +58,9 @@
/obj/machinery/door/poddoor/examine(mob/user)
. = ..()
- . += "The maintenance panel is [panel_open ? "opened" : "closed"]."
+ . += span_notice("The maintenance panel is [panel_open ? "opened" : "closed"].")
if(panel_open)
- . += "The airlock electronics are exposed and could be pried out."
+ . += span_notice("The airlock electronics are exposed and could be pried out.")
/obj/machinery/door/poddoor/deconstruct(disassembled = TRUE, mob/user)
if(!(flags_1 & NODECONSTRUCT_1))
@@ -142,18 +148,18 @@
/obj/machinery/door/poddoor/attack_alien(mob/living/carbon/alien/humanoid/user)
if(density & !(resistance_flags & INDESTRUCTIBLE))
add_fingerprint(user)
- user.visible_message("[user] begins prying open [src].",\
- "You begin digging your claws into [src] with all your might!",\
- "You hear groaning metal...")
+ user.visible_message(span_warning("[user] begins prying open [src]."),\
+ span_noticealien("You begin digging your claws into [src] with all your might"),\
+ span_warning("You hear groaning metal..."))
playsound(src, 'sound/machines/creaking.ogg', 100, TRUE)
var/time_to_open = 5 SECONDS
if(hasPower())
time_to_open = 15 SECONDS
- if(do_after(user, time_to_open, TRUE, src))
+ if(do_after(user, time_to_open, src))
if(density && !open(TRUE)) //The airlock is still closed, but something prevented it opening. (Another player noticed and bolted/welded the airlock in time!)
- to_chat(user, "Despite your efforts, [src] managed to resist your attempts to open it!")
+ to_chat(user, span_warning("Despite your efforts, [src] managed to resist your attempts to open it!"))
else
return ..()
diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm
index aa3e4ece65e9..25da902ea3f5 100644
--- a/code/game/machinery/doppler_array.dm
+++ b/code/game/machinery/doppler_array.dm
@@ -6,6 +6,8 @@
icon = 'icons/obj/machines/research.dmi'
base_icon_state = "tdoppler"
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
verb_say = "states coldly"
var/cooldown = 10
var/next_announce = 0
diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/drone_dispenser.dm
similarity index 99%
rename from code/game/machinery/droneDispenser.dm
rename to code/game/machinery/drone_dispenser.dm
index dbf055d98079..4603044ab285 100644
--- a/code/game/machinery/droneDispenser.dm
+++ b/code/game/machinery/drone_dispenser.dm
@@ -9,6 +9,8 @@
icon = 'icons/obj/machines/droneDispenser.dmi'
icon_state = "on"
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
max_integrity = 250
integrity_failure = 0.33
diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm
index 9d190b2e1369..34d4bb320c46 100644
--- a/code/game/machinery/embedded_controller/access_controller.dm
+++ b/code/game/machinery/embedded_controller/access_controller.dm
@@ -7,8 +7,8 @@
/obj/machinery/doorButtons
power_channel = AREA_USAGE_ENVIRON
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 4
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/idSelf
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index faceb46419d5..6cbd6eaed278 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -23,8 +23,8 @@
integrity_failure = 0.4
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30)
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 6
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
power_channel = AREA_USAGE_ENVIRON
resistance_flags = FIRE_PROOF
diff --git a/code/game/machinery/gulag_item_reclaimer.dm b/code/game/machinery/gulag_item_reclaimer.dm
index 8833a20d90c4..81c422ea31fa 100644
--- a/code/game/machinery/gulag_item_reclaimer.dm
+++ b/code/game/machinery/gulag_item_reclaimer.dm
@@ -6,8 +6,8 @@
req_access = list(ACCESS_SECURITY) //REQACCESS TO ACCESS ALL STORED ITEMS
density = FALSE
use_power = IDLE_POWER_USE
- idle_power_usage = 100
- active_power_usage = 2500
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = IDLE_DRAW_MEDIUM
var/list/stored_items = list()
var/obj/machinery/gulag_teleporter/linked_teleporter = null
diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm
index e147e24717ca..3632c204f36b 100644
--- a/code/game/machinery/gulag_teleporter.dm
+++ b/code/game/machinery/gulag_teleporter.dm
@@ -15,8 +15,8 @@ The console is located at computer/gulag_teleporter.dm
state_open = FALSE
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 200
- active_power_usage = 5000
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_EXTREME
circuit = /obj/item/circuitboard/machine/gulag_teleporter
var/locked = FALSE
var/message_cooldown
diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm
index 9cf4470cab5c..1b0093458e49 100644
--- a/code/game/machinery/harvester.dm
+++ b/code/game/machinery/harvester.dm
@@ -2,12 +2,14 @@
name = "organ harvester"
desc = "An advanced machine used for harvesting organs and limbs from the deceased."
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
icon = 'icons/obj/machines/harvester.dmi'
icon_state = "harvester"
base_icon_state = "harvester"
verb_say = "states"
state_open = FALSE
- idle_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/harvester
light_color = LIGHT_COLOR_BLUE
var/interval = 20
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 4a31d650f9a1..0e6bc6ed6a6d 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -36,8 +36,8 @@ Possible to do for anyone motivated enough:
plane = FLOOR_PLANE
req_access = list(ACCESS_KEYCARD_AUTH) //Used to allow for forced connecting to other (not secure) holopads. Anyone can make a call, though.
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
max_integrity = 300
armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
circuit = /obj/item/circuitboard/machine/holopad
@@ -78,6 +78,8 @@ Possible to do for anyone motivated enough:
var/secure = FALSE
/// If we are currently calling another holopad
var/calling = FALSE
+ /// The last holopad that called this one.
+ var/caller_history
/obj/machinery/holopad/Initialize()
. = ..()
@@ -178,7 +180,9 @@ Possible to do for anyone motivated enough:
/obj/machinery/holopad/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
- . += "The status display reads: Current projection range: [holo_range] units."
+ . += span_notice("The status display reads: Current projection range: [holo_range] units.")
+ if(caller_history)
+ . += span_notice("The caller history displays the last recieved call to be from: [caller_history].")
/obj/machinery/holopad/attackby(obj/item/P, mob/user, params)
if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", P))
@@ -195,11 +199,11 @@ Possible to do for anyone motivated enough:
if(istype(P,/obj/item/disk/holodisk))
if(disk)
- to_chat(user,"There's already a disk inside [src]!")
+ to_chat(user,span_warning("There's already a disk inside [src]!"))
return
if (!user.transferItemToLoc(P,src))
return
- to_chat(user,"You insert [P] into [src].")
+ to_chat(user,span_notice("You insert [P] into [src]."))
disk = P
return
@@ -249,15 +253,15 @@ Possible to do for anyone motivated enough:
if("AIrequest")
if(last_request + 200 < world.time)
last_request = world.time
- to_chat(usr, "You requested an AI's presence.")
+ to_chat(usr, span_info("You requested an AI's presence."))
var/area/area = get_area(src)
for(var/mob/living/silicon/ai/AI in GLOB.silicon_mobs)
if(!AI.client)
continue
- to_chat(AI, "Your presence is requested at \the [area].")
+ to_chat(AI, span_info("Your presence is requested at \the [area]."))
return TRUE
else
- to_chat(usr, "A request for AI presence was already sent recently.")
+ to_chat(usr, span_info("A request for AI presence was already sent recently."))
return
if("holocall")
if(outgoing_call)
@@ -280,7 +284,7 @@ Possible to do for anyone motivated enough:
calling = TRUE
return TRUE
else
- to_chat(usr, "You must stand on the holopad to make a call!")
+ to_chat(usr, span_warning("You must stand on the holopad to make a call!"))
if("connectcall")
var/datum/holocall/call_to_connect = locate(params["holopad"]) in holo_calls
if(!QDELETED(call_to_connect))
@@ -374,6 +378,7 @@ Possible to do for anyone motivated enough:
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad != src)
+ caller_history = get_area_name(HC.calling_holopad)
if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2)))
HC.Answer(src)
break
@@ -392,7 +397,7 @@ Possible to do for anyone motivated enough:
if(is_operational && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it
if (AI && istype(AI.current, /obj/machinery/holopad))
- to_chat(user, "ERROR: \black Image feed in progress.")
+ to_chat(user, span_danger("ERROR: \black Image feed in progress."))
return
var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location.
@@ -415,11 +420,11 @@ Possible to do for anyone motivated enough:
move_hologram(user, loc)
set_holo(user, Hologram)
- visible_message("A holographic image of [user] flickers to life before your eyes!")
+ visible_message(span_notice("A holographic image of [user] flickers to life before your eyes!"))
return Hologram
else
- to_chat(user, "ERROR: Unable to project hologram.")
+ to_chat(user, span_danger("ERROR:Unable to project hologram."))
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
@@ -446,8 +451,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/holopad/proc/SetLightsAndPower()
var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls)
- use_power = total_users > 0 ? ACTIVE_POWER_USE : IDLE_POWER_USE
- active_power_usage = HOLOPAD_PASSIVE_POWER_USAGE + (HOLOGRAM_POWER_USAGE * total_users)
+ //active_power_usage = initial(active_power_usage) * total_users
if(total_users || replay_mode)
set_light(2)
else
@@ -580,7 +584,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
Hologram.set_anchored(TRUE)//So space wind cannot drag it.
Hologram.name = "[record.caller_name] (Hologram)"//If someone decides to right click.
Hologram.set_light(2) //hologram lighting
- visible_message("A holographic image of [record.caller_name] flickers to life before your eyes!")
+ visible_message(span_notice("A holographic image of [record.caller_name] flickers to life before your eyes!"))
return Hologram
/obj/machinery/holopad/proc/replay_start()
diff --git a/code/game/machinery/hypnochair.dm b/code/game/machinery/hypnochair.dm
index b31dd9925375..e14756815bb2 100644
--- a/code/game/machinery/hypnochair.dm
+++ b/code/game/machinery/hypnochair.dm
@@ -6,6 +6,8 @@
base_icon_state = "hypnochair"
circuit = /obj/item/circuitboard/machine/hypnochair
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
opacity = FALSE
var/mob/living/carbon/victim = null ///Keeps track of the victim to apply effects if it teleports away
diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm
index 8117ad2c251a..c82d67a9df62 100644
--- a/code/game/machinery/igniter.dm
+++ b/code/game/machinery/igniter.dm
@@ -6,8 +6,8 @@
base_icon_state = "igniter"
plane = FLOOR_PLANE
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 4
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_LOW
max_integrity = 300
armor = list("melee" = 50, "bullet" = 30, "laser" = 70, "energy" = 50, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
resistance_flags = FIRE_PROOF
diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm
index c7752a8cbfaa..c3e6bead671a 100644
--- a/code/game/machinery/launch_pad.dm
+++ b/code/game/machinery/launch_pad.dm
@@ -3,9 +3,9 @@
desc = "A bluespace pad able to thrust matter through bluespace, teleporting it to or from nearby locations."
icon = 'icons/obj/telescience.dmi'
icon_state = "lpad-idle"
- use_power = TRUE
- idle_power_usage = 200
- active_power_usage = 2500
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_EXTREME
hud_possible = list(DIAG_LAUNCHPAD_HUD)
circuit = /obj/item/circuitboard/machine/launchpad
var/icon_teleport = "lpad-beam"
@@ -149,7 +149,7 @@
teleporting = FALSE
// use a lot of power
- use_power(1000)
+ use_power(active_power_usage)
var/turf/source = target
var/list/log_msg = list()
diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm
index dc5b41ee3821..c0f296c1ffcf 100644
--- a/code/game/machinery/limbgrower.dm
+++ b/code/game/machinery/limbgrower.dm
@@ -7,8 +7,8 @@
icon_state = "limbgrower_idleoff"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 10
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_LOW
circuit = /obj/item/circuitboard/machine/limbgrower
/// The category of limbs we're browing in our UI.
@@ -24,7 +24,7 @@
/// Our internal techweb for limbgrower designs.
var/datum/techweb/stored_research
/// All the categories of organs we can print.
- var/list/categories = list(SPECIES_HUMAN,SPECIES_LIZARD,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ETHEREAL,SPECIES_RACHNID,SPECIES_KEPORI,SPECIES_VOX,"other")
+ var/list/categories = list(SPECIES_HUMAN,SPECIES_SARATHI,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ELZUOSE,SPECIES_RACHNID,SPECIES_KEPORI,SPECIES_VOX,"other")
//yogs grower a little different because we're going to allow meats to be converted to synthflesh because hugbox
var/list/accepted_biomass = list(
/obj/item/reagent_containers/food/snacks/meat/slab/monkey = 25,
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
index 4f91bea3ab7a..7316e5b42422 100644
--- a/code/game/machinery/mass_driver.dm
+++ b/code/game/machinery/mass_driver.dm
@@ -4,8 +4,8 @@
icon = 'icons/obj/stationobjs.dmi'
icon_state = "mass_driver"
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
var/power = 1
var/code = 1
var/id = 1
diff --git a/code/game/machinery/medical_kiosk.dm b/code/game/machinery/medical_kiosk.dm
index d7be7fea98ee..2f60c799ae23 100644
--- a/code/game/machinery/medical_kiosk.dm
+++ b/code/game/machinery/medical_kiosk.dm
@@ -18,6 +18,8 @@
base_icon_state = "kiosk"
layer = ABOVE_MOB_LAYER
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
circuit = /obj/item/circuitboard/machine/medical_kiosk
var/obj/item/scanner_wand
/// Emag mode
@@ -170,7 +172,7 @@
sickness_data = "\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]"
if(altPatient.has_dna()) //Blood levels Information
- if(altPatient.bleed_rate)
+ if(LAZYLEN(altPatient.get_bleeding_parts()))
bleed_status = "Patient is currently bleeding!"
if(blood_percent <= 80)
blood_warning = " Patient has low blood levels. Seek a large meal, or iron supplements."
diff --git a/code/game/machinery/medipen_refiller.dm b/code/game/machinery/medipen_refiller.dm
index e104257b5493..ceb0ed389c17 100644
--- a/code/game/machinery/medipen_refiller.dm
+++ b/code/game/machinery/medipen_refiller.dm
@@ -5,7 +5,7 @@
icon_state = "medipen_refiller"
density = TRUE
circuit = /obj/item/circuitboard/machine/medipen_refiller
- idle_power_usage = 100
+ idle_power_usage = IDLE_DRAW_LOW
/// list of medipen subtypes it can refill
var/list/allowed = list(
/obj/item/reagent_containers/hypospray/medipen = /datum/reagent/medicine/epinephrine,
diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm
index a847b44d39a1..b54c192f4407 100644
--- a/code/game/machinery/navbeacon.dm
+++ b/code/game/machinery/navbeacon.dm
@@ -49,7 +49,7 @@
if(previous_virtual_z)
LAZYREMOVEASSOC(GLOB.navbeacons, "[previous_virtual_z]", src)
if(new_virtual_z)
- LAZYADDASSOC(GLOB.navbeacons, "[new_virtual_z]", src)
+ LAZYADDASSOCLIST(GLOB.navbeacons, "[new_virtual_z]", src)
..()
// set the transponder codes assoc list from codes_txt
diff --git a/code/game/machinery/outpost_electrolyzer.dm b/code/game/machinery/outpost_electrolyzer.dm
new file mode 100644
index 000000000000..29a37c4f95e8
--- /dev/null
+++ b/code/game/machinery/outpost_electrolyzer.dm
@@ -0,0 +1,536 @@
+//allows production of hydrogen from ice chunks
+#define MOLS_PER_ICE 50 //1 ice = 50 mols
+#define MOLS_PER_MERIT 10 //10 mols = 1 merit
+#define MERITS_PER_ICE MOLS_PER_ICE / MOLS_PER_MERIT //1 ice = 5 merits
+#define MERITS_USED_PER_TICK 2
+#define H2_PUMP_SHUTOFF_PRESSURE 4000
+#define CREDITS_TO_MERITS 4 // currently 2:5 credits to mols hydrogen. # of credits per merit
+#define OUTPOST_HYDROGEN_CUT 0.8
+#define HYDROGEN_IDEAL 45000 //used for high and low end of merit multiplier
+#define MERIT_EXPONENT 0.95 //used for diminishing returns, values closer to 1 increase returns, lower decrease.
+
+/obj/machinery/mineral/electrolyzer_unloader
+ name = "ice unloading machine"
+ icon = 'icons/obj/machines/mining_machines.dmi'
+ icon_state = "unloader"
+ density = TRUE
+ input_dir = WEST
+ output_dir = EAST
+ needs_item_input = TRUE
+ processing_flags = START_PROCESSING_MANUALLY
+
+/obj/machinery/mineral/electrolyzer_unloader/pickup_item(datum/source, atom/movable/target, atom/oldLoc)
+ if(istype(target, /obj/structure/ore_box))
+ var/obj/structure/ore_box/box = target
+ for(var/obj/item/stack/ore/ice/chunk in box)
+ unload_mineral(chunk)
+ else if(istype(target, /obj/item/stack/ore/ice))
+ var/obj/item/stack/ore/chunk = target
+ unload_mineral(chunk)
+
+// electrolyzer + console
+
+/obj/machinery/computer/electrolyzer_console
+ name = "electrolyzer console"
+ desc = "Deposits hydrogen merits, with 20% going to outpost upkeep."
+ icon = 'icons/obj/machines/mining_machines.dmi'
+ icon_state = "console"
+
+ var/obj/machinery/mineral/electrolyzer/linked_electrolyzer
+
+/obj/machinery/computer/electrolyzer_console/Initialize()
+ . = ..()
+ find_electrolyzer()
+
+/obj/machinery/computer/electrolyzer_console/proc/find_electrolyzer()
+ for(var/obj/machinery/mineral/electrolyzer/potential in oview(3,src))
+ if(linked_electrolyzer == null)
+ linked_electrolyzer = potential
+ potential.linked_console = src
+
+/obj/machinery/computer/electrolyzer_console/proc/electrolyze_item(obj/item/I)
+ var/obj/item/stack/ore/ice/S = I
+ var/meritval = round(S.get_amount() * MERITS_PER_ICE * OUTPOST_HYDROGEN_CUT,1) // causes a bit of surplus in the "outpost" supply, even if they use all of these merits for hydrogen.
+ GLOB.hydrogen_stored += S.get_amount() * MOLS_PER_ICE
+ new /obj/item/merit/bundle(drop_location(), meritval)
+ qdel(I)
+ playsound(src, 'sound/items/poster_being_created.ogg', 20, FALSE)
+
+/obj/machinery/computer/electrolyzer_console/attackby(item,mob/user)
+ if(istype(item, /obj/item/multitool))
+ var/obj/item/multitool/multi = item
+ if(istype(multi.buffer, /obj/machinery/mineral/electrolyzer))
+ linked_electrolyzer = multi.buffer
+ visible_message("Linked to [linked_electrolyzer]!")
+ return
+ return ..()
+
+/obj/machinery/mineral/electrolyzer
+ name = "ice crusher"
+ desc = "Breaks down ice into hydrogen and oxygen."
+ icon = 'icons/obj/recycling.dmi'
+ icon_state = "grinder-o1"
+ input_dir = WEST
+ density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = 50
+ active_power_usage = 1000
+ max_integrity = 500
+ var/crush_damage = 1000
+ var/obj/machinery/computer/electrolyzer_console/linked_console
+ var/datum/weakref/attached_output
+
+/obj/machinery/mineral/electrolyzer/Initialize()
+ . = ..()
+ update_appearance()
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+
+/obj/machinery/computer/electrolyzer_console/attackby(item,mob/user)
+ if(istype(item, /obj/item/multitool))
+ var/obj/item/multitool/multi = item
+ multi.buffer = src
+ to_chat(user, "[src] stored in [multi].")
+ return
+ return ..()
+
+/obj/machinery/mineral/electrolyzer/CanAllowThrough(atom/movable/mover, border_dir)
+ . = ..()
+ if(!anchored)
+ return
+ if(border_dir == input_dir)
+ return TRUE
+
+/obj/machinery/mineral/electrolyzer/proc/on_entered(datum/source, atom/movable/AM)
+ SIGNAL_HANDLER
+ INVOKE_ASYNC(src, PROC_REF(electrolyze), AM)
+
+/obj/machinery/mineral/electrolyzer/proc/electrolyze(atom/movable/electrolyze_target, sound=TRUE)
+ if(istype(electrolyze_target, /obj/effect) || !linked_console || !isturf(electrolyze_target.loc) || (machine_stat & (BROKEN|NOPOWER)))
+ return
+ if(!istype(electrolyze_target, /obj/item/stack/ore/ice))
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE, 1)
+ if(isliving(electrolyze_target))
+ crush_living(electrolyze_target)
+ return
+ if(!ismob(electrolyze_target)) //MULCH IT IF IT AINT ICE
+ qdel(electrolyze_target)
+ return
+ else
+ linked_console.electrolyze_item(electrolyze_target)
+
+/obj/machinery/mineral/electrolyzer/proc/crush_living(mob/living/L)
+
+ L.forceMove(loc)
+
+ if(issilicon(L))
+ playsound(src, 'sound/items/welder.ogg', 50, TRUE)
+ else
+ playsound(src, 'sound/effects/splat.ogg', 50, TRUE)
+
+ if(iscarbon(L) && L.stat == CONSCIOUS)
+ L.emote("scream")
+
+ // Instantly lie down, also go unconscious from the pain, before you die.
+ L.Unconscious(100)
+ L.adjustBruteLoss(crush_damage)
+
+//Hydrogen pump stuff
+
+/obj/machinery/atmospherics/components/unary/hydrogen_pump
+ name = "hydrogen pump"
+ desc = "Lets you use merits to buy hydrogen."
+ icon = 'icons/obj/atmos.dmi'
+ icon_state = "hydrogen_pump"
+
+ use_power = IDLE_POWER_USE
+ idle_power_usage = 50
+ active_power_usage = 1000
+
+ density = TRUE
+ max_integrity = 400
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 30)
+ layer = OBJ_LAYER
+ showpipe = TRUE
+ pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
+ var/not_processing_bug = TRUE//remove when fixed
+ var/merit
+
+/obj/machinery/atmospherics/components/unary/hydrogen_pump/examine(mob/user)
+ . = ..()
+ if(merit)
+ . += "[src] has [merit] merits, equaling [merit * MOLS_PER_MERIT] mols of hydrogen."
+ else
+ . += "[src] has no merits, get some from the electrolyzer or buy them to get hydrogen!"
+ . += "[src] is currently [on ? "on" : "off"], and shuts off above [H2_PUMP_SHUTOFF_PRESSURE] kPa."
+ . += "[src] can be Alt-Clicked to eject merits."
+ if(not_processing_bug == TRUE)
+ . += "[src] is temporarily disabled. Check back later!"
+
+/obj/machinery/atmospherics/components/unary/hydrogen_pump/process_atmos()
+ ..()
+ var/datum/gas_mixture/air = airs[1] //hydrogen out
+ not_processing_bug = FALSE
+ if(!on)
+ return
+ if(!merit || air.return_pressure() > H2_PUMP_SHUTOFF_PRESSURE)
+ on = FALSE
+ visible_message("[src] shuts off!")
+ playsound(src, 'sound/machines/switch2.ogg', 10, FALSE)
+ return
+ var/meritused
+ if(merit >= MERITS_USED_PER_TICK)
+ merit -= MERITS_USED_PER_TICK
+ meritused = MERITS_USED_PER_TICK
+ else
+ meritused = merit
+ merit = 0
+ on = FALSE
+ air.adjust_moles(GAS_HYDROGEN, meritused * MOLS_PER_MERIT)
+ GLOB.hydrogen_stored -= meritused * MOLS_PER_MERIT
+ air.set_temperature(T20C) //hydrogen from adjust_mols takes the temp of the container, and if the container is empty it defaults to 0K. this works for now
+
+/obj/machinery/atmospherics/components/unary/hydrogen_pump/attackby(obj/item/I, mob/user)
+ if(istype(I, /obj/item/merit/bundle))
+ var/obj/item/merit/bundle/C = I
+ merit += C.value
+ to_chat(user, "You deposit [I], for a total of [merit] merits.")
+ qdel(I)
+ return
+ return ..()
+
+/obj/machinery/atmospherics/components/unary/hydrogen_pump/attack_hand(mob/user)
+ if(..())
+ return
+ on = !on
+ if(on)
+ SSair.start_processing_machine(src)
+ playsound(src, 'sound/machines/switch3.ogg', 10, FALSE)
+ to_chat(user, "You toggle the pump [on ? "on" : "off"].")
+ investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS)
+ update_appearance()
+
+/obj/machinery/atmospherics/components/unary/hydrogen_pump/AltClick(mob/user)
+ if(merit)
+ new /obj/item/merit/bundle(drop_location(), merit)
+ merit = FALSE
+ playsound(src, 'sound/items/poster_being_created.ogg', 10, FALSE)
+ to_chat(user, "You retrieve the hydrogen merits.")
+ else
+ to_chat(user, "There were no merits left to retrieve.")
+
+
+//Hydrogen exchange
+
+/obj/machinery/computer/hydrogen_exchange
+ name = "Hydrogen Exchange"
+ desc = "Credits to Merits at reasonable rates!"
+ icon_screen = "exchange"
+ icon_keyboard = "power_key"
+
+ //GLOB.total_merits_exchanged starts at 0
+ var/merits = NONE
+ var/credits = NONE
+
+/obj/machinery/computer/hydrogen_exchange/attackby(obj/item/I, mob/user)
+ var/value = 0
+ if(istype(I, /obj/item/spacecash/bundle))
+ var/obj/item/spacecash/bundle/C = I
+ value = C.value
+ else if(istype(I, /obj/item/holochip))
+ var/obj/item/holochip/H = I
+ value = H.credits
+ if(value)
+ credits += value
+ to_chat(user, "You deposit [I], for a total of [credits] credits.")
+ qdel(I)
+ return
+ if(istype(I, /obj/item/merit/bundle))
+ var/obj/item/merit/bundle/C = I
+ merits += C.value
+ to_chat(user, "You deposit [I], for a total of [merits] merits.")
+ qdel(I)
+ return
+ return ..()
+
+/obj/machinery/computer/hydrogen_exchange/proc/meritmultiplier()
+ var/extra = clamp(((GLOB.hydrogen_stored / HYDROGEN_IDEAL) + 1), 0, 2) * 0.3 //results in a number between 0 and .6
+ var/actual = round((0.4 + extra), 0.01) //.4 on low end, 1 on high end
+ return actual
+
+/obj/machinery/computer/hydrogen_exchange/proc/dispense_funds()
+ var/makenoise
+ if(merits)
+ new /obj/item/merit/bundle(drop_location(), merits)
+ merits = 0
+ makenoise = TRUE
+ if(credits)
+ new /obj/item/spacecash/bundle(drop_location(), credits)
+ credits = 0
+ makenoise = TRUE
+ if(makenoise)
+ playsound(src, 'sound/machines/coindrop.ogg', 20, FALSE)
+
+/obj/machinery/computer/hydrogen_exchange/proc/resetmerits() //debug proc
+ GLOB.total_merits_exchanged = 0
+
+/obj/machinery/computer/hydrogen_exchange/proc/convert_to_credits()
+ if(merits)
+ playsound(src, 'sound/machines/pda_button1.ogg', 20, FALSE)
+ var/oldtotal = GLOB.total_merits_exchanged ** MERIT_EXPONENT
+ var/newtotal = (GLOB.total_merits_exchanged + merits) ** MERIT_EXPONENT
+ var/reducedmerits = newtotal - oldtotal
+ GLOB.total_merits_exchanged += merits
+ credits += round(reducedmerits * CREDITS_TO_MERITS, 1)
+ merits = 0
+ else
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 20, FALSE)
+
+/obj/machinery/computer/hydrogen_exchange/proc/convert_to_merits()
+ if(credits)
+ playsound(src, 'sound/machines/pda_button1.ogg', 20, FALSE)
+ merits += round(credits * meritmultiplier() / CREDITS_TO_MERITS, 1)
+ credits = 0
+ else
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 20, FALSE)
+
+/obj/machinery/computer/hydrogen_exchange/AltClick(mob/user)
+ dispense_funds()
+ to_chat(user, "You force the credits and merits out of the machine.")
+
+/obj/machinery/computer/hydrogen_exchange/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "HydrogenExchange", name)
+ ui.open()
+
+/obj/machinery/computer/hydrogen_exchange/ui_data(mob/user)
+ var/next_merit_rate
+ if(GLOB.total_merits_exchanged)
+ next_merit_rate = round((GLOB.total_merits_exchanged ** MERIT_EXPONENT) / GLOB.total_merits_exchanged * CREDITS_TO_MERITS, 0.01)
+ else
+ next_merit_rate = CREDITS_TO_MERITS
+ var/list/data = list()
+ data["credits"] = credits
+ data["merits"] = merits
+ data["next_merit_rate"] = next_merit_rate
+ data["credits_to_merits"] = CREDITS_TO_MERITS
+ data["credit_tax"] = (1 - meritmultiplier()) * 100
+ return data
+
+/obj/machinery/computer/hydrogen_exchange/ui_act(action, params)
+ . = ..()
+ if(.)
+ return
+
+ switch(action)
+ if("convert_to_credits")
+ convert_to_credits()
+ . = TRUE
+ if("convert_to_merits")
+ convert_to_merits()
+ . = TRUE
+ if("dispense")
+ dispense_funds()
+ . = TRUE
+
+//SCRIP!
+
+/obj/item/merit
+ name = "hydrogen?"
+ desc = "If you can see this, please make a bug report. If you're a mapper, use the bundle subtype!"
+ icon = 'icons/obj/economy.dmi'
+ icon_state = "merit0"
+ throwforce = 1
+ throw_speed = 2
+ throw_range = 2
+ w_class = WEIGHT_CLASS_TINY
+ var/value = 0
+ grind_results = list(/datum/reagent/iron = 10)
+
+/obj/item/merit/Initialize(mapload, amount)
+ . = ..()
+ if(amount)
+ value = amount
+ update_appearance()
+
+/obj/item/merit/attackby(obj/item/I, mob/user)
+ if(!istype(I, /obj/item/merit))
+ return
+ var/obj/item/merit/bundle/bundle
+ if(istype(I, /obj/item/merit/bundle))
+ bundle = I
+ else
+ var/obj/item/merit/cash = I
+ bundle = new (loc)
+ bundle.value = cash.value
+ user.dropItemToGround(cash)
+ qdel(cash)
+
+ bundle.value += value
+ bundle.update_appearance()
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ H.dropItemToGround(src)
+ H.dropItemToGround(bundle)
+ H.put_in_hands(bundle)
+ to_chat(user, "You add [value] merits worth of money to the bundle. It now holds [bundle.value] merits.")
+ qdel(src)
+
+/obj/item/merit/Destroy()
+ . = ..()
+ value = 0 // Prevents money from be duplicated anytime.//I'll trust eris on this one
+
+/obj/item/merit/bundle
+ icon_state = "merit16"
+
+/obj/item/merit/bundle/Initialize()
+ . = ..()
+ update_appearance()
+
+/obj/item/merit/bundle/update_appearance()
+ icon_state = "nothing"
+ cut_overlays()
+ var/remaining_value = value
+ var/iteration = 0
+ var/coins_only = TRUE
+ var/list/coin_denominations = list(16, 4, 1)
+ var/list/banknote_denominations = list(4096, 1024, 256, 64)
+ for(var/i in banknote_denominations)
+ while(remaining_value >= i && iteration < 50)
+ remaining_value -= i
+ iteration++
+ var/image/banknote = image('icons/obj/economy.dmi', "merit[i]")
+ var/matrix/M = matrix()
+ M.Translate(rand(-6, 6), rand(-4, 8))
+ banknote.transform = M
+ overlays += banknote
+ coins_only = FALSE
+
+ if(remaining_value)
+ for(var/i in coin_denominations)
+ while(remaining_value >= i && iteration < 50)
+ remaining_value -= i
+ iteration++
+ var/image/coin = image('icons/obj/economy.dmi', "merit[i]")
+ var/matrix/M = matrix()
+ M.Translate(rand(-6, 6), rand(-4, 8))
+ coin.transform = M
+ overlays += coin
+
+ if(coins_only)
+ if(value == 1)
+ name = "one hydrogen merit"
+ desc = "Heavier then it looks."
+ drop_sound = 'sound/items/handling/coin_drop.ogg'
+ pickup_sound = 'sound/items/handling/coin_pickup.ogg'
+ else
+ name = "[value] hydrogen merits"
+ desc = "Heavier than they look."
+ gender = PLURAL
+ drop_sound = 'sound/items/handling/coin_drop.ogg'
+ pickup_sound = 'sound/items/handling/coin_pickup.ogg'
+ else
+ if(value <= 3000)
+ name = "[value] hydrogen merits"
+ gender = NEUTER
+ desc = "Some cold, hard cash."
+ drop_sound = 'sound/items/handling/dosh_drop.ogg'
+ pickup_sound = 'sound/items/handling/dosh_pickup.ogg'
+ else
+ name = "[value] hydrogen merit"
+ gender = NEUTER
+ desc = "That's a lot of dosh."
+ drop_sound = 'sound/items/handling/dosh_drop.ogg'
+ pickup_sound = 'sound/items/handling/dosh_pickup.ogg'
+ return ..()
+
+/obj/item/merit/bundle/attack_self(mob/user)
+ var/cashamount = input(user, "How many merits do you want to take? (0 to [value])", "Take Merits", 20) as num
+ cashamount = round(clamp(cashamount, 0, value))
+ if(!cashamount)
+ return
+
+ if(!Adjacent(user))
+ to_chat(user, "You need to be in arm's reach for that!")
+ return
+
+ value -= cashamount
+ if(!value)
+ user.dropItemToGround(src)
+ qdel(src)
+
+ var/obj/item/merit/bundle/bundle = new (user.loc)
+ bundle.value = cashamount
+ update_appearance()
+
+/obj/item/merit/bundle/AltClick(mob/living/user)
+ var/cashamount = input(user, "How many merits do you want to take? (0 to [value])", "Take Merits", 20) as num
+ cashamount = round(clamp(cashamount, 0, value))
+ if(!cashamount)
+ return
+
+ else if(!Adjacent(user))
+ to_chat(user, "You need to be in arm's reach for that!")
+ return
+
+ value -= cashamount
+ if(!value)
+ user.dropItemToGround(src)
+ qdel(src)
+
+ var/obj/item/merit/bundle/bundle = new (user.loc)
+ bundle.value = cashamount
+ bundle.update_appearance()
+ user.put_in_hands(bundle)
+ update_appearance()
+
+/obj/item/merit/bundle/attack_hand(mob/user)
+ if(user.get_inactive_held_item() != src)
+ return ..()
+ if(value == 0)//may prevent any edge case duping
+ qdel(src)
+ return
+ value--
+ user.put_in_hands(new /obj/item/merit/bundle(loc, 1))
+ update_appearance()
+
+//bundles for mapping + testing
+
+/obj/item/merit/bundle/m1
+ value = 1
+ icon_state = "merit1"
+
+/obj/item/merit/bundle/m4
+ value = 4
+ icon_state = "merit4"
+
+/obj/item/merit/bundle/m16
+ value = 16
+ icon_state = "merit16"
+
+/obj/item/merit/bundle/m64
+ value = 64
+ icon_state = "merit64"
+
+/obj/item/merit/bundle/m256
+ value = 256
+ icon_state = "merit256"
+
+/obj/item/merit/bundle/m1024
+ value = 1024
+ icon_state = "merit1024"
+
+/obj/item/merit/bundle/m4096
+ value = 4096
+ icon_state = "merit4096"
+
+#undef MOLS_PER_ICE
+#undef MOLS_PER_MERIT
+#undef MERITS_PER_ICE
+#undef MERITS_USED_PER_TICK
+#undef H2_PUMP_SHUTOFF_PRESSURE
+#undef CREDITS_TO_MERITS
+#undef MERIT_EXPONENT
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index 75498600b007..5891898ef6dc 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -33,8 +33,8 @@ DEFINE_BITFIELD(turret_flags, list(
density = TRUE
desc = "A covered turret that shoots at its enemies."
use_power = IDLE_POWER_USE //this turret uses and requires power
- idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power
- active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
+ idle_power_usage = IDLE_DRAW_MINIMAL //when inactive, this turret takes up constant 50 Equipment power
+ active_power_usage = ACTIVE_DRAW_LOW //when active, this turret takes up constant 300 Equipment power
req_access = list(ACCESS_SECURITY) /// Only people with Security access
power_channel = AREA_USAGE_EQUIP //drains power from the EQUIPMENT channel
max_integrity = 160 //the turret's health
@@ -795,7 +795,7 @@ DEFINE_BITFIELD(turret_flags, list(
max_integrity = 300
always_up = 1
use_power = ACTIVE_POWER_USE
- active_power_usage = 300
+ active_power_usage = ACTIVE_DRAW_MINIMAL
has_cover = 0
scan_range = 9
stun_projectile = /obj/projectile/beam/disabler
diff --git a/code/game/machinery/prisonlabor.dm b/code/game/machinery/prisonlabor.dm
index 6fe329ed4a71..76612018d87a 100644
--- a/code/game/machinery/prisonlabor.dm
+++ b/code/game/machinery/prisonlabor.dm
@@ -4,8 +4,8 @@
icon = 'icons/obj/machines/prison.dmi'
icon_state = "offline"
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_LOW
var/obj/item/stack/license_plates/empty/current_plate
var/pressing = FALSE
diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm
index cc9f8f6d3d59..7d0455ab82f0 100644
--- a/code/game/machinery/quantum_pad.dm
+++ b/code/game/machinery/quantum_pad.dm
@@ -4,8 +4,8 @@
icon = 'icons/obj/telescience.dmi'
icon_state = "qpad-idle"
use_power = IDLE_POWER_USE
- idle_power_usage = 200
- active_power_usage = 5000
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_EXTREME
obj_flags = CAN_BE_HIT | UNIQUE_RENAME
circuit = /obj/item/circuitboard/machine/quantumpad
var/teleport_cooldown = 400 //30 seconds base due to base parts
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index c604b3eeccf6..b0e030206a0f 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -5,8 +5,8 @@
base_icon_state = "recharger"
desc = "A charging dock for energy based weaponry."
use_power = IDLE_POWER_USE
- idle_power_usage = 4
- active_power_usage = 250
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_LOW
circuit = /obj/item/circuitboard/machine/recharger
pass_flags = PASSTABLE
var/obj/item/charging = null
@@ -21,6 +21,7 @@
/obj/item/ammo_box/magazine/recharge,
/obj/item/modular_computer,
/obj/item/gun/ballistic/automatic/powered,
+ /obj/item/gun/ballistic/automatic/assault/e40,
))
/obj/machinery/recharger/RefreshParts()
@@ -50,11 +51,11 @@
if (new_charging)
START_PROCESSING(SSmachines, src)
finished_recharging = FALSE
- use_power = ACTIVE_POWER_USE
+ set_active_power()
using_power = TRUE
update_appearance()
else
- use_power = IDLE_POWER_USE
+ set_idle_power()
using_power = FALSE
update_appearance()
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 7039b015e673..cedf6c0a56ff 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -1,12 +1,12 @@
/obj/machinery/recharge_station
name = "cyborg recharging station"
desc = "This device recharges cyborgs and resupplies them with materials."
- icon = 'icons/obj/objects.dmi'
+ icon = 'icons/obj/machines/borgcharger.dmi'
icon_state = "borgcharger0"
density = FALSE
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 1000
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
req_access = list(ACCESS_ROBOTICS)
state_open = TRUE
circuit = /obj/item/circuitboard/machine/cyborgrecharger
@@ -90,12 +90,12 @@
/obj/machinery/recharge_station/open_machine()
. = ..()
- use_power = IDLE_POWER_USE
+ set_idle_power()
/obj/machinery/recharge_station/close_machine()
. = ..()
if(occupant)
- use_power = ACTIVE_POWER_USE //It always tries to charge, even if it can't.
+ set_active_power() //It always tries to charge, even if it can't.
add_fingerprint(occupant)
/obj/machinery/recharge_station/update_icon_state()
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index b548ecf73125..82265e244448 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -7,6 +7,8 @@
icon_state = "grinder-o0"
layer = ABOVE_ALL_MOB_LAYER // Overhead
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
circuit = /obj/item/circuitboard/machine/recycler
var/safety_mode = FALSE // Temporarily stops machine if it detects a mob
var/icon_name = "grinder-o"
@@ -19,7 +21,7 @@
/obj/machinery/recycler/Initialize()
AddComponent(/datum/component/butchering/recycler, 1, amount_produced,amount_produced/5)
- AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/plasma, /datum/material/gold, /datum/material/diamond, /datum/material/plastic, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace), INFINITY, FALSE, null, null, null, TRUE)
+ AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/plasma, /datum/material/gold, /datum/material/diamond, /datum/material/plastic, /datum/material/uranium, /datum/material/hellstone, /datum/material/titanium, /datum/material/bluespace), INFINITY, FALSE, null, null, null, TRUE)
. = ..()
update_appearance()
req_one_access = get_all_accesses() + get_all_centcom_access()
diff --git a/code/game/machinery/roulette_machine.dm b/code/game/machinery/roulette_machine.dm
index c9e1d108c1e5..a36bf79a41b3 100644
--- a/code/game/machinery/roulette_machine.dm
+++ b/code/game/machinery/roulette_machine.dm
@@ -26,8 +26,8 @@
density = TRUE
use_power = IDLE_POWER_USE
anchored = FALSE
- idle_power_usage = 10
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
max_integrity = 500
armor = list("melee" = 45, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 10, "bio" = 30, "rad" = 30, "fire" = 30, "acid" = 30)
var/static/list/numbers = list("0" = "green", "1" = "red", "3" = "red", "5" = "red", "7" = "red", "9" = "red", "12" = "red", "14" = "red", "16" = "red",\
@@ -39,7 +39,7 @@
var/chosen_bet_type = "0"
var/last_anti_spam = 0
var/anti_spam_cooldown = 20
- var/obj/item/card/id/my_card
+ var/obj/item/card/bank/my_card
var/playing = FALSE
var/locked = FALSE
var/drop_dir = SOUTH
@@ -81,7 +81,7 @@
data["Spinning"] = playing
if(ishuman(user))
var/mob/living/carbon/human/H = user
- var/obj/item/card/id/C = H.get_idcard(TRUE)
+ var/obj/item/card/bank/C = H.get_bankcard()
if(C)
data["AccountBalance"] = C.registered_account.account_balance
else
@@ -114,7 +114,7 @@
return
if(playing)
return ..()
- if(istype(W, /obj/item/card/id))
+ if(istype(W, /obj/item/card/bank))
playsound(src, 'sound/machines/card_slide.ogg', 50, TRUE)
if(machine_stat & MAINT || !on || locked)
@@ -122,7 +122,7 @@
return FALSE
if(my_card)
- var/obj/item/card/id/player_card = W
+ var/obj/item/card/bank/player_card = W
if(player_card.registered_account.account_balance < chosen_bet_amount) //Does the player have enough funds
audible_message("You do not have the funds to play! Lower your bet or get more money.")
playsound(src, 'sound/machines/buzz-two.ogg', 30, TRUE)
@@ -167,7 +167,7 @@
addtimer(CALLBACK(src, PROC_REF(play), user, player_card, chosen_bet_type, chosen_bet_amount, potential_payout), 4) //Animation first
return TRUE
else
- var/obj/item/card/id/new_card = W
+ var/obj/item/card/bank/new_card = W
if(new_card.registered_account)
var/msg = stripped_input(user, "Name of your roulette wheel:", "Roulette Naming", "Roulette Machine")
if(!msg)
@@ -181,7 +181,7 @@
return ..()
///Proc called when player is going to try and play
-/obj/machinery/roulette/proc/play(mob/user, obj/item/card/id/player_id, bet_type, bet_amount, potential_payout)
+/obj/machinery/roulette/proc/play(mob/user, obj/item/card/bank/player_id, bet_type, bet_amount, potential_payout)
var/payout = potential_payout
@@ -203,7 +203,7 @@
playsound(src, 'sound/machines/piston_lower.ogg', 70)
///Ran after a while to check if the player won or not.
-/obj/machinery/roulette/proc/finish_play(obj/item/card/id/player_id, bet_type, bet_amount, potential_payout, rolled_number)
+/obj/machinery/roulette/proc/finish_play(obj/item/card/bank/player_id, bet_type, bet_amount, potential_payout, rolled_number)
last_spin = rolled_number
var/is_winner = check_win(bet_type, bet_amount, rolled_number) //Predetermine if we won
diff --git a/code/game/machinery/scan_gate.dm b/code/game/machinery/scan_gate.dm
index afc154a0c95a..cf83233598aa 100644
--- a/code/game/machinery/scan_gate.dm
+++ b/code/game/machinery/scan_gate.dm
@@ -6,6 +6,7 @@
#define SCANGATE_WANTED "Wanted"
#define SCANGATE_SPECIES "Species"
+//god why cant this use the normal species defines
#define SCANGATE_HUMAN "human"
#define SCANGATE_LIZARD "lizard"
#define SCANGATE_FLY "fly"
@@ -17,7 +18,7 @@
#define SCANGATE_SPIDER "rachnid"
#define SCANGATE_IPC "ipc"
#define SCANGATE_SQUID "squid"
-#define SCANGATE_ETHEREAL "ethereal"
+#define SCANGATE_ELZUOSE "elzuose"
#define SCANGATE_KEPORI "kepori"
/obj/machinery/scanner_gate
@@ -26,7 +27,7 @@
icon = 'icons/obj/machines/scangate.dmi'
icon_state = "scangate"
use_power = IDLE_POWER_USE
- idle_power_usage = 50
+ idle_power_usage = IDLE_DRAW_LOW
circuit = /obj/item/circuitboard/machine/scanner_gate
var/scanline_timer
@@ -146,8 +147,8 @@
scan_species = /datum/species/spider
if(SCANGATE_IPC)
scan_species = /datum/species/ipc
- if(SCANGATE_ETHEREAL)
- scan_species = /datum/species/ethereal
+ if(SCANGATE_ELZUOSE)
+ scan_species = /datum/species/elzuose
if(SCANGATE_KEPORI)
scan_species = /datum/species/kepori
if(is_species(H, scan_species))
@@ -247,5 +248,5 @@
#undef SCANGATE_SPIDER
#undef SCANGATE_IPC
#undef SCANGATE_SQUID
-#undef SCANGATE_ETHEREAL
+#undef SCANGATE_ELZUOSE
#undef SCANGATE_KEPORI
diff --git a/code/game/machinery/sheetifier.dm b/code/game/machinery/sheetifier.dm
index 569bfa4b6f9e..ec9f0f5ff5a3 100644
--- a/code/game/machinery/sheetifier.dm
+++ b/code/game/machinery/sheetifier.dm
@@ -5,8 +5,8 @@
icon_state = "base_machine"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 10
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_LOW
circuit = /obj/item/circuitboard/machine/sheetifier
layer = BELOW_OBJ_LAYER
var/busy_processing = FALSE
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index bc578a856300..df865aee82e5 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -122,25 +122,23 @@
if(.)
return
if(locked && !issilicon(user))
- to_chat(user, "The machine is locked, you are unable to use it!")
+ to_chat(user, span_notice("The machine is locked, you are unable to use it!"))
return
if(panel_open)
- to_chat(user, "The panel must be closed before operating this machine!")
+ to_chat(user, span_warning("The panel must be closed before operating this machine!"))
return
if (active)
- user.visible_message("[user] deactivated \the [src].", \
- "You deactivate \the [src].", \
- "You hear heavy droning fade out.")
+ user.visible_message(span_notice("[user] deactivated \the [src]."), span_notice("You deactivate \the [src]."), span_hear("You hear heavy droning fade out"))
shields_down()
else
if(anchored)
- user.visible_message("[user] activated \the [src].", \
- "You activate \the [src].", \
- "You hear heavy droning.")
+ user.visible_message(span_notice("[user] activated \the [src]."), \
+ span_notice("You activate \the [src]."), \
+ span_hear("You hear heavy droning."))
shields_up()
else
- to_chat(user, "The device must first be secured to the floor!")
+ to_chat(user, span_warning("The device must first be secured to the floor!"))
return
/obj/machinery/shieldgen/attackby(obj/item/W, mob/user, params)
@@ -148,60 +146,60 @@
W.play_tool_sound(src, 100)
panel_open = !panel_open
if(panel_open)
- to_chat(user, "You open the panel and expose the wiring.")
+ to_chat(user, span_notice("You open the panel and expose the wiring."))
else
- to_chat(user, "You close the panel.")
+ to_chat(user, span_notice("You close the panel."))
else if(istype(W, /obj/item/stack/cable_coil) && (machine_stat & BROKEN) && panel_open)
var/obj/item/stack/cable_coil/coil = W
if (coil.get_amount() < 1)
- to_chat(user, "You need one length of cable to repair [src]!")
+ to_chat(user, span_warning("You need one length of cable to repair [src]!"))
return
- to_chat(user, "You begin to replace the wires...")
+ to_chat(user, span_notice("You begin to replace the wires..."))
if(do_after(user, 30, target = src))
if(coil.get_amount() < 1)
return
coil.use(1)
obj_integrity = max_integrity
set_machine_stat(machine_stat & ~BROKEN)
- to_chat(user, "You repair \the [src].")
+ to_chat(user, span_notice("You repair \the [src]."))
update_appearance()
else if(W.tool_behaviour == TOOL_WRENCH)
if(locked)
- to_chat(user, "The bolts are covered! Unlocking this would retract the covers.")
+ to_chat(user, span_warning("The bolts are covered! Unlocking this would retract the covers."))
return
if(!anchored && !isinspace())
W.play_tool_sound(src, 100)
- to_chat(user, "You secure \the [src] to the floor!")
+ to_chat(user, span_notice("You secure \the [src] to the floor!"))
set_anchored(TRUE)
else if(anchored)
W.play_tool_sound(src, 100)
- to_chat(user, "You unsecure \the [src] from the floor!")
+ to_chat(user, span_notice("You unsecure \the [src] from the floor!"))
if(active)
- to_chat(user, "\The [src] shuts off!")
+ to_chat(user, span_notice("\The [src] shuts off!"))
shields_down()
set_anchored(FALSE)
else if(W.GetID())
if(allowed(user) && !(obj_flags & EMAGGED))
locked = !locked
- to_chat(user, "You [locked ? "lock" : "unlock"] the controls.")
+ to_chat(user, span_notice("You [locked ? "lock" : "unlock"] the controls."))
else if(obj_flags & EMAGGED)
- to_chat(user, "Error, access controller damaged!")
+ to_chat(user, span_danger("Error, access controller damaged!"))
else
- to_chat(user, "Access denied.")
+ to_chat(user, span_danger("Access denied."))
else
return ..()
/obj/machinery/shieldgen/emag_act(mob/user)
if(obj_flags & EMAGGED)
- to_chat(user, "The access controller is damaged!")
+ to_chat(user, span_warning("The access controller is damaged!"))
return
obj_flags |= EMAGGED
locked = FALSE
playsound(src, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- to_chat(user, "You short out the access controller.")
+ to_chat(user, span_warning("You short out the access controller."))
/obj/machinery/shieldgen/update_icon_state()
icon_state = "shield[active ? "on" : "off"][(machine_stat & BROKEN) ? "br" : null]"
@@ -219,8 +217,8 @@
req_access = list(ACCESS_TELEPORTER)
flags_1 = CONDUCT_1
use_power = NO_POWER_USE
- idle_power_usage = 10
- active_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_HIGH
circuit = /obj/item/circuitboard/machine/shieldwallgen
max_integrity = 300
var/active = FALSE
@@ -275,9 +273,7 @@
if(!active_power_usage || surplus() >= active_power_usage)
add_load(active_power_usage)
else
- visible_message("The [src.name] shuts down due to lack of power!", \
- "If this message is ever seen, something is wrong.",
- "You hear heavy droning fade out.")
+ visible_message(span_danger("The [src.name] shuts down due to lack of power!"), "If this message is ever seen, something is wrong.",span_hear("You hear heavy droning fade out."))
active = FALSE
log_game("[src] deactivated due to lack of power at [AREACOORD(src)]")
for(var/direction in GLOB.cardinals)
@@ -348,7 +344,7 @@
/obj/machinery/power/shieldwallgen/can_be_unfasten_wrench(mob/user, silent)
if(active)
if(!silent)
- to_chat(user, "Turn off the shield generator first!")
+ to_chat(user, span_warning("Turn off the shield generator first!"))
return FAILED_UNFASTEN
return ..()
@@ -388,11 +384,11 @@
if(item.GetID())
if(allowed(user) && !(obj_flags & EMAGGED))
locked = !locked
- to_chat(user, "You [src.locked ? "lock" : "unlock"] the controls.")
+ to_chat(user, span_notice("You [src.locked ? "lock" : "unlock"] the controls."))
else if(obj_flags & EMAGGED)
- to_chat(user, "Error, access controller damaged!")
+ to_chat(user, span_danger("Error, access controller damaged!"))
else
- to_chat(user, "Access denied.")
+ to_chat(user, span_danger("Access denied."))
else
add_fingerprint(user)
@@ -406,25 +402,23 @@
shock(user,50)
return
if(!anchored)
- to_chat(user, "\The [src] needs to be firmly secured to the floor first!")
+ to_chat(user, span_warning("\The [src] needs to be firmly secured to the floor first!"))
return
if(locked && !issilicon(user))
- to_chat(user, "The controls are locked!")
+ to_chat(user, span_warning("The controls are locked!"))
return
if(!powernet)
- to_chat(user, "\The [src] needs to be powered by a wire!")
+ to_chat(user, span_warning("\The [src] needs to be powered by a wire!"))
return
if(active)
- user.visible_message("[user] turned \the [src] off.", \
- "You turn off \the [src].", \
- "You hear heavy droning fade out.")
+ user.visible_message(span_notice("[user] turned \the [src] off."), \
+ span_notice("You turn off \the [src]."), \
+ span_hear("You hear heavy droning fade out."))
active = FALSE
log_game("[src] was deactivated by [key_name(user)] at [AREACOORD(src)]")
else
- user.visible_message("[user] turned \the [src] on.", \
- "You turn on \the [src].", \
- "You hear heavy droning.")
+ user.visible_message(span_notice("[user] turned \the [src] on."), span_notice("ou turn on \the [src]."), span_hear("ou hear heavy droning."))
active = ACTIVE_SETUPFIELDS
log_game("[src] was activated by [key_name(user)] at [AREACOORD(src)]")
add_fingerprint(user)
@@ -435,28 +429,28 @@
if(!powernet)
return
if(active)
- visible_message("The [src.name] hums as it powers down.", \
+ visible_message(span_notice("The [src.name] hums as it powers down."), \
"If this message is ever seen, something is wrong.", \
- "You hear heavy droning fade out.")
+ span_notice("You hear heavy droning fade out."))
playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, frequency = 6120)
active = FALSE
log_game("[src] was deactivated by wire pulse at [AREACOORD(src)]")
else
- visible_message("The [src.name] beeps as it powers up.", \
+ visible_message(span_notice("The [src.name] beeps as it powers up."), \
"If this message is ever seen, something is wrong.", \
- "You hear heavy droning.")
+ span_notice("You hear heavy droning."))
playsound(src, 'sound/machines/synth_yes.ogg', 50, TRUE, frequency = 6120)
active = ACTIVE_SETUPFIELDS
log_game("[src] was activated by wire pulse at [AREACOORD(src)]")
/obj/machinery/power/shieldwallgen/emag_act(mob/user)
if(obj_flags & EMAGGED)
- to_chat(user, "The access controller is damaged!")
+ to_chat(user, span_warning("The access controller is damaged!"))
return
obj_flags |= EMAGGED
locked = FALSE
playsound(src, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- to_chat(user, "You short out the access controller.")
+ to_chat(user, span_warning("You short out the access controller."))
/obj/machinery/power/shieldwallgen/proc/shock(mob/user, prb)
if(machine_stat & (BROKEN|NOPOWER)) // unpowered, no shock
@@ -511,10 +505,31 @@
/obj/machinery/power/shieldwallgen/atmos/proc/can_be_rotated(mob/user, rotation_type)
if (anchored)
- to_chat(user, "It is fastened to the floor!")
+ to_chat(user, span_warning("It is fastened to the floor!"))
return FALSE
return TRUE
+/obj/machinery/power/shieldwallgen/atmos/attacked_by(obj/item/I, mob/living/user)
+ if(I.tool_behaviour == TOOL_MULTITOOL)
+ var/obj/item/multitool/multi = I
+ if(!panel_open && !locked)
+ if(istype(multi.buffer,/obj/item/assembly/control/shieldwallgen))
+ var/obj/item/assembly/control/shieldwallgen/controller = multi.buffer
+ to_chat(user, span_notice("You copy the ID in your multitool's buffer to the [src]."))
+ id = controller.id
+ return TRUE
+
+ else
+ to_chat(user, span_warning("The controls are locked!"))
+ return
+
+ return ..()
+
+/obj/machinery/power/shieldwallgen/atmos/multitool_act(mob/living/user, obj/item/I)
+ . = ..()
+
+
+
/// Same as in the normal shieldwallgen, but with the shieldwalls replaced with atmos shieldwalls
/obj/machinery/power/shieldwallgen/atmos/setup_field(direction)
if(!direction)
@@ -586,7 +601,7 @@
setDir(get_dir(gen_primary, gen_secondary))
if(hardshield == TRUE)
for(var/mob/living/victim in get_turf(src))
- visible_message("\The [src] is suddenly occupying the same space as \the [victim]!")
+ visible_message(span_danger("\The [src] is suddenly occupying the same space as \the [victim]!"))
victim.gib()
/obj/machinery/shieldwall/Destroy()
diff --git a/code/game/machinery/shuttle/ship_gravity.dm b/code/game/machinery/shuttle/ship_gravity.dm
new file mode 100644
index 000000000000..4f63c60d7824
--- /dev/null
+++ b/code/game/machinery/shuttle/ship_gravity.dm
@@ -0,0 +1,124 @@
+//
+// Ship Gravity Generator
+//
+
+/obj/machinery/power/ship_gravity
+ name = "gravitational generator"
+ desc = "A ship-portable gravity generator, capable of providing gravity throughout the vessel it is installed on."
+ icon = 'icons/obj/machines/ship_gravity.dmi'
+ icon_state = "shipgrav"
+ base_icon_state = "shipgrav"
+ density = TRUE
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_EXTREME
+ circuit = /obj/item/circuitboard/machine/ship_gravity
+ var/charging = FALSE
+ var/active = FALSE
+ var/charge = 0
+
+/obj/machinery/power/ship_gravity/unanchored
+ anchored = FALSE
+
+/obj/machinery/power/ship_gravity/admin
+ idle_power_usage = 0
+ active_power_usage = 0
+ active = TRUE
+
+/obj/machinery/power/ship_gravity/Initialize()
+ . = ..()
+ if(anchored)
+ connect_to_network()
+
+/obj/machinery/power/ship_gravity/process()
+ if(charging && (!active_power_usage || surplus() >= active_power_usage))
+ add_load(active_power_usage)
+ charge = min(charge+1, 5)
+ if(charge >= 5)
+ set_state(TRUE)
+ else
+ charge = max(charge-1, 0)
+ if(!charge)
+ set_state(FALSE)
+ update_appearance()
+
+/obj/machinery/power/ship_gravity/proc/set_state(toggle)
+ if(toggle == active)
+ return
+ if(toggle)
+ active = TRUE
+ playsound(src.loc, 'sound/effects/empulse.ogg', 100, TRUE)
+ visible_message(span_warning("The [src.name] finishes charging!"), blind_message = span_hear("You hear a low hum fade in."))
+ else
+ visible_message(span_danger("The [src.name] shuts down due to lack of power!"), blind_message = span_hear("You hear a low hum fade out."))
+ active = FALSE
+ log_game("[src] deactivated due to lack of power at [AREACOORD(src)]", INVESTIGATE_GRAVITY)
+ update_appearance()
+
+/obj/machinery/power/ship_gravity/update_overlays()
+ . = ..()
+ var/mutable_appearance/charge_state
+ if(active)
+ charge_state = mutable_appearance(icon, "charge_active")
+ if(charge < 5)
+ charge_state = mutable_appearance(icon, "charge_[charge]")
+ . += charge_state
+
+/obj/machinery/power/ship_gravity/examine(mob/user)
+ . = ..()
+ if(anchored)
+ . += span_info("It's secured to the floor, you can unsecure it with a wrench.")
+ else
+ . += span_info("It's currently unsecured, you can secure it with a wrench.")
+ if(in_range(user, src) || isobserver(user))
+ if(!charging && !charge)
+ . += span_info("Its status display is currently turned off.")
+ else
+ . += span_info("Its status display reads: Current charge at [charge*20]%.")
+
+/obj/machinery/power/ship_gravity/screwdriver_act(mob/living/user, obj/item/I)
+ ..()
+ if(charging || charge)
+ to_chat(user, span_notice("You cannot open the maintenance panel on [src] while it is active!"))
+ return TRUE
+ default_deconstruction_screwdriver(user, "shipgrav_o", "shipgrav", I)
+ return TRUE
+
+/obj/machinery/power/ship_gravity/wrench_act(mob/living/user, obj/item/I)
+ . =..()
+ if(active)
+ to_chat(user, span_notice("You cannot unsecure [src] while it is active!"))
+ return TRUE
+ default_unfasten_wrench(user, I)
+ return TRUE
+
+/obj/machinery/power/ship_gravity/crowbar_act(mob/living/user, obj/item/I)
+ . = ..()
+ default_deconstruction_crowbar(I)
+ return TRUE
+
+/obj/machinery/power/ship_gravity/default_unfasten_wrench(mob/user, obj/item/I, time = 20)
+ . = ..()
+ if(. == SUCCESSFUL_UNFASTEN)
+ if(anchored)
+ connect_to_network()
+ else
+ disconnect_from_network()
+ charging = FALSE
+ set_state(FALSE)
+
+/obj/machinery/power/ship_gravity/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
+ . = ..()
+ port.gravgen_list |= WEAKREF(src)
+
+/obj/machinery/power/ship_gravity/interact(mob/user)
+ if(!powernet && active_power_usage)
+ to_chat(user, span_notice("[src] isn't connected to a wire!"))
+ return
+ if(panel_open)
+ return
+ charging = !charging
+ play_click_sound("switch")
+ user.visible_message(span_warning("[user] flips [src]'s power [charging ? "on" : "off"]!"), \
+ span_info("You flip [src]'s power lever, turning it [charging ? "on" : "off"]"), \
+ span_hear("You hear a heavy lever being pulled."))
+ update_appearance()
diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm
index 267c8d102918..d816b16ca7ff 100644
--- a/code/game/machinery/shuttle/shuttle_engine.dm
+++ b/code/game/machinery/shuttle/shuttle_engine.dm
@@ -8,11 +8,12 @@
desc = "A thruster for shuttles."
circuit = /obj/item/circuitboard/machine/shuttle/engine
CanAtmosPass = FALSE //so people can actually tend to their engines
+ dir = EAST //most ships face east
///Whether or not the engine is enabled and can be used. Controlled from helm consoles and by hitting with a multitool.
var/enabled = TRUE
///How much thrust this engine generates when burned fully.
var/thrust = 0
- ///I don't really know what this is but it's used a lot
+ ///Whether this engine is actively providing thrust to the ship
var/thruster_active = FALSE
/**
diff --git a/code/game/machinery/shuttle/shuttle_engine_types.dm b/code/game/machinery/shuttle/shuttle_engine_types.dm
index e5e3d812c098..47711bdda3bc 100644
--- a/code/game/machinery/shuttle/shuttle_engine_types.dm
+++ b/code/game/machinery/shuttle/shuttle_engine_types.dm
@@ -29,7 +29,7 @@
if(heat_creation)
heat_engine()
var/to_use = fuel_use * (percentage / 100) * deltatime
- return resolved_heater.consume_fuel(to_use, fuel_type) / to_use * thrust //This proc returns how much was actually burned, so let's use that and multiply it by the thrust to get all the thrust we CAN give.
+ return resolved_heater.consume_fuel(to_use, fuel_type) / to_use * percentage / 100 * thrust //This proc returns how much was actually burned, so let's use that and multiply it by the thrust to get all the thrust we CAN give.
/obj/machinery/power/shuttle/engine/fueled/return_fuel()
. = ..()
@@ -82,9 +82,16 @@
if(!found.anchored)
continue
attached_heater = WEAKREF(found)
+ var/obj/machinery/atmospherics/components/unary/shuttle/heater/resolved_heater = attached_heater?.resolve()
+ RegisterSignal(resolved_heater, COMSIG_OBJ_DECONSTRUCT, PROC_REF(remove_heater))
update_icon_state()
return TRUE
+/obj/machinery/power/shuttle/engine/fueled/proc/remove_heater(datum/source, disassembled)
+ SIGNAL_HANDLER
+
+ attached_heater = null
+
/obj/machinery/power/shuttle/engine/fueled/plasma
name = "plasma thruster"
desc = "A thruster that burns plasma from an adjacent heater to create thrust."
@@ -101,6 +108,90 @@
thrust = 15
//All fuel code already handled
+/**
+ * ### Combustion/Fire engines
+ * Engines that use oxidizer and fuel to output thrust. Theoretically works with any mix of fuels and oxiders. Wish me luck.
+*/
+
+/obj/machinery/power/shuttle/engine/fire
+ name = "combustion thruster"
+ desc = "A thruster that burns fuel with oxider that is stored in an adjacent heater."
+ icon_state = "burst_plasma"
+ icon_state_off = "burst_plasma_off"
+ circuit = /obj/item/circuitboard/machine/shuttle/engine/fire
+
+ idle_power_usage = 0
+ ///what portion of the mols in the attached heater to "burn"
+ var/fuel_consumption = 0.0125
+ //multiplier for thrust
+ thrust = 3
+ //used by stockparts, efficiency_multiplier
+ var/consumption_multiplier = 1
+ //If this engine should create heat when burned.
+ var/heat_creation = FALSE
+ //A weakref of the connected engine heater with fuel.
+ var/datum/weakref/attached_heater
+
+
+/obj/machinery/power/shuttle/engine/fire/burn_engine(percentage = 100, deltatime)
+ . = ..()
+ var/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/resolved_heater = attached_heater?.resolve()
+ if(!resolved_heater)
+ return
+ if(heat_creation)
+ heat_engine()
+ var/actual_consumption = fuel_consumption * (percentage / 100) * deltatime * consumption_multiplier
+ return resolved_heater.consume_fuel(actual_consumption) * thrust //this proc returns the min of the fuel/oxy possible burns, multiply by our thrust value
+
+/obj/machinery/power/shuttle/engine/fire/return_fuel()
+ . = ..()
+ var/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/resolved_heater = attached_heater?.resolve()
+ return resolved_heater?.return_gas()
+
+/obj/machinery/power/shuttle/engine/fire/return_fuel_cap()
+ . = ..()
+ var/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/resolved_heater = attached_heater?.resolve()
+ return resolved_heater?.return_gas_capacity()
+
+/obj/machinery/power/shuttle/engine/fire/screwdriver_act(mob/living/user, obj/item/I)
+ . = ..()
+ update_icon_state()
+
+/obj/machinery/power/shuttle/engine/fire/update_engine()
+ if(!..())
+ return
+ if(!attached_heater && !set_heater())
+ thruster_active = FALSE
+ return FALSE
+
+/obj/machinery/power/shuttle/engine/fire/proc/set_heater()
+ for(var/direction in GLOB.cardinals)
+ for(var/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/found in get_step(get_turf(src), direction))
+ if(found.dir != dir)
+ continue
+ if(found.panel_open)
+ continue
+ if(!found.anchored)
+ continue
+ attached_heater = WEAKREF(found)
+ var/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/resolved_heater = attached_heater?.resolve()
+ RegisterSignal(resolved_heater, COMSIG_OBJ_DECONSTRUCT, PROC_REF(remove_heater))
+ update_icon_state()
+ return TRUE
+
+/obj/machinery/power/shuttle/engine/fire/proc/remove_heater(datum/source, disassembled)
+ SIGNAL_HANDLER
+
+ var/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/resolved_heater = attached_heater?.resolve()
+ UnregisterSignal(resolved_heater, COMSIG_OBJ_DECONSTRUCT)
+ attached_heater = null
+
+/obj/machinery/power/shuttle/engine/fire/RefreshParts()
+ var/laz = 0
+ for(var/obj/item/stock_parts/micro_laser/L in component_parts)
+ laz += L.rating
+ consumption_multiplier = laz
+
/**
* ### Ion Engines
* Engines that convert electricity to thrust. Yes, I know that's not how it works, it needs a propellant, but this is a video game.
@@ -133,6 +224,7 @@
name = "electric engine precharger"
desc = "A medium-capacity, high transfer superconducting magnetic energy storage unit specially made for use with shuttle engines."
icon = 'icons/obj/shuttle.dmi'
+ dir = EAST
input_level = 5000
input_level_max = 50000
output_level = 50000
diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm
index 94735ba4ab25..2b440f926c32 100644
--- a/code/game/machinery/shuttle/shuttle_heater.dm
+++ b/code/game/machinery/shuttle/shuttle_heater.dm
@@ -4,11 +4,32 @@
//but instead of changing temp, it stores plasma and uses
//it for the engine.
//-----------------------------------------------
+
+#define O2_OXIDATION_VALUE 1
+#define NITRYL_OXIDATION_VALUE 1
+#define NITROUS_OXIDATION_VALUE 3
+
+#define PLASMA_THRUSTER_VALUE 1
+#define TRITRIUM_THRUSTER_VALUE 3
+#define HYDROGEN_THRUSTER_VALUE 0.5
+
+#define NITROUS_COOLING_MULTIPIER 500
+#define NITROUS_COOLING_MIN 173
+
+#define DAMAGE_NONE 0
+#define DAMAGE_LOW 1
+#define DAMAGE_MED 2
+#define DAMAGE_HIGH 3
+
+#define PRESSURE_LIMIT 1010 //in kpa
+#define PRESSURE_DAMAGE_MAX 1200 //gives 10 minutes per stage at the pressure limit
+
/obj/machinery/atmospherics/components/unary/shuttle
name = "shuttle atmospherics device"
desc = "This does something to do with shuttle atmospherics"
icon_state = "heater"
icon = 'icons/obj/shuttle.dmi'
+ dir = EAST
/obj/machinery/atmospherics/components/unary/shuttle/heater
name = "engine heater"
@@ -16,7 +37,7 @@
icon_state = "heater_pipe"
var/icon_state_closed = "heater_pipe"
var/icon_state_open = "heater_pipe_open"
- idle_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/shuttle/heater
density = TRUE
@@ -25,7 +46,7 @@
layer = OBJ_LAYER
showpipe = TRUE
- pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
+ pipe_flags = PIPING_ONE_PER_TURF
var/efficiency_multiplier = 1
var/gas_capacity = 0
@@ -34,6 +55,13 @@
///The internals tank to draw from
var/obj/item/tank/fuel_tank
+/obj/machinery/atmospherics/components/unary/shuttle/heater/on_construction(obj_color, set_layer)
+ var/obj/item/circuitboard/machine/shuttle/heater/board = circuit
+ if(board)
+ piping_layer = board.pipe_layer
+ set_layer = piping_layer
+ ..()
+
/obj/machinery/atmospherics/components/unary/shuttle/heater/New()
. = ..()
SetInitDirections()
@@ -173,3 +201,262 @@
. = ..()
fuel_tank = new /obj/item/tank/internals/plasma/full(src)
use_tank = TRUE
+
+//combustion heater
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater
+ name = "combustion engine heater"
+ desc = "Directs fuel mix into an attached combustion thruster."
+ icon_state = "heater_pipe"
+ var/icon_state_closed = "heater_pipe"
+ var/icon_state_open = "heater_pipe_open"
+ var/gas_amount = 0 //amount of gas used in calculations
+ var/gas_capacity = 0
+ var/efficiency_multiplier = 1
+ var/pressure_damage = 0
+ var/damage_state = 0
+ var/metal_repair = FALSE //used to see if metal's been added during repair step
+ idle_power_usage = 50
+ circuit = /obj/item/circuitboard/machine/shuttle/fire_heater
+
+ density = TRUE
+ max_integrity = 400
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 30)
+ layer = OBJ_LAYER
+ showpipe = TRUE
+
+ pipe_flags = PIPING_ONE_PER_TURF
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/on_construction(obj_color, set_layer)
+ var/obj/item/circuitboard/machine/shuttle/fire_heater/board = circuit
+ if(board)
+ piping_layer = board.pipe_layer
+ set_layer = piping_layer
+ ..()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/New()
+ . = ..()
+ SetInitDirections()
+ update_adjacent_engines()
+ update_gas_stats()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/Destroy()
+ . = ..()
+ update_adjacent_engines()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/on_construction()
+ ..(dir, dir)
+ SetInitDirections()
+ update_adjacent_engines()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/process_atmos()
+ var/datum/gas_mixture/air_contents = airs[1]
+ var/pressure = air_contents.return_pressure()
+ if(pressure > PRESSURE_LIMIT)
+ pressure_damage += pressure / PRESSURE_LIMIT //always more than 1
+ if(rand(1, 48) == 48) //process_atmos() calls around twice a second, so this'll go off on average every 24 seconds.
+ playsound(loc, "hull_creaking", 60, TRUE, 20, pressure_affected = FALSE) // the ship is Not happy
+ if(pressure_damage >= PRESSURE_DAMAGE_MAX)
+ damage_state += 1 //damage state starts at 0, 1 causes temp leak, 2 causes gas leak, 3 causes explosion
+ pressure_damage = 0 // reset our counter here
+ playsound(loc, 'sound/effects/bang.ogg', 240, TRUE, 5)
+ if(damage_state >= DAMAGE_LOW)
+ var/loc_air = loc.return_air()
+ air_contents.temperature_share(loc_air, 0.4) //equalizes temp with its turf
+ if(damage_state >= DAMAGE_MED)
+ assume_air_ratio(air_contents, 0.01) //leaks a bit of its tank
+ if(damage_state >= DAMAGE_HIGH)
+ var/epicenter = loc
+ explosion(epicenter, 2, 2, 3, 3, TRUE, TRUE) //boom
+ update_parents()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/default_change_direction_wrench(mob/user, obj/item/I)
+ if(!..())
+ return FALSE
+ SetInitDirections()
+ var/obj/machinery/atmospherics/node = nodes[1]
+ if(node)
+ node.disconnect(src)
+ nodes[1] = null
+ if(!parents[1])
+ return
+ nullifyPipenet(parents[1])
+
+ atmosinit()
+ node = nodes[1]
+ if(node)
+ node.atmosinit()
+ node.addMember(src)
+ SSair.add_to_rebuild_queue(src)
+ return TRUE
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/RefreshParts()
+ var/cap = 0
+ var/eff = 0
+ for(var/obj/item/stock_parts/matter_bin/M in component_parts)
+ cap += M.rating
+ for(var/obj/item/stock_parts/micro_laser/L in component_parts)
+ eff += L.rating
+ gas_capacity = 5000 * ((cap - 1) ** 2) + 1000
+ efficiency_multiplier = round(sqrt(eff), 0.1)
+ update_gas_stats()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/examine(mob/user)
+ . = ..()
+ . += "The engine heater's gas dial reads [return_gas()] kPa."
+ . += "A lightly burnt hazard sticker reports a safe pressure of [PRESSURE_LIMIT] kPa. "
+ if(damage_state == DAMAGE_MED && metal_repair == FALSE)
+ . += "The engine heater's plating could be repaired with metal."
+ if(damage_state == DAMAGE_MED && metal_repair == TRUE)
+ . += "The engine heater's plating is ready to be bolted down."
+ if(damage_state == DAMAGE_LOW)
+ . += "The engine heater's insulation layer could be pried back into place."
+ if(damage_state == DAMAGE_NONE && pressure_damage >= PRESSURE_DAMAGE_MAX / 2)
+ . += "The engine heater's screws seem loose."
+ if(damage_state == DAMAGE_NONE && pressure_damage < PRESSURE_DAMAGE_MAX / 2)
+ . += "The engine heater is in good condition."
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/proc/return_gas()
+ var/datum/gas_mixture/air_contents = airs[1]
+ return air_contents?.return_pressure()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/proc/return_gas_capacity()
+ var/datum/gas_mixture/air_contents = airs[1]
+ return air_contents?.return_volume()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/proc/update_gas_stats()
+ var/datum/gas_mixture/air_contents = airs[1]
+ if(!air_contents)
+ return
+ air_contents.set_volume(gas_capacity)
+ air_contents.set_temperature(T20C)
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/proc/has_fuel(required, datum/gas/gas_type)
+ var/datum/gas_mixture/air_contents = airs[1]
+ if(!air_contents)
+ return
+ return air_contents.get_moles(gas_type) >= required
+
+/**
+ * consumes a portion of the mols and checks how much could combust to make thrust.
+ * oxidation_power is the total value of all the oxidizers
+ * fuel_power is ^ but for fuel
+ */
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/proc/consume_fuel(gas_consumed)
+ var/datum/gas_mixture/air_contents = airs[1]
+ if(!air_contents)
+ return
+
+ else
+ var/oxidation_power = 0
+ var/fuel_power = 0
+ var/thrust_power = 0
+ var/gas_amount = 0
+
+ for(var/id in air_contents.get_gases())
+ gas_amount = air_contents.get_moles(id) * gas_consumed //this takes a percent (set by gas_consumed) and multiplies it by the total gas to get the amount of gas used by the calculation.
+
+ switch(id)
+ // adds each oxidizer's power to the total oxidation max
+ if(GAS_O2)
+ oxidation_power += O2_OXIDATION_VALUE * gas_amount
+ if(GAS_NITRYL)
+ oxidation_power += NITRYL_OXIDATION_VALUE * gas_amount
+ if(GAS_NITROUS) //burning nitrous cools down the heater's main tank, just like it cools the intake on real cars.
+ oxidation_power += NITROUS_OXIDATION_VALUE * gas_amount
+ var/heat_capacity = gas_amount * NITROUS_COOLING_MULTIPIER
+ var/air_heat_capacity = air_contents.heat_capacity()
+ var/combined_heat_capacity = heat_capacity + air_heat_capacity
+ if(combined_heat_capacity > 0)
+ var/combined_energy = heat_capacity * NITROUS_COOLING_MIN + air_heat_capacity * air_contents.return_temperature()
+ air_contents.set_temperature(combined_energy / combined_heat_capacity)
+ // adds each fuel gas's power to the fuel max (air.get_fuel_amount is busted, and trit should be Better anyways.)
+ if(GAS_PLASMA)
+ fuel_power += PLASMA_THRUSTER_VALUE * gas_amount
+ if(GAS_TRITIUM)
+ fuel_power += TRITRIUM_THRUSTER_VALUE * gas_amount
+ if(GAS_HYDROGEN)
+ fuel_power += HYDROGEN_THRUSTER_VALUE * gas_amount
+
+ air_contents.adjust_moles(id, -gas_amount)
+ thrust_power = min(oxidation_power, fuel_power) * efficiency_multiplier //"simulates" how much possible thrust either oxidizer or fuel could make, and takes the min
+ return thrust_power
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/attackby(obj/item/I, mob/living/user, params)
+ update_adjacent_engines()
+ if(damage_state == DAMAGE_MED && istype(I, /obj/item/stack/sheet/metal) && metal_repair == FALSE) //fix med damage with metal
+ var/obj/item/stack/sheet/metal/S = I
+ if(S.get_amount() < 2)
+ to_chat(user, "You need at least 2 metal sheets to repair [src].")
+ return
+ to_chat(user, "You start adding new plating.")
+ if(do_after(user, 40, src, TRUE))
+ if(!I.use(2))
+ return
+ to_chat(user, "You add new plating.")
+ I.use(1, FALSE, TRUE)
+ metal_repair = TRUE
+ pressure_damage = 0 //lets be nice and not let them explode while fixing this
+ playsound(loc, 'sound/items/deconstruct.ogg', 50)
+ return
+ return
+
+ if(damage_state == DAMAGE_MED && I.tool_behaviour == TOOL_WRENCH && metal_repair == TRUE)
+ to_chat(user, "You start wrenching down the new plating.")
+ if(I.use_tool(src, user, 60, volume=75))
+ metal_repair = FALSE
+ damage_state = DAMAGE_LOW
+ pressure_damage = 0
+ to_chat(user, "You secure the new plating.")
+ return
+ return
+
+ if(damage_state == DAMAGE_LOW && I.tool_behaviour == TOOL_CROWBAR) //fix low damage with screwdriver
+ to_chat(user, "You start prying in the insulation layer.")
+ if(I.use_tool(src, user, 60, volume=75))
+ damage_state = DAMAGE_NONE
+ pressure_damage = 0
+ to_chat(user, "You secure the insulation layer.")
+ return
+ return
+
+ if(damage_state == DAMAGE_NONE && I.tool_behaviour == TOOL_SCREWDRIVER && pressure_damage >= PRESSURE_DAMAGE_MAX / 2) //lets you fix pressure damage before it increases damage state
+ to_chat(user, "You start tightening loose screws.")
+ if(I.use_tool(src, user, 60, volume=75))
+ pressure_damage = 0
+ to_chat(user, "You tighten the screws.")
+ return
+ return
+
+ if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_closed, I))
+ return
+ if(default_pry_open(I))
+ return
+ if(panel_open)
+ if(default_change_direction_wrench(user, I))
+ return
+ if(default_deconstruction_crowbar(I))
+ return
+ return ..()
+
+/obj/machinery/atmospherics/components/unary/shuttle/fire_heater/proc/update_adjacent_engines()
+ var/engine_turf = get_step(src, dir)
+ if(!isturf(engine_turf))
+ return
+ for(var/obj/machinery/power/shuttle/engine/E in engine_turf)
+ E.update_icon_state()
+
+/obj/item/paper/guides/jobs/engi/combustion_thruster
+ name = "paper- 'Combustion Thruster Safety Instructions'"
+ default_raw_text = {"
Combustion Thruster Basics
+
Firstly, combustion thrusters are delicate machines due to their unique function, and therefore come with certain limits to said function.
+ The specific limit to remember is 1000 kPa, above which your warranty will expire and the combustion heater will begin to take damage, with catastrophic failure inevitable after long periods of high pressure.
+ The second thing to keep in mind is the fuel mix you are using. If you put in the wrong ratio, the thruster will waste the excess and you'll get less thrust.
+ The most notable mixes are a 2:1 ratio of hydrogen to oxygen and a 1:1 ratio of plasma to oxygen.
+ Additionally, nitrous oxide has been known to provide beneficial properties on top of being a potent oxidizer.
+
+
It's making scary noises and leaking!
+
Set your internals, pull a fire alarm, grab a fire suit, and continue with the following steps. Ensure you disable all sources of ignition!
+
Place two metal sheets over the leak in the heater.
+
Wrench the new sheets of metal into place to stop the leak.
+
Pry the insulation layer into place with a crowbar to stop the heat transfer.
+
For minor damages, tighten loosened screws.
"}
diff --git a/code/modules/power/turbine.dm b/code/game/machinery/shuttle/turbine.dm
similarity index 54%
rename from code/modules/power/turbine.dm
rename to code/game/machinery/shuttle/turbine.dm
index ba390b1cf873..7d310d37cd30 100644
--- a/code/modules/power/turbine.dm
+++ b/code/game/machinery/shuttle/turbine.dm
@@ -25,48 +25,60 @@
/obj/machinery/power/compressor
name = "compressor"
desc = "The compressor stage of a gas turbine generator."
- icon = 'icons/obj/atmospherics/pipes/simple.dmi'
+ icon = 'icons/obj/atmospherics/components/turbine.dmi'
icon_state = "compressor"
density = TRUE
resistance_flags = FIRE_PROOF
CanAtmosPass = ATMOS_PASS_DENSITY
+ use_power = NO_POWER_USE // powered by gas flow
+ interacts_with_air = TRUE
circuit = /obj/item/circuitboard/machine/power_compressor
- var/obj/machinery/power/turbine/turbine
+ var/obj/machinery/power/shuttle/engine/turbine/turbine
var/datum/gas_mixture/gas_contained
- var/turf/inturf
var/starter = 0
var/rpm = 0
var/rpmtarget = 0
var/capacity = 1e6
var/comp_id = 0
- var/efficiency
+ var/efficiency = 1
+ var/intake_ratio = 0.1 // might add a way to adjust this in-game later
-/obj/machinery/power/turbine/lavaland
+/obj/machinery/power/shuttle/engine/turbine/lavaland
destroy_output = TRUE
/obj/machinery/power/compressor/Destroy()
+ SSair.stop_processing_machine(src)
if (turbine && turbine.compressor == src)
turbine.compressor = null
+ if(isopenturf(loc))
+ loc.assume_air(gas_contained)
+ loc.air_update_turf()
turbine = null
return ..()
-/obj/machinery/power/turbine
+/obj/machinery/power/shuttle/engine/turbine
name = "gas turbine generator"
desc = "A gas turbine used for backup power generation."
- icon = 'icons/obj/atmospherics/pipes/simple.dmi'
+ icon = 'icons/obj/atmospherics/components/turbine.dmi'
icon_state = "turbine"
density = TRUE
resistance_flags = FIRE_PROOF
CanAtmosPass = ATMOS_PASS_DENSITY
+ use_power = NO_POWER_USE // powered by gas flow
+ interacts_with_air = TRUE
circuit = /obj/item/circuitboard/machine/power_turbine
+ thrust = 0 // no thrust by default
+ icon_state_closed = "turbine"
+ icon_state_open = "turbine"
+ icon_state_off = "turbine"
var/opened = 0
var/obj/machinery/power/compressor/compressor
- var/turf/outturf
- var/lastgen
+ var/lastgen = 0
var/productivity = 1
var/destroy_output = FALSE //Destroy the output gas instead of actually outputting it. Used on lavaland to prevent cooking the zlevel
-/obj/machinery/power/turbine/Destroy()
+/obj/machinery/power/shuttle/engine/turbine/Destroy()
+ SSair.stop_processing_machine(src)
if (compressor && compressor.turbine == src)
compressor.turbine = null
compressor = null
@@ -74,29 +86,39 @@
// the inlet stage of the gas turbine electricity generator
-/obj/machinery/power/compressor/Initialize()
+/obj/machinery/power/compressor/Initialize(mapload)
. = ..()
// The inlet of the compressor is the direction it faces
gas_contained = new
- inturf = get_step(src, dir)
+ SSair.start_processing_machine(src, mapload)
locate_machinery()
if(!turbine)
obj_break()
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/machinery/power/compressor/LateInitialize()
+ . = ..()
+ var/turf/comp_turf = get_turf(src)
+ comp_turf.ImmediateCalculateAdjacentTurfs() // turbine blocks atmos so update the turf it's on or stuff breaks
#define COMPFRICTION 5e5
/obj/machinery/power/compressor/locate_machinery()
if(turbine)
return
- turbine = locate() in get_step(src, get_dir(inturf, src))
+ turbine = locate() in get_step(src, turn(dir, 180))
if(turbine)
+ set_machine_stat(machine_stat & ~BROKEN)
turbine.locate_machinery()
+ else
+ turbine = null
+ obj_break()
/obj/machinery/power/compressor/RefreshParts()
var/E = 0
for(var/obj/item/stock_parts/manipulator/M in component_parts)
E += M.rating
- efficiency = E / 6
+ efficiency = max(E / 6, 1)
/obj/machinery/power/compressor/examine(mob/user)
. = ..()
@@ -108,49 +130,63 @@
return
if(default_change_direction_wrench(user, I))
- turbine = null
- inturf = get_step(src, dir)
- locate_machinery()
if(turbine)
to_chat(user, "Turbine connected.")
set_machine_stat(machine_stat & ~BROKEN)
else
to_chat(user, "Turbine not connected.")
- obj_break()
return
default_deconstruction_crowbar(I)
-/obj/machinery/power/compressor/process()
- if(!starter)
- return
- if(!turbine || (turbine.machine_stat & BROKEN))
- starter = FALSE
- if(machine_stat & BROKEN || panel_open)
- starter = FALSE
- return
- cut_overlays()
-
- rpm = 0.9* rpm + 0.1 * rpmtarget
+/obj/machinery/power/compressor/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I)
+ . = ..()
+ if(panel_open)
+ set_machine_stat(machine_stat | MAINT)
+ else
+ set_machine_stat(machine_stat & ~MAINT)
- // It's a simplified version taking only 1/10 of the moles from the turf nearby. It should be later changed into a better version
- // above todo 7 years and counting
+//update when moved or changing direction
+/obj/machinery/power/compressor/setDir(newdir)
+ . = ..()
+ locate_machinery()
- inturf.transfer_air_ratio(gas_contained, 0.1)
+/obj/machinery/power/compressor/Move(atom/newloc, direct, glide_size_override)
+ . = ..()
+ locate_machinery()
-// RPM function to include compression friction - be advised that too low/high of a compfriction value can make things screwy
+/obj/machinery/power/compressor/process(delta_time)
+ return
+/obj/machinery/power/compressor/process_atmos(delta_time)
+ // RPM function to include compression friction - be advised that too low/high of a compfriction value can make things screwy
+ rpm -= 1
+ rpm = (0.9 * rpm) + (0.1 * rpmtarget)
rpm = min(rpm, (COMPFRICTION*efficiency)/2)
- rpm = max(0, rpm - (rpm*rpm)/(COMPFRICTION*efficiency))
+ rpm = max(0, rpm - (rpm**2)/(COMPFRICTION*efficiency))
- if(starter && !(machine_stat & NOPOWER))
- use_power(2800)
- if(rpm<1000)
- rpmtarget = 1000
- else
- if(rpm<1000)
- rpmtarget = 0
+ update_overlays()
+
+ if(!turbine || (turbine.machine_stat & BROKEN))
+ locate_machinery() // try to find the other part if we somehow got disconnected
+
+ if((machine_stat & (BROKEN|MAINT)) || !starter) // if we didn't find it...
+ rpmtarget = 0
+ return
+
+ var/turf/inturf = get_step(src, dir)
+ var/datum/gas_mixture/environment = inturf.return_air()
+ var/external_pressure = environment.return_pressure()
+ var/pressure_delta = external_pressure - gas_contained.return_pressure()
+
+ // Equalize the gas between the environment and the internal gas mix
+ if(pressure_delta > 0)
+ var/datum/gas_mixture/removed = environment.remove_ratio((1 - ((1 - intake_ratio)**delta_time)) * pressure_delta / (external_pressure * 2)) // silly math to keep it consistent with delta_time
+ gas_contained.merge(removed)
+ inturf.air_update_turf()
+/obj/machinery/power/compressor/update_overlays()
+ . = ..()
if(rpm>50000)
add_overlay(mutable_appearance(icon, "comp-o4", FLY_LAYER))
else if(rpm>10000)
@@ -159,91 +195,122 @@
add_overlay(mutable_appearance(icon, "comp-o2", FLY_LAYER))
else if(rpm>500)
add_overlay(mutable_appearance(icon, "comp-o1", FLY_LAYER))
- //TODO: DEFERRED
// These are crucial to working of a turbine - the stats modify the power output. TurbGenQ modifies how much raw energy can you get from
// rpms, TurbGenG modifies the shape of the curve - the lower the value the less straight the curve is.
#define TURBGENQ 100000
#define TURBGENG 0.5
+#define POWER_TO_THRUST 0.001 // power production to thrust ratio
-/obj/machinery/power/turbine/Initialize()
+/obj/machinery/power/shuttle/engine/turbine/Initialize(mapload)
. = ..()
-// The outlet is pointed at the direction of the turbine component
- outturf = get_step(src, dir)
+ SSair.start_processing_machine(src, mapload)
locate_machinery()
if(!compressor)
obj_break()
connect_to_network()
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/machinery/power/shuttle/engine/turbine/LateInitialize()
+ . = ..()
+ var/turf/comp_turf = get_turf(src)
+ comp_turf.ImmediateCalculateAdjacentTurfs() // turbine blocks atmos so update the turf it's on or stuff breaks
-/obj/machinery/power/turbine/RefreshParts()
+/obj/machinery/power/shuttle/engine/turbine/RefreshParts()
var/P = 0
for(var/obj/item/stock_parts/capacitor/C in component_parts)
P += C.rating
productivity = P / 6
-/obj/machinery/power/turbine/examine(mob/user)
+/obj/machinery/power/shuttle/engine/turbine/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "The status display reads: Productivity at [productivity*100]%."
-/obj/machinery/power/turbine/locate_machinery()
+/obj/machinery/power/shuttle/engine/turbine/locate_machinery()
if(compressor)
return
- compressor = locate() in get_step(src, get_dir(outturf, src))
+ compressor = locate() in get_step(src, turn(dir, 180))
if(compressor)
+ set_machine_stat(machine_stat & ~BROKEN)
compressor.locate_machinery()
+ else
+ compressor = null
+ obj_break()
-/obj/machinery/power/turbine/process()
+/obj/machinery/power/shuttle/engine/turbine/process(delta_time)
+ add_avail(lastgen) // add power in process() so it doesn't update power output separately from the rest of the powernet (bad)
+ update_overlays()
+/obj/machinery/power/shuttle/engine/turbine/process_atmos(delta_time)
if(!compressor)
set_machine_stat(BROKEN)
+ locate_machinery() // try to find the missing piece
- if((machine_stat & BROKEN) || panel_open)
+ if(machine_stat & (BROKEN|MAINT)) // we're only running half a turbine, don't continue
return
- if(!compressor.starter)
- return
- cut_overlays()
// This is the power generation function. If anything is needed it's good to plot it in EXCEL before modifying
// the TURBGENQ and TURBGENG values
lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) * TURBGENQ * productivity
+ thrust = lastgen * POWER_TO_THRUST // second law
- add_avail(lastgen)
-
- // Weird function but it works. Should be something else...
-
- var/newrpm = ((compressor.gas_contained.return_temperature()) * compressor.gas_contained.total_moles())/4
+ var/turf/outturf = get_step(src, dir)
+ if(!LAZYLEN(outturf.atmos_adjacent_turfs))
+ compressor.rpmtarget = 0
+ return
- newrpm = max(0, newrpm)
+ // Move gas from the compressor to the outlet
+ var/datum/gas_mixture/environment = outturf.return_air()
+ var/internal_pressure = compressor.gas_contained.return_pressure()
+ var/pressure_delta = internal_pressure - environment.return_pressure()
- if(!compressor.starter || newrpm > 1000)
- compressor.rpmtarget = newrpm
+ // Now set the compressor's RPM target based on how much gas is flowing through
+ compressor.rpmtarget = max(0, pressure_delta * compressor.gas_contained.return_volume() / (R_IDEAL_GAS_EQUATION * 4))
- if(compressor.gas_contained.total_moles()>0)
- var/oamount = min(compressor.gas_contained.total_moles(), (compressor.rpm+100)/35000*compressor.capacity)
+ // Equalize the gas between the internal gas mix and the environment
+ if(pressure_delta > 0)
+ var/datum/gas_mixture/removed = compressor.gas_contained.remove_ratio(pressure_delta / (internal_pressure * 2))
if(destroy_output)
- compressor.gas_contained.set_moles(compressor.gas_contained.get_moles() - oamount)
- else
- outturf.assume_air_moles(compressor.gas_contained, oamount)
+ qdel(removed)
+ return
+ outturf.assume_air(removed)
+ outturf.air_update_turf()
+
+// Return the current thrust amount
+/obj/machinery/power/shuttle/engine/turbine/burn_engine(percentage, deltatime)
+ return thrust * deltatime * (percentage / 100)
+
+// Return the current power output
+/obj/machinery/power/shuttle/engine/turbine/return_fuel()
+ return lastgen
+
+// Return the maximum power output
+/obj/machinery/power/shuttle/engine/turbine/return_fuel_cap()
+ return ((COMPFRICTION*(compressor ? compressor.efficiency : 1) / (TURBGENQ*4))**TURBGENG) * TURBGENQ * productivity
+
+// Return the maximum power output
+/obj/machinery/power/shuttle/engine/turbine/update_engine()
+ if(!(flags_1 & INITIALIZED_1))
+ return FALSE
+ thruster_active = !panel_open && compressor
+ return thruster_active
// If it works, put an overlay that it works!
-
+/obj/machinery/power/shuttle/engine/turbine/update_overlays()
+ . = ..()
if(lastgen > 100)
add_overlay(mutable_appearance(icon, "turb-o", FLY_LAYER))
-/obj/machinery/power/turbine/attackby(obj/item/I, mob/user, params)
+/obj/machinery/power/shuttle/engine/turbine/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, initial(icon_state), initial(icon_state), I))
return
if(default_change_direction_wrench(user, I))
- compressor = null
- outturf = get_step(src, dir)
- locate_machinery()
if(compressor)
to_chat(user, "Compressor connected.")
- set_machine_stat(machine_stat & ~BROKEN)
else
to_chat(user, "Compressor not connected.")
obj_break()
@@ -251,25 +318,42 @@
default_deconstruction_crowbar(I)
-/obj/machinery/power/turbine/ui_interact(mob/user, datum/tgui/ui)
+/obj/machinery/power/shuttle/engine/turbine/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I)
+ . = ..()
+ if(panel_open)
+ set_machine_stat(machine_stat | MAINT)
+ else
+ set_machine_stat(machine_stat & ~MAINT)
+
+// update if it moves or changes direction
+/obj/machinery/power/shuttle/engine/turbine/setDir(newdir)
+ . = ..()
+ locate_machinery()
+
+/obj/machinery/power/shuttle/engine/turbine/Move(atom/newloc, direct, glide_size_override)
+ . = ..()
+ locate_machinery()
+
+/obj/machinery/power/shuttle/engine/turbine/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TurbineComputer", name)
ui.open()
-/obj/machinery/power/turbine/ui_data(mob/user)
+/obj/machinery/power/shuttle/engine/turbine/ui_data(mob/user)
var/list/data = list()
data["compressor"] = compressor ? TRUE : FALSE
- data["compressor_broke"] = (!compressor || (compressor.machine_stat & BROKEN)) ? TRUE : FALSE
+ data["compressor_broke"] = (!compressor || (compressor.machine_stat & (BROKEN|MAINT))) ? TRUE : FALSE
data["turbine"] = compressor?.turbine ? TRUE : FALSE
- data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.machine_stat & BROKEN)) ? TRUE : FALSE
+ data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.machine_stat & (BROKEN|MAINT))) ? TRUE : FALSE
data["online"] = compressor?.starter
data["power"] = DisplayPower(compressor?.turbine?.lastgen)
data["rpm"] = compressor?.rpm
data["temp"] = compressor?.gas_contained.return_temperature()
+ data["pressure"] = compressor?.gas_contained.return_pressure()
return data
-/obj/machinery/power/turbine/ui_act(action, params)
+/obj/machinery/power/shuttle/engine/turbine/ui_act(action, params)
. = ..()
if(.)
return
@@ -306,7 +390,7 @@
/obj/machinery/computer/turbine_computer/locate_machinery()
if(id)
- for(var/obj/machinery/power/compressor/C in GLOB.machines)
+ for(var/obj/machinery/power/compressor/C in SSair.atmos_air_machinery)
if(C.comp_id == id)
compressor = C
return
@@ -322,13 +406,14 @@
/obj/machinery/computer/turbine_computer/ui_data(mob/user)
var/list/data = list()
data["compressor"] = compressor ? TRUE : FALSE
- data["compressor_broke"] = (!compressor || (compressor.machine_stat & BROKEN)) ? TRUE : FALSE
+ data["compressor_broke"] = (!compressor || (compressor.machine_stat & (BROKEN|MAINT))) ? TRUE : FALSE
data["turbine"] = compressor?.turbine ? TRUE : FALSE
- data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.machine_stat & BROKEN)) ? TRUE : FALSE
+ data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.machine_stat & (BROKEN|MAINT))) ? TRUE : FALSE
data["online"] = compressor?.starter
data["power"] = DisplayPower(compressor?.turbine?.lastgen)
data["rpm"] = compressor?.rpm
data["temp"] = compressor?.gas_contained.return_temperature()
+ data["pressure"] = compressor?.gas_contained.return_pressure()
return data
/obj/machinery/computer/turbine_computer/ui_act(action, params)
@@ -345,6 +430,7 @@
locate_machinery()
. = TRUE
+#undef POWER_TO_THRUST
#undef COMPFRICTION
#undef TURBGENQ
#undef TURBGENG
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/sleeper.dm
similarity index 98%
rename from code/game/machinery/Sleeper.dm
rename to code/game/machinery/sleeper.dm
index f0a1c403cfa4..3d4d05336c3c 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/sleeper.dm
@@ -11,6 +11,8 @@
icon_state = "sleeper"
base_icon_state = "sleeper"
density = FALSE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
state_open = TRUE
circuit = /obj/item/circuitboard/machine/sleeper
clicksound = 'sound/machines/pda_button1.ogg'
@@ -100,7 +102,7 @@
playsound(src, 'sound/machines/synth_yes.ogg', 50, TRUE, frequency = rand(5120, 8800))
target.apply_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT)
target.ExtinguishMob()
- use_power = ACTIVE_POWER_USE
+ set_active_power()
/obj/machinery/sleeper/proc/thaw_them(mob/living/target)
if(IS_IN_STASIS(target))
@@ -109,7 +111,8 @@
/obj/machinery/sleeper/process()
if(!occupant || !isliving(occupant))
- use_power = IDLE_POWER_USE
+ if(use_static_power != IDLE_POWER_USE)
+ set_idle_power()
return
var/mob/living/L_occupant = occupant
if(stasis_running())
diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm
index 0ae88638d5b3..2038612c2791 100644
--- a/code/game/machinery/slotmachine.dm
+++ b/code/game/machinery/slotmachine.dm
@@ -22,7 +22,7 @@
base_icon_state = "slots"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/computer/slot_machine
light_color = LIGHT_COLOR_BROWN
unique_icon = TRUE
diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm
index 37e079715dcd..2582c57da903 100644
--- a/code/game/machinery/stasis.dm
+++ b/code/game/machinery/stasis.dm
@@ -9,8 +9,8 @@
can_buckle = TRUE
buckle_lying = 90
circuit = /obj/item/circuitboard/machine/stasis
- idle_power_usage = 40
- active_power_usage = 340
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_HIGH
var/stasis_enabled = TRUE
var/last_stasis_sound = FALSE
var/stasis_can_toggle = 0
@@ -112,12 +112,12 @@
playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 2, frequency = freq)
target.apply_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT)
target.ExtinguishMob()
- use_power = ACTIVE_POWER_USE
+ set_active_power()
/obj/machinery/stasis/proc/thaw_them(mob/living/target)
target.remove_status_effect(STATUS_EFFECT_STASIS, STASIS_MACHINE_EFFECT)
if(target == occupant)
- use_power = IDLE_POWER_USE
+ set_idle_power()
/obj/machinery/stasis/post_buckle_mob(mob/living/L)
if(!can_be_occupant(L))
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 1e402ee02e5a..9e1b5b28690b 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -22,7 +22,7 @@
icon_state = "frame"
density = FALSE
use_power = IDLE_POWER_USE
- idle_power_usage = 10
+ idle_power_usage = IDLE_DRAW_MINIMAL
maptext_height = 26
maptext_width = 32
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index e86d4ae9f0f9..107c5656c034 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -1,3 +1,5 @@
+#define BASE_UV_CYCLES 7
+
// SUIT STORAGE UNIT /////////////////
/obj/machinery/suit_storage_unit
name = "suit storage unit"
@@ -6,7 +8,10 @@
icon_state = "ssu_classic"
base_icon_state = "ssu_classic"
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_MINIMAL
max_integrity = 250
+ circuit = /obj/item/circuitboard/machine/suit_storage_unit
var/obj/item/clothing/suit/space/suit = null
var/obj/item/clothing/head/helmet/space/helmet = null
@@ -40,7 +45,9 @@
*/
var/uv_super = FALSE
/// How many cycles remain for the decontamination sequence.
- var/uv_cycles = 6
+ var/uv_cycles = 7
+ /// Time reduction from stock parts
+ var/lasers_bonus = 0
/// Cooldown for occupant breakout messages via relaymove()
var/message_cooldown
/// How long it takes to break out of the SSU.
@@ -191,6 +198,19 @@
storage = new storage_type(src)
update_appearance()
+/obj/machinery/suit_storage_unit/examine(mob/user)
+ . = ..()
+ . += span_notice("Number of UV cycles reduced by [lasers_bonus].")
+ if(locked)
+ . += span_notice("The locking bolts on \the [src] are engaged, preventing it from being pried open.")
+
+/obj/machinery/suit_storage_unit/RefreshParts()
+ lasers_bonus = 0
+ for(var/obj/item/stock_parts/micro_laser/lasers in component_parts)
+ lasers_bonus += ((lasers.rating) * 0.25)
+
+ uv_cycles = BASE_UV_CYCLES - lasers_bonus
+
/obj/machinery/suit_storage_unit/Destroy()
QDEL_NULL(suit)
QDEL_NULL(helmet)
@@ -250,7 +270,15 @@
if(!(flags_1 & NODECONSTRUCT_1))
open_machine()
dump_contents()
- new /obj/item/stack/sheet/metal (loc, 2)
+ on_deconstruction()
+ if(circuit)
+ circuit.forceMove(loc)
+ circuit = null
+ if(length(component_parts))
+ spawn_frame(disassembled)
+ for(var/obj/item/I in component_parts)
+ I.forceMove(loc)
+ component_parts.Cut()
qdel(src)
/obj/machinery/suit_storage_unit/interact(mob/living/user)
@@ -318,7 +346,7 @@
else
if (occupant)
var/mob/living/mob_occupant = occupant
- to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!")
+ to_chat(mob_occupant, span_userdanger("[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!"))
cook()
if ("lock", "unlock")
if (!state_open)
@@ -364,27 +392,27 @@
return
var/mob/living/target = A
if(!state_open)
- to_chat(user, "The unit's doors are shut!")
+ to_chat(user, span_warning("The unit's doors are shut!"))
return
if(!is_operational)
- to_chat(user, "The unit is not operational!")
+ to_chat(user, span_warning("The unit is not operational!"))
return
if(occupant || helmet || suit || storage)
- to_chat(user, "It's too cluttered inside to fit in!")
+ to_chat(user, span_warning("It's too cluttered inside to fit in!"))
return
if(target == user)
- user.visible_message("[user] starts squeezing into [src]!", "You start working your way into [src]...")
+ user.visible_message(span_warning("[user] starts squeezing into [src]!"), span_notice("You start working your way into [src]..."))
else
- target.visible_message("[user] starts shoving [target] into [src]!", "[user] starts shoving you into [src]!")
+ target.visible_message(span_warning("[user] starts shoving [target] into [src]!"), span_userdanger("[user] starts shoving you into [src]!"))
- if(do_mob(user, target, 30))
+ if(do_after(user, 30, target))
if(occupant || helmet || suit || storage)
return
if(target == user)
- user.visible_message("[user] slips into [src] and closes the door behind [user.p_them()]!", "You slip into [src]'s cramped space and shut its door.")
+ user.visible_message(span_warning("[user] slips into [src] and closes the door behind [user.p_them()]!"), span_notice("You slip into [src]'s cramped space and shut its door."))
else
- target.visible_message("[user] pushes [target] into [src] and shuts its door!", "[user] shoves you into [src] and shuts the door!")
+ target.visible_message(span_warning("[user] pushes [target] into [src] and shuts its door!"), span_userdanger("[user] shoves you into [src] and shuts the door!"))
close_machine(target)
add_fingerprint(user)
@@ -398,11 +426,12 @@
*/
/obj/machinery/suit_storage_unit/proc/cook()
var/mob/living/mob_occupant = occupant
- if(uv_cycles)
+ if(uv_cycles > 0)
uv_cycles--
uv = TRUE
locked = TRUE
update_appearance()
+ use_power(ACTIVE_DRAW_HIGH)
if(occupant)
if(uv_super)
mob_occupant.adjustFireLoss(rand(20, 36))
@@ -411,11 +440,11 @@
mob_occupant.emote("scream")
addtimer(CALLBACK(src, PROC_REF(cook)), 50)
else
- uv_cycles = initial(uv_cycles)
+ uv_cycles = (BASE_UV_CYCLES - lasers_bonus)
uv = FALSE
locked = FALSE
if(uv_super)
- visible_message("[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.")
+ visible_message(span_warning("[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber."))
playsound(src, 'sound/machines/creaking.ogg', 50, TRUE)
helmet = null
qdel(helmet)
@@ -429,10 +458,16 @@
wires.cut_all()
else
if(!occupant)
- visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green.")
+ visible_message(span_notice("[src]'s door slides open. The glowing yellow lights dim to a gentle green."))
else
- visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.")
+ visible_message(span_warning("[src]'s door slides open, barraging you with the nauseating smell of charred flesh."))
mob_occupant.radiation = 0
+ if(iscarbon(mob_occupant))
+ var/mob/living/carbon/bacon = mob_occupant
+ for(var/obj/item/bodypart/grilling as anything in bacon.get_bleeding_parts(TRUE))
+ if(!grilling.can_bandage())
+ continue
+ grilling.apply_bandage(0.005, 600, "cauterization")
playsound(src, 'sound/machines/airlocks/standard/close.ogg', 25, TRUE)
var/list/things_to_clear = list() //Done this way since using GetAllContents on the SSU itself would include circuitry and such.
if(suit)
@@ -469,7 +504,7 @@
if(locked)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
- to_chat(user, "[src]'s door won't budge!")
+ to_chat(user, span_warning("[src]'s door won't budge!"))
return
open_machine()
dump_contents()
@@ -481,21 +516,21 @@
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
- user.visible_message("You see [user] kicking against the doors of [src]!", \
- "You start kicking against the doors... (this will take about [DisplayTimeText(breakout_time)].)", \
- "You hear a thump from [src].")
+ user.visible_message(span_notice("You see [user] kicking against the doors of [src]!"), \
+ span_notice("You start kicking against the doors... (this will take about [DisplayTimeText(breakout_time)].)"), \
+ span_hear("You hear a thump from [src]."))
if(do_after(user,(breakout_time), target = src))
if(!user || user.stat != CONSCIOUS || user.loc != src)
return
- user.visible_message("[user] successfully broke out of [src]!", \
- "You successfully break out of [src]!")
+ user.visible_message(span_warning("[user] successfully broke out of [src]!"), \
+ span_notice("You successfully break out of [src]!"))
open_machine()
dump_contents()
add_fingerprint(user)
if(locked)
- visible_message("You see [user] kicking against the doors of [src]!", \
- "You start kicking against the doors...")
+ visible_message(span_notice("You see [user] kicking against the doors of [src]!"), \
+ span_notice("You start kicking against the doors..."))
addtimer(CALLBACK(src, PROC_REF(resist_open), user), 300)
else
open_machine()
@@ -503,42 +538,42 @@
/obj/machinery/suit_storage_unit/proc/resist_open(mob/user)
if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here.
- visible_message("You see [user] burst out of [src]!", \
- "You escape the cramped confines of [src]!")
+ visible_message(span_notice("You see [user] burst out of [src]!"), \
+ span_notice("You escape the cramped confines of [src]!"))
open_machine()
/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params)
if(state_open && is_operational)
if(istype(I, /obj/item/clothing/suit))
if(suit)
- to_chat(user, "The unit already contains a suit!.")
+ to_chat(user, span_warning("The unit already contains a suit!."))
return
if(!user.transferItemToLoc(I, src))
return
suit = I
else if(istype(I, /obj/item/clothing/head))
if(helmet)
- to_chat(user, "The unit already contains a helmet!")
+ to_chat(user, span_warning("The unit already contains a helmet!"))
return
if(!user.transferItemToLoc(I, src))
return
helmet = I
else if(istype(I, /obj/item/clothing/mask))
if(mask)
- to_chat(user, "The unit already contains a mask!")
+ to_chat(user, span_warning("The unit already contains a mask!"))
return
if(!user.transferItemToLoc(I, src))
return
mask = I
else
if(storage)
- to_chat(user, "The auxiliary storage compartment is full!")
+ to_chat(user, span_warning("The auxiliary storage compartment is full!"))
return
if(!user.transferItemToLoc(I, src))
return
storage = I
- visible_message("[user] inserts [I] into [src]", "You load [I] into [src].")
+ visible_message(span_notice("[user] inserts [I] into [src]"), span_notice("You load [I] into [src]."))
update_appearance()
return
@@ -561,7 +596,7 @@
*/
/obj/machinery/suit_storage_unit/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I)
if(!(flags_1 & NODECONSTRUCT_1) && I.tool_behaviour == TOOL_SCREWDRIVER && uv)
- to_chat(user, "It might not be wise to fiddle with [src] while it's running...")
+ to_chat(user, span_warning("It might not be wise to fiddle with [src] while it's running..."))
return TRUE
return ..()
@@ -570,8 +605,12 @@
. = !(state_open || panel_open || is_operational || locked || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR
if(.)
I.play_tool_sound(src, 50)
- visible_message("[usr] pries open \the [src].", "You pry open \the [src].")
+ visible_message(span_notice("[usr] pries open \the [src]."), span_notice("You pry open \the [src]."))
open_machine()
+ // todo, make it not deconstruct while locked
+ if(!locked)
+ if(default_deconstruction_crowbar(I))
+ return TRUE
// Mapping helper unit takes whatever lies on top of it
/obj/machinery/suit_storage_unit/inherit/Initialize(mapload)
@@ -596,3 +635,6 @@
AM.forceMove(src)
storage = AM
update_appearance()
+
+
+#undef BASE_UV_CYCLES
diff --git a/code/game/machinery/telecomms/machines/broadcaster.dm b/code/game/machinery/telecomms/machines/broadcaster.dm
index f9cbc692e050..2a12e6bcf937 100644
--- a/code/game/machinery/telecomms/machines/broadcaster.dm
+++ b/code/game/machinery/telecomms/machines/broadcaster.dm
@@ -14,7 +14,7 @@ GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages
desc = "A dish-shaped machine used to broadcast processed subspace signals."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 25
+ idle_power_usage = IDLE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/telecomms/broadcaster
/obj/machinery/telecomms/broadcaster/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
diff --git a/code/game/machinery/telecomms/machines/bus.dm b/code/game/machinery/telecomms/machines/bus.dm
index 2496ee41c874..6428456d1614 100644
--- a/code/game/machinery/telecomms/machines/bus.dm
+++ b/code/game/machinery/telecomms/machines/bus.dm
@@ -14,7 +14,7 @@
desc = "A mighty piece of hardware used to send massive amounts of data quickly."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
netspeed = 40
circuit = /obj/item/circuitboard/machine/telecomms/bus
var/change_frequency = 0
diff --git a/code/game/machinery/telecomms/machines/hub.dm b/code/game/machinery/telecomms/machines/hub.dm
index dedf7c7f3a77..a01225b4f4fd 100644
--- a/code/game/machinery/telecomms/machines/hub.dm
+++ b/code/game/machinery/telecomms/machines/hub.dm
@@ -14,7 +14,7 @@
desc = "A mighty piece of hardware used to send/receive massive amounts of data."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 80
+ idle_power_usage = IDLE_DRAW_MINIMAL
long_range_link = TRUE
netspeed = 40
circuit = /obj/item/circuitboard/machine/telecomms/hub
diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm
index d11067c290fd..d9f927a7c355 100644
--- a/code/game/machinery/telecomms/machines/message_server.dm
+++ b/code/game/machinery/telecomms/machines/message_server.dm
@@ -12,8 +12,8 @@
name = "Blackbox Recorder"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 10
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70)
var/obj/item/stored
@@ -80,8 +80,8 @@
desc = "A machine that processes and routes PDA and request console messages."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 10
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/telecomms/message_server
var/list/datum/data_pda_msg/pda_msgs = list()
diff --git a/code/game/machinery/telecomms/machines/processor.dm b/code/game/machinery/telecomms/machines/processor.dm
index 86bc02438d95..6c13ee65d510 100644
--- a/code/game/machinery/telecomms/machines/processor.dm
+++ b/code/game/machinery/telecomms/machines/processor.dm
@@ -12,7 +12,7 @@
desc = "This machine is used to process large quantities of information."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 30
+ idle_power_usage = IDLE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/telecomms/processor
var/process_mode = 1 // 1 = Uncompress Signals, 0 = Compress Signals
diff --git a/code/game/machinery/telecomms/machines/receiver.dm b/code/game/machinery/telecomms/machines/receiver.dm
index 79b989648d55..33b0bc7028ec 100644
--- a/code/game/machinery/telecomms/machines/receiver.dm
+++ b/code/game/machinery/telecomms/machines/receiver.dm
@@ -12,7 +12,7 @@
desc = "This machine has a dish-like shape and green lights. It is designed to detect and process subspace radio activity."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 30
+ idle_power_usage = IDLE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/telecomms/receiver
/obj/machinery/telecomms/receiver/receive_signal(datum/signal/subspace/signal)
diff --git a/code/game/machinery/telecomms/machines/relay.dm b/code/game/machinery/telecomms/machines/relay.dm
index ffaeda72e26d..763c42dbbf9c 100644
--- a/code/game/machinery/telecomms/machines/relay.dm
+++ b/code/game/machinery/telecomms/machines/relay.dm
@@ -12,7 +12,7 @@
desc = "A mighty piece of hardware used to send massive amounts of data far away."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 30
+ idle_power_usage = IDLE_DRAW_MINIMAL
netspeed = 5
long_range_link = 1
circuit = /obj/item/circuitboard/machine/telecomms/relay
diff --git a/code/game/machinery/telecomms/machines/server.dm b/code/game/machinery/telecomms/machines/server.dm
index 664d45b5b1c1..5607b6bbec8c 100644
--- a/code/game/machinery/telecomms/machines/server.dm
+++ b/code/game/machinery/telecomms/machines/server.dm
@@ -11,7 +11,7 @@
desc = "A machine used to store data and network statistics."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 15
+ idle_power_usage = IDLE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/telecomms/server
var/list/log_entries = list()
var/totaltraffic = 0 // gigabytes (if > 1024, divide by 1024 -> terrabytes)
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index 6e0551b25d41..1a342f0554cd 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -9,8 +9,8 @@
icon_state = "tele0"
base_icon_state = "tele"
use_power = IDLE_POWER_USE
- idle_power_usage = 10
- active_power_usage = 2000
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_HIGH
circuit = /obj/item/circuitboard/machine/teleporter_hub
var/accuracy = 0
var/obj/machinery/teleport/station/power_station
@@ -106,8 +106,8 @@
icon_state = "controller"
base_icon_state = "controller"
use_power = IDLE_POWER_USE
- idle_power_usage = 10
- active_power_usage = 2000
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_HIGH
circuit = /obj/item/circuitboard/machine/teleporter_station
var/engaged = FALSE
var/obj/machinery/computer/teleporter/teleporter_console
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index 6a36a0ee01d6..17e3fc0116b8 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -306,8 +306,8 @@
mechsyringe.forceMove(get_turf(chassis))
reagents.trans_to(mechsyringe, min(mechsyringe.volume, reagents.total_volume), transfered_by = chassis.occupant)
syringes -= mechsyringe
- mechsyringe.icon = 'icons/obj/chemical.dmi'
- mechsyringe.icon_state = "syringeproj"
+ mechsyringe.icon = 'icons/obj/chemical/misc.dmi'
+ mechsyringe.icon_state = "potgreen"
playsound(chassis, 'sound/items/syringeproj.ogg', 50, TRUE)
log_message("Launched [mechsyringe] from [src], targeting [target].", LOG_MECHA)
var/mob/originaloccupant = chassis.occupant
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 4a16a6f9b249..b0b40ea0877e 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -6,7 +6,7 @@
var/fire_sound
var/projectiles_per_shot = 1
var/variance = 0
- var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter
+ var/randomspread = FALSE //use random spread for machineguns, instead of shotgun scatter
var/projectile_delay = 0
var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the weapon is fired.
var/kickback = TRUE //Will using this weapon in no grav push mecha back.
@@ -137,8 +137,8 @@
desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles."
icon_state = "mecha_plasmacutter"
item_state = "plasmacutter"
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
energy_drain = 30
projectile = /obj/projectile/plasma/adv/mech
fire_sound = 'sound/weapons/plasma_cutter.ogg'
@@ -347,7 +347,7 @@
projectiles_cache_max = 1200
projectiles_per_shot = 3
variance = 6
- randomspread = 1
+ randomspread = TRUE
projectile_delay = 2
harmful = TRUE
ammo_type = "lmg"
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 6814f0cc2e7f..83a2c4861c90 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -5,8 +5,8 @@
desc = "Nothing is being built."
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 20
- active_power_usage = 5000
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_HIGH
req_access = list(ACCESS_ROBOTICS)
circuit = /obj/item/circuitboard/machine/mechfab
var/time_coeff = 1
@@ -196,10 +196,10 @@
rmat.silo_log(src, "built", -1, "[D.name]", res_coef)
add_overlay("fab-active")
- use_power = ACTIVE_POWER_USE
+ set_active_power()
updateUsrDialog()
sleep(get_construction_time_w_coeff(D))
- use_power = IDLE_POWER_USE
+ set_idle_power()
cut_overlay("fab-active")
desc = initial(desc)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index d2c712d32ea8..48cc0388b508 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -158,7 +158,7 @@
return cell
/obj/mecha/Destroy()
- if(occupant)
+ if(occupant && iscarbon(occupant))
occupant.SetSleeping(destruction_sleep_duration)
go_out()
var/mob/living/silicon/ai/AI
@@ -831,7 +831,7 @@
//An actual AI (simple_animal mecha pilot) entering the mech
-/obj/mecha/proc/aimob_enter_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob)
+/obj/mecha/proc/aimob_enter_mech(mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/pilot_mob)
if(pilot_mob && pilot_mob.Adjacent(src))
if(occupant)
return
@@ -841,7 +841,7 @@
pilot_mob.forceMove(src)
GrantActions(pilot_mob)//needed for checks, and incase a badmin puts somebody in the mob
-/obj/mecha/proc/aimob_exit_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob)
+/obj/mecha/proc/aimob_exit_mech(mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/pilot_mob)
if(occupant == pilot_mob)
occupant = null
if(pilot_mob.mecha == src)
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 42c32e04fa98..fbe90058fc3e 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -210,7 +210,7 @@
M.visible_message("[user] starts buckling [M] to [src]!",\
"[user] starts buckling you to [src]!",\
"You hear metal clanking.")
- if(!do_after(user, 2 SECONDS, TRUE, M))
+ if(!do_after(user, 2 SECONDS, M))
return FALSE
// Sanity check before we attempt to buckle. Is everything still in a kosher state for buckling after the 3 seconds have elapsed?
diff --git a/code/game/objects/effects/anomalies/_anomalies.dm b/code/game/objects/effects/anomalies/_anomalies.dm
index e62b1e52f7b3..4a85f9321154 100644
--- a/code/game/objects/effects/anomalies/_anomalies.dm
+++ b/code/game/objects/effects/anomalies/_anomalies.dm
@@ -133,7 +133,7 @@
/obj/effect/anomaly/attackby(obj/item/weapon, mob/user, params)
if(weapon.tool_behaviour == TOOL_ANALYZER && aSignal)
to_chat(user, span_notice("You start analyzing [src]."))
- if(do_after(user, 20, TRUE, src))
+ if(do_after(user, 20, src, hidden = TRUE))
to_chat(user, span_notice("[src]'s primary field is fluctuating along frequency [format_frequency(aSignal.frequency)], code [aSignal.code]."))
if(bSignal)
to_chat(user, span_notice("A second field is fluctuating along [format_frequency(bSignal.frequency)], code [bSignal.code]. It is highly unstable." ))
diff --git a/code/game/objects/effects/anomalies/anomalies_hallucination.dm b/code/game/objects/effects/anomalies/anomalies_hallucination.dm
index fc7e4e3c9859..ab859a3b3215 100644
--- a/code/game/objects/effects/anomalies/anomalies_hallucination.dm
+++ b/code/game/objects/effects/anomalies/anomalies_hallucination.dm
@@ -28,7 +28,7 @@
/obj/effect/anomaly/hallucination/proc/hallucination_pulse(turf/open/location, effectrange)
for(var/mob/living/carbon/human/user in view(location, effectrange))
// If they are immune to the anomaly
- if (iscarbon(user) && !user.research_scanner)
+ if (user.research_scanner)
continue
// Blind people don't get hallucinations.
diff --git a/code/game/objects/effects/anomalies/anomalies_static.dm b/code/game/objects/effects/anomalies/anomalies_static.dm
index 205a8778d394..ab574ee475dd 100644
--- a/code/game/objects/effects/anomalies/anomalies_static.dm
+++ b/code/game/objects/effects/anomalies/anomalies_static.dm
@@ -39,19 +39,19 @@
playsound(src, 'sound/effects/walkietalkie.ogg', 75)
if(stored_mob && looking.stat != DEAD && prob(25))
say_fucky_things()
- if (!HAS_TRAIT(looking, TRAIT_MINDSHIELD) && looking.stat != DEAD || !looking.research_scanner && looking.stat != DEAD || !HAS_TRAIT(looking, TRAIT_DEAF))
- looking.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 200)
- playsound(src, 'sound/effects/stall.ogg', 50)
- if(looking.getOrganLoss(ORGAN_SLOT_BRAIN) >= 150 && looking.stat != DEAD)
- if(prob(20))
- var/mob/living/carbon/victim = looking
- var/obj/effect/anomaly/tvstatic/planetary/expansion
- expansion = new(get_turf(victim))
- visible_message(" The static overtakes [victim], [expansion] taking their place!")
- victim.death()
- expansion.stored_mob = victim
- victim.forceMove(expansion)
- return
+ if(HAS_TRAIT(looking, TRAIT_MINDSHIELD) || looking.stat == DEAD || looking.research_scanner || HAS_TRAIT(looking, TRAIT_DEAF))
+ continue
+ looking.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 200)
+ playsound(src, 'sound/effects/stall.ogg', 50)
+ if(looking.getOrganLoss(ORGAN_SLOT_BRAIN) >= 150 && looking.stat != DEAD)
+ if(prob(20))
+ var/mob/living/carbon/victim = looking
+ var/obj/effect/anomaly/tvstatic/planetary/expansion
+ expansion = new(get_turf(victim))
+ visible_message(span_warning("The static overtakes [victim], [expansion] taking their place!"))
+ victim.death()
+ expansion.stored_mob = victim
+ victim.forceMove(expansion)
/obj/effect/anomaly/tvstatic/Bumped(atom/movable/AM)
@@ -89,13 +89,13 @@
/obj/effect/anomaly/tvstatic/detonate()
for(var/mob/living/carbon/human/looking in range(effectrange, src))
- visible_message(" The static lashes out, agony filling your mind as its tendrils scrape your thoughts!")
+ visible_message(span_boldwarning(" The static lashes out, agony filling your mind as its tendrils scrape your thoughts!"))
if (!HAS_TRAIT(looking, TRAIT_MINDSHIELD) && looking.stat != DEAD)
looking.adjustOrganLoss(ORGAN_SLOT_BRAIN, 100, 200)
playsound(src, 'sound/effects/stall.ogg', 100)
if(stored_mob)
mangle_corpse()
- visible_message("The static sputters out [stored_mob], their body coming out in a burst of blood and gore!")
+ visible_message(span_warning("The static sputters out [stored_mob], their body coming out in a burst of blood and gore!"))
new /obj/effect/gibspawner/human(loc)
stored_mob.forceMove(get_turf(src))
stored_mob = null
@@ -111,7 +111,7 @@
var/turf/T = get_turf(src)
if(T)
if(stored_mob)
- visible_message("The static spits out [stored_mob], their body coming out in a burst!")
+ visible_message(span_warning("The static spits out [stored_mob], their body coming out in a burst!"))
stored_mob.forceMove(get_turf(src))
stored_mob = null
. = ..()
@@ -122,8 +122,11 @@
immobile = TRUE
/obj/effect/anomaly/tvstatic/planetary/Initialize(mapload)
- if(prob(25))
- stored_mob = /obj/effect/mob_spawn/human/corpse/damaged
+ if(prob(25) & !stored_mob)
+ var/obj/effect/mob_spawn/human/corpse/damaged/legioninfested/vicspawner = new (src)
+ var/mob/living/carbon/victim = (vicspawner.spawned_mob_ref)?.resolve()
+ src.stored_mob = victim
+ victim.forceMove(src)
. = ..()
/obj/effect/particle_effect/staticball
diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm
index ccfd89363482..4177d8957965 100644
--- a/code/game/objects/effects/contraband.dm
+++ b/code/game/objects/effects/contraband.dm
@@ -875,10 +875,10 @@
desc = "Terra, or Earth as it's called by inhabitants, the third planet in the Sol system. Home to the only life as humans knew it, until contact with the outside universe. This poster in particular is trying to attract tourists to Terra, listing attractions like the Grand Orrery and Neue Waldstätte."
icon_state = "poster-solgov-terra"
-/obj/structure/sign/poster/solgov/ares
- name = "Ares"
- desc = "Ares, fourth planet in the Sol system. While evidence suggests that Aphrodite and Ares may have once had life, Terra was the only one that kept it. This poster in particular is trying to attract tourists to Ares, listing attractions like skiing resorts and ancient robot exhibits."
- icon_state = "poster-solgov-ares"
+/obj/structure/sign/poster/solgov/mars
+ name = "Mars"
+ desc = "Mars, fourth planet in the Sol system. While evidence suggests that Venus and Mars may have once had life, Terra was the only one that kept it. This poster in particular is trying to attract tourists to Mars, listing attractions like skiing resorts and ancient robot exhibits."
+ icon_state = "poster-solgov-mars"
/obj/structure/sign/poster/solgov/luna
name = "Luna"
@@ -892,7 +892,7 @@
/obj/structure/sign/poster/solgov/skiing
name = "Lo-Fly Skiing Advert"
- desc = "An advertisement for some low-gravity skiing resort on Ares. \"Popular with SUNS groups!\""
+ desc = "An advertisement for some low-gravity skiing resort on Mars. \"Popular with SUNS groups!\""
icon_state = "poster-solgov-loskiing"
/obj/structure/sign/poster/solgov/recyle
diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index c14086ff0f3b..7ff53391f6e0 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -4,7 +4,7 @@ GLOBAL_LIST(gang_tags)
name = "rune"
desc = "Graffiti. Damn kids."
icon = 'icons/effects/crayondecal.dmi'
- icon_state = "rune1"
+ icon_state = "firedanger"
gender = NEUTER
plane = GAME_PLANE //makes the graffiti visible over a wall.
mergeable_decal = FALSE
diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm
index 975f94102ecf..2dfea3173feb 100644
--- a/code/game/objects/effects/decals/decal.dm
+++ b/code/game/objects/effects/decals/decal.dm
@@ -39,7 +39,7 @@
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/obj/effect/turf_decal
- icon = 'icons/turf/decals.dmi'
+ icon = 'icons/turf/decals/decals.dmi'
icon_state = "warningfulltile"
plane = FLOOR_PLANE
layer = TURF_DECAL_LAYER
diff --git a/code/game/objects/effects/decals/turfdecal/flooring_decals.dm b/code/game/objects/effects/decals/turfdecal/flooring_decals.dm
index f56bebfc7ba0..fc23ed89c278 100644
--- a/code/game/objects/effects/decals/turfdecal/flooring_decals.dm
+++ b/code/game/objects/effects/decals/turfdecal/flooring_decals.dm
@@ -138,6 +138,8 @@ TURF_DECAL_COLOR_HELPER(opaque/grey, COLOR_FLOORTILE_GRAY, 255)
TURF_DECAL_COLOR_HELPER(opaque/lightgrey, "#a8b2b6", 255)
TURF_DECAL_COLOR_HELPER(opaque/bottlegreen, "#57967f", 255)
TURF_DECAL_COLOR_HELPER(opaque/ntblue, "#283674", 255)
+TURF_DECAL_COLOR_HELPER(opaque/nsorange, "#FF6600", 255)
+TURF_DECAL_COLOR_HELPER(opaque/vired, "#d40000", 255)
TURF_DECAL_COLOR_HELPER(opaque/solgovblue, "#2d2a4e", 255)
TURF_DECAL_COLOR_HELPER(opaque/solgovgold, "#eeac2e", 255)
TURF_DECAL_COLOR_HELPER(opaque/syndiered, "#730622", 255)
@@ -163,6 +165,8 @@ TURF_DECAL_COLOR_HELPER(transparent/grey, COLOR_FLOORTILE_GRAY, 140)
TURF_DECAL_COLOR_HELPER(transparent/lightgrey, "#a8b2b6", 140)
TURF_DECAL_COLOR_HELPER(transparent/bottlegreen, "#57967f", 140)
TURF_DECAL_COLOR_HELPER(transparent/ntblue, "#283674", 140)
+TURF_DECAL_COLOR_HELPER(transparent/nsorange, "#FF6600", 140)
+TURF_DECAL_COLOR_HELPER(opaque/vired, "#d40000", 140)
TURF_DECAL_COLOR_HELPER(transparent/solgovblue, "#2d2a4e", 140)
TURF_DECAL_COLOR_HELPER(transparent/solgovgold, "#eeac2e", 140)
TURF_DECAL_COLOR_HELPER(transparent/syndiered, "#730622", 140)
@@ -414,7 +418,6 @@ TURF_DECAL_COLOR_HELPER(transparent/inteqbrown, "#4b2a18", 140)
/obj/effect/turf_decal/plaque
name = "plaque"
icon_state = "plaque"
- icon = 'icons/turf/decals.dmi'
/obj/effect/turf_decal/chapel
name = "chapel"
@@ -797,6 +800,438 @@ TURF_DECAL_COLOR_HELPER(transparent/inteqbrown, "#4b2a18", 140)
/obj/effect/turf_decal/solgov/all/bottom_right
icon_state = "bottom-right-all"
+// suns
+
+/obj/effect/turf_decal/suns
+ icon = 'icons/turf/decals/suns_floor.dmi'
+ icon_state = "suns-columm1-bottom"
+
+/obj/effect/turf_decal/suns/capital_s
+ icon_state = "capital-s"
+
+/obj/effect/turf_decal/suns/capital_u
+ icon_state = "capital-u"
+
+/obj/effect/turf_decal/suns/capital_n
+ icon_state = "capital-n"
+
+/obj/effect/turf_decal/suns/capital_s/fancy
+ icon_state = "capitalfancy-s"
+
+/obj/effect/turf_decal/suns/capital_u/fancy
+ icon_state = "capitalfancy-u"
+
+/obj/effect/turf_decal/suns/capital_n/fancy
+ icon_state = "capitalfancy-n"
+
+/obj/effect/turf_decal/suns/capital_s/marble
+ icon_state = "capitalmarble-s"
+
+/obj/effect/turf_decal/suns/capital_u/marble
+ icon_state = "capitalmarble-u"
+
+/obj/effect/turf_decal/suns/capital_n/marble
+ icon_state = "capitalmarble-n"
+
+// borders
+
+/obj/effect/turf_decal/suns/line
+ icon_state = "suns-border"
+
+/obj/effect/turf_decal/suns/line/corner
+ icon_state = "suns-bordercorner"
+
+/obj/effect/turf_decal/suns/line/end
+ icon_state = "suns-borderend"
+
+/obj/effect/turf_decal/suns/line/fill
+ icon_state = "suns-fill"
+
+/obj/effect/turf_decal/suns/line/fill/corner
+ icon_state = "suns-fillcorner"
+
+/obj/effect/turf_decal/suns/line/fill/end
+ icon_state = "suns-fillend"
+
+/obj/effect/turf_decal/suns/line/fancy
+ icon_state = "sunsfancy-border"
+
+/obj/effect/turf_decal/suns/line/fancy/corner
+ icon_state = "sunsfancy-bordercorner"
+
+/obj/effect/turf_decal/suns/line/fancy/end
+ icon_state = "sunsfancy-borderend"
+
+/obj/effect/turf_decal/suns/line/fancy/fill
+ icon_state = "sunsfancy-fill"
+
+/obj/effect/turf_decal/suns/line/fancy/fill/corner
+ icon_state = "sunsfancy-fillcorner"
+
+/obj/effect/turf_decal/suns/line/fancy/fill/end
+ icon_state = "sunsfancy-fillend"
+
+/obj/effect/turf_decal/suns/line/marble
+ icon_state = "sunsmarble-border"
+
+/obj/effect/turf_decal/suns/line/marble/corner
+ icon_state = "sunsmarble-bordercorner"
+
+/obj/effect/turf_decal/suns/line/marble/end
+ icon_state = "sunsmarble-borderend"
+
+/obj/effect/turf_decal/suns/line/marble/fill
+ icon_state = "sunsmarble-fill"
+
+/obj/effect/turf_decal/suns/line/marble/fill/corner
+ icon_state = "sunsmarble-fillcorner"
+
+/obj/effect/turf_decal/suns/line/marble/fill/end
+ icon_state = "sunsmarble-fillend"
+
+// suns 3x6 decal
+
+/obj/effect/turf_decal/suns/columm1
+ icon_state = "suns-columm1-bottom"
+
+/obj/effect/turf_decal/suns/columm1/middle
+ icon_state = "suns-columm1-middle"
+
+/obj/effect/turf_decal/suns/columm1/top
+ icon_state = "suns-columm1-top"
+
+/obj/effect/turf_decal/suns/columm2
+ icon_state = "suns-columm2-bottom"
+
+/obj/effect/turf_decal/suns/columm2/middle
+ icon_state = "suns-columm2-middle"
+
+/obj/effect/turf_decal/suns/columm2/top
+ icon_state = "suns-columm2-top"
+
+/obj/effect/turf_decal/suns/columm3
+ icon_state = "suns-columm3-bottom"
+
+/obj/effect/turf_decal/suns/columm3/middle
+ icon_state = "suns-columm3-middle"
+
+/obj/effect/turf_decal/suns/columm3/top
+ icon_state = "suns-columm3-top"
+
+/obj/effect/turf_decal/suns/columm4
+ icon_state = "suns-columm4-middle"
+
+/obj/effect/turf_decal/suns/columm4/top
+ icon_state = "suns-columm4-top"
+
+/obj/effect/turf_decal/suns/columm5
+ icon_state = "suns-columm5-middle"
+
+/obj/effect/turf_decal/suns/columm5/top
+ icon_state = "suns-columm5-top"
+
+/obj/effect/turf_decal/suns/columm6
+ icon_state = "suns-columm6-middle"
+
+/obj/effect/turf_decal/suns/columm6/top
+ icon_state = "suns-columm6-top"
+
+/obj/effect/turf_decal/suns/marble/columm1
+ icon_state = "sunsmarble-columm1-bottom"
+
+/obj/effect/turf_decal/suns/marble/columm1/middle
+ icon_state = "sunsmarble-columm1-middle"
+
+/obj/effect/turf_decal/suns/marble/columm1/top
+ icon_state = "sunsmarble-columm1-top"
+
+/obj/effect/turf_decal/suns/marble/columm2
+ icon_state = "sunsmarble-columm2-bottom"
+
+/obj/effect/turf_decal/suns/marble/columm2/middle
+ icon_state = "sunsmarble-columm2-middle"
+
+/obj/effect/turf_decal/suns/marble/columm2/top
+ icon_state = "sunsmarble-columm2-top"
+
+/obj/effect/turf_decal/suns/marble/columm3
+ icon_state = "sunsmarble-columm3-bottom"
+
+/obj/effect/turf_decal/suns/marble/columm3/middle
+ icon_state = "sunsmarble-columm3-middle"
+
+/obj/effect/turf_decal/suns/marble/columm3/top
+ icon_state = "sunsmarble-columm3-top"
+
+/obj/effect/turf_decal/suns/marble/columm4
+ icon_state = "sunsmarble-columm4-middle"
+
+/obj/effect/turf_decal/suns/marble/columm4/top
+ icon_state = "sunsmarble-columm4-top"
+
+/obj/effect/turf_decal/suns/marble/columm5
+ icon_state = "sunsmarble-columm5-middle"
+
+/obj/effect/turf_decal/suns/marble/columm5/top
+ icon_state = "sunsmarble-columm5-top"
+
+/obj/effect/turf_decal/suns/marble/columm6
+ icon_state = "sunsmarble-columm6-middle"
+
+/obj/effect/turf_decal/suns/marble/columm6/top
+ icon_state = "sunsmarble-columm6-top"
+
+/obj/effect/turf_decal/suns/fancy/columm1
+ icon_state = "sunsfancy-columm1-bottom"
+
+/obj/effect/turf_decal/suns/fancy/columm1/middle
+ icon_state = "sunsfancy-columm1-middle"
+
+/obj/effect/turf_decal/suns/fancy/columm1/top
+ icon_state = "sunsfancy-columm1-top"
+
+/obj/effect/turf_decal/suns/fancy/columm2
+ icon_state = "sunsfancy-columm2-bottom"
+
+/obj/effect/turf_decal/suns/fancy/columm2/middle
+ icon_state = "sunsfancy-columm2-middle"
+
+/obj/effect/turf_decal/suns/fancy/columm2/top
+ icon_state = "sunsfancy-columm2-top"
+
+/obj/effect/turf_decal/suns/fancy/columm3
+ icon_state = "sunsfancy-columm3-bottom"
+
+/obj/effect/turf_decal/suns/fancy/columm3/middle
+ icon_state = "sunsfancy-columm3-middle"
+
+/obj/effect/turf_decal/suns/fancy/columm3/top
+ icon_state = "sunsfancy-columm3-top"
+
+/obj/effect/turf_decal/suns/fancy/columm4
+ icon_state = "sunsfancy-columm4-middle"
+
+/obj/effect/turf_decal/suns/fancy/columm4/top
+ icon_state = "sunsfancy-columm4-top"
+
+/obj/effect/turf_decal/suns/fancy/columm5
+ icon_state = "sunsfancy-columm5-middle"
+
+/obj/effect/turf_decal/suns/fancy/columm5/top
+ icon_state = "sunsfancy-columm5-top"
+
+/obj/effect/turf_decal/suns/fancy/columm6
+ icon_state = "sunsfancy-columm6-middle"
+
+/obj/effect/turf_decal/suns/fancy/columm6/top
+ icon_state = "sunsfancy-columm6-top"
+
+
+// suns alt decal
+
+/obj/effect/turf_decal/suns/alt
+ icon_state = "sunsalt-top-left"
+
+/obj/effect/turf_decal/suns/alt/top_left
+ icon_state = "sunsalt-top-left"
+
+/obj/effect/turf_decal/suns/alt/top_center
+ icon_state = "sunsalt-top-center"
+
+/obj/effect/turf_decal/suns/alt/top_right
+ icon_state = "sunsalt-top-right"
+
+/obj/effect/turf_decal/suns/alt/middle_left
+ icon_state = "sunsalt-middle-left"
+
+/obj/effect/turf_decal/suns/alt/middle_center
+ icon_state = "sunsalt-middle-center"
+
+/obj/effect/turf_decal/suns/alt/middle_right
+ icon_state = "sunsalt-middle-right"
+
+/obj/effect/turf_decal/suns/alt/bottom_left
+ icon_state = "sunsalt-bottom-left"
+
+/obj/effect/turf_decal/suns/alt/bottom_center
+ icon_state = "sunsalt-bottom-center"
+
+/obj/effect/turf_decal/suns/alt/bottom_right
+ icon_state = "sunsalt-bottom-right"
+
+/obj/effect/turf_decal/suns/alt/fancy
+ icon_state = "sunsaltfancy-top-left"
+
+/obj/effect/turf_decal/suns/alt/fancy/top_left
+ icon_state = "sunsaltfancy-top-left"
+
+/obj/effect/turf_decal/suns/alt/fancy/top_center
+ icon_state = "sunsaltfancy-top-center"
+
+/obj/effect/turf_decal/suns/alt/fancy/top_right
+ icon_state = "sunsaltfancy-top-right"
+
+/obj/effect/turf_decal/suns/alt/fancy/middle_left
+ icon_state = "sunsaltfancy-middle-left"
+
+/obj/effect/turf_decal/suns/alt/fancy/middle_center
+ icon_state = "sunsaltfancy-middle-center"
+
+/obj/effect/turf_decal/suns/alt/fancy/middle_right
+ icon_state = "sunsaltfancy-middle-right"
+
+/obj/effect/turf_decal/suns/alt/fancy/bottom_left
+ icon_state = "sunsaltfancy-bottom-left"
+
+/obj/effect/turf_decal/suns/alt/fancy/bottom_center
+ icon_state = "sunsaltfancy-bottom-center"
+
+/obj/effect/turf_decal/suns/alt/fancy/bottom_right
+ icon_state = "sunsaltfancy-bottom-right"
+
+/obj/effect/turf_decal/suns/alt/marble
+ icon_state = "sunsaltmarble-top-left"
+
+/obj/effect/turf_decal/suns/alt/marble/top_left
+ icon_state = "sunsaltmarble-top-left"
+
+/obj/effect/turf_decal/suns/alt/marble/top_center
+ icon_state = "sunsaltmarble-top-center"
+
+/obj/effect/turf_decal/suns/alt/marble/top_right
+ icon_state = "sunsaltmarble-top-right"
+
+/obj/effect/turf_decal/suns/alt/marble/middle_left
+ icon_state = "sunsaltmarble-middle-left"
+
+/obj/effect/turf_decal/suns/alt/marble/middle_center
+ icon_state = "sunsaltmarble-middle-center"
+
+/obj/effect/turf_decal/suns/alt/marble/middle_right
+ icon_state = "sunsaltmarble-middle-right"
+
+/obj/effect/turf_decal/suns/alt/marble/bottom_left
+ icon_state = "sunsaltmarble-bottom-left"
+
+/obj/effect/turf_decal/suns/alt/marble/bottom_center
+ icon_state = "sunsaltmarble-bottom-center"
+
+/obj/effect/turf_decal/suns/alt/marble/bottom_right
+ icon_state = "sunsaltmarble-bottom-right"
+
+/obj/effect/turf_decal/suns/alt/transparent
+ icon_state = "sunsalttrans-top-left"
+
+/obj/effect/turf_decal/suns/alt/transparent/top_left
+ icon_state = "sunsalttrans-top-left"
+
+/obj/effect/turf_decal/suns/alt/transparent/top_center
+ icon_state = "sunsalttrans-top-center"
+
+/obj/effect/turf_decal/suns/alt/transparent/top_right
+ icon_state = "sunsalttrans-top-right"
+
+/obj/effect/turf_decal/suns/alt/transparent/middle_left
+ icon_state = "sunsalttrans-middle-left"
+
+/obj/effect/turf_decal/suns/alt/transparent/middle_center
+ icon_state = "sunsalttrans-middle-center"
+
+/obj/effect/turf_decal/suns/alt/transparent/middle_right
+ icon_state = "sunsalttrans-middle-right"
+
+/obj/effect/turf_decal/suns/alt/transparent/bottom_left
+ icon_state = "sunsalttrans-bottom-left"
+
+/obj/effect/turf_decal/suns/alt/transparent/bottom_center
+ icon_state = "sunsalttrans-bottom-center"
+
+/obj/effect/turf_decal/suns/alt/transparent/bottom_right
+ icon_state = "sunsalttrans-bottom-right"
+
+// suns 3x6 decal transparent
+
+/obj/effect/turf_decal/suns/transparent/columm1
+ icon_state = "sunstrans-columm1-bottom"
+
+/obj/effect/turf_decal/suns/transparent/columm1/middle
+ icon_state = "sunstrans-columm1-middle"
+
+/obj/effect/turf_decal/suns/transparent/columm1/top
+ icon_state = "sunstrans-columm1-top"
+
+/obj/effect/turf_decal/suns/transparent/columm2
+ icon_state = "sunstrans-columm2-bottom"
+
+/obj/effect/turf_decal/suns/transparent/columm2/middle
+ icon_state = "sunstrans-columm2-middle"
+
+/obj/effect/turf_decal/suns/transparent/columm2/top
+ icon_state = "sunstrans-columm2-top"
+
+/obj/effect/turf_decal/suns/transparent/columm3
+ icon_state = "sunstrans-columm3-bottom"
+
+/obj/effect/turf_decal/suns/transparent/columm3/middle
+ icon_state = "sunstrans-columm3-middle"
+
+/obj/effect/turf_decal/suns/transparent/columm3/top
+ icon_state = "sunstrans-columm3-top"
+
+/obj/effect/turf_decal/suns/transparent/columm4
+ icon_state = "sunstrans-columm4-middle"
+
+/obj/effect/turf_decal/suns/transparent/columm4/top
+ icon_state = "sunstrans-columm4-top"
+
+/obj/effect/turf_decal/suns/transparent/columm5
+ icon_state = "sunstrans-columm5-middle"
+
+/obj/effect/turf_decal/suns/transparent/columm5/top
+ icon_state = "sunstrans-columm5-top"
+
+/obj/effect/turf_decal/suns/transparent/columm6
+ icon_state = "sunstrans-columm6-middle"
+
+/obj/effect/turf_decal/suns/transparent/columm6/top
+ icon_state = "sunstrans-columm6-top"
+
+// nanotrasen
+
+/obj/effect/turf_decal/nanotrasen //placeholder for sorting these together, add 3x3 NT and Vigilitas logos later
+ icon = 'icons/obj/nanotrasen_floor.dmi'
+ icon_state = "NS-2x2" //also placeholder
+
+/obj/effect/turf_decal/nanotrasen/ns
+ icon_state = "NS-2x2"
+
+/obj/effect/turf_decal/nanotrasen/ns/top_left
+ icon_state = "NS-top-left"
+
+/obj/effect/turf_decal/nanotrasen/ns/top
+ icon_state = "NS-top-center"
+
+/obj/effect/turf_decal/nanotrasen/ns/top_right
+ icon_state = "NS-top-right"
+
+/obj/effect/turf_decal/nanotrasen/ns/center_left
+ icon_state = "NS-center-left"
+
+/obj/effect/turf_decal/nanotrasen/ns/center
+ icon_state = "NS-center"
+
+/obj/effect/turf_decal/nanotrasen/ns/center_right
+ icon_state = "NS-center-right"
+
+/obj/effect/turf_decal/nanotrasen/ns/bottom_left
+ icon_state = "NS-bottom-left"
+
+/obj/effect/turf_decal/nanotrasen/ns/bottom
+ icon_state = "NS-bottom-center"
+
+/obj/effect/turf_decal/nanotrasen/ns/bottom_right
+ icon_state = "NS-bottom-right"
+
/obj/effect/turf_decal/road
name = "road decal"
icon_state = "road"
diff --git a/code/game/objects/effects/decals/turfdecal/markings.dm b/code/game/objects/effects/decals/turfdecal/markings.dm
index e0a0746f5a2d..860f8f0bd2b2 100644
--- a/code/game/objects/effects/decals/turfdecal/markings.dm
+++ b/code/game/objects/effects/decals/turfdecal/markings.dm
@@ -229,32 +229,28 @@
/obj/effect/turf_decal/syndicateemblem/top/right
icon_state = "s3,3"
+/obj/effect/turf_decal/atmos
+ icon = 'icons/turf/decals/decals.dmi'
+
/obj/effect/turf_decal/atmos/oxygen
- icon = 'icons/turf/decals.dmi'
icon_state = "oxygen"
/obj/effect/turf_decal/atmos/carbon_dioxide
- icon = 'icons/turf/decals.dmi'
icon_state = "carbon_dioxide"
/obj/effect/turf_decal/atmos/nitrogen
- icon = 'icons/turf/decals.dmi'
icon_state = "nitrogen"
/obj/effect/turf_decal/atmos/air
- icon = 'icons/turf/decals.dmi'
icon_state = "air"
/obj/effect/turf_decal/atmos/nitrous_oxide
- icon = 'icons/turf/decals.dmi'
icon_state = "nitrous_oxide"
/obj/effect/turf_decal/atmos/plasma
- icon = 'icons/turf/decals.dmi'
icon_state = "plasma"
/obj/effect/turf_decal/atmos/mix
- icon = 'icons/turf/decals.dmi'
icon_state = "mix"
/**
@@ -339,169 +335,129 @@
// centered number decals
+
/obj/effect/turf_decal/number/one
- icon = 'icons/turf/decals.dmi'
icon_state = "1"
/obj/effect/turf_decal/number/two
- icon = 'icons/turf/decals.dmi'
icon_state = "2"
/obj/effect/turf_decal/number/three
- icon = 'icons/turf/decals.dmi'
icon_state = "3"
/obj/effect/turf_decal/number/four
- icon = 'icons/turf/decals.dmi'
icon_state = "4"
/obj/effect/turf_decal/number/five
- icon = 'icons/turf/decals.dmi'
icon_state = "5"
/obj/effect/turf_decal/number/six
- icon = 'icons/turf/decals.dmi'
icon_state = "6"
/obj/effect/turf_decal/number/seven
- icon = 'icons/turf/decals.dmi'
icon_state = "7"
/obj/effect/turf_decal/number/eight
- icon = 'icons/turf/decals.dmi'
icon_state = "8"
/obj/effect/turf_decal/number/nine
- icon = 'icons/turf/decals.dmi'
icon_state = "9"
/obj/effect/turf_decal/number/zero
- icon = 'icons/turf/decals.dmi'
icon_state = "0"
// right-shifted number decals (1s digit)
/obj/effect/turf_decal/number/right_one
- icon = 'icons/turf/decals.dmi'
icon_state = "-1"
/obj/effect/turf_decal/number/right_two
- icon = 'icons/turf/decals.dmi'
icon_state = "-2"
/obj/effect/turf_decal/number/right_three
- icon = 'icons/turf/decals.dmi'
icon_state = "-3"
/obj/effect/turf_decal/number/right_four
- icon = 'icons/turf/decals.dmi'
icon_state = "-4"
/obj/effect/turf_decal/number/right_five
- icon = 'icons/turf/decals.dmi'
icon_state = "-5"
/obj/effect/turf_decal/number/right_six
- icon = 'icons/turf/decals.dmi'
icon_state = "-6"
/obj/effect/turf_decal/number/right_seven
- icon = 'icons/turf/decals.dmi'
icon_state = "-7"
/obj/effect/turf_decal/number/right_eight
- icon = 'icons/turf/decals.dmi'
icon_state = "-8"
/obj/effect/turf_decal/number/right_nine
- icon = 'icons/turf/decals.dmi'
icon_state = "-9"
/obj/effect/turf_decal/number/right_zero
- icon = 'icons/turf/decals.dmi'
icon_state = "-0"
// left-shifted number decals (10s digit)
/obj/effect/turf_decal/number/left_one
- icon = 'icons/turf/decals.dmi'
icon_state = "1-"
/obj/effect/turf_decal/number/left_two
- icon = 'icons/turf/decals.dmi'
icon_state = "2-"
/obj/effect/turf_decal/number/left_three
- icon = 'icons/turf/decals.dmi'
icon_state = "3-"
/obj/effect/turf_decal/number/left_four
- icon = 'icons/turf/decals.dmi'
icon_state = "4-"
/obj/effect/turf_decal/number/left_five
- icon = 'icons/turf/decals.dmi'
icon_state = "5-"
/obj/effect/turf_decal/number/left_six
- icon = 'icons/turf/decals.dmi'
icon_state = "6-"
/obj/effect/turf_decal/number/left_seven
- icon = 'icons/turf/decals.dmi'
icon_state = "7-"
/obj/effect/turf_decal/number/left_eight
- icon = 'icons/turf/decals.dmi'
icon_state = "8-"
/obj/effect/turf_decal/number/left_nine
- icon = 'icons/turf/decals.dmi'
icon_state = "9-"
/obj/effect/turf_decal/number/left_zero
- icon = 'icons/turf/decals.dmi'
icon_state = "0-"
/obj/effect/turf_decal/dept/hop
- icon = 'icons/turf/decals.dmi'
icon_state = "hop"
/obj/effect/turf_decal/dept/bar
- icon = 'icons/turf/decals.dmi'
icon_state = "bar"
/obj/effect/turf_decal/dept/cargo
- icon = 'icons/turf/decals.dmi'
icon_state = "cargo"
/obj/effect/turf_decal/dept/medical
- icon = 'icons/turf/decals.dmi'
icon_state = "med"
/obj/effect/turf_decal/dept/science
- icon = 'icons/turf/decals.dmi'
icon_state = "sci"
/obj/effect/turf_decal/dept/security
- icon = 'icons/turf/decals.dmi'
icon_state = "sec"
/obj/effect/turf_decal/dept/mining
- icon = 'icons/turf/decals.dmi'
icon_state = "mine"
/obj/effect/turf_decal/zoo
- icon = 'icons/turf/decals.dmi'
icon_state = "zoo"
/obj/effect/turf_decal/no
- icon = 'icons/turf/decals.dmi'
icon_state = "no"
/obj/effect/turf_decal/radiation
- icon = 'icons/turf/decals.dmi'
icon_state = "radiation"
/obj/effect/turf_decal/radiation/white
- icon = 'icons/turf/decals.dmi'
icon_state = "radiation-w"
diff --git a/code/game/objects/effects/decals/turfdecal/weather.dm b/code/game/objects/effects/decals/turfdecal/weather.dm
index 04dcf807314a..0c8284b53f8c 100644
--- a/code/game/objects/effects/decals/turfdecal/weather.dm
+++ b/code/game/objects/effects/decals/turfdecal/weather.dm
@@ -13,12 +13,10 @@
/obj/effect/turf_decal/weather/dirt
name = "dirt siding"
- icon = 'icons/turf/decals.dmi'
icon_state = "dirt_side"
/obj/effect/turf_decal/weather/dirt/corner
name = "corner"
- icon = 'icons/turf/decals.dmi'
icon_state = "dirt_side_corner"
/obj/effect/turf_decal/weather/sand
@@ -36,30 +34,24 @@
/obj/effect/turf_decal/weather/asteroid
name = "asteroid siding"
- icon = 'icons/turf/decals.dmi'
icon_state = "asteroid_side"
/obj/effect/turf_decal/weather/asteroid/corner
name = "corner"
- icon = 'icons/turf/decals.dmi'
icon_state = "asteroid_side_corner"
/obj/effect/turf_decal/weather/whitesands
name = "salted sand siding"
- icon = 'icons/turf/decals.dmi'
icon_state = "ws_side"
/obj/effect/turf_decal/weather/whitesands/corner
name = "corner"
- icon = 'icons/turf/decals.dmi'
icon_state = "ws_side_corner"
/obj/effect/turf_decal/weather/rock
name = "rock siding"
- icon = 'icons/turf/decals.dmi'
icon_state = "rock_side"
/obj/effect/turf_decal/weather/rock/corner
name = "corner"
- icon = 'icons/turf/decals.dmi'
icon_state = "rock_side_corner"
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index b08d7bf6737c..078c435bd213 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -45,7 +45,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark)
. = ..()
GLOB.start_landmarks_list += src
if(jobspawn_override)
- LAZYADDASSOC(GLOB.jobspawn_overrides, name, src)
+ LAZYADDASSOCLIST(GLOB.jobspawn_overrides, name, src)
if(name != "start")
tag = "start*[name]"
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
deleted file mode 100644
index 0ca73652857c..000000000000
--- a/code/game/objects/effects/mines.dm
+++ /dev/null
@@ -1,217 +0,0 @@
-
-/obj/effect/mine
- name = "dummy mine"
- desc = "Better stay away from that thing."
- density = FALSE
- anchored = TRUE
- icon = 'icons/obj/items_and_weapons.dmi'
- icon_state = "uglymine"
- var/triggered = 0
-
-/obj/effect/mine/Initialize()
- . = ..()
- var/static/list/loc_connections = list(
- COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
- )
- AddElement(/datum/element/connect_loc, loc_connections)
-
-/obj/effect/mine/proc/mineEffect(mob/victim)
- to_chat(victim, "*click*")
-
-/obj/effect/mine/proc/on_entered(datum/source, atom/movable/AM)
- SIGNAL_HANDLER
- if(isturf(loc))
- if(ismob(AM))
- var/mob/MM = AM
- if(!(MM.movement_type & FLYING))
- INVOKE_ASYNC(src, PROC_REF(triggermine), AM)
- else
- INVOKE_ASYNC(src, PROC_REF(triggermine), AM)
-
-/obj/effect/mine/proc/triggermine(mob/victim)
- if(triggered)
- return
- visible_message("[victim] sets off [icon2html(src, viewers(src))] [src]!")
- var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
- s.set_up(3, 1, src)
- s.start()
- mineEffect(victim)
- SEND_SIGNAL(src, COMSIG_MINE_TRIGGERED)
- triggered = 1
- qdel(src)
-
-
-/obj/effect/mine/explosive
- name = "explosive mine"
- var/range_devastation = 0
- var/range_heavy = 1
- var/range_light = 2
- var/range_flash = 3
-
-/obj/effect/mine/explosive/mineEffect(mob/victim)
- explosion(loc, range_devastation, range_heavy, range_light, range_flash)
-
-/obj/effect/mine/stun
- name = "stun mine"
- var/stun_time = 80
-
-/obj/effect/mine/shrapnel
- name = "shrapnel mine"
- var/shrapnel_type = /obj/projectile/bullet/shrapnel
- var/shrapnel_magnitude = 3
-
-/obj/effect/mine/shrapnel/mineEffect(mob/victim)
- AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_magnitude)
-
-/obj/effect/mine/shrapnel/human_only
- name = "sophisticated shrapnel mine"
- desc = "A deadly mine, this one seems to be modified to trigger for humans only?"
-
-/obj/effect/mine/shrapnel/human_only/on_entered(datum/source, atom/movable/AM)
- if(!ishuman(AM))
- return
- . = ..()
-
-/obj/effect/mine/shrapnel/sting
- name = "stinger mine"
- shrapnel_type = /obj/projectile/bullet/pellet/stingball
-
-/obj/effect/mine/stun/mineEffect(mob/living/victim)
- if(isliving(victim))
- victim.Paralyze(stun_time)
-
-/obj/effect/mine/kickmine
- name = "kick mine"
-
-/obj/effect/mine/kickmine/mineEffect(mob/victim)
- if(isliving(victim) && victim.client)
- to_chat(victim, "You have been kicked FOR NO REISIN!")
- qdel(victim.client)
-
-
-/obj/effect/mine/gas
- name = "oxygen mine"
- var/gas_amount = 360
- var/gas_type = "o2"
-
-/obj/effect/mine/gas/mineEffect(mob/victim)
- atmos_spawn_air("[gas_type]=[gas_amount]")
-
-
-/obj/effect/mine/gas/plasma
- name = "plasma mine"
- gas_type = "plasma"
-
-
-/obj/effect/mine/gas/n2o
- name = "\improper N2O mine"
- gas_type = "n2o"
-
-
-/obj/effect/mine/gas/water_vapor
- name = "chilled vapor mine"
- gas_amount = 500
- gas_type = "water_vapor"
-
-/obj/effect/mine/sound
- name = "honkblaster 1000"
- var/sound = 'sound/items/bikehorn.ogg'
-
-/obj/effect/mine/sound/mineEffect(mob/victim)
- playsound(loc, sound, 100, TRUE)
-
-
-/obj/effect/mine/sound/bwoink
- name = "bwoink mine"
- sound = 'sound/effects/adminhelp.ogg'
-
-/obj/effect/mine/pickup
- name = "He"
- desc = "He."
- icon = 'icons/obj/marg.dmi'
- icon_state = "marg"
- density = FALSE
- var/duration = 0
- pixel_x = -8
- pixel_y = 1
-
-/obj/effect/mine/pickup/Initialize()
- . = ..()
- animate(src, time = 20, loop = -1)
-
-/obj/effect/mine/pickup/triggermine(mob/victim)
- if(triggered)
- return
- triggered = 1
- invisibility = INVISIBILITY_ABSTRACT
- mineEffect(victim)
- qdel(src)
-
-
-/obj/effect/mine/pickup/bloodbath
- name = "His Odium"
- desc = "Embrace my righteous fury."
- duration = 1200 //2min
- color = "#FF0000"
- var/mob/living/doomslayer
- var/obj/item/chainsaw/doomslayer/chainsaw
-
-/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim)
- if(!victim.client || !istype(victim))
- return
- to_chat(victim, "RIP AND TEAR")
-
- INVOKE_ASYNC(src, PROC_REF(blood_delusion), victim)
-
- chainsaw = new(victim.loc)
- victim.log_message("entered a marg frenzy", LOG_ATTACK)
-
- ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
- victim.drop_all_held_items()
- victim.put_in_hands(chainsaw, forced = TRUE)
- chainsaw.attack_self(victim)
- victim.reagents.add_reagent(/datum/reagent/medicine/adminordrazine,25)
- to_chat(victim, "KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!")
-
- var/datum/client_colour/colour = victim.add_client_colour(/datum/client_colour/bloodlust)
- QDEL_IN(colour, 11)
- doomslayer = victim
- RegisterSignal(src, COMSIG_PARENT_QDELETING, PROC_REF(end_blood_frenzy))
- QDEL_IN(WEAKREF(src), duration)
-
-/obj/effect/mine/pickup/bloodbath/proc/end_blood_frenzy()
- if(doomslayer)
- to_chat(doomslayer, "Your bloodlust seeps back into the bog of your subconscious and you regain self control.")
- doomslayer.log_message("exited a blood frenzy", LOG_ATTACK)
- if(chainsaw)
- qdel(chainsaw)
-
-/obj/effect/mine/pickup/bloodbath/proc/blood_delusion(mob/living/carbon/victim)
- new /datum/hallucination/delusion(victim, TRUE, "demon", duration, 0)
-
-/obj/effect/mine/pickup/healing
- name = "His Benevolence"
- desc = "Come, come. Your wounds shall be undone by my mercy."
-
-
-/obj/effect/mine/pickup/healing/mineEffect(mob/living/carbon/victim)
- if(!victim.client || !istype(victim))
- return
- to_chat(victim, "You feel great!")
- victim.revive(full_heal = TRUE, admin_revive = TRUE)
-
-/obj/effect/mine/pickup/speed
- name = "His Purpose"
- desc = "Come, let me quicken you to brilliance."
- duration = 300
-
-/obj/effect/mine/pickup/speed/mineEffect(mob/living/carbon/victim)
- if(!victim.client || !istype(victim))
- return
- to_chat(victim, "You feel fast!")
- victim.add_movespeed_modifier(/datum/movespeed_modifier/yellow_orb)
- addtimer(CALLBACK(src, PROC_REF(finish_effect), victim), duration)
-
-/obj/effect/mine/pickup/speed/proc/finish_effect(mob/living/carbon/victim)
- victim.remove_movespeed_modifier(/datum/movespeed_modifier/yellow_orb)
- to_chat(victim, "You slow down.")
diff --git a/code/game/objects/effects/spawners/bundle.dm b/code/game/objects/effects/spawners/bundle.dm
index 19e7b1c957fa..edab392613f3 100644
--- a/code/game/objects/effects/spawners/bundle.dm
+++ b/code/game/objects/effects/spawners/bundle.dm
@@ -141,18 +141,6 @@
/obj/item/clothing/head/wizard/fake,
/obj/item/staff)
-/obj/effect/spawner/bundle/costume/sexyclown
- name = "sexy clown costume spawner"
- items = list(
- /obj/item/clothing/mask/gas/sexyclown,
- /obj/item/clothing/under/rank/civilian/clown/sexy)
-
-/obj/effect/spawner/bundle/costume/sexymime
- name = "sexy mime costume spawner"
- items = list(
- /obj/item/clothing/mask/gas/sexymime,
- /obj/item/clothing/under/rank/civilian/mime/sexy)
-
/obj/effect/spawner/bundle/costume/mafia
name = "black mafia outfit spawner"
items = list(
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index 3370c8b4543d..db99d0c4e4d8 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -50,14 +50,14 @@
lootdoubles = FALSE
loot = list(
- /obj/item/gun/ballistic/automatic/pistol = 8,
+ /obj/item/gun/ballistic/automatic/pistol/syndicate = 8,
/obj/item/gun/ballistic/shotgun/automatic/combat = 5,
/obj/item/gun/ballistic/automatic/pistol/deagle,
/obj/item/gun/ballistic/revolver/mateba
)
/obj/effect/spawner/lootdrop/armory_contraband/metastation
- loot = list(/obj/item/gun/ballistic/automatic/pistol = 5,
+ loot = list(/obj/item/gun/ballistic/automatic/pistol/syndicate = 5,
/obj/item/gun/ballistic/shotgun/automatic/combat = 5,
/obj/item/gun/ballistic/automatic/pistol/deagle,
/obj/item/storage/box/syndie_kit/throwing_weapons = 3,
@@ -87,7 +87,7 @@
/obj/item/assembly/flash/handheld = 1,
/obj/item/restraints/handcuffs/cable/zipties = 1,
/obj/item/restraints/handcuffs = 1,
- /obj/item/radio/off = 1,
+ /obj/item/radio = 1,
/obj/item/lighter = 3,
/obj/item/storage/box/matches = 3,
/obj/item/reagent_containers/syringe/contraband/space_drugs = 1,
@@ -115,7 +115,6 @@
/obj/effect/spawner/lootdrop/gambling
name = "gambling valuables spawner"
loot = list(
- /obj/item/gun/ballistic/revolver/russian = 5,
/obj/item/clothing/head/trapper = 3,
/obj/item/storage/box/syndie_kit/throwing_weapons,
/obj/item/coin/gold,
@@ -468,12 +467,18 @@
/obj/structure/salvageable/destructive_analyzer
)
+/obj/effect/spawner/lootdrop/ripley
+ name = "25% mech 75% wreckage ripley spawner"
+ loot = list(/obj/mecha/working/ripley/mining = 1,
+ /obj/structure/mecha_wreckage/ripley = 5)
+ lootdoubles = FALSE
+
/obj/effect/spawner/lootdrop/salvage_50
name = "50% salvage spawner"
loot = list(
/obj/effect/spawner/lootdrop/maintenance = 13,
/obj/effect/spawner/lootdrop/salvage_machine = 12,
- /obj/effect/spawner/lootdrop/whiteship_cere_ripley = 12,
+ /obj/effect/spawner/lootdrop/ripley = 12,
/obj/structure/closet/crate/secure/loot = 13,
"" = 50
)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index df7c5ae431c5..033307e5472f 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -22,7 +22,14 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
///Icon file for right inhand overlays
var/righthand_file = 'icons/mob/inhands/items_righthand.dmi'
- var/supports_variations = null //This is a bitfield that defines what variations exist for bodyparts like Digi legs.
+ ///This is a bitfield that defines what variations exist for bodyparts like Digi legs.
+ var/supports_variations = null
+
+ ///If set, kepori wearing this use this instead of their clothing file
+ var/kepoi_override_icon
+
+ ///If set, vox wearing this use this instead of their clothing file
+ var/vox_override_icon
/// Needs to follow this syntax: either a list() with the x and y coordinates of the pixel you want to get the colour from, or a hexcolour. Colour one replaces red, two replaces blue, and three replaces green in the icon state.
var/list/greyscale_colors[3]
@@ -69,8 +76,11 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
///Whether or not we use stealthy audio levels for this item's attack sounds
var/stealthy_audio = FALSE
- ///How large is the object, used for stuff like whether it can fit in backpacks or not
+ /// Weight class for how much storage capacity it uses and how big it physically is meaning storages can't hold it if their maximum weight class isn't as high as it.
var/w_class = WEIGHT_CLASS_NORMAL
+ /// Volume override for the item, otherwise automatically calculated from w_class.
+ var/w_volume
+
///This is used to determine on which slots an item can fit.
var/slot_flags = 0
pass_flags = PASSTABLE
@@ -192,6 +202,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
var/canMouseDown = FALSE
+ //for setting world icons on the go
+ var/inventory_state
+ var/world_state
+
/obj/item/Initialize()
if(attack_verb)
@@ -381,7 +395,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(grav > STANDARD_GRAVITY)
var/grav_power = min(3,grav - STANDARD_GRAVITY)
to_chat(user,"You start picking up [src]...")
- if(!do_mob(user,src,30*grav_power))
+ if(!do_after(user, 30*grav_power, src))
return
@@ -508,12 +522,12 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/proc/equipped(mob/user, slot, initial = FALSE)
SHOULD_CALL_PARENT(1)
visual_equipped(user, slot, initial)
- SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
for(var/X in actions)
var/datum/action/A = X
if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
item_flags |= IN_INVENTORY
+ SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
if(!initial)
if(equip_sound && (slot_flags & slot))
playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE)
@@ -684,7 +698,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if (callback) //call the original callback
. = callback.Invoke()
item_flags &= ~IN_INVENTORY
- if(!pixel_y && !pixel_x)
+ if(!pixel_y && !pixel_x && !(item_flags & NO_PIXEL_RANDOM_DROP))
pixel_x = rand(-8,8)
pixel_y = rand(-8,8)
@@ -699,6 +713,9 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/proc/get_belt_overlay() //Returns the icon used for overlaying the object on a belt
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state)
+/obj/item/proc/get_helmet_overlay() // returns the icon for overlaying on a helmet
+ return mutable_appearance('icons/mob/clothing/helmet_overlays.dmi', icon_state)
+
/obj/item/proc/update_slot_icon()
if(!ismob(loc))
return
@@ -842,6 +859,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/MouseEntered(location, control, params)
. = ..()
+ SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params)
if((item_flags & IN_INVENTORY || item_flags & IN_STORAGE) && usr.client.prefs.enable_tips && !QDELETED(src))
var/timedelay = usr.client.prefs.tip_delay/100
var/user = usr
@@ -856,7 +874,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
. = ..()
remove_outline()
-/obj/item/MouseExited()
+/obj/item/MouseExited(location,control,params)
+ SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params)
deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes
closeToolTip(usr)
remove_outline()
@@ -907,7 +926,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
var/datum/callback/tool_check = CALLBACK(src, PROC_REF(tool_check_callback), user, amount, extra_checks)
if(ismob(target))
- if(!do_mob(user, target, delay, extra_checks=tool_check))
+ if(!do_after(user, delay, target, extra_checks=tool_check))
return
else
@@ -979,6 +998,11 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
dropped(M, FALSE)
return ..()
+/// Get an item's volume that it uses when being stored.
+/obj/item/proc/get_w_volume()
+ // if w_volume is 0 you fucked up.
+ return w_volume || AUTO_SCALE_VOLUME(w_class)
+
/obj/item/proc/embedded(mob/living/carbon/human/embedded_mob)
return
@@ -1025,7 +1049,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
* * forced- Do we want this to go through 100%?
*/
/obj/item/proc/tryEmbed(atom/target, forced=FALSE, silent=FALSE)
- if(!isbodypart(target) && !iscarbon(target) && !isclosedturf(target))
+ if(!isbodypart(target) && !iscarbon(target))
return
if(!forced && !LAZYLEN(embedding))
return
diff --git a/code/game/objects/items/attachments/_attachment.dm b/code/game/objects/items/attachments/_attachment.dm
new file mode 100644
index 000000000000..a6c25ec8cdf3
--- /dev/null
+++ b/code/game/objects/items/attachments/_attachment.dm
@@ -0,0 +1,99 @@
+///Most of the logic of attachments is held within the component which allows you to add other items as attachments in theory
+/obj/item/attachment
+ name = "broken attachment"
+ desc = "alert coders"
+ icon = 'icons/obj/guns/attachments.dmi'
+
+ //Slot the attachment goes on, also used in descriptions so should be player readable
+ var/slot = ATTACHMENT_SLOT_RAIL
+ ///various yes no flags associated with attachments. See defines for these: [_DEFINES/guns.dm]
+ var/attach_features_flags = ATTACH_REMOVABLE_HAND
+ ///See attachment component
+ var/list/valid_parents = list()
+ ///Unused.. but could hold extra callbacks I assume?
+ var/list/signals = list()
+ ///Component that handles most of the logic of attachments
+ var/datum/component/attachment/attachment_comp
+
+ ///If the attachment is on or off
+ var/toggled = FALSE
+ var/toggle_on_sound = 'sound/items/flashlight_on.ogg'
+ var/toggle_off_sound = 'sound/items/flashlight_off.ogg'
+
+ ///Determines the amount of pixels to move the icon state for the overlay. in the x direction
+ var/pixel_shift_x = 16
+ ///Determines the amount of pixels to move the icon state for the overlay. in the y direction
+ var/pixel_shift_y = 16
+
+ //Toggle modifers are handled seperatly
+ ///Modifier applied to the parent
+ var/spread_mod = 0
+ ///Modifier applied to the parent
+ var/spread_unwielded_mod = 0
+ ///Modifier applied to the parent, deciseconds
+ var/wield_delay = 0
+ ///Modifier applied to the parent
+ var/size_mod = 0
+
+/obj/item/attachment/Initialize()
+ . = ..()
+ attachment_comp = AddComponent( \
+ /datum/component/attachment, \
+ slot, \
+ attach_features_flags, \
+ valid_parents, \
+ CALLBACK(src, PROC_REF(apply_attachment)), \
+ CALLBACK(src, PROC_REF(remove_attachment)), \
+ CALLBACK(src, PROC_REF(toggle_attachment)), \
+ CALLBACK(src, PROC_REF(on_preattack)), \
+ signals)
+
+/obj/item/attachment/Destroy()
+ qdel(attachment_comp)
+ attachment_comp = null
+ . = ..()
+
+/obj/item/attachment/proc/toggle_attachment(obj/item/gun/gun, mob/user)
+ SHOULD_CALL_PARENT(TRUE)
+
+ playsound(user, toggled ? toggle_on_sound : toggle_off_sound, 40, TRUE)
+ toggled = !toggled
+ icon_state = "[initial(icon_state)][toggled ? "-on" : ""]"
+
+/// Checks if a user should be allowed to attach this attachment to the given parent
+/obj/item/attachment/proc/apply_attachment(obj/item/gun/gun, mob/user)
+ SHOULD_CALL_PARENT(TRUE)
+
+ if(toggled)
+ to_chat(user, span_warning("You cannot attach [src] while it is active!"))
+ return FALSE
+
+ apply_modifiers(gun, user, TRUE)
+ playsound(src.loc, 'sound/weapons/gun/pistol/mag_insert_alt.ogg', 75, 1)
+ return TRUE
+
+/obj/item/attachment/proc/remove_attachment(obj/item/gun/gun, mob/user)
+ SHOULD_CALL_PARENT(TRUE)
+
+ if(toggled)
+ toggle_attachment(gun, user)
+
+ apply_modifiers(gun, user, FALSE)
+ playsound(src.loc, 'sound/weapons/gun/pistol/mag_release_alt.ogg', 75, 1)
+ return TRUE
+
+/obj/item/attachment/proc/on_preattack(obj/item/gun/gun, atom/target, mob/user, list/params)
+ return FALSE
+
+///Handles the modifiers to the parent gun
+/obj/item/attachment/proc/apply_modifiers(obj/item/gun/gun, mob/user, attaching)
+ if(attaching)
+ gun.spread += spread_mod
+ gun.spread_unwielded += spread_unwielded_mod
+ gun.wield_delay += wield_delay
+ gun.w_class += size_mod
+ else
+ gun.spread -= spread_mod
+ gun.spread_unwielded -= spread_unwielded_mod
+ gun.wield_delay -= wield_delay
+ gun.w_class -= size_mod
diff --git a/code/game/objects/items/attachments/bayonet.dm b/code/game/objects/items/attachments/bayonet.dm
new file mode 100644
index 000000000000..6b1961f4b693
--- /dev/null
+++ b/code/game/objects/items/attachments/bayonet.dm
@@ -0,0 +1,22 @@
+/obj/item/attachment/bayonet
+ name = "bayonet"
+ desc = "Stabby-Stabby"
+ icon_state = "bayonet"
+ force = 15
+ throwforce = 10
+ pickup_sound = 'sound/items/handling/knife1_pickup.ogg'
+ drop_sound = 'sound/items/handling/knife3_drop.ogg'
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ sharpness = IS_SHARP_ACCURATE
+
+ pixel_shift_x = 1
+ pixel_shift_y = 4
+ spread_mod = 1
+ wield_delay = 0.1 SECONDS
+
+/obj/item/attachment/bayonet/on_preattack(obj/item/gun/gun, atom/target, mob/living/user, list/params)
+ if(user.a_intent == INTENT_HARM && user.CanReach(target, src, TRUE))
+ melee_attack_chain(user, target, params)
+ return COMPONENT_NO_ATTACK
+
diff --git a/code/game/objects/items/attachments/laser_sight.dm b/code/game/objects/items/attachments/laser_sight.dm
new file mode 100644
index 000000000000..082da1153de5
--- /dev/null
+++ b/code/game/objects/items/attachments/laser_sight.dm
@@ -0,0 +1,23 @@
+/obj/item/attachment/laser_sight
+ name = "laser sight"
+ desc = "Designed to be rail-mounted on a compatible firearm to provide increased accuracy and decreased spread."
+ icon_state = "laserpointer"
+
+ attach_features_flags = ATTACH_REMOVABLE_HAND|ATTACH_TOGGLE
+ pixel_shift_x = 1
+ pixel_shift_y = 4
+ wield_delay = 0.1 SECONDS
+
+/obj/item/attachment/laser_sight/toggle_attachment(obj/item/gun/gun, mob/user)
+ . = ..()
+
+ if(toggled)
+ gun.spread -= 3
+ gun.spread_unwielded -= 3
+ gun.wield_delay -= 0.3 SECONDS
+ else
+ gun.spread += 3
+ gun.spread_unwielded += 3
+ gun.wield_delay += 0.3 SECONDS
+
+ playsound(user, toggled ? 'sound/weapons/magin.ogg' : 'sound/weapons/magout.ogg', 40, TRUE)
diff --git a/code/game/objects/items/attachments/rail_light.dm b/code/game/objects/items/attachments/rail_light.dm
new file mode 100644
index 000000000000..0cfbe9661e9e
--- /dev/null
+++ b/code/game/objects/items/attachments/rail_light.dm
@@ -0,0 +1,33 @@
+/obj/item/attachment/rail_light
+ name = "rail light"
+ desc = "A flashlight made to be mounted on a firearm."
+ icon_state = "raillight"
+ light_color = COLOR_LIGHT_ORANGE
+ light_system = MOVABLE_LIGHT_DIRECTIONAL
+ light_range = 4
+ light_power = 0.8
+ light_on = FALSE
+
+ attach_features_flags = ATTACH_REMOVABLE_HAND|ATTACH_TOGGLE
+ pixel_shift_x = 1
+ pixel_shift_y = 4
+ wield_delay = 0.1 SECONDS
+
+/obj/item/attachment/rail_light/toggle_attachment(obj/item/gun/gun, mob/user)
+ . = ..()
+ set_light_on(toggled)
+ update_icon()
+
+/obj/item/attachment/rail_light/apply_attachment(obj/item/gun/gun, mob/user)
+ . = ..()
+ if(!.)
+ return
+
+ set_light_flags(light_flags | LIGHT_ATTACHED)
+
+/obj/item/attachment/rail_light/remove_attachment(obj/item/gun/gun, mob/user)
+ . = ..()
+ if(!.)
+ return
+
+ set_light_flags(light_flags & ~LIGHT_ATTACHED)
diff --git a/code/game/objects/items/attachments/silencer.dm b/code/game/objects/items/attachments/silencer.dm
new file mode 100644
index 000000000000..31cf3fc15b36
--- /dev/null
+++ b/code/game/objects/items/attachments/silencer.dm
@@ -0,0 +1,19 @@
+/obj/item/attachment/silencer
+ name = "suppressor"
+ desc = "An attachment for the barrel of a firearm. Muffles the gunshot and muzzle flash."
+ icon_state = "silencer"
+
+ slot = ATTACHMENT_SLOT_MUZZLE
+ pixel_shift_x = 1
+ pixel_shift_y = 2
+ spread_mod = -1
+ size_mod = 1
+
+/obj/item/attachment/silencer/apply_attachment(obj/item/gun/gun, mob/user)
+ . = ..()
+ gun.suppressed = TRUE
+
+/obj/item/attachment/silencer/remove_attachment(obj/item/gun/gun, mob/user)
+ . = ..()
+ gun.suppressed = FALSE
+ return TRUE
diff --git a/code/game/objects/items/attachments/stock.dm b/code/game/objects/items/attachments/stock.dm
new file mode 100644
index 000000000000..1fe286c14296
--- /dev/null
+++ b/code/game/objects/items/attachments/stock.dm
@@ -0,0 +1,40 @@
+/obj/item/attachment/foldable_stock
+ name = "folding stock"
+ desc = "A folding stock that can be attached to certain weapons to improve stability and decreases recoil."
+ icon_state = "skm-carbine-stock"
+ slot = ATTACHMENT_SLOT_STOCK
+ attach_features_flags = ATTACH_TOGGLE
+
+ pixel_shift_x = 17
+ pixel_shift_y = 18
+
+ var/toggled_slowdown = 0.10
+ var/toggled_wield_delay = -0.4 SECONDS
+ var/toggled_recoil_bonus = -2
+ var/toggled_spread_bonus = -5
+
+/obj/item/attachment/foldable_stock/toggle_attachment(obj/item/gun/gun, mob/user)
+ . = ..()
+
+ if(toggled)
+ to_chat(user, span_notice("You unfold the stock on the [src]."))
+ gun.w_class += 1
+ gun.wield_delay += toggled_wield_delay
+ gun.wield_slowdown += toggled_slowdown
+ gun.recoil += toggled_recoil_bonus
+ gun.spread += toggled_spread_bonus
+ else
+ to_chat(user, span_notice("You fold the stock on the [src]."))
+ gun.w_class -= 1
+ gun.wield_delay -= toggled_wield_delay
+ gun.wield_slowdown -= toggled_slowdown
+ gun.recoil -= toggled_recoil_bonus
+ gun.spread -= toggled_spread_bonus
+
+ if(gun.wielded)
+ user.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/gun, multiplicative_slowdown = gun.wield_slowdown)
+
+ playsound(src, SOUND_EMPTY_MAG, 100, 1)
+
+/obj/item/attachment/foldable_stock/inteq
+ icon_state = "skm-inteqsmg-stock"
diff --git a/code/game/objects/items/bank_card.dm b/code/game/objects/items/bank_card.dm
new file mode 100644
index 000000000000..4a7f2f9d2f21
--- /dev/null
+++ b/code/game/objects/items/bank_card.dm
@@ -0,0 +1,160 @@
+/obj/item/card/bank
+ name = "cash card"
+ desc = "Managed by a bank outside the sector."
+ icon_state = "data_1"
+ var/mining_points = 0 //For redeeming at mining equipment vendors
+
+ var/registered_name = null // The name registered_name on the card
+ var/datum/bank_account/registered_account
+ var/obj/machinery/paystand/my_store
+
+/obj/item/card/bank/Destroy()
+ if (registered_account)
+ registered_account.bank_cards -= src
+ if (my_store && my_store.my_card == src)
+ my_store.my_card = null
+ return ..()
+
+/obj/item/card/bank/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/holochip))
+ insert_money(W, user)
+ return
+ else if(istype(W, /obj/item/spacecash/bundle))
+ insert_money(W, user, TRUE)
+ return
+ else if(istype(W, /obj/item/coin))
+ insert_money(W, user, TRUE)
+ return
+ else if(istype(W, /obj/item/storage/bag/money))
+ var/obj/item/storage/bag/money/money_bag = W
+ var/list/money_contained = money_bag.contents
+
+ var/money_added = mass_insert_money(money_contained, user)
+
+ if (money_added)
+ to_chat(user, "You stuff the contents into the card! They disappear in a puff of bluespace smoke, adding [money_added] worth of credits to the linked account.")
+ return
+ else
+ return ..()
+
+/obj/item/card/bank/proc/insert_money(obj/item/I, mob/user, physical_currency)
+ var/cash_money = I.get_item_credit_value()
+ if(!cash_money)
+ to_chat(user, "[I] doesn't seem to be worth anything!")
+ return
+
+ if(!registered_account)
+ to_chat(user, "[src] doesn't have a linked account to deposit [I] into!")
+ return
+
+ registered_account.adjust_money(cash_money)
+ SSblackbox.record_feedback("amount", "credits_inserted", cash_money)
+ log_econ("[cash_money] credits were inserted into [src] owned by [src.registered_name]")
+ if(physical_currency)
+ to_chat(user, "You stuff [I] into [src]. It disappears in a small puff of bluespace smoke, adding [cash_money] credits to the linked account.")
+ else
+ to_chat(user, "You insert [I] into [src], adding [cash_money] credits to the linked account.")
+
+ to_chat(user, "The linked account now reports a balance of [registered_account.account_balance] cr.")
+ qdel(I)
+
+/obj/item/card/bank/proc/mass_insert_money(list/money, mob/user)
+ if (!money || !money.len)
+ return FALSE
+
+ var/total = 0
+
+ for (var/obj/item/physical_money in money)
+ var/cash_money = physical_money.get_item_credit_value()
+
+ total += cash_money
+
+ registered_account.adjust_money(cash_money)
+ SSblackbox.record_feedback("amount", "credits_inserted", total)
+ log_econ("[total] credits were inserted into [src] owned by [src.registered_name]")
+ QDEL_LIST(money)
+
+ return total
+
+/obj/item/card/bank/proc/alt_click_can_use_id(mob/living/user)
+ if(!isliving(user))
+ return
+ if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
+ return
+
+ return TRUE
+
+// Returns true if new account was set.
+/obj/item/card/bank/proc/set_new_account(mob/living/user)
+ . = FALSE
+ var/datum/bank_account/old_account = registered_account
+
+ var/new_bank_id = input(user, "Enter your account ID number.", "Account Reclamation", 111111) as num | null
+
+ if (isnull(new_bank_id))
+ return
+
+ if(!alt_click_can_use_id(user))
+ return
+ if(!new_bank_id || new_bank_id < 111111 || new_bank_id > 999999)
+ to_chat(user, "The account ID number needs to be between 111111 and 999999.")
+ return
+ if (registered_account && registered_account.account_id == new_bank_id)
+ to_chat(user, "The account ID was already assigned to this card.")
+ return
+
+ for(var/A in SSeconomy.bank_accounts)
+ var/datum/bank_account/B = A
+ if(B.account_id == new_bank_id)
+ if (old_account)
+ old_account.bank_cards -= src
+
+ B.bank_cards += src
+ registered_account = B
+ to_chat(user, "The provided account has been linked to this ID card.")
+
+ return TRUE
+
+ to_chat(user, "The account ID number provided is invalid.")
+ return
+
+/obj/item/card/bank/AltClick(mob/living/user)
+ if(!alt_click_can_use_id(user))
+ return
+
+ if(!registered_account)
+ set_new_account(user)
+ return
+
+ var/amount_to_remove = FLOOR(input(user, "How much do you want to withdraw? Current Balance: [registered_account.account_balance]", "Withdraw Funds", 5) as num|null, 1)
+
+ if(!amount_to_remove || amount_to_remove < 0)
+ return
+ if(!alt_click_can_use_id(user))
+ return
+ if(registered_account.adjust_money(-amount_to_remove))
+ var/obj/item/holochip/holochip = new (user.drop_location(), amount_to_remove)
+ user.put_in_hands(holochip)
+ to_chat(user, "You withdraw [amount_to_remove] credits into a holochip.")
+ SSblackbox.record_feedback("amount", "credits_removed", amount_to_remove)
+ log_econ("[amount_to_remove] credits were removed from [src] owned by [registered_account.account_holder]")
+ return
+ else
+ var/difference = amount_to_remove - registered_account.account_balance
+ registered_account.bank_card_talk("ERROR: The linked account requires [difference] more credit\s to perform that withdrawal.", TRUE)
+
+/obj/item/card/bank/examine(mob/user)
+ . = ..()
+ if(registered_account)
+ . += "The account linked to the ID belongs to '[registered_account.account_holder]' and reports a balance of [registered_account.account_balance] cr."
+ . += "The card indicates that the holder is [registered_account.holder_age] years old. [(registered_account.holder_age < AGE_MINOR) ? "There's a holographic stripe that reads 'MINOR: DO NOT SERVE ALCOHOL OR TOBACCO' along the bottom of the card." : ""]"
+ . += "Alt-Click the ID to pull money from the linked account in the form of holochips."
+ . += "You can insert credits into the linked account by pressing holochips, cash, or coins against the ID."
+ . += "If you lose this ID card, you can reclaim your account by Alt-Clicking a blank ID card while holding it and entering your account ID number."
+ else
+ . += "There is no registered account linked to this card. Alt-Click to add one."
+ if(mining_points)
+ . += "There's [mining_points] mining equipment redemption point\s loaded onto this card."
+
+/obj/item/card/bank/GetBankCard()
+ return src
diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm
index f44359ca656c..31af53aa3fc7 100644
--- a/code/game/objects/items/cardboard_cutouts.dm
+++ b/code/game/objects/items/cardboard_cutouts.dm
@@ -104,7 +104,7 @@
var/new_appearance = show_radial_menu(user, src, possible_appearances, custom_check = CALLBACK(src, PROC_REF(check_menu), user, crayon), radius = 36, require_near = TRUE)
if(!new_appearance)
return FALSE
- if(!do_after(user, 10, FALSE, src, TRUE))
+ if(!do_after(user, 10, src, progress = TRUE))
return FALSE
if(!check_menu(user, crayon))
return FALSE
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index 630759c85afe..fb79cc447ab9 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -140,8 +140,8 @@
playsound(src, 'sound/items/bikehorn.ogg', 50, TRUE)
/obj/item/card/id
- name = "identification card"
- desc = "A card used to provide ID and determine access across the station."
+ name = "access card"
+ desc = "These cards provide access to different sections of a ship."
icon_state = "id"
item_state = "card-id"
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
@@ -149,17 +149,15 @@
slot_flags = ITEM_SLOT_ID
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
- var/mining_points = 0 //For redeeming at mining equipment vendors
var/list/access = list()
var/list/ship_access = list()
var/registered_name = null // The name registered_name on the card
var/assignment = null
var/access_txt // mapping aid
- var/datum/bank_account/registered_account
- var/obj/machinery/paystand/my_store
+ //var/datum/bank_account/registered_account
var/uses_overlays = TRUE
var/icon/cached_flat_icon
- var/registered_age = 13 // default age for ss13 players
+ var/registered_age = 18 // default age for ss13 players
var/job_icon
var/faction_icon
@@ -167,23 +165,25 @@
. = ..()
if(mapload && access_txt)
access = text2access(access_txt)
+ SEND_SIGNAL(src, COSMIG_ACCESS_UPDATED)
update_label()
update_appearance()
RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, PROC_REF(update_in_wallet))
-/obj/item/card/id/Destroy()
- if (registered_account)
- registered_account.bank_cards -= src
- if (my_store && my_store.my_card == src)
- my_store.my_card = null
- return ..()
-
/obj/item/card/id/attack_self(mob/user)
if(Adjacent(user))
- var/minor
- if(registered_name && registered_age && registered_age < AGE_MINOR)
- minor = " (MINOR)"
- user.visible_message("[user] shows you: [icon2html(src, viewers(user))] [src.name][minor].", "You show \the [src.name][minor].")
+ var/id_message = "\the [initial(name)] "
+ var/list/id_info = list()
+ if(assignment)
+ id_info += "JOB: [assignment]"
+ if(registered_name)
+ id_info += "NAME: [registered_name]"
+ if(id_info)
+ id_message += id_info.Join(", ")
+ var/self_message = span_notice("You show [id_message]")
+ var/other_message = span_notice("[user] shows you: [icon2html(src, viewers(user))] [id_message]")
+
+ user.visible_message(other_message, self_message)
add_fingerprint(user)
/obj/item/card/id/vv_edit_var(var_name, var_value)
@@ -193,162 +193,29 @@
if(NAMEOF(src, assignment),NAMEOF(src, registered_name),NAMEOF(src, registered_age))
update_label()
-/obj/item/card/id/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/holochip))
- insert_money(W, user)
- return
- else if(istype(W, /obj/item/spacecash/bundle))
- insert_money(W, user, TRUE)
- return
- else if(istype(W, /obj/item/coin))
- insert_money(W, user, TRUE)
- return
- else if(istype(W, /obj/item/storage/bag/money))
- var/obj/item/storage/bag/money/money_bag = W
- var/list/money_contained = money_bag.contents
-
- var/money_added = mass_insert_money(money_contained, user)
-
- if (money_added)
- to_chat(user, "You stuff the contents into the card! They disappear in a puff of bluespace smoke, adding [money_added] worth of credits to the linked account.")
- return
- else
- return ..()
-
-/obj/item/card/id/proc/insert_money(obj/item/I, mob/user, physical_currency)
- var/cash_money = I.get_item_credit_value()
- if(!cash_money)
- to_chat(user, "[I] doesn't seem to be worth anything!")
- return
-
- if(!registered_account)
- to_chat(user, "[src] doesn't have a linked account to deposit [I] into!")
- return
-
- registered_account.adjust_money(cash_money)
- SSblackbox.record_feedback("amount", "credits_inserted", cash_money)
- log_econ("[cash_money] credits were inserted into [src] owned by [src.registered_name]")
- if(physical_currency)
- to_chat(user, "You stuff [I] into [src]. It disappears in a small puff of bluespace smoke, adding [cash_money] credits to the linked account.")
- else
- to_chat(user, "You insert [I] into [src], adding [cash_money] credits to the linked account.")
-
- to_chat(user, "The linked account now reports a balance of [registered_account.account_balance] cr.")
- qdel(I)
-
-/obj/item/card/id/proc/mass_insert_money(list/money, mob/user)
- if (!money || !money.len)
- return FALSE
-
- var/total = 0
-
- for (var/obj/item/physical_money in money)
- var/cash_money = physical_money.get_item_credit_value()
-
- total += cash_money
-
- registered_account.adjust_money(cash_money)
- SSblackbox.record_feedback("amount", "credits_inserted", total)
- log_econ("[total] credits were inserted into [src] owned by [src.registered_name]")
- QDEL_LIST(money)
-
- return total
-
-/obj/item/card/id/proc/alt_click_can_use_id(mob/living/user)
- if(!isliving(user))
- return
- if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
- return
-
- return TRUE
-
-// Returns true if new account was set.
-/obj/item/card/id/proc/set_new_account(mob/living/user)
- . = FALSE
- var/datum/bank_account/old_account = registered_account
-
- var/new_bank_id = input(user, "Enter your account ID number.", "Account Reclamation", 111111) as num | null
-
- if (isnull(new_bank_id))
- return
-
- if(!alt_click_can_use_id(user))
- return
- if(!new_bank_id || new_bank_id < 111111 || new_bank_id > 999999)
- to_chat(user, "The account ID number needs to be between 111111 and 999999.")
- return
- if (registered_account && registered_account.account_id == new_bank_id)
- to_chat(user, "The account ID was already assigned to this card.")
- return
-
- for(var/A in SSeconomy.bank_accounts)
- var/datum/bank_account/B = A
- if(B.account_id == new_bank_id)
- if (old_account)
- old_account.bank_cards -= src
-
- B.bank_cards += src
- registered_account = B
- to_chat(user, "The provided account has been linked to this ID card.")
-
- return TRUE
-
- to_chat(user, "The account ID number provided is invalid.")
- return
-
-/obj/item/card/id/AltClick(mob/living/user)
- if(!alt_click_can_use_id(user))
- return
-
- if(!registered_account)
- set_new_account(user)
- return
-
- var/amount_to_remove = FLOOR(input(user, "How much do you want to withdraw? Current Balance: [registered_account.account_balance]", "Withdraw Funds", 5) as num|null, 1)
-
- if(!amount_to_remove || amount_to_remove < 0)
- return
- if(!alt_click_can_use_id(user))
- return
- if(registered_account.adjust_money(-amount_to_remove))
- var/obj/item/holochip/holochip = new (user.drop_location(), amount_to_remove)
- user.put_in_hands(holochip)
- to_chat(user, "You withdraw [amount_to_remove] credits into a holochip.")
- SSblackbox.record_feedback("amount", "credits_removed", amount_to_remove)
- log_econ("[amount_to_remove] credits were removed from [src] owned by [src.registered_name]")
- return
- else
- var/difference = amount_to_remove - registered_account.account_balance
- registered_account.bank_card_talk("ERROR: The linked account requires [difference] more credit\s to perform that withdrawal.", TRUE)
-
/obj/item/card/id/examine(mob/user)
. = ..()
- if(registered_account)
- . += "The account linked to the ID belongs to '[registered_account.account_holder]' and reports a balance of [registered_account.account_balance] cr."
- . += "There's more information below, you can look again to take a closer look..."
-
-/obj/item/card/id/examine_more(mob/user)
- var/list/msg = list("You examine [src] closer, and note the following...")
-
+ . += " CARD INFO:"
+ if(registered_name)
+ . += "NAME:"
+ . += "[registered_name]"
if(registered_age)
- msg += "The card indicates that the holder is [registered_age] years old. [(registered_age < AGE_MINOR) ? "There's a holographic stripe that reads 'MINOR: DO NOT SERVE ALCOHOL OR TOBACCO' along the bottom of the card." : ""]"
- if(mining_points)
- msg += "There's [mining_points] mining equipment redemption point\s loaded onto this card."
+ . += "AGE:"
+ . += "[registered_age] years old [(registered_age < AGE_MINOR) ? "There's a holographic stripe that reads 'MINOR: DO NOT SERVE ALCOHOL OR TOBACCO' along the bottom of the card." : ""]"
if(length(ship_access))
+ . += "SHIP ACCESS:"
+
+ var/list/ship_factions = list()
+ for(var/datum/overmap/ship/controlled/ship in ship_access)
+ var/faction = ship.get_faction()
+ if(!(faction in ship_factions))
+ ship_factions += faction
+ . += "[ship_factions.Join(", ")]"
+
var/list/ship_names = list()
for(var/datum/overmap/ship/controlled/ship in ship_access)
ship_names += ship.name
- msg += "The card has access to the following ships: [ship_names.Join(", ")]"
- if(registered_account)
- msg += "The account linked to the ID belongs to '[registered_account.account_holder]' and reports a balance of [registered_account.account_balance] cr."
- msg += "Alt-Click the ID to pull money from the linked account in the form of holochips."
- msg += "You can insert credits into the linked account by pressing holochips, cash, or coins against the ID."
- if(registered_account.account_holder == user.real_name)
- msg += "If you lose this ID card, you can reclaim your account by Alt-Clicking a blank ID card while holding it and entering your account ID number."
- else
- msg += "There is no registered account linked to this card. Alt-Click to add one."
-
- return msg
+ . += "[ship_names.Join(", ")]"
/obj/item/card/id/GetAccess()
return access
@@ -393,11 +260,13 @@
/obj/item/card/id/proc/add_ship_access(datum/overmap/ship/controlled/ship)
if (ship)
ship_access += ship
+ SEND_SIGNAL(src, COSMIG_ACCESS_UPDATED)
// Removes the referenced ship from the card
/obj/item/card/id/proc/remove_ship_access(datum/overmap/ship/controlled/ship)
if (ship)
ship_access -= ship
+ SEND_SIGNAL(src, COSMIG_ACCESS_UPDATED)
// Finds the referenced ship in the list
/obj/item/card/id/proc/has_ship_access(datum/overmap/ship/controlled/ship)
@@ -407,16 +276,14 @@
/*
Usage:
update_label()
- Sets the id name to whatever registered_name and assignment is
+ Sets the id name to whatever the assignment is
*/
/obj/item/card/id/proc/update_label()
- var/blank = !registered_name
- name = "[blank ? initial(name) : "[registered_name]'s ID Card"][(!assignment) ? "" : " ([assignment])"]"
+ name = "[(istype(src, /obj/item/card/id/syndicate)) ? "[initial(name)]" : "access card"][(!assignment) ? "" : " ([assignment])"]"
/obj/item/card/id/silver
- name = "silver identification card"
- desc = "A silver card which shows honour and dedication."
+ desc = "A silver-colored card, usually given to higher-ranking officials in ships and stations."
icon_state = "silver"
item_state = "silver_id"
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
@@ -428,8 +295,7 @@ update_label()
access = list(ACCESS_CHANGE_IDS)
/obj/item/card/id/gold
- name = "gold identification card"
- desc = "A golden card which shows power and might."
+ desc = "A golden-colored card, usually given to those at the top of the hierarchy in a ship."
icon_state = "gold"
item_state = "gold_id"
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
@@ -467,7 +333,7 @@ update_label()
else
return ..()
- var/popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset", "Change Account ID")
+ var/popup_input = alert(user, "Choose Action", "Agent ID", "Show", "Forge/Reset")
if(user.incapacitated())
return
if(popup_input == "Forge/Reset" && !forged)
@@ -497,17 +363,6 @@ update_label()
to_chat(user, "You successfully forge the ID card.")
log_game("[key_name(user)] has forged \the [initial(name)] with name \"[registered_name]\" and occupation \"[assignment]\".")
- // First time use automatically sets the account id to the user.
- if (first_use && !registered_account)
- if(ishuman(user))
- var/mob/living/carbon/human/accountowner = user
-
- for(var/bank_account in SSeconomy.bank_accounts)
- var/datum/bank_account/account = bank_account
- if(account.account_id == accountowner.account_id)
- account.bank_cards += src
- registered_account = account
- to_chat(user, "Your account number has been automatically assigned.")
return
else if (popup_input == "Forge/Reset" && forged)
registered_name = initial(registered_name)
@@ -519,9 +374,6 @@ update_label()
forged = FALSE
to_chat(user, "You successfully reset the ID card.")
return
- else if (popup_input == "Change Account ID")
- set_new_account(user)
- return
return ..()
/obj/item/card/id/syndicate/anyone
@@ -532,14 +384,10 @@ update_label()
access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER)
/obj/item/card/id/syndicate_command
- name = "syndicate ID card"
- desc = "An ID straight from the Syndicate."
- registered_name = "Syndicate"
- assignment = "Syndicate Overlord"
+ desc = "An access card widely utilized by Coalition splinters in the frontier."
icon_state = "syndie"
access = list(ACCESS_SYNDICATE)
uses_overlays = FALSE
- registered_age = null
/obj/item/card/id/syndicate_command/crew_id
assignment = "Operative"
@@ -569,15 +417,12 @@ update_label()
/obj/item/card/id/patient //Aegis ID
assignment = "Long Term Patient"
uses_overlays = FALSE
- access = list(ACCESS_SYNDICATE)
/obj/item/card/id/captains_spare
- desc = "The spare ID of the High Lord himself."
icon_state = "gold"
item_state = "gold_id"
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
- registered_name = "Captain"
assignment = "Captain"
registered_age = null
@@ -596,11 +441,9 @@ update_label()
..()
/obj/item/card/id/centcom
- name = "\improper CentCom ID"
- desc = "An ID straight from Central Command."
+ name = "\improper Nanotrasen Central Command access card"
+ desc = "An access card sourced from Nanotrasen's Central Command."
icon_state = "centcom"
- registered_name = "Central Command"
- assignment = "Central Command"
uses_overlays = FALSE
registered_age = null
@@ -615,8 +458,6 @@ update_label()
name = "\improper CentCom ID"
desc = "An ERT ID card."
icon_state = "ert_commander"
- registered_name = "Emergency Response Team Commander"
- assignment = "Emergency Response Team Commander"
uses_overlays = FALSE
registered_age = null
@@ -625,8 +466,6 @@ update_label()
. = ..()
/obj/item/card/id/ert/security
- registered_name = "Security Response Officer"
- assignment = "Security Response Officer"
icon_state = "ert_security"
/obj/item/card/id/ert/security/Initialize()
@@ -634,8 +473,6 @@ update_label()
. = ..()
/obj/item/card/id/ert/engineer
- registered_name = "Engineering Response Officer"
- assignment = "Engineering Response Officer"
icon_state = "ert_engineer"
/obj/item/card/id/ert/engineer/Initialize()
@@ -643,8 +480,6 @@ update_label()
. = ..()
/obj/item/card/id/ert/medical
- registered_name = "Medical Response Officer"
- assignment = "Medical Response Officer"
icon_state = "ert_medic"
/obj/item/card/id/ert/medical/Initialize()
@@ -652,8 +487,6 @@ update_label()
. = ..()
/obj/item/card/id/ert/chaplain
- registered_name = "Religious Response Officer"
- assignment = "Religious Response Officer"
icon_state = "ert_chaplain"
/obj/item/card/id/ert/chaplain/Initialize()
@@ -661,8 +494,6 @@ update_label()
. = ..()
/obj/item/card/id/ert/janitor
- registered_name = "Janitorial Response Officer"
- assignment = "Janitorial Response Officer"
icon_state = "ert_janitor"
/obj/item/card/id/ert/janitor/Initialize()
@@ -670,8 +501,6 @@ update_label()
. = ..()
/obj/item/card/id/ert/clown
- registered_name = "Entertainment Response Officer"
- assignment = "Entertainment Response Officer"
icon_state = "ert_clown"
/obj/item/card/id/ert/clown/Initialize()
@@ -679,12 +508,10 @@ update_label()
. = ..()
/obj/item/card/id/ert/deathsquad
- name = "\improper Death Squad ID"
- desc = "A Death Squad ID card."
+ desc = "An access card colored in black and red."
icon_state = "deathsquad" //NO NO SIR DEATH SQUADS ARENT A PART OF NANOTRASEN AT ALL
- registered_name = "Death Commando"
- assignment = "Death Commando"
uses_overlays = FALSE
+ job_icon = "deathsquad"
/obj/item/card/id/debug
name = "\improper Debug ID"
@@ -748,11 +575,6 @@ update_label()
registered_name = "Prisoner #13-007"
icon_state = "prisoner_007"
-/obj/item/card/id/mining
- name = "mining ID"
- access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MECH_MINING, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
- custom_price = 250
-
/obj/item/card/id/away
name = "\proper a perfectly generic identification card"
desc = "A perfectly generic identification card. Looks like it could use some flavor."
@@ -774,13 +596,26 @@ update_label()
name = "bunker access ID"
/obj/item/card/id/solgov
- name = "\improper SolGov ID"
- desc = "A SolGov ID with no proper access to speak of."
+ name = "\improper SolGov keycard"
+ desc = "A SolGov keycard with no proper access to speak of."
assignment = "Officer"
icon_state = "solgov"
uses_overlays = FALSE
/obj/item/card/id/solgov/commander
- name = "\improper SolGov ID"
- desc = "A SolGov ID with no proper access to speak of. This one indicates a Commander."
+ name = "\improper SolGov commander keycard"
+ desc = "A SolGov keycard with no proper access to speak of. This one indicates a Commander."
assignment = "Commander"
+
+/obj/item/card/id/suns
+ name = "\improper SUNS keycard"
+ desc = "A keycard belonging to the Student-Union Association of Naturalistic Sciences."
+ assignment = "Student"
+ icon_state = "suns"
+ uses_overlays = FALSE
+
+/obj/item/card/id/suns/command
+ name = "\improper SUNS command keycard"
+ desc = "A keycard belonging to the Student-Union Association of Naturalistic Sciences. This one has a gold stripe, indicating a command member."
+ assignment = "Academic Staff"
+ icon_state = "sunscommand"
diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm
index f63a5e9dd45a..baa541662e20 100644
--- a/code/game/objects/items/chrono_eraser.dm
+++ b/code/game/objects/items/chrono_eraser.dm
@@ -51,7 +51,7 @@
item_flags = DROPDEL
ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam)
can_charge = FALSE
- fire_delay = 50
+ fire_delay = 5 SECONDS
var/obj/item/chrono_eraser/TED = null
var/obj/structure/chrono_field/field = null
var/turf/startpos = null
diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm
index 0258e86e8a7f..6b7b364118d4 100644
--- a/code/game/objects/items/cigs_lighters.dm
+++ b/code/game/objects/items/cigs_lighters.dm
@@ -783,7 +783,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/lighter/liz/ignition_effect(atom/A, mob/user)
if(get_temperature())
. = "[user] spits fire at [A], igniting it."
- playsound(src, 'sound/magic/fireball.ogg', 10, TRUE)
+ playsound(src, 'sound/voice/lizard/firespit.ogg', 20, TRUE)
/obj/item/lighter/enigma
name = "\improper Enigma Shipworks Lighter"
diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm
index 54dcfb36c131..47739ded1551 100644
--- a/code/game/objects/items/circuitboards/computer_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm
@@ -362,7 +362,7 @@
build_path = /obj/machinery/computer/bounty
/obj/item/circuitboard/computer/cargo
- name = "Supply Console (Computer Board)"
+ name = "Outpost Comms Console (Computer Board)"
icon_state = "supply"
build_path = /obj/machinery/computer/cargo
var/contraband = FALSE
@@ -381,16 +381,6 @@
obj_flags |= EMAGGED
to_chat(user, "You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.")
-/obj/item/circuitboard/computer/cargo/express
- name = "Outpost Comms Console (Computer Board)"
- build_path = /obj/machinery/computer/cargo/express
-
-/obj/item/circuitboard/computer/cargo/express/multitool_act(mob/living/user)
- return
-
-/obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user)
- return
-
/obj/item/circuitboard/computer/mining
name = "Outpost Status Display (Computer Board)"
icon_state = "supply"
diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm
index 7b2724f9e53f..0a3a6f14d097 100644
--- a/code/game/objects/items/circuitboards/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm
@@ -201,8 +201,19 @@
name = "Circulator/Heat Exchanger (Machine Board)"
icon_state = "engineering"
build_path = /obj/machinery/atmospherics/components/binary/circulator
+ var/pipe_layer = PIPING_LAYER_DEFAULT
req_components = list()
+/obj/item/circuitboard/machine/circulator/attackby(obj/item/I, mob/user, params)
+ if(I.tool_behaviour == TOOL_MULTITOOL)
+ pipe_layer = (pipe_layer >= PIPING_LAYER_MAX) ? PIPING_LAYER_MIN : (pipe_layer + 1)
+ to_chat(user, "You change the circuitboard to layer [pipe_layer].")
+ return
+
+/obj/item/circuitboard/machine/circulator/examine()
+ . = ..()
+ . += "It is set to layer [pipe_layer]."
+
/obj/item/circuitboard/machine/emitter
name = "Emitter (Machine Board)"
icon_state = "engineering"
@@ -257,7 +268,7 @@
/obj/item/circuitboard/machine/power_turbine
name = "Power Turbine (Machine Board)"
icon_state = "engineering"
- build_path = /obj/machinery/power/turbine
+ build_path = /obj/machinery/power/shuttle/engine/turbine
req_components = list(
/obj/item/stack/cable_coil = 5,
/obj/item/stock_parts/capacitor = 6)
@@ -389,6 +400,17 @@
name = "Freezer (Machine Board)"
build_path = PATH_FREEZER
+/obj/item/circuitboard/machine/ship_gravity
+ name = "Gravity Generator (Machine Board)"
+ icon_state = "engineering"
+ build_path = /obj/machinery/power/ship_gravity
+ req_components = list(
+ /obj/item/stock_parts/capacitor = 5,
+ /obj/item/stack/sheet/bluespace_crystal = 1,
+ /obj/item/stock_parts/micro_laser = 4
+ )
+ needs_anchored = FALSE
+
#undef PATH_FREEZER
#undef PATH_HEATER
@@ -1420,6 +1442,15 @@
/obj/item/stack/cable_coil = 5,
/obj/item/stock_parts/micro_laser = 1)
+/obj/item/circuitboard/machine/shuttle/engine/fire
+ name = "Combustion Thruster (Machine Board)"
+ build_path = /obj/machinery/power/shuttle/engine/fire
+ req_components = list(
+ /obj/item/stock_parts/micro_laser = 1,
+ /obj/item/assembly/igniter = 1,
+ /obj/item/stack/sheet/plasteel = 2
+ )
+
/obj/item/circuitboard/machine/shuttle/engine/electric
name = "Ion Thruster (Machine Board)"
build_path = /obj/machinery/power/shuttle/engine/electric
@@ -1459,10 +1490,42 @@
/obj/item/circuitboard/machine/shuttle/heater
name = "Fueled Engine Heater (Machine Board)"
+ desc = "You can use mulitool to switch pipe layers"
build_path = /obj/machinery/atmospherics/components/unary/shuttle/heater
+ var/pipe_layer = PIPING_LAYER_DEFAULT
req_components = list(/obj/item/stock_parts/micro_laser = 2,
/obj/item/stock_parts/matter_bin = 1)
+/obj/item/circuitboard/machine/shuttle/heater/attackby(obj/item/I, mob/user, params)
+ if(I.tool_behaviour == TOOL_MULTITOOL)
+ pipe_layer = (pipe_layer >= PIPING_LAYER_MAX) ? PIPING_LAYER_MIN : (pipe_layer + 1)
+ to_chat(user, "You change the circuitboard to layer [pipe_layer].")
+ return
+
+/obj/item/circuitboard/machine/shuttle/heater/examine()
+ . = ..()
+ . += "It is set to layer [pipe_layer]."
+
+/obj/item/circuitboard/machine/shuttle/fire_heater
+ name = "Combustion Engine Heater (Machine Board)"
+ desc = "You can use mulitool to switch pipe layers"
+ var/pipe_layer = PIPING_LAYER_DEFAULT
+ build_path = /obj/machinery/atmospherics/components/unary/shuttle/fire_heater
+ req_components = list(
+ /obj/item/stock_parts/micro_laser = 1,
+ /obj/item/stock_parts/matter_bin = 1
+ )
+
+/obj/item/circuitboard/machine/shuttle/fire_heater/attackby(obj/item/I, mob/user, params)
+ if(I.tool_behaviour == TOOL_MULTITOOL)
+ pipe_layer = (pipe_layer >= PIPING_LAYER_MAX) ? PIPING_LAYER_MIN : (pipe_layer + 1)
+ to_chat(user, "You change the circuitboard to layer [pipe_layer].")
+ return
+
+/obj/item/circuitboard/machine/shuttle/fire_heater/examine()
+ . = ..()
+ . += "It is set to layer [pipe_layer]."
+
/obj/item/circuitboard/machine/shuttle/smes
name = "Electric Engine Precharger (Machine Board)"
build_path = /obj/machinery/power/smes/shuttle
@@ -1490,22 +1553,8 @@
/obj/item/stock_parts/manipulator = 2,
)
-/obj/item/circuitboard/machine/coffeemaker
- name = "Modello 3 Coffeemaker"
- build_path = /obj/machinery/coffeemaker
- req_components = list(
- /obj/item/stack/sheet/glass = 1,
- /obj/item/reagent_containers/glass/beaker = 2,
- /obj/item/stock_parts/capacitor = 1,
- /obj/item/stock_parts/micro_laser = 2,
- )
-
-/obj/item/circuitboard/machine/coffeemaker/impressa
- name = "Impressa Coffeemaker"
- build_path = /obj/machinery/coffeemaker/impressa
- req_components = list(
- /obj/item/stack/sheet/glass = 1,
- /obj/item/reagent_containers/glass/beaker = 2,
- /obj/item/stock_parts/capacitor = 1,
- /obj/item/stock_parts/micro_laser = 2,
- )
+/obj/item/circuitboard/machine/suit_storage_unit
+ name = "Suit Storage Unit"
+ icon_state = "engineering"
+ build_path = /obj/machinery/suit_storage_unit
+ req_components = list(/obj/item/stock_parts/micro_laser = 4)
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 5ca8fa313c60..d703ae86ca7d 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -43,16 +43,15 @@
var/drawtype
var/text_buffer = ""
- var/static/list/graffiti = list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","body","cyka","star","poseur tag","prolizard","antilizard")
+ var/static/list/graffiti = list("face","guy","end","body")
+ var/static/list/code = list("getout","empty","unsafe","camp","safepath","jackpot","dismantle")
var/static/list/symbols = list("danger","firedanger","electricdanger","biohazard","radiation","safe","evac","space","med","trade","shop","food","peace","like","skull","nay","heart","credit")
- var/static/list/drawings = list("smallbrush","brush","largebrush","splatter","snake","stickman","carp","ghost","clown","taser","disk","fireaxe","toolbox","corgi","cat","toilet","blueprint","beepsky","scroll","bottle","shotgun")
- var/static/list/oriented = list("arrow","line","thinline","shortline","body","chevron","footprint","clawprint","pawprint") // These turn to face the same way as the drawer
- var/static/list/runes = list("rune1","rune2","rune3","rune4","rune5","rune6")
+ var/static/list/drawings = list("smallbrush","brush","splatter","snake","carp","ghost","taser","disk","fireaxe","toolbox","corgi","cat","toilet","blueprint","beepsky","scroll","bottle","shotgun")
+ var/static/list/oriented = list("arrow","line","thinline","shortline","body","chevron","footprint","clawprint","pawprint","dogo","nogo") // These turn to face the same way as the drawer
var/static/list/randoms = list(RANDOM_ANY, RANDOM_RUNE, RANDOM_ORIENTED,
RANDOM_NUMBER, RANDOM_GRAFFITI, RANDOM_LETTER, RANDOM_SYMBOL, RANDOM_PUNCTUATION, RANDOM_DRAWING)
- var/static/list/graffiti_large_h = list("yiffhell", "secborg", "paint")
- var/static/list/all_drawables = graffiti + symbols + drawings + oriented + runes + graffiti_large_h
+ var/static/list/all_drawables = graffiti + code + symbols + drawings + oriented
var/paint_mode = PAINT_NORMAL
@@ -176,15 +175,15 @@
. = list()
- var/list/g_items = list()
+ var/list/g_items = list() //i hate tgcode
. += list(list("name" = "Graffiti", "items" = g_items))
for(var/g in graffiti)
g_items += list(list("item" = g))
- var/list/glh_items = list()
- . += list(list("name" = "Graffiti Large Horizontal", "items" = glh_items))
- for(var/glh in graffiti_large_h)
- glh_items += list(list("item" = glh))
+ var/list/c_items = list()
+ . += list(list("name" = "Code", "items" = c_items))
+ for(var/c in code)
+ c_items += list(list("item" = c))
var/list/S_items = list()
. += list(list("name" = "Symbols", "items" = S_items))
@@ -201,11 +200,6 @@
for(var/O in oriented)
O_items += list(list("item" = O))
- var/list/R_items = list()
- . += list(list(name = "Runes", "items" = R_items))
- for(var/R in runes)
- R_items += list(list("item" = R))
-
var/list/rand_items = list()
. += list(list(name = "Random", "items" = rand_items))
for(var/i in randoms)
@@ -245,9 +239,6 @@
drawtype = stencil
. = TRUE
text_buffer = ""
- if(stencil in graffiti_large_h)
- paint_mode = PAINT_LARGE_HORIZONTAL
- text_buffer = ""
else
paint_mode = PAINT_NORMAL
if("select_colour")
@@ -281,8 +272,6 @@
var/istagger = HAS_TRAIT(user, TRAIT_TAGGER)
var/cost = 1
- if(paint_mode == PAINT_LARGE_HORIZONTAL)
- cost = 5
if(istype(target, /obj/item/canvas))
cost = 0
if(ishuman(user))
@@ -311,8 +300,6 @@
drawing = pick(drawings)
if(RANDOM_GRAFFITI)
drawing = pick(graffiti)
- if(RANDOM_RUNE)
- drawing = pick(runes)
if(RANDOM_ORIENTED)
drawing = pick(oriented)
if(RANDOM_NUMBER)
diff --git a/code/game/objects/items/decal_painter.dm b/code/game/objects/items/decal_painter.dm
index e6043d584a84..7b12190ba581 100644
--- a/code/game/objects/items/decal_painter.dm
+++ b/code/game/objects/items/decal_painter.dm
@@ -201,9 +201,9 @@
to_chat(user, "\The [src] can only be used on flooring.")
return
if(color_disallowed.Find(decal_state))
- F.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', decal_state, decal_dir, FALSE, color, null, null, alpha)
+ F.AddElement(/datum/element/decal, 'icons/turf/decals/decals.dmi', decal_state, decal_dir, FALSE, color, null, null, alpha)
else
- F.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', decal_state, decal_dir, FALSE, decal_color, null, null, alpha)
+ F.AddElement(/datum/element/decal, 'icons/turf/decals/decals.dmi', decal_state, decal_dir, FALSE, decal_color, null, null, alpha)
playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE)
/obj/item/decal_painter/attack_self(mob/user)
@@ -215,7 +215,7 @@
/obj/item/decal_painter/interact(mob/user as mob) //TODO: Make TGUI for this because ouch
if(!decal_icon)
- decal_icon = icon('icons/turf/decals.dmi', decal_state, decal_dir)
+ decal_icon = icon('icons/turf/decals/decals.dmi', decal_state, decal_dir)
user << browse_rsc(decal_icon, "floor.png")
var/dat = {"
@@ -288,7 +288,7 @@
decal_color = chosen_colour
- decal_icon = icon('icons/turf/decals.dmi', decal_state, decal_dir)
+ decal_icon = icon('icons/turf/decals/decals.dmi', decal_state, decal_dir)
if(usr)
attack_self(usr)
diff --git a/code/game/objects/items/desk_flags.dm b/code/game/objects/items/desk_flags.dm
index 3e7c299fc3bd..c1af9cfe6c3f 100644
--- a/code/game/objects/items/desk_flags.dm
+++ b/code/game/objects/items/desk_flags.dm
@@ -1,6 +1,6 @@
/obj/item/desk_flag
name = "blank desk flag"
- desc = "Show your patriotism with WaffleCo. brand desk flags!"
+ desc = "Show your patriotism with desk flags!"
icon = 'icons/obj/deskflags.dmi'
icon_state = "flag"
force = 3
@@ -30,3 +30,8 @@
name = "gezenan desk flag"
desc = "A small banner on a pole depicting the sigil of the Pan-Gezenan Federation."
icon_state = "gezena"
+
+/obj/item/desk_flag/suns
+ name = "SUNS desk flag"
+ desc = "A little desk decoration in the gold and purple color palette of SUNS."
+ icon_state = "suns"
diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm
index 37613679e628..c8a918732a9d 100644
--- a/code/game/objects/items/devices/PDA/PDA_types.dm
+++ b/code/game/objects/items/devices/PDA/PDA_types.dm
@@ -239,3 +239,8 @@
name = "brig physician PDA"
default_cartridge = /obj/item/cartridge/medical
icon_state = "pda-brig_phys"
+
+/obj/item/pda/suns
+ name = "SUNS PDA"
+ default_cartridge = /obj/item/cartridge/medical
+ icon_state = "pda-suns"
diff --git a/code/game/objects/items/devices/mines.dm b/code/game/objects/items/devices/mines.dm
new file mode 100644
index 000000000000..1772cbf497c3
--- /dev/null
+++ b/code/game/objects/items/devices/mines.dm
@@ -0,0 +1,709 @@
+
+/obj/item/mine
+ name = "mine"
+ desc = "An anti-personnel mine. This one explodes into nothing and does nothing. Why can you see this? You should't be able to see this. Stop looking at this."
+ icon = 'icons/obj/landmine.dmi'
+ w_class = WEIGHT_CLASS_SMALL
+ throw_speed = 3
+ throw_range = 5
+ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
+ icon_state = "mine"
+ item_state = "assembly"//when we get custom sprites replace this. please
+ base_icon_state = "mine"
+
+ /// Is our mine live?
+ var/armed = FALSE
+ /// Is our mine currently exploding?
+ var/triggered = FALSE
+
+ /// Sets a delay for mines going live after being planted
+ var/arm_delay = 5 SECONDS
+ /// Use to set a delay after activation to trigger the explosion.
+ var/blast_delay = 1 DECISECONDS
+
+ var/manufacturer = MANUFACTURER_NONE
+
+
+/obj/item/mine/Initialize(mapload)
+ . = ..()
+ if(armed)
+ now_armed()
+
+
+/obj/item/mine/examine(mob/user)
+ . = ..()
+ if(!armed)
+ . += span_info("It appears to be inactive...")
+ else
+ . += span_info("It looks ready to explode.")
+
+ if(manufacturer)
+ . += span_notice("It has [manufacturer] engraved on it.")
+
+/obj/item/mine/update_icon_state()
+ . = ..()
+ icon_state = "[base_icon_state][triggered ? "_exploding" : null][!armed && anchored ? "_arming" : null][armed && anchored && !triggered ? "_armed" : null]"
+
+//mines have a small chance to be triggered by damage, but they take longer to explode
+/obj/item/mine/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir)
+ . = ..()
+ if(prob(35) & obj_integrity > 0)
+ blast_delay = blast_delay * 2
+ trigger_mine()
+
+//insert your horrible fate here
+/obj/item/mine/proc/mine_effect(mob/victim)
+ return
+
+//handles controlled deactivation
+/obj/item/mine/proc/disarm()
+ if(triggered) //no turning back now
+ return
+ anchored = FALSE
+ armed = FALSE
+ update_appearance(UPDATE_ICON_STATE)
+ return
+
+//using an unarmed mine inhand deploys it.
+/obj/item/mine/attack_self(mob/user)
+ if(!armed)
+ user.visible_message(span_danger("[user] deploys the [src]."), span_notice("You deploy the [src]."))
+
+ user.dropItemToGround(src)
+ anchored = TRUE
+ playsound(src, 'sound/machines/click.ogg', 60, TRUE)
+
+ if(arm_delay)
+ armed = FALSE
+ update_appearance(UPDATE_ICON_STATE)
+ addtimer(CALLBACK(src, PROC_REF(now_armed)), arm_delay)
+ else
+ armed = TRUE
+ message_admins("[key_name(user)] has placed \a [src] at ([x],[y],[z]).")
+
+//let them know the mine's done cooking
+/obj/item/mine/proc/now_armed()
+ armed = TRUE
+ update_appearance(UPDATE_ICON_STATE)
+ playsound(src, 'sound/machines/nuke/angry_beep.ogg', 55, FALSE, 1)
+ visible_message("\The [src] beeps softly, indicating it is now active.", vision_distance = COMBAT_MESSAGE_RANGE)
+
+/// Can this mine trigger on the passed movable?
+/obj/item/mine/proc/can_trigger(atom/movable/on_who)
+ //var/badtype = typecacheof(list(/obj/effect, /obj/item/mine))
+ if(triggered || !isturf(loc) || !armed || iseffect(on_who) || istype(on_who, /obj/item/mine))
+ return FALSE
+ //if(on_who == badtype)//no recursive self triggering. Bad landmine
+ // return FALSE
+ return TRUE
+
+/// When something sets off a mine
+/obj/item/mine/proc/trigger_mine(atom/movable/triggerer)
+ if(obj_integrity <= 0)
+ return
+ if(triggered) //too busy detonating to detonate again
+ return
+ if(triggerer)
+ triggerer.visible_message(span_danger("[icon2html(src, viewers(src))] [triggerer] sets off \the [src]. It's gonna blow!"), span_danger("[icon2html(src, viewers(src))] \The [src] activates."))
+ else
+ visible_message(span_danger("[icon2html(src, viewers(src))] \the [src] begins to flash bright red!"))
+ triggered = TRUE
+ update_appearance(UPDATE_ICON_STATE)
+ if(blast_delay >= 5 DECISECONDS)
+ playsound(src, 'sound/items/mine_activate.ogg', 70, FALSE)
+ else
+ playsound(src, 'sound/items/mine_activate_short.ogg', 80, FALSE)
+ light_color = "#FF0000"
+ light_power = 5
+ light_range = 3
+ if(!blast_delay)//addtimer gets mad if the delay is 0
+ blast_now(triggerer)
+ else
+ addtimer(CALLBACK(src, PROC_REF(blast_now), triggerer), blast_delay)
+
+//NOW we actually blow up
+/obj/item/mine/proc/blast_now(atom/movable/triggerer)
+ var/datum/effect_system/spark_spread/sporks = new /datum/effect_system/spark_spread
+ sporks.set_up(3, 1, src)
+ sporks.start()
+ if(ismob(triggerer))
+ mine_effect(triggerer)
+ else
+ mine_effect()
+ visible_message(span_danger("[icon2html(src, viewers(src))] \the [src] detonates!"))
+ SEND_SIGNAL(src, COMSIG_MINE_TRIGGERED, triggerer)
+ if(triggered)//setting triggered to false in mine_effect() creates a reusable mine
+ qdel(src)
+
+//trying to pick up a live mine is probably up there when it comes to terrible ideas
+/obj/item/mine/attack_hand(mob/user)
+ if(armed)
+ user.visible_message(span_warning("[user] extends their hand towards \the [src]!"), span_userdanger("You extend your arms to pick up \the [src], knowing that it will likely blow up when you touch it!"))
+ if(do_after(user, 5 SECONDS, target = src))//SO SO generous. You can still step back from the edge.
+ if(prob(10))
+ user.visible_message(span_notice("[user] picks up \the [src], which miraculously doesn't explode!"), span_notice("You pick up \the [src], which miraculously doesn't explode!"))
+ disarm()
+ else
+ user.visible_message(span_danger("[user] attempts to pick up \the [src] only to hear a beep as it activates in their hand!"), span_danger("You attempt to pick up \the [src] only to hear a beep as it activates in your hands!"))
+ anchored = FALSE
+ trigger_mine(user)
+ return . =..()
+ else
+ user.visible_message(span_notice("[user] withdraws their hand from \the [src]."), span_notice("You decide against picking up \the [src]."))
+ . =..()
+
+//just don't.
+/obj/item/mine/attackby(obj/item/I, mob/user)
+ if(!armed)
+ to_chat(user, span_notice("You smack \the [src] with [I]. Thankfully, nothing happens."))
+ return
+ else//please stop hitting the live mine with a rock
+ if(user.a_intent != INTENT_HARM)//are you SURE you want to hit the live mine with a rock
+ user.visible_message(user, span_notice("[user] gently pokes \the [src] with [I]. Nothing seems to happen."), span_notice("You gently prod \the [src] with [I]. Thankfully, nothing happens."))
+ else//at this point it's just natural selection
+ user.visible_message(span_danger("[user] hits \the [src] with [I], activating it!"), span_userdanger("[icon2html(src, viewers(src))]You hit \the [src] with [I]. The light goes red."))
+ trigger_mine(user)
+
+//
+//PRESSURE BASED MINE:
+//Mine that explodes when stepped on.
+/obj/item/mine/pressure
+ name = "dummy landmine"
+ /// When true, mines trigger instantly on being stepped upon
+ var/hair_trigger = FALSE
+ /// Has the mine loc been entered?
+ var/clicked = FALSE
+ /// Prevents a mine from being screwdrivable (e.g. cannot be disarmed)
+ var/sealed = FALSE
+ /// Disables the mine without disarming it. perfect for practical jokes
+ var/dud = FALSE
+
+ /// Are the wires exposed?
+ var/open_panel = FALSE
+
+ /// Who's got their foot on the mine's pressure plate
+ /// Stepping on the mine will set this to the first mob who stepped over it
+ /// The mine will not detonate via movement unless the first mob steps off of it
+ var/datum/weakref/foot_on_mine
+
+/obj/item/mine/pressure/Initialize()
+ . = ..()
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ COMSIG_ATOM_EXITED = PROC_REF(on_exited),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+ wires = new /datum/wires/mine(src)
+
+/obj/item/mine/pressure/examine(mob/user)
+ . = ..()
+ if(hair_trigger)
+ . += span_danger("It's been rigged to detonate as soon as someone steps on it.")
+ else
+ var/atom/movable/unlucky_sod = foot_on_mine?.resolve()
+ if(user == unlucky_sod)
+ . += span_bolddanger("The pressure plate is depressed. Any movement you make will set it off now.")
+ else if(!isnull(unlucky_sod))
+ . += span_danger("The pressure plate is depressed by [unlucky_sod]. Any move they make'll set it off now.")
+
+//step 1: the mistake
+/obj/item/mine/pressure/proc/on_entered(datum/source, atom/movable/arrived)
+ SIGNAL_HANDLER
+ if(!can_trigger(arrived))
+ return
+ // All other movment types rn can easily avoid it
+ if(!(arrived.movement_type == GROUND))
+ return
+ // Someone already on it
+ if(foot_on_mine?.resolve())
+ return
+
+ if(dud == FALSE)//we don't actually need this if the mine's been disabled
+ foot_on_mine = WEAKREF(arrived)
+
+ if(ismob(arrived))
+ var/mob/living/fool = arrived
+ fool.do_alert_animation(fool)
+ if(!hair_trigger)
+ fool.Immobilize(25 DECISECONDS, TRUE)
+ to_chat(fool, span_userdanger("You step on \the [src] and freeze."))
+ visible_message(span_danger("[icon2html(src, viewers(src))] *click*"))
+ if(dud == FALSE)//see wirecutting
+ clicked = TRUE
+ if(hair_trigger)
+ trigger_mine(arrived)
+ playsound(src, 'sound/machines/click.ogg', 100, TRUE)
+
+//step 2: the consequences
+/obj/item/mine/pressure/proc/on_exited(datum/source, atom/movable/gone)
+ SIGNAL_HANDLER
+ if(hair_trigger)
+ return
+ if(!clicked)
+ return
+ if(!can_trigger(gone))
+ return
+ // Check that the guy who's on it is stepping off
+ if(foot_on_mine && !IS_WEAKREF_OF(gone, foot_on_mine))
+ return
+ INVOKE_ASYNC(src, PROC_REF(trigger_mine), gone)
+ foot_on_mine = null
+
+/obj/item/mine/pressure/disarm()
+ clicked = FALSE
+ . = ..()
+
+/obj/item/mine/pressure/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
+ trigger_mine(AM)
+ ..()
+
+//handles disarming(and failing to disarm)
+/obj/item/mine/pressure/attackby(obj/item/I, mob/user)
+ if(I.tool_behaviour == TOOL_SCREWDRIVER)
+ if(sealed)
+ to_chat(user, "You can't see any way to access \the [src]'s wiring.")
+ return
+ open_panel = !open_panel
+ update_appearance(UPDATE_ICON_STATE)
+ to_chat(user, "You [open_panel ? "reveal" : "hide"] \the [src]'s wiring.")
+ I.play_tool_sound(src, 50)
+ return
+ else if(is_wire_tool(I) && open_panel)
+ wires.interact(user)
+ return
+ else
+ . = ..()
+
+//
+//PROXIMITY MINES
+//Mines that explode when someone moves nearby. Simpler, because I don't have to worry about saving step info or disarming logic
+//
+
+/obj/item/mine/proximity
+ name = "dummy proximity mine"
+ blast_delay = 15 DECISECONDS
+ arm_delay = 10 SECONDS//clear the area
+ ///needed for the proximity checks.
+ var/datum/proximity_monitor/proximity_monitor
+ var/proximity_range = 2
+
+/obj/item/mine/proximity/Initialize(mapload)
+ . = ..()
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/item/mine/proximity/examine(mob/user)
+ . = ..()
+ if(armed)
+ . += span_danger("It's been rigged to detonate as soon as someone moves nearby...")
+ else
+ . += span_notice("When armed, it activates based on the proximity of living targets.")
+
+/obj/item/mine/proximity/now_armed()
+ . = ..()
+ proximity_monitor = new(src, proximity_range)
+ light_color = "#FF0000"
+ light_power = 1
+ light_range = 1
+
+/obj/item/mine/proximity/disarm()
+ . = ..()
+ QDEL_NULL(proximity_monitor)
+
+/obj/item/mine/proximity/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ QDEL_NULL(proximity_monitor)
+ . = ..()
+
+/obj/item/mine/proximity/HasProximity(atom/movable/triggerer)
+ if(!iscarbon(triggerer))//let's keep these on player movements for now.
+ return
+ if(!can_trigger(triggerer))
+ return
+ var/mob/living/clueless = triggerer
+ clueless.do_alert_animation(clueless)
+ trigger_mine(triggerer)
+ QDEL_NULL(proximity_monitor)
+ return
+
+//
+//LANDMINE TYPES
+//Rylie please help me make these more immersive
+//
+
+/obj/item/mine/pressure/explosive
+ name = "\improper G-80 Landmine"
+ desc = "An anti-infantry explosive produced during the corporate wars. Watch your step."
+
+ //customize explosive power
+ var/range_devastation = 0
+ var/range_heavy = 1
+ var/range_light = 5
+ var/range_flame = 1
+
+ //using this to indicate pb
+ var/range_flash = 1
+
+ //customize shrapnel. Magnitude zero prevents them from spawning
+ var/shrapnel_type = /obj/projectile/bullet/shrapnel
+ var/shrapnel_magnitude = 3
+
+ /// If TRUE, we spawn extra pellets to eviscerate a person still sitting on it, otherwise it just spawns a ring of pellets around the tile we're on (making setting it off an offensive move)
+ var/shred_triggerer = TRUE
+
+ manufacturer = MANUFACTURER_SCARBOROUGH
+
+/obj/item/mine/pressure/explosive/mine_effect(mob/victim)
+ explosion(loc, range_devastation, range_heavy, range_light, range_flash, 1, 0, range_flame, 0, 1)
+ if(shrapnel_magnitude > 0)
+ AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_magnitude)
+
+
+/obj/item/mine/pressure/explosive/rusty
+ name = "\improper Rusted Landmine"
+ desc = "An anti-infantry explosive, designed to go off underfoot. This one has seen better days."
+ manufacturer = MANUFACTURER_NONE
+ range_heavy = 0
+ range_light = 3
+ shrapnel_type = /obj/projectile/bullet/shrapnel/rusty
+
+
+/obj/item/mine/pressure/explosive/fire
+ name = "\improper G-82 Incindeary"
+ desc = "An anti-infantry explosive produced during the corporate wars. Transforms into superheated slag and a ball of fire on detonation. "
+
+ range_flame = 6
+ range_light = 3
+ range_flash = 3
+
+ shrapnel_type = /obj/projectile/bullet/shrapnel/hot
+ shrapnel_magnitude = 4
+
+/obj/item/mine/pressure/explosive/fire/mine_effect(mob/victim)
+ if(victim.is_holding(src))//in case it's been picked up
+ for(var/turf/T in view(4,victim))
+ T.IgniteTurf(15)
+ new /obj/effect/hotspot(T)
+ else
+ for(var/turf/T in view(4,src))
+ T.IgniteTurf(15)
+ new /obj/effect/hotspot(T)
+ . = ..()
+
+
+/obj/item/mine/pressure/explosive/heavy
+ name = "\improper G-81 Anti-Tank Mine"
+ desc = "An immense anti-vehicle explosive built during the corporate wars. Someone has recklessly switched out the detonator for one that activates for lighter targets."
+ w_class = WEIGHT_CLASS_BULKY
+ range_heavy = 6
+ range_light = 9
+ shrapnel_magnitude = 7
+ shrapnel_type = /obj/projectile/bullet/shrapnel/mega
+ blast_delay = 50//run.
+ sealed = TRUE//unless we specifically give it to people disarmed, we probably don't want them stealing this
+
+
+/obj/item/mine/pressure/explosive/shrapnel
+ name = "\improper G-84 Fragmentation"
+ desc = "An anti-infantry explosive built during the corporate wars. Metal banding inside creates additional deadly shrapnel on detonation. "
+
+ range_heavy = 1
+ range_light = 4
+
+ shrapnel_magnitude = 6
+ shred_triggerer = TRUE
+
+/obj/item/mine/pressure/explosive/rad
+ name = "\improper G-85 Fission"
+ desc = "An anti-infantry explosive produced during the corporate wars. This one detonates a small microfission core, creating a bloom of deadly radiation. "
+ range_light = 4
+ range_flame = 2
+ shrapnel_magnitude = 7
+ shrapnel_type = /obj/projectile/bullet/shrapnel/spicy
+ var/radpower = 750
+
+/obj/item/mine/pressure/explosive/rad/mine_effect(mob/victim)
+ radiation_pulse(src, radpower, 1)
+ . = ..()
+
+//put this on military ships for disarming practice
+/obj/item/mine/pressure/training
+ name = "\improper G-MTH Defusal Trainer"
+ desc = "A mothballed anti-personnel explosive, equipped with VISCERAL DEFUSAL ACTION for training purposes. Though Scarborough was forced to decomission their stockpiles of mines as part of the ceasefire, the deployed minefields remain."
+ arm_delay = 2 SECONDS
+ manufacturer = MANUFACTURER_SCARBOROUGH
+
+/obj/item/mine/pressure/training/mine_effect(mob/living/victim)
+ src.say("BOOM! Better luck next time!")
+ src.visible_message(span_notice("The mine resets itself for another disarming attempt."))
+ triggered = FALSE
+ disarm()
+ . = ..()
+
+/obj/item/mine/pressure/gas
+ name = "chilled vapor mine"
+ desc = "A non-lethal security deterrent."
+ var/gas_amount = 500
+ var/gas_type = "water_vapor"
+ hair_trigger = TRUE
+
+/obj/item/mine/pressure/gas/mine_effect(mob/victim)
+ atmos_spawn_air("[gas_type]=[gas_amount]")
+
+
+/obj/item/mine/proximity/explosive
+ name = "\improper G-80P Bouncer"
+ desc = "An anti-infantry explosive produced during the corporate wars. This one has been rearmed with a proximity movement detector."
+
+ var/range_devastation = 0
+ var/range_heavy = 2
+ var/range_light = 4
+ var/range_flame = 1
+
+ var/range_flash = 1
+
+ var/shrapnel_type = /obj/projectile/bullet/shrapnel
+ var/shrapnel_magnitude = 5
+
+ manufacturer = MANUFACTURER_SCARBOROUGH
+
+/obj/item/mine/proximity/explosive/mine_effect(mob/victim)
+ explosion(loc, range_devastation, range_heavy, range_light, range_flash, 1, 0, range_flame, 0, 1)
+ if(shrapnel_magnitude > 0)
+ AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_magnitude)
+
+
+//like all real 'less' than lethal crowd control options this is, in fact, not very good at being nonlethal
+/obj/item/mine/proximity/explosive/sting
+ name = "\improper'Stinger' Crowd Management Device"
+ desc = "A \"less\" than lethal crowd control weapon, designed to demoralise and scatter anti-NT protestors. The bands of ballistic gel inside strike targets and incapacitate without causing serious maiming. In Theory."
+
+ range_heavy = 0
+ range_light = 1
+ range_flash = 3
+ range_flame = 0
+
+ shrapnel_magnitude = 8
+ shrapnel_type = /obj/projectile/bullet/pellet/stingball
+ manufacturer = MANUFACTURER_NANOTRASEN_OLD
+
+
+/obj/item/mine/proximity/explosive/plasma
+ name = "\improper Etherbor EP-3"
+ desc = "An anti-infantry explosive designed by the PGF for denial of territory to enemy forces. Radiates high energy plasma to eradicate nearby targets."
+ range_light = 2
+ range_flame = 3
+ range_heavy = 0
+ shrapnel_magnitude = 8
+ shrapnel_type = /obj/projectile/energy/plasmabolt
+ manufacturer = MANUFACTURER_PGF
+
+/obj/item/mine/proximity/explosive/plasma/mine_effect(mob/victim)
+ if(victim.is_holding(src))//in case it's been picked up
+ for(var/turf/T in view(3,victim))
+ T.IgniteTurf(25, "green")
+ else
+ for(var/turf/T in view(3,src))
+ T.IgniteTurf(25, "green")
+ . = ..()
+
+//Manhacks... so pretty...
+/obj/item/mine/proximity/spawner
+ name = "debug spawner mine"
+ desc = "Real no Virus. 100% free. Coders hate him!"
+ var/spawn_type = null //manhacks go here :)
+ var/spawn_number = 5
+
+/obj/item/mine/proximity/spawner/mine_effect(mob/victim)
+ if(isturf(loc))
+ var/turf/T = get_turf(src)
+ playsound(T, 'sound/effects/phasein.ogg', 100, TRUE)
+ spawn_and_random_walk(spawn_type, T, spawn_number, walk_chance=50, admin_spawn=((flags_1 & ADMIN_SPAWNED_1) ? TRUE : FALSE))
+ . = ..()
+
+/obj/item/mine/proximity/spawner/manhack
+ name = "\improper P-83 Lacerator"
+ desc = "An anti-infantry device produced during the corporate wars. The explosive payload has been swapped out for 'viscerator'-type antipersonnel drones."
+ spawn_type = /mob/living/simple_animal/hostile/viscerator
+
+//
+//GIMMICK MINES//
+//pretty much exclusively for adminbus & code dependencies
+//
+
+/obj/item/mine/pressure/kickmine
+ name = "\improper A-00 'Adminbus'"
+ desc = "An Anti-Griefer proximity expulsive. Delivers Justice."
+ blast_delay = null//funnier this way
+ hair_trigger = TRUE
+
+/obj/item/mine/pressure/kickmine/mine_effect(mob/victim)
+ if(isliving(victim) && victim.client && Adjacent(victim))
+ to_chat(victim, span_userdanger("You have been kicked from the game. Take this time to think about what you've done."))
+ qdel(victim.client)
+
+/obj/item/mine/pressure/sound
+ name = "sonic mine"
+ desc = "A potent tool of psychological warfare."
+ var/sound = 'sound/effects/adminhelp.ogg'
+ blast_delay = null
+ hair_trigger = TRUE
+
+/obj/item/mine/pressure/sound/mine_effect(mob/victim)
+ playsound(loc, sound, 100, TRUE)
+
+/obj/item/mine/pressure/pickup
+ name = "pickup mine"
+ desc = "does nothing"
+ icon = 'icons/obj/marg.dmi'
+ icon_state = "marg"
+ density = FALSE
+ var/duration = 0
+ pixel_x = -8
+ pixel_y = 1
+ anchored = TRUE
+ armed = TRUE
+ blast_delay = null
+ hair_trigger = TRUE
+
+/obj/item/mine/pressure/pickup/Initialize()
+ . = ..()
+ animate(src, time = 20, loop = -1)
+
+/obj/item/mine/pressure/pickup/trigger_mine(mob/victim)
+ if(triggered)
+ return
+ triggered = TRUE
+ invisibility = INVISIBILITY_ABSTRACT
+ mine_effect(victim)
+ qdel(src)
+
+
+/obj/item/mine/pressure/pickup/bloodbath
+ name = "bloody orb"
+ desc = "Embrace righteous fury."
+ duration = 1200 //2min
+ color = "#FF0000"
+ var/mob/living/doomslayer
+ var/obj/item/chainsaw/doomslayer/chainsaw
+
+/obj/item/mine/pressure/pickup/bloodbath/mine_effect(mob/living/carbon/victim)
+ if(!victim.client || !istype(victim))
+ return
+ to_chat(victim, "RIP AND TEAR")
+
+ INVOKE_ASYNC(src, PROC_REF(blood_delusion), victim)
+
+ chainsaw = new(victim.loc)
+ victim.log_message("entered a marg frenzy", LOG_ATTACK)
+
+ ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
+ victim.drop_all_held_items()
+ victim.put_in_hands(chainsaw, forced = TRUE)
+ chainsaw.attack_self(victim)
+ victim.reagents.add_reagent(/datum/reagent/medicine/adminordrazine,25)
+ to_chat(victim, "KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!")
+
+ var/datum/client_colour/colour = victim.add_client_colour(/datum/client_colour/bloodlust)
+ QDEL_IN(colour, 11)
+ doomslayer = victim
+ RegisterSignal(src, COMSIG_PARENT_QDELETING, PROC_REF(end_blood_frenzy))
+ QDEL_IN(WEAKREF(src), duration)
+
+/obj/item/mine/pressure/pickup/bloodbath/proc/end_blood_frenzy()
+ if(doomslayer)
+ to_chat(doomslayer, "Your bloodlust seeps back into the bog of your subconscious and you regain self control.")
+ doomslayer.log_message("exited a blood frenzy", LOG_ATTACK)
+ if(chainsaw)
+ qdel(chainsaw)
+
+/obj/item/mine/pressure/pickup/bloodbath/proc/blood_delusion(mob/living/carbon/victim)
+ new /datum/hallucination/delusion(victim, TRUE, "demon", duration, 0)
+
+/obj/item/mine/pressure/pickup/healing
+ name = "healing orb"
+ desc = "Your wounds shall be undone."
+
+/obj/item/mine/pressure/pickup/healing/mine_effect(mob/living/carbon/victim)
+ if(!victim.client || !istype(victim))
+ return
+ to_chat(victim, "You feel great!")
+ victim.revive(full_heal = TRUE, admin_revive = TRUE)
+
+/obj/item/mine/pressure/pickup/speed
+ name = "quick orb"
+ desc = "Quickens you."
+ duration = 300
+
+/obj/item/mine/pressure/pickup/speed/mine_effect(mob/living/carbon/victim)
+ if(!victim.client || !istype(victim))
+ return
+ to_chat(victim, "You feel fast!")
+ victim.add_movespeed_modifier(/datum/movespeed_modifier/yellow_orb)
+ addtimer(CALLBACK(src, PROC_REF(finish_effect), victim), duration)
+
+/obj/item/mine/pressure/pickup/speed/proc/finish_effect(mob/living/carbon/victim)
+ victim.remove_movespeed_modifier(/datum/movespeed_modifier/yellow_orb)
+ to_chat(victim, "You slow down.")
+
+
+
+//
+//mapping tool that generates "live" variants of all mine subtypes, which are anchored and ready to blow.
+//Add new mine variants you make below as a LIVE_MINE_HELPER define containing their subtyping.
+//
+
+#define LIVE_MINE_HELPER(mine_type) \
+ /obj/item/mine/##mine_type/live { \
+ anchored = TRUE; \
+ armed = TRUE; \
+ }
+
+LIVE_MINE_HELPER(pressure/explosive)
+LIVE_MINE_HELPER(pressure/explosive/fire)
+LIVE_MINE_HELPER(pressure/explosive/rusty)
+LIVE_MINE_HELPER(pressure/explosive/rad)
+LIVE_MINE_HELPER(pressure/explosive/heavy)
+LIVE_MINE_HELPER(pressure/explosive/shrapnel)
+
+LIVE_MINE_HELPER(proximity/explosive)
+LIVE_MINE_HELPER(proximity/explosive/sting)
+LIVE_MINE_HELPER(proximity/spawner/manhack)
+LIVE_MINE_HELPER(proximity/explosive/plasma)
+
+LIVE_MINE_HELPER(pressure/gas)
+LIVE_MINE_HELPER(pressure/kickmine)
+LIVE_MINE_HELPER(pressure/sound)
+
+//
+// spawners (random mines, minefields, non-guaranteed mine)
+//
+
+/obj/effect/spawner/lootdrop/mine
+ name = "live mine spawner (random)"
+ lootcount = 1
+ fan_out_items = TRUE
+ loot = list(
+ /obj/item/mine/pressure/explosive/live = 10,
+ /obj/item/mine/pressure/explosive/shrapnel/live = 3,
+ /obj/item/mine/pressure/explosive/rad/live = 3,
+ /obj/item/mine/pressure/explosive/fire/live = 3)
+
+/obj/effect/spawner/minefield
+ name = "minefield spawner"
+ var/minerange = 9
+ var/minetype = /obj/item/mine/pressure/explosive/rusty/live
+
+/obj/effect/spawner/minefield/Initialize(mapload)
+ . = ..()
+ for(var/turf/open/T in view(minerange,loc))
+ if(prob(5))
+ new minetype(T)
+
+/obj/effect/spawner/minefield/random
+ name = "random minefield spawner"
+ minetype = /obj/effect/spawner/lootdrop/mine
+
+/obj/effect/spawner/minefield/manhack
+ name = "manhack field spawner"
+ minetype = /obj/item/mine/proximity/spawner/manhack/live
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index dca088c1be2e..204371ca0e51 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -28,7 +28,7 @@
custom_materials = list(/datum/material/iron=50, /datum/material/glass=20)
custom_premium_price = 450
toolspeed = 1
- usesound = 'sound/weapons/empty.ogg'
+ usesound = SOUND_EMPTY_MAG
var/obj/machinery/buffer // simple machine buffer for device linkage
var/mode = 0
diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm
index bf08b704beb0..61486cf07bf2 100644
--- a/code/game/objects/items/devices/paicard.dm
+++ b/code/game/objects/items/devices/paicard.dm
@@ -85,7 +85,7 @@
pai.master_dna = M.dna.unique_enzymes
to_chat(pai, "You have been bound to a new master.")
pai.laws.set_zeroth_law("Serve your master.")
- pai.emittersemicd = FALSE
+ pai.emittercurrent_cooldown = FALSE
if(href_list["wipe"])
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
if(confirm == "Yes")
diff --git a/code/game/objects/items/devices/portable_chem_mixer.dm b/code/game/objects/items/devices/portable_chem_mixer.dm
index fa777fec1124..1964e2dbd04a 100644
--- a/code/game/objects/items/devices/portable_chem_mixer.dm
+++ b/code/game/objects/items/devices/portable_chem_mixer.dm
@@ -1,7 +1,7 @@
/obj/item/storage/portable_chem_mixer
name = "Portable Chemical Mixer"
desc = "A portable device that dispenses and mixes chemicals. Can be upgraded to hold more beakers by inserting a vortex anomaly core. All necessary reagents need to be supplied with beakers. A label indicates that a screwdriver is required to open it for refills. This device can be worn on a belt. The letters 'S&T' are imprinted on the side."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "portablechemicalmixer_open"
w_class = WEIGHT_CLASS_HUGE
slot_flags = ITEM_SLOT_BELT
diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm
index 3a6ba2f73950..5b69cab9cc7b 100644
--- a/code/game/objects/items/devices/powersink.dm
+++ b/code/game/objects/items/devices/powersink.dm
@@ -10,6 +10,7 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_BULKY
flags_1 = CONDUCT_1
+ item_flags = NO_PIXEL_RANDOM_DROP
throwforce = 5
throw_speed = 1
throw_range = 2
diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm
index 73cae6b853bc..f8ced22c54be 100644
--- a/code/game/objects/items/devices/radio/encryptionkey.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey.dm
@@ -88,6 +88,11 @@
icon_state = "solgov_cypherkey"
channels = list(RADIO_CHANNEL_SOLGOV = 1)
+// /obj/item/encryptionkey/suns
+// name = "\improper SUNS encryption key"
+// icon_state = "suns_cypherkey"
+// channels = list(RADIO_CHANNEL_SUNS = 1)
+
/obj/item/encryptionkey/wideband
name = "wideband encryption key"
icon = 'icons/obj/radio.dmi'
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index e44cf557b9a2..0f0081c90454 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -22,6 +22,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
custom_materials = list(/datum/material/iron=75)
subspace_transmission = TRUE
headset = TRUE
+ listening = TRUE
canhear_range = 0 // can't hear headsets from very far away
slot_flags = ITEM_SLOT_EARS
@@ -117,6 +118,26 @@ GLOBAL_LIST_INIT(channel_tokens, list(
name = "team leader headset"
command = TRUE
+/obj/item/radio/headset/syndicate/suns
+ name = "SUNS headset"
+ icon_state = "suns_headset"
+ desc = "A headset worn by staff and students of SUNS, both in the frontier and elsewhere."
+
+/obj/item/radio/headset/syndicate/suns/command
+ name = "SUNS command headset"
+ desc = "A headset worn by staff and students of SUNS, both in the frontier and elsewhere. This one is worn by command staff."
+ command = TRUE
+
+/obj/item/radio/headset/syndicate/alt/suns
+ name = "SUNS bowman headset"
+ icon_state = "suns_headset_alt"
+ desc = "A headset worn by staff and students of SUNS, both in the frontier and elsewhere. Protects ears from distractions during exams."
+
+/obj/item/radio/headset/syndicate/alt/suns/command
+ name = "SUNS bowman command headset"
+ desc = "A headset worn by staff and students of SUNS, both in the frontier and elsewhere. This one is worn by command staff. Protects ears from distractions during exams."
+ command = TRUE
+
//nanotrasen
/obj/item/radio/headset/nanotrasen
name = "nanotrasen radio headset"
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index 2c7262139b17..944fe7462583 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -4,6 +4,7 @@
icon = 'icons/obj/radio.dmi'
icon_state = "intercom"
anchored = TRUE
+ listening = TRUE
w_class = WEIGHT_CLASS_BULKY
canhear_range = 2
dog_fashion = null
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index dc35bebb1e30..cc528f103fe2 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -27,7 +27,7 @@
var/last_chatter_time // The time since we last played a radio chatter sound. (WS edit - Radio Chatter #434)
var/broadcasting = FALSE // Whether the radio will transmit dialogue it hears nearby.
- var/listening = TRUE // Whether the radio is currently receiving.
+ var/listening = FALSE // Whether the radio is currently receiving.
var/prison_radio = FALSE // If true, the transmit wire starts cut.
var/unscrewed = FALSE // Whether wires are accessible. Toggleable by screwdrivering.
var/freerange = FALSE // If true, the radio has access to the full spectrum.
@@ -436,12 +436,6 @@
recalculateChannels()
-
-/obj/item/radio/off // Station bounced radios, their only difference is spawning with the speakers off, this was made to help the lag.
- listening = 0 // And it's nice to have a subtype too for future features.
- dog_fashion = /datum/dog_fashion/back
-
-
/obj/item/radio/old
name = "old radio"
icon_state = "radio"
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 3f40f82fe0ae..cdded7e418ef 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -357,7 +357,7 @@ GENE SCANNER
if(blood_id)
if(ishuman(C))
var/mob/living/carbon/human/H = C
- if(H.bleed_rate)
+ if(LAZYLEN(H.get_bleeding_parts()))
render_list += "Subject is bleeding!\n"
var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
var/blood_type = C.dna.blood_type.name
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index 34563d5e649c..113a72fb8d8d 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -62,7 +62,7 @@
if(target != user)
target.visible_message("[user] is trying to inject [target] with [src]!", \
"[user] is trying to inject you with [src]!")
- if(!do_mob(user, target) || used)
+ if(!do_after(user, target = target) || used)
return
target.visible_message("[user] injects [target] with the syringe with [src]!", \
"[user] injects you with the syringe with [src]!")
@@ -90,11 +90,6 @@
desc = "This will make you big and strong, but give you a bad skin condition."
add_mutations = list(HULK)
-/obj/item/dnainjector/firebreath
- name = "\improper DNA injector (Fire Breath)"
- desc = "Restores the dragon ancestry."
- add_mutations = list(FIREBREATH)
-
/obj/item/dnainjector/xraymut
name = "\improper DNA injector (X-ray)"
desc = "Finally you can see what the Captain does."
@@ -252,30 +247,6 @@
name = "\improper DNA injector (Anti-Unintelligible)"
remove_mutations = list(UNINTELLIGIBLE)
-/obj/item/dnainjector/swedishmut
- name = "\improper DNA injector (Swedish)"
- add_mutations = list(SWEDISH)
-
-/obj/item/dnainjector/antiswedish
- name = "\improper DNA injector (Anti-Swedish)"
- remove_mutations = list(SWEDISH)
-
-/obj/item/dnainjector/chavmut
- name = "\improper DNA injector (Chav)"
- add_mutations = list(CHAV)
-
-/obj/item/dnainjector/antichav
- name = "\improper DNA injector (Anti-Chav)"
- remove_mutations = list(CHAV)
-
-/obj/item/dnainjector/elvismut
- name = "\improper DNA injector (Elvis)"
- add_mutations = list(ELVIS)
-
-/obj/item/dnainjector/antielvis
- name = "\improper DNA injector (Anti-Elvis)"
- remove_mutations = list(ELVIS)
-
/obj/item/dnainjector/lasereyesmut
name = "\improper DNA injector (Laser Eyes)"
add_mutations = list(LASEREYES)
diff --git a/code/game/objects/items/dyekit.dm b/code/game/objects/items/dyekit.dm
index 2cbfbca6332b..86c6e90a3290 100644
--- a/code/game/objects/items/dyekit.dm
+++ b/code/game/objects/items/dyekit.dm
@@ -38,3 +38,30 @@
return
playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 5)
human_target.update_hair()
+
+/obj/item/colorsalve
+ name = "Elzuose color salve"
+ desc = "A Kalixcian beauty product for Elzuose that comes in the form of a salve packaged with various color additives. Used to temporarily change the pigment color of light emitting cells in the skin, requiring an extensive amount of time to prepare and apply. Wears off after a few hours."
+ icon = 'icons/obj/dyespray.dmi'
+ icon_state = "colorsalve"
+
+/obj/item/colorsalve/attack_self(mob/living/user)
+ if(!iselzuose(user))
+ return
+
+ var/mob/living/carbon/human/H = user
+ var/datum/species/elzuose/species_datum = H.dna.species
+ // select new color
+ var/new_etherealcolor = input(user, "Choose your Elzuose color:", "Character Preference", species_datum.default_color) as color|null
+ if(new_etherealcolor)
+ var/temp_hsv = RGBtoHSV(new_etherealcolor)
+ if(ReadHSV(temp_hsv)[3] >= ReadHSV("#505050")[3]) // elzu colors should be bright ok??
+ if(!do_after(usr, 30 SECONDS, user))
+ return
+ playsound(src, 'sound/effects/ointment.ogg', 5, TRUE, 5)
+ species_datum.default_color = sanitize_hexcolor(new_etherealcolor, 6, TRUE)
+ species_datum.current_color = species_datum.health_adjusted_color(user, species_datum.default_color)
+ species_datum.spec_updatehealth(user)
+ user.visible_message(span_notice("[user] applies the salve, changing [user.p_their()] color to [new_etherealcolor]"))
+ else
+ to_chat(user, span_danger("Invalid color. Your color is not bright enough."))
diff --git a/code/game/objects/items/eightball.dm b/code/game/objects/items/eightball.dm
index 111dd3aa96bc..1396521aaf9a 100644
--- a/code/game/objects/items/eightball.dm
+++ b/code/game/objects/items/eightball.dm
@@ -59,7 +59,7 @@
shaking = TRUE
start_shaking(user)
- if(do_after(user, shake_time, needhand=TRUE, target=user, progress=TRUE))
+ if(do_after(user, shake_time, target=user))
var/answer = get_answer()
say(answer)
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index 6a1e439422a4..813e53111f61 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -183,9 +183,9 @@
update_appearance()
#define REQUIRED_POWER_TO_FIRE_FLAMETHROWER 10
-#define FLAMETHROWER_POWER_MULTIPLIER 0.5
-#define FLAMETHROWER_RANGE 4
-#define FLAMETHROWER_RELEASE_AMOUNT 8
+#define FLAMETHROWER_POWER_MULTIPLIER 0.8
+#define FLAMETHROWER_RANGE 5
+#define FLAMETHROWER_RELEASE_AMOUNT 5
/obj/item/flamethrower/proc/flame_turf(target)
if(!beaker)
diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm
index 0681892fd47e..50da920b06f1 100644
--- a/code/game/objects/items/granters.dm
+++ b/code/game/objects/items/granters.dm
@@ -12,7 +12,7 @@
/obj/item/book/granter/proc/turn_page(mob/user)
playsound(user, pick('sound/effects/pageturn1.ogg','sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg'), 30, TRUE)
- if(do_after(user, 50, TRUE, src))
+ if(do_after(user, 50, src, hidden = TRUE))
if(remarks.len)
to_chat(user, "[pick(remarks)]")
else
@@ -57,7 +57,7 @@
on_reading_stopped()
reading = FALSE
return
- if(do_after(user, 50, TRUE, src))
+ if(do_after(user, 50, src, hidden = TRUE))
on_reading_finished(user)
reading = FALSE
return TRUE
@@ -247,19 +247,6 @@
user.Stun(40, ignore_canstun = TRUE)
user.petrify(30)
-/obj/item/book/granter/spell/cards
- spell = /obj/effect/proc_holder/spell/aimed/spell_cards
- spellname = "spellcards"
- icon_state ="bookspellcards"
- desc = "The ultimate card trick, for users ten and up."
- remarks = list("It's all about the razzmataz.", "...I don't think I'll actually be sawing anyone in half", "These are pretty flimsy, most armor would defeat them.", "They do burn damage? Weird.", "Why the dumb stance? It's just a flick of the hand...", "Are these cards? They feel stiffer then pages.", "Best performed using a top hat...")
-
-/obj/item/book/granter/spell/cards/recoil(mob/living/user)
- ..()
- to_chat(user,"The cards are against you!")
- user.Stun(40, ignore_canstun = TRUE)
- user.petrify(30)
-
/obj/item/book/granter/spell/shapechange
spell = /obj/effect/proc_holder/spell/targeted/shapeshift
spellname = "shapechange"
diff --git a/code/game/objects/items/grenades/discogrenade.dm b/code/game/objects/items/grenades/discogrenade.dm
index be2ec68f0cb1..84ce765d59d3 100644
--- a/code/game/objects/items/grenades/discogrenade.dm
+++ b/code/game/objects/items/grenades/discogrenade.dm
@@ -91,7 +91,7 @@
return
if(target.stat != CONSCIOUS) //Only conscious people can dance
return
- if(!target || isethereal(target)) //Non humans and non etherals can't dance
+ if(!target || iselzuose(target)) //Non humans and non etherals can't dance
return
var/distance = max(0,get_dist(get_turf(src), target_turf))
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index 496fc07288ec..9fece4feedd4 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -57,7 +57,8 @@
"[user] is trying to put [src.name] on you!")
playsound(loc, cuffsound, 30, TRUE, -2)
- if(do_mob(user, C, 30) && C.canBeHandcuffed())
+ log_combat(user, C, "attempted to handcuff")
+ if(do_after(user, 3 SECONDS, C) && C.canBeHandcuffed())
if(iscyborg(user))
apply_cuffs(C, user, TRUE)
else
@@ -272,6 +273,11 @@
update_appearance()
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
+/obj/item/restraints/legcuffs/beartrap/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
+ if(armed)
+ close_trap()
+ ..()
+
/obj/item/restraints/legcuffs/beartrap/proc/on_entered(datum/source, AM as mob|obj)
SIGNAL_HANDLER
if(armed && isturf(loc))
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index cd01cef70503..0affcd107af0 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -1,150 +1,12 @@
// CHAPLAIN CUSTOM ARMORS //
-/obj/item/clothing/head/helmet/chaplain
- name = "crusader helmet"
- desc = "Deus Vult."
- icon_state = "knight_templar"
- item_state = "knight_templar"
- armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
- flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR
- flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
- strip_delay = 80
- dog_fashion = null
-
-/obj/item/clothing/suit/armor/riot/chaplain
- name = "crusader armour"
- desc = "God wills it!"
- icon_state = "chaplain_templar"
- item_state = "knight_templar"
- allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
- slowdown = 0
- clothing_flags = NONE
-
-/obj/item/choice_beacon/holy
- name = "armaments beacon"
- desc = "Contains a set of armaments for the chaplain."
-
-/obj/item/choice_beacon/holy/canUseBeacon(mob/living/user)
- if(user.mind && user.mind.holy_role)
- return ..()
- else
- playsound(src, 'sound/machines/buzz-sigh.ogg', 40, TRUE)
- return FALSE
-
-/obj/item/choice_beacon/holy/generate_display_names()
- var/static/list/holy_item_list
- if(!holy_item_list)
- holy_item_list = list()
- var/list/templist = typesof(/obj/item/storage/box/holy)
- for(var/V in templist)
- var/atom/A = V
- holy_item_list[initial(A.name)] = A
- return holy_item_list
-
-/obj/item/choice_beacon/holy/spawn_option(obj/choice,mob/living/M)
- if(!GLOB.holy_armor_type)
- ..()
- playsound(src, 'sound/effects/pray_chaplain.ogg', 40, TRUE)
- SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]")
- GLOB.holy_armor_type = choice
- else
- to_chat(M, "A selection has already been made. Self-Destructing...")
- return
-
-
/obj/item/storage/box/holy
- name = "Templar Kit"
-
-/obj/item/storage/box/holy/PopulateContents()
- new /obj/item/clothing/head/helmet/chaplain(src)
- new /obj/item/clothing/suit/armor/riot/chaplain(src)
-
-/obj/item/storage/box/holy/student
- name = "Profane Scholar Kit"
-
-/obj/item/storage/box/holy/student/PopulateContents()
- new /obj/item/clothing/suit/armor/riot/chaplain/studentuni(src)
- new /obj/item/clothing/head/helmet/chaplain/cage(src)
-
-/obj/item/clothing/suit/armor/riot/chaplain/studentuni
- name = "student robe"
- desc = "The uniform of a bygone institute of learning."
- icon_state = "chaplain_studentuni"
- item_state = "studentuni"
- body_parts_covered = ARMS|CHEST
- allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
-
-/obj/item/clothing/head/helmet/chaplain/cage
- name = "cage"
- desc = "A cage that restrains the will of the self, allowing one to see the profane world for what it is."
- flags_inv = HIDEHAIR //bald
- mob_overlay_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
- icon_state = "cage"
- item_state = "cage"
- worn_x_dimension = 64
- worn_y_dimension = 64
-
-/obj/item/storage/box/holy/sentinel
- name = "Stone Sentinel Kit"
-
-/obj/item/storage/box/holy/sentinel/PopulateContents()
- new /obj/item/clothing/suit/armor/riot/chaplain/ancient(src)
- new /obj/item/clothing/head/helmet/chaplain/ancient(src)
-
-/obj/item/clothing/head/helmet/chaplain/ancient
- name = "ancient helmet"
- desc = "None may pass!"
- icon_state = "knight_ancient"
- item_state = "knight_ancient"
-
-/obj/item/clothing/suit/armor/riot/chaplain/ancient
- name = "ancient armour"
- desc = "Defend the treasure..."
- icon_state = "chaplain_ancient"
- item_state = "knight_ancient"
-
-/obj/item/storage/box/holy/witchhunter
name = "Witchhunter Kit"
-/obj/item/storage/box/holy/witchhunter/PopulateContents()
- new /obj/item/clothing/suit/armor/riot/chaplain/witchhunter(src)
- new /obj/item/clothing/head/helmet/chaplain/witchunter_hat(src)
-
-/obj/item/clothing/suit/armor/riot/chaplain/witchhunter
- name = "witchunter garb"
- desc = "This worn outfit saw much use back in the day."
- icon_state = "chaplain_witchhunter"
- item_state = "witchhunter"
- body_parts_covered = CHEST|GROIN|LEGS|ARMS
-
-/obj/item/clothing/head/helmet/chaplain/witchunter_hat
- name = "witchunter hat"
- desc = "This hat saw much use back in the day."
- icon_state = "witchhunterhat"
- item_state = "witchhunterhat"
- flags_cover = HEADCOVERSEYES
- flags_inv = HIDEEYES|HIDEHAIR
-
-/obj/item/storage/box/holy/adept
- name = "Divine Adept Kit"
-
-/obj/item/storage/box/holy/adept/PopulateContents()
- new /obj/item/clothing/suit/armor/riot/chaplain/adept(src)
- new /obj/item/clothing/head/helmet/chaplain/adept(src)
-
-/obj/item/clothing/head/helmet/chaplain/adept
- name = "adept hood"
- desc = "Its only heretical when others do it."
- icon_state = "crusader"
- item_state = "crusader"
- flags_cover = HEADCOVERSEYES
- flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
+/obj/item/storage/box/holy/PopulateContents()
+ new /obj/item/clothing/head/witchunter(src)
+ new /obj/item/clothing/suit/armor/witchhunter(src)
-/obj/item/clothing/suit/armor/riot/chaplain/adept
- name = "adept robes"
- desc = "The ideal outfit for burning the unfaithful."
- icon_state = "chaplain_crusader"
- item_state = "crusader"
/obj/item/storage/box/holy/follower
name = "Followers of the Chaplain Kit"
@@ -203,62 +65,6 @@
var/reskinned = FALSE
var/chaplain_spawnable = TRUE
-/obj/item/nullrod/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
-
-/obj/item/nullrod/attack_self(mob/user)
- if(user.mind && (user.mind.holy_role) && !reskinned)
- reskin_holy_weapon(user)
-
-/**
- * reskin_holy_weapon: Shows a user a list of all available nullrod reskins and based on his choice replaces the nullrod with the reskinned version
- *
- * Arguments:
- * * M The mob choosing a nullrod reskin
- */
-/obj/item/nullrod/proc/reskin_holy_weapon(mob/M)
- if(GLOB.holy_weapon_type)
- return
- var/list/display_names = list()
- var/list/nullrod_icons = list()
- for(var/V in typesof(/obj/item/nullrod))
- var/obj/item/nullrod/rodtype = V
- if(initial(rodtype.chaplain_spawnable))
- display_names[initial(rodtype.name)] = rodtype
- nullrod_icons += list(initial(rodtype.name) = image(icon = initial(rodtype.icon), icon_state = initial(rodtype.icon_state)))
-
- nullrod_icons = sortList(nullrod_icons)
- var/choice = show_radial_menu(M, src , nullrod_icons, custom_check = CALLBACK(src, PROC_REF(check_menu), M), radius = 42, require_near = TRUE)
- if(!choice || !check_menu(M))
- return
-
- var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new
- var/obj/item/nullrod/holy_weapon = new A
- GLOB.holy_weapon_type = holy_weapon.type
-
- SSblackbox.record_feedback("tally", "chaplain_weapon", 1, "[choice]")
-
- if(holy_weapon)
- holy_weapon.reskinned = TRUE
- qdel(src)
- M.put_in_active_hand(holy_weapon)
-
-/**
- * check_menu: Checks if we are allowed to interact with a radial menu
- *
- * Arguments:
- * * user The mob interacting with a menu
- */
-/obj/item/nullrod/proc/check_menu(mob/user)
- if(!istype(user))
- return FALSE
- if(QDELETED(src) || reskinned)
- return FALSE
- if(user.incapacitated() || !user.is_holding(src))
- return FALSE
- return TRUE
-
/obj/item/nullrod/godhand
icon_state = "disintegrate"
item_state = "disintegrate"
@@ -648,13 +454,6 @@
hitsound = 'sound/weapons/bite.ogg'
var/used_blessing = FALSE
-/obj/item/nullrod/carp/attack_self(mob/living/user)
- if(used_blessing)
- else if(user.mind && (user.mind.holy_role))
- to_chat(user, "You are blessed by Carp-Sie. Wild space carp will no longer attack you.")
- user.faction |= "carp"
- used_blessing = TRUE
-
/obj/item/nullrod/claymore/bostaff //May as well make it a "claymore" and inherit the blocking
name = "monk's staff"
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts, it is now used to harass the clown."
@@ -671,33 +470,6 @@
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
-/obj/item/nullrod/tribal_knife
- icon_state = "crysknife"
- item_state = "crysknife"
- lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
- name = "arrhythmic knife"
- w_class = WEIGHT_CLASS_HUGE
- desc = "They say fear is the true mind killer, but stabbing them in the head works too. Honour compels you to not sheathe it once drawn."
- sharpness = IS_SHARP
- slot_flags = null
- hitsound = 'sound/weapons/bladeslice.ogg'
- attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
- item_flags = SLOWS_WHILE_IN_HAND
-
-/obj/item/nullrod/tribal_knife/Initialize(mapload)
- . = ..()
- START_PROCESSING(SSobj, src)
- AddComponent(/datum/component/butchering, 50, 100)
-
-/obj/item/nullrod/tribal_knife/Destroy()
- STOP_PROCESSING(SSobj, src)
- . = ..()
-
-/obj/item/nullrod/tribal_knife/process()
- slowdown = rand(-2, 2)
-
-
/obj/item/nullrod/pitchfork
icon_state = "pitchfork0"
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
diff --git a/code/game/objects/items/implants/implanter.dm b/code/game/objects/items/implants/implanter.dm
index 5b8db550a87d..6de461954cb2 100644
--- a/code/game/objects/items/implants/implanter.dm
+++ b/code/game/objects/items/implants/implanter.dm
@@ -27,7 +27,7 @@
M.visible_message("[user] is attempting to implant [M].")
var/turf/T = get_turf(M)
- if(T && (M == user || do_mob(user, M, 50)))
+ if(T && (M == user || do_after(user, 5 SECONDS, M)))
if(src && imp)
if(imp.implant(M, user))
if (M == user)
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index 2732e0d37719..9e90329404f0 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -66,10 +66,13 @@
/obj/item/kitchen/knife
name = "kitchen knife"
- icon_state = "knife"
- item_state = "knife"
+ icon = 'icons/obj/item/knife.dmi'
+ lefthand_file = 'icons/mob/inhands/weapons/knifes_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/weapons/knifes_righthand.dmi'
+ icon_state = "kitchenknife"
+ item_state = "kitchenknife"
desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come."
- pickup_sound = 'sound/items/handling/knife1_pickup.ogg'
+ pickup_sound = 'sound/items/handling/knife1_pickup.ogg'
drop_sound = 'sound/items/handling/knife3_drop.ogg'
flags_1 = CONDUCT_1
force = 10
@@ -97,7 +100,6 @@
/obj/item/kitchen/knife/plastic
name = "plastic knife"
icon_state = "plastic_knife"
- item_state = "knife"
desc = "A very safe, barely sharp knife made of plastic. Good for cutting food and not much else."
force = 0
w_class = WEIGHT_CLASS_TINY
@@ -155,8 +157,8 @@
/obj/item/kitchen/knife/butcher
name = "butcher's cleaver"
- icon_state = "butch"
- item_state = "butch"
+ icon_state = "cleaver"
+ item_state = "cleaver"
desc = "A huge thing used for chopping and chopping up meat."
flags_1 = CONDUCT_1
force = 15
@@ -175,9 +177,47 @@
/obj/item/kitchen/knife/hunting/set_butchering()
AddComponent(/datum/component/butchering, 80 - force, 100, force + 10)
+/obj/item/kitchen/knife/switchblade
+ name = "switchblade"
+ icon_state = "switchblade"
+ lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
+ desc = "A sharp, concealable, spring-loaded knife."
+ flags_1 = CONDUCT_1
+ force = 3
+ w_class = WEIGHT_CLASS_SMALL
+ throwforce = 5
+ custom_materials = list(/datum/material/iron=12000)
+ hitsound = 'sound/weapons/genhit.ogg'
+ attack_verb = list("stubbed", "poked")
+ resistance_flags = FIRE_PROOF
+ var/extended = 0
+
+/obj/item/kitchen/knife/switchblade/attack_self(mob/user)
+ extended = !extended
+ playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
+ if(extended)
+ force = 20
+ w_class = WEIGHT_CLASS_NORMAL
+ throwforce = 23
+ icon_state = "switchblade_ext"
+ attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ sharpness = IS_SHARP
+ else
+ force = 3
+ w_class = WEIGHT_CLASS_SMALL
+ throwforce = 5
+ icon_state = "switchblade"
+ attack_verb = list("stubbed", "poked")
+ hitsound = 'sound/weapons/genhit.ogg'
+ sharpness = IS_BLUNT
+
/obj/item/kitchen/knife/combat
name = "combat knife"
- icon_state = "buckknife"
+ icon = 'icons/obj/world/melee.dmi'
+ icon_state = "combatknife"
+ item_state = "combatknife"
desc = "A military combat utility survival knife."
embedding = list("pain_mult" = 4, "embed_chance" = 65, "fall_chance" = 10, "ignore_throwspeed_threshold" = TRUE)
force = 20
@@ -185,9 +225,14 @@
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
bayonet = TRUE
+/obj/item/kitchen/knife/combat/Initialize()
+ . = ..()
+ AddElement(/datum/element/world_icon, null, icon, 'icons/obj/item/knife.dmi')
+
/obj/item/kitchen/knife/combat/survival
name = "survival knife"
icon_state = "survivalknife"
+ item_state = "survivalknife"
embedding = list("pain_mult" = 4, "embed_chance" = 35, "fall_chance" = 10)
desc = "A hunting grade survival knife."
force = 15
diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm
index 693858bf1b2e..05af8fcadbad 100644
--- a/code/game/objects/items/manuals.dm
+++ b/code/game/objects/items/manuals.dm
@@ -256,8 +256,8 @@
-
Trickwines for idiots
- Okay, so you just joined the SRM and you want to make some brews! I'm tired of explaining all of this so I'm jotting it all down for you clowns.
+
Trickwines for brewers
+ Okay, so you just joined the SRM and you want to make some brews! I'm tired of explaining all of this so I'm jotting it all down for the new hires.
Trickwines almost all share the same effect. When you drink them, they provide a beneficial effect and when you toss them at someone it provides some sort of bad effect.
Breakaway flasks
Honestly, I love these things. I'm not a scientist so I cant exactly explain how it works but somehow when you fuse plasma into glass it makes it ultra sharp and makes it really good for cracking over fauna heads.
@@ -273,22 +273,27 @@
Soon it will drops some apples and you can grind them for the bacteria.
Once you have enough you can fabricate it the same way you would a normal barrel.
+
Ratios
+ A common trend among Trickwines is the ratio of 3:1:1.
+ 3 parts being an ethonal, the other 2 parts are often made from flora or fauna.
+
Ashwine
- It's kind of our trademark, and it's one of the simplest trickwines to make. The Montagnes love using this stuff in ceremonies as well so it should get you some good boy points.
+ It's kind of our trademark, and it's one of the simplest trickwines to make.
+ These are the most common wines used in ceremonies so we often stock ships with the moonflowers needed to make them.
It's made with a ratio of 3:1:1 absinthe, mushroom hallucinogen, and ash respectively.
Mushroom hallucinogens come from mushroom caps and you can ferment absinthe from moonflowers.
Its a mild hallucinogenic but seems to have powerful cleansing effects on the devoted SRM.
It can also really fuck someone up, causing their vision to go shaky and blurry which makes it difficult for them to fight.
Icewine
- This one helps stopping foes in their tracks. It's also got a nice taste.
+ This one helps stopping foes in their tracks. One of my favorite flavor wise.
Its made with 3:1:1 saké, polar bear fur, frost oil(grind chilled peppers).
You can get polar bear fur and frost oil from grinding up polar bear hides and chilled peppers.
It's pretty good at sealing burns and lowering your temperature quickly.
However, it completely encases foes in ice and drops their temperature substantially.
Shockwine
- Easily my favorite, this thing is great at scorching most fauna.
+ Easily my favorite for its splashed effect, this thing is great at scorching most fauna.
Its made with vodka, calcium, and lemon juice.
If you did not know, vodka requires enzymes instead of the normal fermenting process.
It's a nice upper. Great if you're trying to run away.
@@ -301,15 +306,18 @@
Its made out of ground up fireblossems with some nice hard cider and a bit of welding fuel with of course a ratio of 3:1:1.
Forcewine
- I once had a duel with a wizard and and I was able to completly ignore a few of his spells! Its like they just fizzled out when they hit me.
- Would recomend for any esoteric senarios even though I have only been in a few of those.
- You can also use it to entrap Fauna inside of a forcefield like bubble, Gives you time to breath and laugh at them.
- 3:1:1 Tequila, Space Montain Wind, and I know its strange but hollow water, Its that stuff you can extract from geysers
+ Two intresting effects from the consumption of Forcewine.
+ First it seems to give you an "anti magic" effect, I have read about of tales of how it fizzled out some sort of great curse that we could best trace back to a ancient cult.
+ Second is it protects the mind from cohersion and mind control.
+ From my research this seems to act like nanotrasen mindshield implants.
+ Would recomend for any esoteric senarios. We wont see these alot but its always smart to prepare for the worst.
+ You can also use it to entrap Fauna inside of a forcefield like bubble, Gives you time to breath and prepare an attack.
+ 3:1:1. Tequila, Space Montain Wind, and I know its one of the most difficult things to come by but hollow water, Its that stuff you can extract from geysers
Prismwine
Gives you a nice shiny layer of armour, fire seems to have alot harder time sticking to me when i tested it.
Throwing it seeems to do the reverse acting like a magnifying glass to burns and lasers
- Made 3:1:1 with good ol Gin, then add plasma and tinea luxor which is found from mushroom stems
+ 3:1:1. Good ol Gin, then add plasma and tinea luxor which is found from mushroom stems
Some of these can be a bit situatinal but its always nice to have a few in your bag for emergecys.
As a bonus, most of the other factions have no clue how to make these so you can sell them for a fair chunk of cash.
diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm
index f4fbd42be38b..9d90a1a43373 100644
--- a/code/game/objects/items/melee/misc.dm
+++ b/code/game/objects/items/melee/misc.dm
@@ -646,31 +646,6 @@
held_sausage.desc = "[held_sausage.desc] It has been cooked to perfection on \a [target]."
update_appearance()
-/obj/item/melee/cleric_mace
- name = "cleric mace"
- desc = "The grandson of the club, yet the grandfather of the baseball bat. Most notably used by holy orders in days past."
- icon = 'icons/obj/items_and_weapons.dmi'
- icon_state = "mace_greyscale"
- item_state = "mace_greyscale"
- lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
- material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Material type changes the prefix as well as the color.
- custom_materials = list(/datum/material/iron = 12000) //Defaults to an Iron Mace.
- slot_flags = ITEM_SLOT_BELT
- force = 14
- w_class = WEIGHT_CLASS_BULKY
- throwforce = 8
- armour_penetration = 50
- attack_verb = list("smacked", "struck", "cracked", "beaten")
- var/overlay_state = "mace_handle"
- var/mutable_appearance/overlay
-
-/obj/item/melee/cleric_mace/Initialize()
- . = ..()
- overlay = mutable_appearance(icon, overlay_state)
- overlay.appearance_flags = RESET_COLOR
- add_overlay(overlay)
-
/obj/item/melee/greykingsword
name = "blade of the grey-king"
desc = "A legendary sword made with 3 replica katanas nailed together and dipped in heavy narcotics."
diff --git a/code/game/objects/items/miscellaneous.dm b/code/game/objects/items/miscellaneous.dm
index 487d5d2c96ca..619ebf3eb0e9 100644
--- a/code/game/objects/items/miscellaneous.dm
+++ b/code/game/objects/items/miscellaneous.dm
@@ -1,8 +1,8 @@
/obj/item/caution
- desc = "Caution! Wet Floor!"
name = "wet floor sign"
- icon = 'icons/obj/janitor.dmi'
+ desc = "No running."
icon_state = "caution"
+ icon = 'icons/obj/janitor.dmi'
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
force = 1
@@ -13,11 +13,10 @@
attack_verb = list("warned", "cautioned", "smashed")
/obj/item/choice_beacon
- name = "choice beacon"
- desc = "Hey, why are you viewing this?!! Please let CentCom know about this odd occurrence."
- icon = 'icons/obj/device.dmi'
- icon_state = "gangtool-blue"
- item_state = "radio"
+ name = "choice box"
+ desc = "A box containing items to choose."
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "deliverypackage3"
var/uses = 1
/obj/item/choice_beacon/attack_self(mob/user)
@@ -31,41 +30,31 @@
if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return TRUE
else
- playsound(src, 'sound/machines/buzz-sigh.ogg', 40, TRUE)
return FALSE
/obj/item/choice_beacon/proc/generate_options(mob/living/M)
var/list/display_names = generate_display_names()
if(!display_names.len)
return
- var/choice = input(M,"Which item would you like to order?","Select an Item") as null|anything in sortList(display_names)
+ var/choice = input(M,"Which item would you like to pick?","Select an Item") as null|anything in sortList(display_names)
if(!choice || !M.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
spawn_option(display_names[choice],M)
uses--
if(!uses)
+ new /obj/effect/decal/cleanable/wrapping(get_turf(M))
qdel(src)
else
to_chat(M, "[uses] use[uses > 1 ? "s" : ""] remaining on the [src].")
/obj/item/choice_beacon/proc/spawn_option(obj/choice,mob/living/M)
- var/obj/new_item = new choice()
- var/obj/structure/closet/supplypod/bluespacepod/pod = new()
- pod.explosionSize = list(0,0,0,0)
- new_item.forceMove(pod)
- var/msg = "After making your selection, you notice a strange target on the ground. It might be best to step back!"
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(istype(H.ears, /obj/item/radio/headset))
- msg = "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows: Item request received. Your package is inbound, please stand back from the landing site. Message ends.\""
- to_chat(M, msg)
-
- new /obj/effect/pod_landingzone(get_turf(src), pod)
+ new choice(get_turf(M))
+ playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, TRUE)
/obj/item/choice_beacon/hero
- name = "heroic beacon"
- desc = "To summon heroes from the past to protect the future."
+ name = "heroic box"
+ desc = "To become heroes from the past to protect the future."
/obj/item/choice_beacon/hero/generate_display_names()
var/static/list/hero_item_list
@@ -137,8 +126,8 @@
new /obj/item/grenade/chem_grenade/ghostbuster(src)
/obj/item/choice_beacon/augments
- name = "augment beacon"
- desc = "Summons augmentations. Can be used 3 times!"
+ name = "augment box"
+ desc = "Contains augmentations. Can be used 3 times!"
uses = 3
/obj/item/choice_beacon/augments/generate_display_names()
@@ -157,10 +146,6 @@
augment_list[initial(A.name)] = A
return augment_list
-/obj/item/choice_beacon/augments/spawn_option(obj/choice,mob/living/M)
- new choice(get_turf(M))
- to_chat(M, "You hear something crackle from the beacon for a moment before a voice speaks. \"Please stand by for a message from S.E.L.F. Message as follows: Item request received. Your package has been transported, use the autosurgeon supplied to apply the upgrade. Message ends.\"")
-
/obj/item/skub
desc = "It's skub."
name = "skub"
@@ -217,8 +202,10 @@
#undef NICKNAME_CAP
/obj/item/choice_beacon/ouija
- name = "spirit board delivery beacon"
+ name = "spirit board box"
desc = "Ghost communication on demand! It is unclear how this thing is still operational."
+ icon_state = "deliverybox"
+ w_class = WEIGHT_CLASS_BULKY
/obj/item/choice_beacon/ouija/generate_display_names()
var/static/list/ouija_spaghetti_list
diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm
index d9311f5e2b43..a08b1398aad8 100644
--- a/code/game/objects/items/pet_carrier.dm
+++ b/code/game/objects/items/pet_carrier.dm
@@ -165,7 +165,7 @@
user.visible_message("[user] starts loading [target] into [src].", \
"You start loading [target] into [src]...", null, null, target)
to_chat(target, "[user] starts loading you into [user.p_their()] [name]!")
- if(!do_mob(user, target, 30))
+ if(!do_after(user, 3 SECONDS, target))
return
if(target in occupants)
return
diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm
index 060e59f0f5de..5108a8713633 100644
--- a/code/game/objects/items/pneumaticCannon.dm
+++ b/code/game/objects/items/pneumaticCannon.dm
@@ -11,8 +11,8 @@
icon = 'icons/obj/pneumaticCannon.dmi'
icon_state = "pneumaticCannon"
item_state = "bulldog"
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 50)
var/maxWeightClass = 20 //The max weight of items that can fit into the cannon
var/loadedWeightClass = 0 //The weight of items currently in the cannon
diff --git a/code/game/objects/items/puzzle_pieces.dm b/code/game/objects/items/puzzle_pieces.dm
index 5d6b409e8d32..9f937312b561 100644
--- a/code/game/objects/items/puzzle_pieces.dm
+++ b/code/game/objects/items/puzzle_pieces.dm
@@ -1,6 +1,6 @@
//**************
-//*****Keys*******************
-//************** ** **
+//*****Keys*****
+//**************
/obj/item/keycard
name = "security keycard"
desc = "This feels like it belongs to a door."
@@ -21,50 +21,35 @@
color = "#f0da12"
puzzle_id = "cheese"
-/obj/item/keycard/swordfish
- name = "titanic keycard"
- desc = "Smells like it was at the bottom of a harbor."
- color = "#3bbbdb"
- puzzle_id = "swordfish"
+/obj/item/keycard/harmfactory
+ name = "factory keycard"
+ desc = "A keycard opening a door within the world's worst factory"
+ color = "#727a7c"
+ puzzle_id = "factory"
+
+/obj/item/keycard/harmfactory/stockroom
+ name = "stockroom keycard"
+ desc = "A keycard opening a door within the world's worst factory"
+ color = "#cf2323"
+ puzzle_id = "stockroom"
+
+/obj/item/keycard/harmfactory/office
+ name = "office keycard"
+ desc = "A keycard opening a door within the world's worst factory"
+ color = "#1dac22"
+ puzzle_id = "office"
+
+/obj/item/keycard/harmfactory/entry
+ name = "entry keycard"
+ desc = "A keycard opening a door within the world's worst factory"
+ color = "#1a27e7"
+ puzzle_id = "entry"
+
+
/obj/item/keycard/gatedrop
icon_state = "golden_key"
-/obj/item/keycard/gatedrop/drakelair
- name = "Drake's Key"
- desc = "A dull, golden key originally kept by a menacing ash drake."
- puzzle_id = "drakelairkey"
-
-/obj/item/keycard/gatedrop/disciple
- name = "Altar Key"
- desc = "A key held dear by the late Disciple of The Priest. Only by shutting themselves in with their stone idol were they able to spare those they love most from their madness and obsession."
- puzzle_id = "disciplekey"
-
-/obj/item/keycard/gatedrop/guard
- name = "Armory Key"
- desc = "A golden key entrusted to the Captain of the Holy Guard of The Priest. Entrusted by His Holiness to guard the greatest weapon in His arsenal"
- puzzle_id = "guardcap"
-
-/obj/item/keycard/gatedrop/heathen
- name = "Heathen's Key"
- desc = "And thus the Heathen stole away with the key to the forbidden gates. Hiding with his sect of followers until death cometh."
- puzzle_id = "heathen"
-
-/obj/item/keycard/gatedrop/gatekeeper
- name = "GateKeeper's Key"
- desc = "Only by slaying the keeper of the gates may one path through into the depths of The Priest's holiest sanctums."
- puzzle_id = "gatekeeper"
-
-/obj/item/keycard/gatedrop/bishop
- name = "Key of the lost"
- desc = "A key held only by the warring Bishop, forever lost to the Golden City of old."
- puzzle_id = "bishopkey"
-
-/obj/item/keycard/gatedrop/priest
- name = "The Priest's Key"
- desc = "A key belonging to a once peaceful scholar, brought to death and ruin through means of violence by savage outsider."
- puzzle_id = "priestkey"
-
/obj/item/keycard/gatedrop/lavacanyon
name = "Vault Key"
desc = "A dusty key, smudged with dried blood."
@@ -128,6 +113,26 @@
desc = "If nautical nonsense be something you wish."
puzzle_id = "swordfish"
+/obj/machinery/door/keycard/harmfactory
+ name = "keycard locked door"
+ desc = "Seems to have a scanner for the factory keycard"
+ puzzle_id = "factory"
+
+/obj/machinery/door/keycard/harmfactory/stockroom
+ name = "keycard locked door"
+ desc = "Seems to have a scanner for the stockroom keycard"
+ puzzle_id = "stockroom"
+
+/obj/machinery/door/keycard/harmfactory/office
+ name = "keycard locked door"
+ desc = "Seems to have a scanner for the office keycard"
+ puzzle_id = "office"
+
+/obj/machinery/door/keycard/harmfactory/entry
+ name = "keycard locked door"
+ desc = "Seems to have a scanner for the entry keycard"
+ puzzle_id = "entry"
+
/obj/machinery/door/keycard/gates
gender = PLURAL
name = "locked gates"
@@ -155,39 +160,6 @@
. = ..()
icon_state = density ? "closed" : "open"
-/obj/machinery/door/keycard/gates/drakelair
- puzzle_id = "drakelairkey"
-
-/obj/machinery/door/keycard/gates/disciple
- name = "Tithe Gates"
- desc = "Gates protecting the ritual tithe collected by The Priest and his Disciples."
- puzzle_id = "disciplekey"
-
-/obj/machinery/door/keycard/gates/guard
- name = "Armory Gates"
- desc = "Gates protecting the most versatile and dangerous of The Priest's armory."
- puzzle_id = "guardcap"
-
-/obj/machinery/door/keycard/gates/heathen
- name = "Sect Gates"
- desc = "Gates guarding the forbidden treasures stolen away by the Heathen. Bloody in nature, and hidden from sight."
- puzzle_id = "heathen"
-
-/obj/machinery/door/keycard/gates/gatekeeper
- name = "Sanctum Gates"
- desc = "The Gatekeeper holds the key, only through bloodshed can they be opened."
- puzzle_id = "gatekeeper"
-
-/obj/machinery/door/keycard/gates/bishop
- name = "Lost Golden City Gates"
- desc = "He took their lives and locked their culture and heritage behind indestructible gates of virtue. The Bishop spread conversion through death and swallowed the key."
- puzzle_id = "bishopkey"
-
-/obj/machinery/door/keycard/gates/priest
- name = "The Priest's Treasury"
- desc = "Gates holding The Priest's eternal hoarde. Drakeborn, incapable of avoiding the grand desire to collect and learn."
- puzzle_id = "priestkey"
-
/obj/machinery/door/keycard/gates/lavacanyon
puzzle_id = "lavacanyonkey"
diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm
index 0ba32f33099a..e2507dfb911b 100644
--- a/code/game/objects/items/religion.dm
+++ b/code/game/objects/items/religion.dm
@@ -87,14 +87,6 @@
/obj/item/banner/security/mundane
inspiration_available = FALSE
-/datum/crafting_recipe/security_banner
- name = "Securistan Banner"
- result = /obj/item/banner/security/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/security/officer = 1)
- category = CAT_MISC
-
/obj/item/banner/medical
name = "meditopia banner"
desc = "The banner of Meditopia, generous benefactors that cure wounds and shelter the weak."
@@ -111,14 +103,6 @@
/obj/item/banner/medical/check_inspiration(mob/living/carbon/human/H)
return H.stat //Meditopia is moved to help those in need
-/datum/crafting_recipe/medical_banner
- name = "Meditopia Banner"
- result = /obj/item/banner/medical/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/medical = 1)
- category = CAT_MISC
-
/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
H.adjustToxLoss(-15)
H.setOxyLoss(0)
@@ -140,14 +124,6 @@
/obj/item/banner/science/check_inspiration(mob/living/carbon/human/H)
return H.on_fire //Sciencia is pleased by dedication to the art of Toxins
-/datum/crafting_recipe/science_banner
- name = "Sciencia Banner"
- result = /obj/item/banner/science/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/rnd/scientist = 1)
- category = CAT_MISC
-
/obj/item/banner/cargo
name = "cargonia banner"
desc = "The banner of the eternal Cargonia, with the mystical power of conjuring any object into existence."
@@ -161,14 +137,6 @@
/obj/item/banner/cargo/mundane
inspiration_available = FALSE
-/datum/crafting_recipe/cargo_banner
- name = "Cargonia Banner"
- result = /obj/item/banner/cargo/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/cargo/tech = 1)
- category = CAT_MISC
-
/obj/item/banner/engineering
name = "engitopia banner"
desc = "The banner of Engitopia, wielders of limitless power."
@@ -185,14 +153,6 @@
/obj/item/banner/engineering/special_inspiration(mob/living/carbon/human/H)
H.radiation = 0
-/datum/crafting_recipe/engineering_banner
- name = "Engitopia Banner"
- result = /obj/item/banner/engineering/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/engineering/engineer = 1)
- category = CAT_MISC
-
/obj/item/banner/command
name = "command banner"
desc = "The banner of Command, a staunch and ancient line of bueraucratic kings and queens."
@@ -206,14 +166,6 @@
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
return HAS_TRAIT(H, TRAIT_MINDSHIELD) //Command is stalwart but rewards their allies.
-/datum/crafting_recipe/command_banner
- name = "Command Banner"
- result = /obj/item/banner/command/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/command/captain/parade = 1)
- category = CAT_MISC
-
/obj/item/banner/red
name = "red banner"
icon_state = "banner-red"
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index a0e5865e1528..243b84b7e1ec 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -176,7 +176,7 @@
return
to_chat(user, "You connect to [M]'s power line...")
- while(do_after(user, 15, target = M, progress = 0))
+ while(do_after(user, 15, target = M, progress = TRUE))
if(!user || !user.cell || mode != "draw")
return
@@ -210,7 +210,7 @@
to_chat(user, "You connect to [target]'s power port...")
- while(do_after(user, 15, target = target, progress = 0))
+ while(do_after(user, 15, target = target, progress = TRUE))
if(!user || !user.cell || mode != "draw")
return
@@ -248,7 +248,7 @@
to_chat(user, "You connect to [target]'s power port...")
- while(do_after(user, 15, target = target, progress = 0))
+ while(do_after(user, 15, target = target, progress = TRUE))
if(!user || !user.cell || mode != "charge")
return
diff --git a/code/game/objects/items/shrapnel.dm b/code/game/objects/items/shrapnel.dm
index 8bf29c9a807a..959649c8c59b 100644
--- a/code/game/objects/items/shrapnel.dm
+++ b/code/game/objects/items/shrapnel.dm
@@ -1,6 +1,6 @@
/obj/item/shrapnel // frag grenades
name = "shrapnel shard"
- embedding = list(embed_chance=70, ignore_throwspeed_threshold=TRUE, fall_chance=4, embed_chance_turf_mod=-100)
+ embedding = list(embed_chance=70, ignore_throwspeed_threshold=TRUE, fall_chance=2, embed_chance_turf_mod=-100)
custom_materials = list(/datum/material/iron=50)
armour_penetration = -20
icon = 'icons/obj/shards.dmi'
@@ -8,9 +8,14 @@
w_class = WEIGHT_CLASS_TINY
item_flags = DROPDEL
-/obj/item/shrapnel/stingball // stingbang grenades
- name = "stingball"
- embedding = list(embed_chance=90, fall_chance=3, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.7, pain_mult=5, jostle_pain_mult=6, rip_time=15, embed_chance_turf_mod=-100)
+/obj/item/shrapnel/hot
+ name = "molten slag"
+ embedding = list(embed_chance=70, ignore_throwspeed_threshold=TRUE, fall_chance=2, embed_chance_turf_mod=-100)
+ damtype = BURN
+
+/obj/item/shrapnel/stingball
+ name = "clump of ballistic gel"
+ embedding = list(embed_chance=15, fall_chance=2, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.8, pain_mult=3, jostle_pain_mult=5, rip_time=15, embed_chance_turf_mod=-100)
icon_state = "tiny"
/obj/item/shrapnel/bullet // bullets
@@ -28,35 +33,79 @@
/obj/projectile/bullet/shrapnel
name = "flying shrapnel shard"
- damage = 9
+ damage = 10
range = 10
- armour_penetration = -30
- dismemberment = 5
+ armour_penetration = -20
+ dismemberment = 25
ricochets_max = 2
ricochet_chance = 40
shrapnel_type = /obj/item/shrapnel
ricochet_incidence_leeway = 60
hit_stunned_targets = TRUE
+/obj/projectile/bullet/shrapnel/Initialize()
+ . = ..()
+ def_zone = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+
+/obj/projectile/bullet/shrapnel/rusty
+ damage = 8
+ armour_penetration = -35
+ dismemberment = 15
+ ricochets_max = 3//duller = less likely to stick in a wall
+ ricochet_chance = 60
+
/obj/projectile/bullet/shrapnel/mega
+ damage = 20
name = "flying shrapnel hunk"
range = 25
- dismemberment = 10
+ dismemberment = 35
ricochets_max = 4
ricochet_chance = 90
ricochet_decay_chance = 0.9
+/obj/projectile/bullet/shrapnel/hot
+ name = "white-hot metal slag"
+ damage = 8
+ range = 8
+ armour_penetration = -35
+ dismemberment = 10
+ shrapnel_type = /obj/item/shrapnel/hot
+ damage_type = BURN
+
+/obj/projectile/bullet/shrapnel/hot/on_hit(atom/target, blocked = FALSE)
+ . = ..()
+ if(iscarbon(target))
+ var/mob/living/carbon/M = target
+ M.adjust_fire_stacks(15)
+ M.IgniteMob()
+
+/obj/projectile/bullet/shrapnel/spicy
+ name = "radioactive slag"
+ damage_type = BURN
+ damage = 10
+ range = 8
+ dismemberment = 10
+ armour_penetration = -35
+ shrapnel_type = /obj/item/shrapnel/hot
+
+/obj/projectile/bullet/shrapnel/spicy/on_hit(atom/target, blocked = FALSE)
+ . = ..()
+ if(iscarbon(target))
+ var/mob/living/carbon/M = target
+ M.apply_effect(250,EFFECT_IRRADIATE,0)
+
/obj/projectile/bullet/pellet/stingball
- name = "stingball pellet"
- damage = 3
- stamina = 8
- ricochets_max = 4
+ name = "ballistic gel clump"
+ damage = 5
+ stamina = 15
+ ricochets_max = 6
ricochet_chance = 66
ricochet_decay_chance = 1
ricochet_decay_damage = 0.9
ricochet_auto_aim_angle = 10
ricochet_auto_aim_range = 2
ricochet_incidence_leeway = 0
+ knockdown = 20
shrapnel_type = /obj/item/shrapnel/stingball
/obj/projectile/bullet/pellet/stingball/mega
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 32d923eef985..264ab12646ea 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -31,17 +31,17 @@
return
if(target == user)
playsound(src, islist(apply_sounds) ? pick(apply_sounds) : apply_sounds, 25)
- if(!do_mob(user, target, self_delay, extra_checks=CALLBACK(target, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
- return
if(!silent)
user.visible_message("[user] starts to apply \the [src] on [user.p_them()]self...", "You begin applying \the [src] on yourself...")
+ if(!do_after(user, self_delay, target, extra_checks=CALLBACK(target, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
+ return
else if(other_delay)
playsound(src, islist(apply_sounds) ? pick(apply_sounds) : apply_sounds, 25)
- if(!do_mob(user, target, other_delay, extra_checks=CALLBACK(target, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
- return
if(!silent)
user.visible_message("[user] starts to apply \the [src] on [target].", "You begin applying \the [src] on [target]...")
+ if(!do_after(user, other_delay, target, extra_checks=CALLBACK(target, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
+ return
if(heal(target, user))
@@ -137,12 +137,13 @@
/obj/item/stack/medical/gauze
name = "medical gauze"
- desc = "A roll of elastic cloth that is extremely effective at stopping bleeding, but does not heal wounds."
+ desc = "A roll of elastic cloth that is extremely effective at stopping bleeding and slowly heals wounds."
gender = PLURAL
singular_name = "medical gauze"
icon_state = "gauze"
apply_sounds = list('sound/effects/rip1.ogg', 'sound/effects/rip2.ogg')
- var/stop_bleeding = 1800
+ var/bleed_reduction = 0.02
+ var/lifespan = 150
self_delay = 20
max_amount = 12
grind_results = list(/datum/reagent/cellulose = 2)
@@ -152,13 +153,16 @@
amount = 12
/obj/item/stack/medical/gauze/heal(mob/living/target, mob/user)
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- if(!H.bleedsuppress && H.bleed_rate) //so you can't stack bleed suppression
- H.suppress_bloodloss(stop_bleeding)
- to_chat(user, "You stop the bleeding of [target]!")
+ if(iscarbon(target))
+ var/mob/living/carbon/C = target
+ var/obj/item/bodypart/BP = C.get_bodypart(check_zone(user.zone_selected))
+ if(!BP)
+ to_chat(user, span_warning("[C] doesn't have \a [parse_zone(user.zone_selected)]!"))
+ return
+ if(BP.can_bandage(user))
+ BP.apply_bandage(bleed_reduction, lifespan, name)
+ user.visible_message(span_notice("[user] wraps [C]'s [parse_zone(BP.body_zone)] with [src]."), span_notice("You wrap [C]'s [parse_zone(check_zone(user.zone_selected))] with [src]."), span_hear("You hear ruffling cloth."))
return TRUE
- to_chat(user, "You can not use \the [src] on [target]!")
/obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_WIRECUTTER || I.get_sharpness())
@@ -178,8 +182,8 @@
/obj/item/stack/medical/gauze/improvised
name = "improvised gauze"
singular_name = "improvised gauze"
- desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds."
- stop_bleeding = 900
+ desc = "A roll of cloth roughly cut from something that can stop bleeding and slowly heal wounds."
+ bleed_reduction = 0.005
/obj/item/stack/medical/gauze/cyborg
custom_materials = null
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index f0be0cdd7e81..b5f78d46e951 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -9,6 +9,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
new/datum/stack_recipe("modern railing corner", /obj/structure/railing/modern/corner, 1, time = 10, window_checks = TRUE), \
new/datum/stack_recipe("modern railing end", /obj/structure/railing/modern/end, 3, time = 18, window_checks = TRUE), \
new/datum/stack_recipe("ladder", /obj/structure/ladder/crafted, 15, time = 150, one_per_turf = TRUE, on_floor = FALSE), \
+ new/datum/stack_recipe("handrail", /obj/structure/chair/handrail, 4, time = 15, one_per_turf = TRUE), \
))
/obj/item/stack/rods
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 200fc408768f..9fc6fa808a46 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -160,6 +160,9 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
/obj/item/stack/sheet/mineral/uranium/twenty
amount = 20
+/obj/item/stack/sheet/mineral/uranium/ten
+ amount = 10
+
/obj/item/stack/sheet/mineral/uranium/five
amount = 5
@@ -210,6 +213,9 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
/obj/item/stack/sheet/mineral/plasma/twenty
amount = 20
+/obj/item/stack/sheet/mineral/plasma/ten
+ amount = 10
+
/obj/item/stack/sheet/mineral/plasma/five
amount = 5
@@ -326,32 +332,6 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
/obj/item/stack/sheet/mineral/silver/five
amount = 5
-/*
- * Clown
- */
-/obj/item/stack/sheet/mineral/bananium
- name = "bananium"
- icon_state = "sheet-bananium"
- item_state = "sheet-bananium"
- singular_name = "bananium sheet"
- sheettype = "bananium"
- custom_materials = list(/datum/material/bananium=MINERAL_MATERIAL_AMOUNT)
-
- grind_results = list(/datum/reagent/consumable/banana = 20)
- point_value = 50
- merge_type = /obj/item/stack/sheet/mineral/bananium
- material_type = /datum/material/bananium
- walltype = /turf/closed/wall/mineral/bananium
-
-GLOBAL_LIST_INIT(bananium_recipes, list ( \
- new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
- new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
- ))
-
-/obj/item/stack/sheet/mineral/bananium/get_main_recipes()
- . = ..()
- . += GLOB.bananium_recipes
-
/*
* Titanium
*/
@@ -430,7 +410,6 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
. = ..()
. += GLOB.plastitanium_recipes
-
/*
* Snow
*/
@@ -459,56 +438,6 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \
. = ..()
. += GLOB.snow_recipes
-/****************************** Others ****************************/
-
-/*
- * Adamantine
-*/
-
-/obj/item/stack/sheet/mineral/adamantine
- name = "adamantine"
- icon_state = "sheet-adamantine"
- item_state = "sheet-adamantine"
- singular_name = "adamantine sheet"
- custom_materials = list(/datum/material/adamantine=MINERAL_MATERIAL_AMOUNT)
- merge_type = /obj/item/stack/sheet/mineral/adamantine
- grind_results = list(/datum/reagent/liquidadamantine = 10)
-
-/obj/item/stack/sheet/mineral/adamantine/ten
- amount = 10
-
-/*
- * Runite
- */
-
-/obj/item/stack/sheet/mineral/runite
- name = "runite"
- desc = "Rare material found in distant lands."
- singular_name = "runite bar"
- icon_state = "sheet-runite"
- item_state = "sheet-runite"
- custom_materials = list(/datum/material/runite=MINERAL_MATERIAL_AMOUNT)
- merge_type = /obj/item/stack/sheet/mineral/runite
- material_type = /datum/material/runite
-
-/obj/item/stack/sheet/mineral/runite/ten
- amount = 10
-
-/*
- * Mythril
- */
-/obj/item/stack/sheet/mineral/mythril
- name = "mythril"
- icon_state = "sheet-mythril"
- item_state = "sheet-mythril"
- singular_name = "mythril sheet"
- novariants = TRUE
- custom_materials = list(/datum/material/mythril=MINERAL_MATERIAL_AMOUNT)
- merge_type = /obj/item/stack/sheet/mineral/mythril
-
-/obj/item/stack/sheet/mineral/mythril/ten
- amount = 10
-
/*
* Alien Alloy
*/
@@ -567,3 +496,35 @@ GLOBAL_LIST_INIT(abductor_recipes, list ( \
/obj/item/stack/sheet/mineral/coal/ten
amount = 10
+
+/*
+ * Hellstone
+ */
+/obj/item/stack/sheet/mineral/hidden
+ name = "????????"
+ singular_name = "????????"
+
+/obj/item/stack/sheet/mineral/hidden/hellstone
+ name = "hellstone"
+ icon_state = "sheet-hellstone"
+ item_state = "sheet-hellstone"
+ singular_name = "hellstone bar"
+ sheettype = "hellstone"
+ resistance_flags = FIRE_PROOF | LAVA_PROOF
+ custom_materials = list(/datum/material/hellstone=MINERAL_MATERIAL_AMOUNT)
+ grind_results = list(/datum/reagent/clf3 = 5)
+ point_value = 20
+ merge_type = /obj/item/stack/sheet/mineral/hidden/hellstone
+ material_type = /datum/material/hellstone
+
+/obj/item/stack/sheet/mineral/hidden/hellstone/fifty
+ amount = 50
+
+/obj/item/stack/sheet/mineral/hidden/hellstone/twenty
+ amount = 20
+
+/obj/item/stack/sheet/mineral/hidden/hellstone/ten
+ amount = 10
+
+/obj/item/stack/sheet/mineral/hidden/hellstone/five
+ amount = 5
diff --git a/code/game/objects/items/stacks/sheets/recipes/recipes_metal.dm b/code/game/objects/items/stacks/sheets/recipes/recipes_metal.dm
new file mode 100644
index 000000000000..6860f34be5c7
--- /dev/null
+++ b/code/game/objects/items/stacks/sheets/recipes/recipes_metal.dm
@@ -0,0 +1,250 @@
+GLOBAL_LIST_INIT(metal_recipes, list ( \
+ new/datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("double bed", /obj/structure/bed/double, 4, one_per_turf = TRUE, on_floor = TRUE), \
+ null, \
+ new/datum/stack_recipe_list("office chairs", list( \
+ new/datum/stack_recipe("gray office chair", /obj/structure/chair/office, 5, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("light office chair", /obj/structure/chair/office/light, 5, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("dark office chair", /obj/structure/chair/office/dark, 5, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("purple office chair", /obj/structure/chair/office/purple, 5, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe_list("bench chairs", list( \
+ new/datum/stack_recipe("purple bench chair", /obj/structure/chair/bench/purple, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("beige bench chair", /obj/structure/chair/bench/beige, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("grey bench chair", /obj/structure/chair/bench/grey, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("blue bench chair", /obj/structure/chair/bench/blue, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("red bench chair", /obj/structure/chair/bench/red, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("olive bench chair", /obj/structure/chair/bench/olive, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe_list("comfy chairs", list( \
+ new/datum/stack_recipe("purple comfy chair", /obj/structure/chair/comfy/purple, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("beige comfy chair", /obj/structure/chair/comfy/beige, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("grey comfy chair", /obj/structure/chair/comfy/grey, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("orange comfy chair", /obj/structure/chair/comfy/orange, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("blue comfy chair", /obj/structure/chair/comfy/blue, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("red comfy chair", /obj/structure/chair/comfy/red, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("olive comfy chair", /obj/structure/chair/comfy/olive, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe_list("comfy chairs (old)", list( \
+ new/datum/stack_recipe("old purple comfy chair", /obj/structure/chair/comfy/purple/old, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old beige comfy chair", /obj/structure/chair/comfy/beige/old, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old grey comfy chair", /obj/structure/chair/comfy/grey/old, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old orange comfy chair", /obj/structure/chair/comfy/orange/old, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old blue comfy chair", /obj/structure/chair/comfy/blue/old, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old red comfy chair", /obj/structure/chair/comfy/red/old, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old olive comfy chair", /obj/structure/chair/comfy/olive/old, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe_list("comfy chairs (old - alt)", list( \
+ new/datum/stack_recipe("old purple comfy chair (alt)", /obj/structure/chair/comfy/purple/old/alt, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old beige comfy chair (alt)", /obj/structure/chair/comfy/beige/old/alt, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old grey comfy chair (alt)", /obj/structure/chair/comfy/grey/old/alt, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old orange comfy chair (alt)", /obj/structure/chair/comfy/orange/old/alt, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old blue comfy chair (alt)", /obj/structure/chair/comfy/blue/old/alt, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old red comfy chair (alt)", /obj/structure/chair/comfy/red/old/alt, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old olive comfy chair (alt)", /obj/structure/chair/comfy/olive/old/alt, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe_list("comfy chairs (corpo)", list( \
+ new/datum/stack_recipe("purple corpo chair", /obj/structure/chair/comfy/purple/corpo, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("beige corpo chair", /obj/structure/chair/comfy/beige/corpo, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("grey corpo chair", /obj/structure/chair/comfy/grey/corpo, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("orange corpo chair", /obj/structure/chair/comfy/orange/corpo, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("blue corpo chair", /obj/structure/chair/comfy/blue/corpo, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("red corpo chair", /obj/structure/chair/comfy/red/corpo, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("olive corpo chair", /obj/structure/chair/comfy/olive/corpo, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe_list("sofas", list( \
+ // New brown Sofa
+ new/datum/stack_recipe("brown sofa (middle)", /obj/structure/chair/sofa/brown, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("brown sofa (left)", /obj/structure/chair/sofa/brown/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("brown sofa (right)", /obj/structure/chair/sofa/brown/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("brown sofa (corner)", /obj/structure/chair/sofa/brown/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("brown sofa (internal corner)", /obj/structure/chair/sofa/brown/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // New purple sofa
+ new/datum/stack_recipe("purple sofa (middle)", /obj/structure/chair/sofa/purple, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("purple sofa (left)", /obj/structure/chair/sofa/purple/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("purple sofa (right)", /obj/structure/chair/sofa/purple/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("purple sofa (corner)", /obj/structure/chair/sofa/purple/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("purple sofa (internal corner)", /obj/structure/chair/sofa/purple/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // New blue Sofa
+ new/datum/stack_recipe("blue sofa (middle)", /obj/structure/chair/sofa/blue, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("blue sofa (left)", /obj/structure/chair/sofa/blue/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("blue sofa (right)", /obj/structure/chair/sofa/blue/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("blue sofa (corner)", /obj/structure/chair/sofa/blue/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("blue sofa (internal corner)", /obj/structure/chair/sofa/blue/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // New red Sofa
+ new/datum/stack_recipe("red sofa (middle)", /obj/structure/chair/sofa/red, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("red sofa (left)", /obj/structure/chair/sofa/red/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("red sofa (right)", /obj/structure/chair/sofa/red/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("red sofa (corner)", /obj/structure/chair/sofa/red/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("red sofa (internal corner)", /obj/structure/chair/sofa/red/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // New grey Sofa
+ new/datum/stack_recipe("grey sofa (middle)", /obj/structure/chair/sofa/grey, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("grey sofa (left)", /obj/structure/chair/sofa/grey/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("grey sofa (right)", /obj/structure/chair/sofa/grey/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("grey sofa (corner)", /obj/structure/chair/sofa/grey/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("grey sofa (internal corner)", /obj/structure/chair/sofa/grey/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // New olive Sofa
+ new/datum/stack_recipe("olive sofa (middle)", /obj/structure/chair/sofa/olive, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("olive sofa (left)", /obj/structure/chair/sofa/olive/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("olive sofa (right)", /obj/structure/chair/sofa/olive/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("olive sofa (corner)", /obj/structure/chair/sofa/olive/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("olive sofa (internal corner)", /obj/structure/chair/sofa/olive/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe_list("sofas (old)", list(
+ // Old brown Sofa
+ new/datum/stack_recipe("old brown sofa (middle)", /obj/structure/chair/sofa/brown/old, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old brown sofa (left)", /obj/structure/chair/sofa/brown/old/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old brown sofa (right)", /obj/structure/chair/sofa/brown/old/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old brown sofa (corner)", /obj/structure/chair/sofa/brown/old/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old brown sofa (internal corner)", /obj/structure/chair/sofa/brown/old/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Old purple Sofa
+ new/datum/stack_recipe("old purple sofa (middle)", /obj/structure/chair/sofa/purple/old, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old purple sofa (left)", /obj/structure/chair/sofa/purple/old/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old purple sofa (right)", /obj/structure/chair/sofa/purple/old/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old purple sofa (corner)", /obj/structure/chair/sofa/purple/old/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old purple sofa (internal corner)", /obj/structure/chair/sofa/purple/old/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Old blue Sofa
+ new/datum/stack_recipe("old blue sofa (middle)", /obj/structure/chair/sofa/blue/old, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old blue sofa (left)", /obj/structure/chair/sofa/blue/old/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old blue sofa (right)", /obj/structure/chair/sofa/blue/old/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old blue sofa (corner)", /obj/structure/chair/sofa/blue/old/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old blue sofa (internal corner)", /obj/structure/chair/sofa/blue/old/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Old red Sofa
+ new/datum/stack_recipe("old red sofa (middle)", /obj/structure/chair/sofa/red/old, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old red sofa (left)", /obj/structure/chair/sofa/red/old/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old red sofa (right)", /obj/structure/chair/sofa/red/old/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old red sofa (corner)", /obj/structure/chair/sofa/red/old/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old red sofa (internal corner)", /obj/structure/chair/sofa/red/old/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Old grey Sofa
+ new/datum/stack_recipe("old grey sofa (middle)", /obj/structure/chair/sofa/grey/old, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old grey sofa (left)", /obj/structure/chair/sofa/grey/old/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old grey sofa (right)", /obj/structure/chair/sofa/grey/old/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old grey sofa (corner)", /obj/structure/chair/sofa/grey/old/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old grey sofa (internal corner)", /obj/structure/chair/sofa/grey/old/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Old olive Sofa
+ new/datum/stack_recipe("old olive sofa (middle)", /obj/structure/chair/sofa/olive/old, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old olive sofa (left)", /obj/structure/chair/sofa/olive/old/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old olive sofa (right)", /obj/structure/chair/sofa/olive/old/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old olive sofa (corner)", /obj/structure/chair/sofa/olive/old/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("old olive sofa (internal corner)", /obj/structure/chair/sofa/olive/old/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe_list("sofas (corpo)", list(
+ // Corpo brown Sofa
+ new/datum/stack_recipe("corpo brown sofa (middle)", /obj/structure/chair/sofa/brown/corpo, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo brown sofa (left)", /obj/structure/chair/sofa/brown/corpo/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo brown sofa (right)", /obj/structure/chair/sofa/brown/corpo/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo brown sofa (corner)", /obj/structure/chair/sofa/brown/corpo/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo brown sofa (internal corner)", /obj/structure/chair/sofa/brown/corpo/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Corpo purple Sofa
+ new/datum/stack_recipe("corpo purple sofa (middle)", /obj/structure/chair/sofa/purple/corpo, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo purple sofa (left)", /obj/structure/chair/sofa/purple/corpo/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo purple sofa (right)", /obj/structure/chair/sofa/purple/corpo/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo purple sofa (corner)", /obj/structure/chair/sofa/purple/corpo/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo purple sofa (internal corner)", /obj/structure/chair/sofa/purple/corpo/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Corpo blue Sofa
+ new/datum/stack_recipe("corpo blue sofa (middle)", /obj/structure/chair/sofa/blue/corpo, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo blue sofa (left)", /obj/structure/chair/sofa/blue/corpo/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo blue sofa (right)", /obj/structure/chair/sofa/blue/corpo/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo blue sofa (corner)", /obj/structure/chair/sofa/blue/corpo/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo blue sofa (internal corner)", /obj/structure/chair/sofa/blue/corpo/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Corpo red Sofa
+ new/datum/stack_recipe("corpo red sofa (middle)", /obj/structure/chair/sofa/red/corpo, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo red sofa (left)", /obj/structure/chair/sofa/red/corpo/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo red sofa (right)", /obj/structure/chair/sofa/red/corpo/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo red sofa (corner)", /obj/structure/chair/sofa/red/corpo/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo red sofa (internal corner)", /obj/structure/chair/sofa/red/corpo/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Corpo grey Sofa
+ new/datum/stack_recipe("corpo grey sofa (middle)", /obj/structure/chair/sofa/grey/corpo, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo grey sofa (left)", /obj/structure/chair/sofa/grey/corpo/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo grey sofa (right)", /obj/structure/chair/sofa/grey/corpo/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo grey sofa (corner)", /obj/structure/chair/sofa/grey/corpo/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo grey sofa (internal corner)", /obj/structure/chair/sofa/grey/corpo/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ // Corpo olive Sofa
+ new/datum/stack_recipe("corpo olive sofa (middle)", /obj/structure/chair/sofa/olive/corpo, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo olive sofa (left)", /obj/structure/chair/sofa/olive/corpo/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo olive sofa (right)", /obj/structure/chair/sofa/olive/corpo/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo olive sofa (corner)", /obj/structure/chair/sofa/olive/corpo/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("corpo olive sofa (internal corner)", /obj/structure/chair/sofa/olive/corpo/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ null, \
+ new/datum/stack_recipe("rack parts", /obj/item/rack_parts), \
+ new/datum/stack_recipe("crate shelf parts", /obj/item/rack_parts/shelf), \
+ new/datum/stack_recipe_list("closets", list(
+ new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("emergency closet", /obj/structure/closet/emcloset/empty, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("fire-safety closet", /obj/structure/closet/firecloset/empty, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("tool closet", /obj/structure/closet/toolcloset/empty, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("radiation closet", /obj/structure/closet/radiation/empty, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE)
+ )),
+ null, \
+ new/datum/stack_recipe_list("crates", list(
+ new/datum/stack_recipe("crate", /obj/structure/closet/crate, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("internals crate", /obj/structure/closet/crate/internals, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("engineering crate", /obj/structure/closet/crate/engineering, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("medical crate", /obj/structure/closet/crate/medical, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("science crate", /obj/structure/closet/crate/science, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
+ new/datum/stack_recipe("hydroponics crate", /obj/structure/closet/crate/hydroponics, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE)
+ )),
+ null, \
+ new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
+ null, \
+ new/datum/stack_recipe("plasteel floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \
+ new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \
+ null, \
+ new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE, trait_booster = TRAIT_QUICK_BUILD, trait_modifier = 0.75), \
+ null, \
+ new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("machine frame", /obj/structure/frame/machine, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ null, \
+ new/datum/stack_recipe_list("airlock assemblies", list( \
+ new/datum/stack_recipe("standard airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("public airlock assembly", /obj/structure/door_assembly/door_assembly_public, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("command airlock assembly", /obj/structure/door_assembly/door_assembly_com, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("security airlock assembly", /obj/structure/door_assembly/door_assembly_sec, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("engineering airlock assembly", /obj/structure/door_assembly/door_assembly_eng, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("mining airlock assembly", /obj/structure/door_assembly/door_assembly_min, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("atmospherics airlock assembly", /obj/structure/door_assembly/door_assembly_atmo, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("research airlock assembly", /obj/structure/door_assembly/door_assembly_research, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("freezer airlock assembly", /obj/structure/door_assembly/door_assembly_fre, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("science airlock assembly", /obj/structure/door_assembly/door_assembly_science, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("medical airlock assembly", /obj/structure/door_assembly/door_assembly_med, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("virology airlock assembly", /obj/structure/door_assembly/door_assembly_viro, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_mai, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("external airlock assembly", /obj/structure/door_assembly/door_assembly_ext, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("external maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_extmai, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("airtight hatch assembly", /obj/structure/door_assembly/door_assembly_hatch, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("maintenance hatch assembly", /obj/structure/door_assembly/door_assembly_mhatch, 4, time = 50, one_per_turf = 1, on_floor = 1), \
+ )), \
+ null, \
+ new/datum/stack_recipe("firelock frame (fulltile)", /obj/structure/firelock_frame, 3, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("firelock frame (directional)", /obj/structure/firelock_frame/border, 1, time = 25, on_floor = TRUE), \
+ new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("meatspike frame", /obj/structure/kitchenspike_frame, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("reflector frame", /obj/structure/reflector, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ null, \
+ new/datum/stack_recipe("grenade casing", /obj/item/grenade/chem_grenade), \
+ new/datum/stack_recipe("light fixture frame", /obj/item/wallframe/light_fixture, 2), \
+ new/datum/stack_recipe("small light fixture frame", /obj/item/wallframe/light_fixture/small, 1), \
+ null, \
+ new/datum/stack_recipe("apc frame", /obj/item/wallframe/apc, 2), \
+ new/datum/stack_recipe("air alarm frame", /obj/item/wallframe/airalarm, 2), \
+ new/datum/stack_recipe("airlock controller frame", /obj/item/wallframe/advanced_airlock_controller, 2), \
+ new/datum/stack_recipe("fire alarm frame", /obj/item/wallframe/firealarm, 2), \
+ new/datum/stack_recipe("extinguisher cabinet frame", /obj/item/wallframe/extinguisher_cabinet, 2), \
+ new/datum/stack_recipe("button frame", /obj/item/wallframe/button, 1), \
+ null, \
+ new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("voting box", /obj/structure/votebox, 15, time = 50), \
+ new/datum/stack_recipe("mortar", /obj/item/reagent_containers/glass/mortar/metal, 3), \
+ new/datum/stack_recipe("pestle", /obj/item/pestle, 1, time = 50), \
+ new/datum/stack_recipe("hygienebot assembly", /obj/item/bot_assembly/hygienebot, 2, time = 50), \
+ new/datum/stack_recipe_list("weight machines", list( \
+ new/datum/stack_recipe("chest press", /obj/structure/weightmachine/stacklifter, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("bench press", /obj/structure/weightmachine/weightlifter, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ )), \
+ new/datum/stack_recipe("shower", /obj/machinery/shower, 3, time = 25)
+))
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 09b2338b244f..ead6b8aeb8f1 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -14,112 +14,6 @@
/*
* Metal
*/
-GLOBAL_LIST_INIT(metal_recipes, list ( \
- new/datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("double bed", /obj/structure/bed/double, 4, one_per_turf = TRUE, on_floor = TRUE), \
- null, \
- new/datum/stack_recipe_list("office chairs", list( \
- new/datum/stack_recipe("gray office chair", /obj/structure/chair/office, 5, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("light office chair", /obj/structure/chair/office/light, 5, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("dark office chair", /obj/structure/chair/office/dark, 5, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("purple office chair", /obj/structure/chair/office/purple, 5, one_per_turf = TRUE, on_floor = TRUE), \
- )), \
- new/datum/stack_recipe_list("comfy chairs", list( \
- new/datum/stack_recipe("beige comfy chair", /obj/structure/chair/comfy/beige, 2, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("black comfy chair", /obj/structure/chair/comfy/black, 2, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("brown comfy chair", /obj/structure/chair/comfy/brown, 2, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("lime comfy chair", /obj/structure/chair/comfy/lime, 2, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("teal comfy chair", /obj/structure/chair/comfy/teal, 2, one_per_turf = TRUE, on_floor = TRUE), \
- )), \
- new/datum/stack_recipe_list("sofas", list(
- new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, 1, one_per_turf = TRUE, on_floor = TRUE),
- new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, 1, one_per_turf = TRUE, on_floor = TRUE),
- new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/right, 1, one_per_turf = TRUE, on_floor = TRUE),
- new /datum/stack_recipe("sofa (corner)", /obj/structure/chair/sofa/corner, 1, one_per_turf = TRUE, on_floor = TRUE),
- new /datum/stack_recipe("red sofa (middle)", /obj/structure/chair/sofa/red, 1, one_per_turf = TRUE, on_floor = TRUE),
- new /datum/stack_recipe("red sofa (left)", /obj/structure/chair/sofa/left, 1, one_per_turf = TRUE, on_floor = TRUE),
- new /datum/stack_recipe("red sofa (right)", /obj/structure/chair/sofa/red/right, 1, one_per_turf = TRUE, on_floor = TRUE),
- new /datum/stack_recipe("red sofa (corner)", /obj/structure/chair/sofa/red/corner, 1, one_per_turf = TRUE, on_floor = TRUE),
- new /datum/stack_recipe("red sofa (internal corner)", /obj/structure/chair/sofa/red/internal_corner, 1, one_per_turf = TRUE, on_floor = TRUE)
- )),
- null, \
- new/datum/stack_recipe("rack parts", /obj/item/rack_parts), \
- new/datum/stack_recipe("crate shelf parts", /obj/item/rack_parts/shelf), \
- new/datum/stack_recipe_list("closets", list(
- new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("emergency closet", /obj/structure/closet/emcloset/empty, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("fire-safety closet", /obj/structure/closet/firecloset/empty, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("tool closet", /obj/structure/closet/toolcloset/empty, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("radiation closet", /obj/structure/closet/radiation/empty, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE)
- )),
- null, \
- new/datum/stack_recipe_list("crates", list(
- new/datum/stack_recipe("crate", /obj/structure/closet/crate, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("internals crate", /obj/structure/closet/crate/internals, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("engineering crate", /obj/structure/closet/crate/engineering, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("medical crate", /obj/structure/closet/crate/medical, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("science crate", /obj/structure/closet/crate/science, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE),
- new/datum/stack_recipe("hydroponics crate", /obj/structure/closet/crate/hydroponics, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE)
- )),
- null, \
- new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
- null, \
- new/datum/stack_recipe("plasteel floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \
- new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \
- null, \
- new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE, trait_booster = TRAIT_QUICK_BUILD, trait_modifier = 0.75), \
- null, \
- new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("machine frame", /obj/structure/frame/machine, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
- null, \
- new /datum/stack_recipe_list("airlock assemblies", list( \
- new /datum/stack_recipe("standard airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("public airlock assembly", /obj/structure/door_assembly/door_assembly_public, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("command airlock assembly", /obj/structure/door_assembly/door_assembly_com, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("security airlock assembly", /obj/structure/door_assembly/door_assembly_sec, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("engineering airlock assembly", /obj/structure/door_assembly/door_assembly_eng, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("mining airlock assembly", /obj/structure/door_assembly/door_assembly_min, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("atmospherics airlock assembly", /obj/structure/door_assembly/door_assembly_atmo, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("research airlock assembly", /obj/structure/door_assembly/door_assembly_research, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("freezer airlock assembly", /obj/structure/door_assembly/door_assembly_fre, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("science airlock assembly", /obj/structure/door_assembly/door_assembly_science, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("medical airlock assembly", /obj/structure/door_assembly/door_assembly_med, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("virology airlock assembly", /obj/structure/door_assembly/door_assembly_viro, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_mai, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("external airlock assembly", /obj/structure/door_assembly/door_assembly_ext, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("external maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_extmai, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("airtight hatch assembly", /obj/structure/door_assembly/door_assembly_hatch, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new /datum/stack_recipe("maintenance hatch assembly", /obj/structure/door_assembly/door_assembly_mhatch, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- )), \
- null, \
- new/datum/stack_recipe("firelock frame (fulltile)", /obj/structure/firelock_frame, 3, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("firelock frame (directional)", /obj/structure/firelock_frame/border, 1, time = 25, on_floor = TRUE), \
- new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("meatspike frame", /obj/structure/kitchenspike_frame, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("reflector frame", /obj/structure/reflector, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
- null, \
- new/datum/stack_recipe("grenade casing", /obj/item/grenade/chem_grenade), \
- new/datum/stack_recipe("light fixture frame", /obj/item/wallframe/light_fixture, 2), \
- new/datum/stack_recipe("small light fixture frame", /obj/item/wallframe/light_fixture/small, 1), \
- null, \
- new/datum/stack_recipe("apc frame", /obj/item/wallframe/apc, 2), \
- new/datum/stack_recipe("air alarm frame", /obj/item/wallframe/airalarm, 2), \
- new/datum/stack_recipe("airlock controller frame", /obj/item/wallframe/advanced_airlock_controller, 2), \
- new/datum/stack_recipe("fire alarm frame", /obj/item/wallframe/firealarm, 2), \
- new/datum/stack_recipe("extinguisher cabinet frame", /obj/item/wallframe/extinguisher_cabinet, 2), \
- new/datum/stack_recipe("button frame", /obj/item/wallframe/button, 1), \
- null, \
- new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("voting box", /obj/structure/votebox, 15, time = 50), \
- new/datum/stack_recipe("mortar", /obj/item/reagent_containers/glass/mortar/metal, 3), \
- new/datum/stack_recipe("pestle", /obj/item/pestle, 1, time = 50), \
- new/datum/stack_recipe("hygienebot assembly", /obj/item/bot_assembly/hygienebot, 2, time = 50), \
- new/datum/stack_recipe("shower", /obj/machinery/shower, 3, time = 25)
-))
/obj/item/stack/sheet/metal
name = "metal"
@@ -137,10 +31,6 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
tableVariant = /obj/structure/table
material_type = /datum/material/iron
-/obj/item/stack/sheet/metal/narsie_act()
- new /obj/item/stack/sheet/runed_metal(loc, amount)
- qdel(src)
-
/obj/item/stack/sheet/metal/fifty
amount = 50
@@ -165,7 +55,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
/*
* Plasteel
*/
-// WS Begin: carpet
+
GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \
new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \
@@ -185,7 +75,6 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("shutters frame", /obj/structure/poddoor_assembly/shutters, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("blast door frame", /obj/structure/poddoor_assembly, 15, time = 50, one_per_turf = 1, on_floor = 1)
))
-// WS End: carpet
/obj/item/stack/sheet/plasteel
name = "plasteel"
@@ -252,6 +141,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("loom", /obj/structure/loom, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("mortar", /obj/item/reagent_containers/glass/mortar, 3), \
new/datum/stack_recipe("firebrand", /obj/item/match/firebrand, 2, time = 100), \
+ new/datum/stack_recipe("torch", /obj/item/candle/tribal_torch, 4, time = 30), \
null, \
new/datum/stack_recipe_list("pews", list(
new /datum/stack_recipe("pew (middle)", /obj/structure/chair/pew, 3, one_per_turf = TRUE, on_floor = TRUE),
@@ -331,9 +221,9 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \
force = 0
throwforce = 0
merge_type = /obj/item/stack/sheet/cotton
- var/pull_effort = 30
- var/loom_result = /obj/item/stack/sheet/cotton/cloth
grind_results = list(/datum/reagent/cellulose = 20)
+ var/pull_effort = 10
+ var/loom_result = /obj/item/stack/sheet/cotton/cloth
GLOBAL_LIST_INIT(cloth_recipes, list ( \
new/datum/stack_recipe("white jumpskirt", /obj/item/clothing/under/color/jumpskirt/white, 3), /*Ladies first*/ \
@@ -355,6 +245,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
new/datum/stack_recipe("rag", /obj/item/reagent_containers/glass/rag, 1), \
new/datum/stack_recipe("towel", /obj/item/towel, 2), \
new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \
+ new/datum/stack_recipe("double bedsheet", /obj/item/bedsheet/double, 4), \
new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \
null, \
new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \
@@ -367,6 +258,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
new/datum/stack_recipe("19x19 canvas", /obj/item/canvas/nineteenXnineteen, 3), \
new/datum/stack_recipe("23x19 canvas", /obj/item/canvas/twentythreeXnineteen, 4), \
new/datum/stack_recipe("23x23 canvas", /obj/item/canvas/twentythreeXtwentythree, 5), \
+ new/datum/stack_recipe("punching bag", /obj/structure/punching_bag, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
))
/obj/item/stack/sheet/cotton/cloth
@@ -447,7 +339,6 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \
singular_name = "raw durathread ball"
icon_state = "sheet-durathreadraw"
merge_type = /obj/item/stack/sheet/cotton/durathread
- pull_effort = 70
loom_result = /obj/item/stack/sheet/durathread
grind_results = list()
@@ -548,52 +439,6 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
else
. = ..()
-
-/*
- * Runed Metal
- */
-
-GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
- new/datum/stack_recipe("runed door", /obj/machinery/door/airlock/cult, 1, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("runed girder", /obj/structure/girder/cult, 1, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("pylon", /obj/structure/destructible/cult/pylon, 4, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("forge", /obj/structure/destructible/cult/forge, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("archives", /obj/structure/destructible/cult/tome, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("altar", /obj/structure/destructible/cult/talisman, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
- ))
-
-/obj/item/stack/sheet/runed_metal
- name = "runed metal"
- desc = "Sheets of cold metal with shifting inscriptions writ upon them."
- singular_name = "runed metal sheet"
- icon_state = "sheet-runed"
- item_state = "sheet-runed"
- icon = 'icons/obj/stack_objects.dmi'
- custom_materials = list(/datum/material/runedmetal = MINERAL_MATERIAL_AMOUNT)
- merge_type = /obj/item/stack/sheet/runed_metal
- novariants = TRUE
- grind_results = list(/datum/reagent/iron = 5, /datum/reagent/blood = 15)
- material_type = /datum/material/runedmetal
-
-/obj/item/stack/sheet/runed_metal/attack_self(mob/living/user)
- if(!iscultist(user))
- to_chat(user, "Only one with forbidden knowledge could hope to work this metal...")
- return FALSE
- return ..()
-
-/obj/item/stack/sheet/runed_metal/get_main_recipes()
- . = ..()
- . += GLOB.runed_metal_recipes
-
-/obj/item/stack/sheet/runed_metal/fifty
- amount = 50
-
-/obj/item/stack/sheet/runed_metal/ten
- amount = 10
-
-/obj/item/stack/sheet/runed_metal/five
- amount = 5
-
/*
* Bronze
*/
diff --git a/code/game/objects/items/stacks/tape.dm b/code/game/objects/items/stacks/tape.dm
index d22b1be85344..63fc55116d5a 100644
--- a/code/game/objects/items/stacks/tape.dm
+++ b/code/game/objects/items/stacks/tape.dm
@@ -80,7 +80,8 @@
grind_results = list(/datum/reagent/cellulose = 5)
usesound = 'sound/items/tape.ogg'
- var/stop_bleed = 600
+ var/lifespan = 300
+ var/bleed_reduction = 0.002
var/nonorganic_heal = 5
var/self_delay = 30 //! Also used for the tapecuff delay
var/other_delay = 10
@@ -114,7 +115,7 @@
return
if(use(1))
playsound(loc, usesound, 30, TRUE, -2)
- if(do_mob(user, C, other_delay) && (!C.is_mouth_covered() || !C.is_muzzled()))
+ if(do_after(user, other_delay, C) && (!C.is_mouth_covered() || !C.is_muzzled()))
apply_gag(C, user)
C.visible_message("[user] tapes [C]s mouth shut.", \
"[user] taped your mouth shut!")
@@ -134,7 +135,7 @@
"[user] is trying to put [src.name] on you!")
playsound(loc, usesound, 30, TRUE, -2)
- if(do_mob(user, C, self_delay) && (C.canBeHandcuffed()))
+ if(do_after(user, self_delay, C) && (C.canBeHandcuffed()))
apply_tapecuffs(C, user)
C.visible_message("[user] tapecuffs [C].", \
"[user] tapecuffs you.")
@@ -152,11 +153,11 @@
if(C == user)
playsound(loc, usesound, 30, TRUE, -2)
user.visible_message("[user] starts to apply \the [src] on [user.p_them()]self...", "You begin applying \the [src] on yourself...")
- if(!do_mob(user, C, self_delay, extra_checks=CALLBACK(C, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
+ if(!do_after(user, self_delay, C, extra_checks=CALLBACK(C, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
return
else if(other_delay)
user.visible_message("[user] starts to apply \the [src] on [C].", "You begin applying \the [src] on [C]...")
- if(!do_mob(user, C, other_delay, extra_checks=CALLBACK(C, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
+ if(!do_after(user, other_delay, C, extra_checks=CALLBACK(C, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
return
if(heal(C, user))
@@ -173,21 +174,17 @@
if(!affecting) //Missing limb?
to_chat(user, "[C] doesn't have \a [parse_zone(user.zone_selected)]!")
return
- if(!IS_ORGANIC_LIMB(affecting))
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(!H.bleedsuppress && H.bleed_rate)
- H.suppress_bloodloss(stop_bleed)
- to_chat(user, "You tape up the bleeding of [C]!")
- return TRUE
- to_chat(user, "[C] has a problem \the [src] won't fix!")
- else //Robotic patch-up
+ if(IS_ROBOTIC_LIMB(affecting)) //Robotic patch-up
if(affecting.brute_dam)
user.visible_message("[user] applies \the [src] on [C]'s [affecting.name].", "You apply \the [src] on [C]'s [affecting.name].")
if(affecting.heal_damage(nonorganic_heal))
C.update_damage_overlays()
return TRUE
- to_chat(user, "[src] can't patch what [C] has...")
+ if(affecting.can_bandage(user))
+ affecting.apply_bandage(bleed_reduction, lifespan, name)
+ to_chat(user, "You tape up [C]'s [parse_zone(affecting.body_zone)]!")
+ return TRUE
+ to_chat(user, "[src] can't patch what [C] has...")
/obj/item/stack/tape/proc/apply_gag(mob/living/carbon/target, mob/user)
if(target.is_muzzled() || target.is_mouth_covered())
@@ -272,7 +269,7 @@
desc = "This roll of silver sorcery can fix just about anything."
icon_state = "tape_d"
- stop_bleed = 800
+ lifespan = 400
nonorganic_heal = 20
prefix = "super sticky"
conferred_embed = EMBED_HARMLESS_SUPERIOR
@@ -297,7 +294,6 @@
desc = "Specialty insulated strips of adhesive plastic. Made for securing cables."
icon_state = "tape_e"
- stop_bleed = 400
nonorganic_heal = 10
prefix = "insulated sticky"
siemens_coefficient = 0
@@ -321,6 +317,6 @@
desc = "Now THIS is engineering."
icon_state = "tape_y"
- stop_bleed = 1000
+ lifespan = 500
nonorganic_heal = 30
prefix = "industry-standard sticky"
diff --git a/code/game/objects/items/stacks/tiles/tile_mineral.dm b/code/game/objects/items/stacks/tiles/tile_mineral.dm
index c5e05b5212fc..ad00f3902c50 100644
--- a/code/game/objects/items/stacks/tiles/tile_mineral.dm
+++ b/code/game/objects/items/stacks/tiles/tile_mineral.dm
@@ -48,16 +48,6 @@
mineralType = "diamond"
custom_materials = list(/datum/material/diamond=500)
-/obj/item/stack/tile/mineral/bananium
- name = "bananium tile"
- singular_name = "bananium floor tile"
- desc = "A tile made out of bananium, HOOOOOOOOONK!"
- icon_state = "tile_bananium"
- item_state = "tile-bananium"
- turf_type = /turf/open/floor/mineral/bananium
- mineralType = "bananium"
- custom_materials = list(/datum/material/bananium=500)
-
/obj/item/stack/tile/mineral/abductor
name = "alien floor tile"
singular_name = "alien floor tile"
diff --git a/code/game/objects/items/stacks/tiles/tiles_suns.dm b/code/game/objects/items/stacks/tiles/tiles_suns.dm
new file mode 100644
index 000000000000..fd9d85ff4bf1
--- /dev/null
+++ b/code/game/objects/items/stacks/tiles/tiles_suns.dm
@@ -0,0 +1,64 @@
+/obj/item/stack/tile/suns
+ name = "white marble tile"
+ singular_name = "white marble floor tile"
+ icon_state = "tile_suns_light"
+ turf_type = /turf/open/floor/suns
+ tile_reskin_types = list(
+ /obj/item/stack/tile/suns/plain,
+ /obj/item/stack/tile/suns/pattern,
+ /obj/item/stack/tile/suns/hatch,
+ /obj/item/stack/tile/suns/diagonal,
+ /obj/item/stack/tile/suns/grid,
+ /obj/item/stack/tile/suns/dark,
+ /obj/item/stack/tile/suns/dark/plain,
+ /obj/item/stack/tile/suns/dark/pattern)
+
+/obj/item/stack/tile/suns/plain
+ name = "white plain marble tile"
+ singular_name = "white plain marble floor tile"
+ icon_state = "tile_suns_lightplain"
+ turf_type = /turf/open/floor/suns/plain
+
+/obj/item/stack/tile/suns/pattern
+ name = "patterned white marble tile"
+ singular_name = "patterned white marble floor tile"
+ icon_state = "tile_suns_lightpattern"
+ turf_type = /turf/open/floor/suns/pattern
+
+/obj/item/stack/tile/suns/hatch
+ name = "hatched wood tile"
+ singular_name = "hatched wood floor tile"
+ icon_state = "tile_suns_lighthatched"
+ turf_type = /turf/open/floor/suns/hatch
+
+/obj/item/stack/tile/suns/diagonal
+ name = "diagonal wooden tile"
+ singular_name = "diagonal wooden floor tile"
+ icon_state = "tile_suns_lightdiag"
+ turf_type = /turf/open/floor/suns/diagonal
+
+/obj/item/stack/tile/suns/grid
+ name = "dark grid tile"
+ singular_name = "dark grid floor floor tile"
+ icon_state = "tile_suns_darkchunky"
+ turf_type = /turf/open/floor/suns/grid
+
+/obj/item/stack/tile/suns/dark
+ name = "black marble tile"
+ singular_name = "black marble floor tile"
+ icon_state = "tile_suns_dark"
+ turf_type = /turf/open/floor/suns/dark
+
+/obj/item/stack/tile/suns/dark/plain
+ name = "black plain marble tile"
+ singular_name = "black plain marble floor tile"
+ icon_state = "tile_suns_darkplain"
+ turf_type = /turf/open/floor/suns/dark/plain
+
+/obj/item/stack/tile/suns/dark/pattern
+ name = "patterned black marble tile"
+ singular_name = "patterned black marble floor tile"
+ icon_state = "tile_suns_darkpattern"
+ turf_type = /turf/open/floor/suns/dark/pattern
+
+
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index ac5b14568dad..92123969a4cd 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -20,7 +20,7 @@
righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
pickup_sound = "rustle"
drop_sound = "rustle"
- w_class = WEIGHT_CLASS_BULKY
+ w_class = WEIGHT_CLASS_HUGE
slot_flags = ITEM_SLOT_BACK //ERROOOOO
resistance_flags = NONE
max_integrity = 300
@@ -31,9 +31,9 @@
/obj/item/storage/backpack/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_combined_w_class = 21
- STR.max_w_class = WEIGHT_CLASS_NORMAL
- STR.max_items = 21
+ STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT
+ STR.max_volume = STORAGE_VOLUME_BACKPACK
+ STR.max_w_class = MAX_WEIGHT_CLASS_BACKPACK
STR.use_sound = 'sound/items/storage/unzip.ogg'
/*
@@ -58,9 +58,8 @@
/obj/item/storage/backpack/holding/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.allow_big_nesting = TRUE
- STR.max_w_class = WEIGHT_CLASS_GIGANTIC
- STR.max_combined_w_class = 35
+ STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT
+ STR.max_volume = STORAGE_VOLUME_BAG_OF_HOLDING
/obj/item/storage/backpack/santabag
name = "Santa's Gift Bag"
@@ -218,10 +217,16 @@
greyscale_colors = list(list(11, 12), list(17, 18), list(10, 11))
supports_variations = VOX_VARIATION
+/obj/item/storage/backpack/satchel/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_volume = STORAGE_VOLUME_BACKPACK
+ STR.max_w_class = MAX_WEIGHT_CLASS_M_CONTAINER
+
/obj/item/storage/backpack/satchel/leather
name = "leather satchel"
desc = "It's a very fancy satchel made with fine leather."
- icon = 'icons/obj/storage.dmi' //WS Edit - Suitcases
+ icon = 'icons/obj/storage.dmi'
icon_state = "satchel"
item_state = "satchel"
@@ -427,11 +432,13 @@
item_state = "duffel"
slowdown = 1
greyscale_colors = list(list(21, 11), list(14, 19), list(15, 16))
+ w_class = WEIGHT_CLASS_HUGE
/obj/item/storage/backpack/duffelbag/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_combined_w_class = 30
+ STR.max_volume = STORAGE_VOLUME_DUFFLEBAG
+ STR.max_w_class = MAX_WEIGHT_CLASS_DUFFEL
LAZYINITLIST(STR.exception_hold) // This code allows you to fit one mob holder into a duffel bag
STR.exception_hold += typecacheof(/obj/item/clothing/head/mob_holder)
@@ -617,7 +624,7 @@
new /obj/item/ammo_box/magazine/smgm45(src)
new /obj/item/ammo_box/magazine/smgm45(src)
new /obj/item/gun/ballistic/automatic/smg/c20r(src)
- new /obj/item/suppressor/specialoffer(src)
+ new /obj/item/attachment/silencer(src)
/obj/item/storage/backpack/duffelbag/syndie/bulldogbundle
desc = "A large duffel bag containing a Bulldog, some drums, and a pair of thermal imaging glasses."
@@ -634,7 +641,7 @@
/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents()
new /obj/item/clothing/shoes/magboots/syndie(src)
new /obj/item/storage/firstaid/tactical(src)
- new /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy(src)
+ new /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/riot(src)
new /obj/item/ammo_box/foambox/riot(src)
/obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle
@@ -644,7 +651,7 @@
new /obj/item/reagent_containers/spray/chemsprayer/bioterror(src)
new /obj/item/storage/box/syndie_kit/chemical(src)
new /obj/item/gun/syringe/syndicate(src)
- new /obj/item/gun/ballistic/automatic/smg/c20r/toy(src)
+ new /obj/item/gun/ballistic/automatic/smg/c20r/toy/riot(src)
new /obj/item/storage/box/syringes(src)
new /obj/item/ammo_box/foambox/riot(src)
new /obj/item/grenade/chem_grenade/bioterrorfoam(src)
diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm
index dc3d2deff0ba..ecee3894ccbb 100644
--- a/code/game/objects/items/storage/bags.dm
+++ b/code/game/objects/items/storage/bags.dm
@@ -45,10 +45,12 @@
/obj/item/storage/bag/trash/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_w_class = WEIGHT_CLASS_SMALL
- STR.max_combined_w_class = 30
- STR.max_items = 30
+ STR.max_w_class = WEIGHT_CLASS_NORMAL
+ STR.max_combined_w_class = 50
+ STR.max_items = 50
STR.set_holdable(null, list(/obj/item/disk/nuclear))
+ STR.limited_random_access = TRUE
+ STR.limited_random_access_stack_position = 3
/obj/item/storage/bag/trash/update_icon_state()
switch(contents.len)
@@ -83,8 +85,9 @@
/obj/item/storage/bag/trash/bluespace/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_combined_w_class = 60
- STR.max_items = 60
+ STR.max_combined_w_class = 75
+ STR.max_items = 75
+ STR.max_w_class = WEIGHT_CLASS_BULKY
/obj/item/storage/bag/trash/bluespace/cyborg
insertable = FALSE
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index d6ef29b86233..2904745f25aa 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -10,7 +10,7 @@
attack_verb = list("whipped", "lashed", "disciplined")
max_integrity = 300
equip_sound = 'sound/items/equip/toolbelt_equip.ogg'
- w_class = WEIGHT_CLASS_BULKY
+ w_class = WEIGHT_CLASS_NORMAL
var/content_overlays = FALSE //If this is true, the belt will gain overlays based on what it's holding
supports_variations = VOX_VARIATION
greyscale_icon_state = "belt"
@@ -248,6 +248,16 @@
new /obj/item/hypospray/mkii(src)
update_appearance()
+/obj/item/storage/belt/medical/webbing/surgery/PopulateContents()
+ new /obj/item/scalpel(src)
+ new /obj/item/circular_saw(src)
+ new /obj/item/surgicaldrill(src)
+ new /obj/item/retractor(src)
+ new /obj/item/cautery(src)
+ new /obj/item/hemostat(src)
+ new /obj/item/hypospray/mkii(src)
+ update_appearance()
+
/obj/item/storage/belt/security
name = "security belt"
desc = "Can hold security gear like handcuffs and flashes."
@@ -270,7 +280,15 @@
/obj/item/assembly/flash/handheld,
/obj/item/clothing/glasses,
/obj/item/ammo_casing/shotgun,
- /obj/item/ammo_box,
+ /obj/item/ammo_box/magazine,
+ /obj/item/ammo_box/c38, //speed loaders don't have a common path like magazines. pain.
+ /obj/item/ammo_box/a357, //some day we should refactor these into an ammo_box/speedloader type
+ /obj/item/ammo_box/a4570, //but not today
+ /obj/item/ammo_box/a858, //oh boy stripper clips too
+ /obj/item/ammo_box/vickland_a308,
+ /obj/item/ammo_box/a300,
+ /obj/item/ammo_box/aac_300blk_stripper,
+ /obj/item/ammo_box/amagpellet_claris, //that's the last of the clips
/obj/item/reagent_containers/food/snacks/donut,
/obj/item/kitchen/knife/combat,
/obj/item/flashlight/seclite,
@@ -506,13 +524,12 @@
/obj/item/reagent_containers/food/snacks/rofflewaffles,
/obj/item/reagent_containers/food/snacks/donkpocket,
/obj/item/reagent_containers/food/drinks/soda_cans/cola,
- /obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind,
- /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb,
- /obj/item/reagent_containers/food/drinks/soda_cans/starkist,
+ /obj/item/reagent_containers/food/drinks/soda_cans/comet_trail,
+ /obj/item/reagent_containers/food/drinks/soda_cans/tadrixx,
+ /obj/item/reagent_containers/food/drinks/soda_cans/lunapunch,
/obj/item/reagent_containers/food/drinks/soda_cans/space_up,
- /obj/item/reagent_containers/food/drinks/soda_cans/pwr_game,
- /obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime,
- /obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola
+ /obj/item/reagent_containers/food/drinks/soda_cans/pacfuel,
+ /obj/item/reagent_containers/food/drinks/soda_cans/orange_soda
))
new rig_snacks(src)
@@ -592,33 +609,6 @@
/obj/item/multitool = 1)
generate_items_inside(items_inside,src)
-
-/obj/item/storage/belt/wands
- name = "wand belt"
- desc = "A belt designed to hold various rods of power. A veritable fanny pack of exotic magic."
- icon_state = "soulstone"
- item_state = "soulstone"
-
-/obj/item/storage/belt/wands/ComponentInitialize()
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_items = 6
- STR.set_holdable(list(
- /obj/item/gun/magic/wand
- ))
-
-/obj/item/storage/belt/wands/full/PopulateContents()
- new /obj/item/gun/magic/wand/death(src)
- new /obj/item/gun/magic/wand/resurrection(src)
- new /obj/item/gun/magic/wand/polymorph(src)
- new /obj/item/gun/magic/wand/teleport(src)
- new /obj/item/gun/magic/wand/door(src)
- new /obj/item/gun/magic/wand/fireball(src)
-
- for(var/obj/item/gun/magic/wand/W in contents) //All wands in this pack come in the best possible condition
- W.max_charges = initial(W.max_charges)
- W.charges = W.max_charges
-
/obj/item/storage/belt/janitor
name = "janibelt"
desc = "A belt used to hold most janitorial supplies."
@@ -698,6 +688,7 @@
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 40
+ STR.max_combined_w_class = 40
STR.display_numerical_stacking = TRUE
STR.set_holdable(list(
/obj/item/ammo_casing
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index 45fee1d67660..67dba503642d 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -1,3 +1,10 @@
+//need to refactor this.
+GLOBAL_LIST_INIT(biblenames, list("Bible", "Quran", "Scrapbook", "Burning Bible", "Clown Bible", "Banana Bible", "Creeper Bible", "White Bible", "Holy Light", "The God Delusion", "Tome", "The King in Yellow", "Ithaqua", "Scientology", "Melted Bible", "Necronomicon", "Insulationism", "Guru Granth Sahib"))
+//If you get these two lists not matching in size, there will be runtimes and I will hurt you in ways you couldn't even begin to imagine
+// if your bible has no custom itemstate, use one of the existing ones
+GLOBAL_LIST_INIT(biblestates, list("bible", "koran", "scrapbook", "burning", "honk1", "honk2", "creeper", "white", "holylight", "atheist", "tome", "kingyellow", "ithaqua", "scientology", "melted", "necronomicon", "insuls", "gurugranthsahib"))
+GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning", "honk1", "honk2", "creeper", "white", "holylight", "atheist", "tome", "kingyellow", "ithaqua", "scientology", "melted", "necronomicon", "kingyellow", "gurugranthsahib"))
+
/obj/item/storage/book
name = "hollowed book"
desc = "I guess someone didn't like it."
@@ -17,18 +24,6 @@
/obj/item/storage/book/attack_self(mob/user)
to_chat(user, "The pages of [title] have been cut out!")
-GLOBAL_LIST_INIT(biblenames, list("Bible", "Quran", "Scrapbook", "Burning Bible", "Clown Bible", "Banana Bible", "Creeper Bible", "White Bible", "Holy Light", "The God Delusion", "Tome", "The King in Yellow", "Ithaqua", "Scientology", "Melted Bible", "Necronomicon", "Insulationism", "Guru Granth Sahib"))
-//If you get these two lists not matching in size, there will be runtimes and I will hurt you in ways you couldn't even begin to imagine
-// if your bible has no custom itemstate, use one of the existing ones
-GLOBAL_LIST_INIT(biblestates, list("bible", "koran", "scrapbook", "burning", "honk1", "honk2", "creeper", "white", "holylight", "atheist", "tome", "kingyellow", "ithaqua", "scientology", "melted", "necronomicon", "insuls", "gurugranthsahib"))
-GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning", "honk1", "honk2", "creeper", "white", "holylight", "atheist", "tome", "kingyellow", "ithaqua", "scientology", "melted", "necronomicon", "kingyellow", "gurugranthsahib"))
-
-/mob/proc/bible_check() //The bible, if held, might protect against certain things
- var/obj/item/storage/book/bible/B = locate() in src
- if(is_holding(B))
- return B
- return 0
-
/obj/item/storage/book/bible
name = "bible"
desc = "Apply to head repeatedly."
@@ -41,205 +36,6 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning",
var/deity_name = "Christ"
force_string = "holy"
-/obj/item/storage/book/bible/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, FALSE, TRUE)
-
-/obj/item/storage/book/bible/attack_self(mob/living/carbon/human/H)
- if(!istype(H))
- return
- if(!H.can_read(src))
- return FALSE
- // If H is the Chaplain, we can set the icon_state of the bible (but only once!)
- if(!GLOB.bible_icon_state && H.mind.holy_role == HOLY_ROLE_HIGHPRIEST)
- var/dat = "Pick Bible Style
Pick a bible style
"
- for(var/i in 1 to GLOB.biblestates.len)
- var/icon/bibleicon = icon('icons/obj/storage.dmi', GLOB.biblestates[i])
- var/nicename = GLOB.biblenames[i]
- H << browse_rsc(bibleicon, nicename)
- dat += {"
"
- H << browse(dat, "window=editicon;can_close=0;can_minimize=0;size=250x650")
-
-/obj/item/storage/book/bible/Topic(href, href_list)
- if(!usr.canUseTopic(src, BE_CLOSE))
- return
- if(href_list["seticon"] && !GLOB.bible_icon_state)
- var/iconi = text2num(href_list["seticon"])
- var/biblename = GLOB.biblenames[iconi]
- icon_state = GLOB.biblestates[iconi]
- item_state = GLOB.bibleitemstates[iconi]
-
- if(icon_state == "honk1" || icon_state == "honk2")
- var/mob/living/carbon/human/H = usr
- H.dna.add_mutation(CLOWNMUT)
- H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(H), ITEM_SLOT_MASK)
- if(icon_state == "insuls")
- var/mob/living/carbon/human/H =usr
- var/obj/item/clothing/gloves/color/fyellow/insuls = new
- insuls.name = "insuls"
- insuls.desc = "A mere copy of the true insuls."
- insuls.siemens_coefficient = 0.99999
- H.equip_to_slot(insuls, ITEM_SLOT_GLOVES)
- GLOB.bible_icon_state = icon_state
- GLOB.bible_item_state = item_state
-
- SSblackbox.record_feedback("text", "religion_book", 1, "[biblename]")
- usr << browse(null, "window=editicon")
-
-/obj/item/storage/book/bible/proc/bless(mob/living/L, mob/living/user)
- if(GLOB.religious_sect)
- return GLOB.religious_sect.sect_bless(L,user)
- if(!ishuman(L))
- return
- var/mob/living/carbon/human/H = L
- for(var/X in H.bodyparts)
- var/obj/item/bodypart/BP = X
- if(!IS_ORGANIC_LIMB(BP))
- to_chat(user, "[src.deity_name] refuses to heal this metallic taint!")
- return 0
-
- var/heal_amt = 10
- var/list/hurt_limbs = H.get_damaged_bodyparts(1, 1, null, BODYTYPE_ORGANIC)
-
- if(hurt_limbs.len)
- for(var/X in hurt_limbs)
- var/obj/item/bodypart/affecting = X
- if(affecting.heal_damage(heal_amt, heal_amt, null, BODYTYPE_ORGANIC))
- H.update_damage_overlays()
- H.visible_message("[user] heals [H] with the power of [deity_name]!")
- to_chat(H, "May the power of [deity_name] compel you to be healed!")
- playsound(src.loc, "punch", 25, TRUE, -1)
- SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "blessing", /datum/mood_event/blessing)
- return 1
-
-/obj/item/storage/book/bible/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE)
-
- if (!user.IsAdvancedToolUser())
- to_chat(user, "You don't have the dexterity to do this!")
- return
-
- if (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
- to_chat(user, "[src] slips out of your hand and hits your head.")
- user.take_bodypart_damage(10)
- user.Unconscious(400)
- return
-
- var/chaplain = 0
- if(user.mind && (user.mind.holy_role))
- chaplain = 1
-
- if(!chaplain)
- to_chat(user, "The book sizzles in your hands.")
- user.take_bodypart_damage(0,10)
- return
-
- if (!heal_mode)
- return ..()
-
- var/smack = 1
-
- if (M.stat != DEAD)
- if(chaplain && user == M)
- to_chat(user, "You can't heal yourself!")
- return
-
- if(prob(60) && bless(M, user))
- smack = 0
- else if(iscarbon(M))
- var/mob/living/carbon/C = M
- if(!istype(C.head, /obj/item/clothing/head/helmet))
- C.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5, 60)
- to_chat(C, "You feel dumber.")
-
- if(smack)
- M.visible_message("[user] beats [M] over the head with [src]!", \
- "[user] beats [M] over the head with [src]!")
- playsound(src.loc, "punch", 25, TRUE, -1)
- log_combat(user, M, "attacked", src)
-
- else
- M.visible_message("[user] smacks [M]'s lifeless corpse with [src].")
- playsound(src.loc, "punch", 25, TRUE, -1)
-
-/obj/item/storage/book/bible/afterattack(atom/A, mob/user, proximity)
- . = ..()
- if(!proximity)
- return
- if(isfloorturf(A))
- to_chat(user, "You hit the floor with the bible.")
- if(user.mind && (user.mind.holy_role))
- for(var/obj/effect/rune/R in orange(2,user))
- R.invisibility = 0
- if(user?.mind?.holy_role)
- if(A.reagents && A.reagents.has_reagent(/datum/reagent/water)) // blesses all the water in the holder
- to_chat(user, "You bless [A].")
- var/water2holy = A.reagents.get_reagent_amount(/datum/reagent/water)
- A.reagents.del_reagent(/datum/reagent/water)
- A.reagents.add_reagent(/datum/reagent/water/holywater,water2holy)
- if(A.reagents && A.reagents.has_reagent(/datum/reagent/fuel/unholywater)) // yeah yeah, copy pasted code - sue me
- to_chat(user, "You purify [A].")
- var/unholy2clean = A.reagents.get_reagent_amount(/datum/reagent/fuel/unholywater)
- A.reagents.del_reagent(/datum/reagent/fuel/unholywater)
- A.reagents.add_reagent(/datum/reagent/water/holywater,unholy2clean)
- if(istype(A, /obj/item/storage/book/bible) && !istype(A, /obj/item/storage/book/bible/syndicate))
- to_chat(user, "You purify [A], conforming it to your belief.")
- var/obj/item/storage/book/bible/B = A
- B.name = name
- B.icon_state = icon_state
- B.item_state = item_state
- if(istype(A, /obj/item/cult_bastard) && !iscultist(user))
- var/obj/item/cult_bastard/sword = A
- to_chat(user, "You begin to exorcise [sword].")
- playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,TRUE)
- if(do_after(user, 40, target = sword))
- playsound(src,'sound/effects/pray_chaplain.ogg',60,TRUE)
- for(var/obj/item/soulstone/SS in sword.contents)
- SS.usability = TRUE
- for(var/mob/living/simple_animal/shade/EX in SS)
- SSticker.mode.remove_cultist(EX.mind, 1, 0)
- EX.icon_state = "ghost1"
- EX.name = "Purified [EX.name]"
- SS.release_shades(user)
- qdel(SS)
- new /obj/item/nullrod/claymore(get_turf(sword))
- user.visible_message("[user] purifies [sword]!")
- qdel(sword)
- else if(istype(A, /obj/item/soulstone) && !iscultist(user))
- var/obj/item/soulstone/SS = A
- if(SS.purified)
- return
- to_chat(user, "You begin to exorcise [SS].")
- playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,TRUE)
- if(do_after(user, 40, target = SS))
- playsound(src,'sound/effects/pray_chaplain.ogg',60,TRUE)
- SS.usability = TRUE
- SS.purified = TRUE
- SS.icon_state = "purified_soulstone"
- for(var/mob/M in SS.contents)
- if(M.mind)
- SS.icon_state = "purified_soulstone2"
- if(iscultist(M))
- SSticker.mode.remove_cultist(M.mind, FALSE, FALSE)
- for(var/mob/living/simple_animal/shade/EX in SS)
- EX.icon_state = "ghost1"
- EX.name = "Purified [initial(EX.name)]"
- user.visible_message("[user] purifies [SS]!")
- else if(istype(A, /obj/item/nullrod/scythe/talking))
- var/obj/item/nullrod/scythe/talking/sword = A
- to_chat(user, "You begin to exorcise [sword]...")
- playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,TRUE)
- if(do_after(user, 40, target = sword))
- playsound(src,'sound/effects/pray_chaplain.ogg',60,TRUE)
- for(var/mob/living/simple_animal/shade/S in sword.contents)
- to_chat(S, "You were destroyed by the exorcism!")
- qdel(S)
- sword.possessed = FALSE //allows the chaplain (or someone else) to reroll a new spirit for their sword
- sword.name = initial(sword.name)
- REMOVE_TRAIT(sword, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) //in case the "sword" is a possessed dummy
- user.visible_message("[user] exorcises [sword]!", \
- "You successfully exorcise [sword]!")
-
/obj/item/storage/book/bible/koran
name = "Koran"
icon_state = "koran"
@@ -253,34 +49,6 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning",
new /obj/item/reagent_containers/food/drinks/bottle/whiskey(src)
/obj/item/storage/book/bible/syndicate
+ name = "Syndicate Tome"
icon_state ="ebook"
deity_name = "The Syndicate"
- throw_speed = 2
- throwforce = 18
- throw_range = 7
- force = 18
- hitsound = 'sound/weapons/sear.ogg'
- damtype = BURN
- name = "Syndicate Tome"
- attack_verb = list("attacked", "burned", "blessed", "damned", "scorched")
- var/uses = 1
-
-/obj/item/storage/book/bible/syndicate/attack_self(mob/living/carbon/human/H)
- if (uses)
- H.mind.holy_role = HOLY_ROLE_PRIEST
- uses -= 1
- to_chat(H, "You try to open the book AND IT BITES YOU!")
- playsound(src.loc, 'sound/effects/snap.ogg', 50, TRUE)
- H.apply_damage(5, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
- to_chat(H, "Your name appears on the inside cover, in blood.")
- var/ownername = H.real_name
- desc += "The name [ownername] is written in blood inside the cover."
-
-/obj/item/storage/book/bible/syndicate/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE)
- if (user.a_intent == INTENT_HELP)
- return ..()
- else
- return ..(M,user,heal_mode = FALSE)
-
-/obj/item/storage/book/bible/syndicate/add_blood_DNA(list/blood_dna)
- return FALSE
diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm
index 3c9395208fad..8aa7b1d9c478 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -121,9 +121,15 @@
var/mask_type = /obj/item/clothing/mask/breath
var/internal_type = /obj/item/tank/internals/emergency_oxygen
var/medipen_type = /obj/item/reagent_containers/hypospray/medipen
+ var/radio_type = /obj/item/radio
/obj/item/storage/box/survival/PopulateContents()
- new mask_type(src)
+ if(!isnull(mask_type))
+ new mask_type(src)
+
+ if(!isnull(radio_type))
+ new radio_type(src)
+
if(!isnull(medipen_type))
new medipen_type(src)
@@ -132,10 +138,6 @@
else
new /obj/item/tank/internals/plasmaman/belt(src)
-/obj/item/storage/box/survival/radio/PopulateContents()
- ..() // we want the survival stuff too.
- new /obj/item/radio/off(src)
-
// Mining survival box
/obj/item/storage/box/survival/mining
mask_type = /obj/item/clothing/mask/gas/explorer
@@ -148,10 +150,6 @@
/obj/item/storage/box/survival/engineer
internal_type = /obj/item/tank/internals/emergency_oxygen/engi
-/obj/item/storage/box/survival/engineer/radio/PopulateContents()
- ..() // we want the regular items too.
- new /obj/item/radio/off(src)
-
// Syndie survival box
/obj/item/storage/box/survival/syndie
mask_type = /obj/item/clothing/mask/gas/syndicate
@@ -162,10 +160,6 @@
/obj/item/storage/box/survival/security
mask_type = /obj/item/clothing/mask/gas/sechailer
-/obj/item/storage/box/survival/security/radio/PopulateContents()
- ..() // we want the regular stuff too
- new /obj/item/radio/off(src)
-
// Medical survival box
/obj/item/storage/box/survival/medical
mask_type = /obj/item/clothing/mask/breath/medical
@@ -173,16 +167,14 @@
/obj/item/storage/box/survival/clip
internal_type = /obj/item/tank/internals/emergency_oxygen/engi //clip actually cares about their personnel
-/obj/item/storage/box/survival/clip/PopulateContents()
- . = ..()
- new /obj/item/radio/off(src)
-
/obj/item/storage/box/survival/clip/balaclava
mask_type = /obj/item/clothing/mask/gas/sechailer/balaclava
-
-/obj/item/storage/box/survival/clip/balaclava
internal_type = /obj/item/tank/internals/emergency_oxygen/double
+/obj/item/storage/box/survival/frontier
+ mask_type = null // we spawn in gas masks in frontiersmen bags alongside this, so it isn't nessary
+ internal_type = /obj/item/tank/internals/emergency_oxygen //frontiersmen dont
+
/obj/item/storage/box/gloves
name = "box of latex gloves"
desc = "Contains sterile latex gloves."
@@ -620,35 +612,6 @@
for(var/i in 1 to 6)
new /obj/item/cartridge/security(src)
-/obj/item/storage/box/firingpins
- name = "box of standard firing pins"
- desc = "A box full of standard firing pins, to allow newly-developed firearms to operate."
- icon_state = "secbox"
- illustration = "firingpin"
-
-/obj/item/storage/box/firingpins/PopulateContents()
- for(var/i in 1 to 5)
- new /obj/item/firing_pin(src)
-
-/obj/item/storage/box/firingpins/paywall
- name = "box of paywall firing pins"
- desc = "A box full of paywall firing pins, to allow newly-developed firearms to operate behind a custom-set paywall."
- illustration = "firingpin"
-
-/obj/item/storage/box/firingpins/paywall/PopulateContents()
- for(var/i in 1 to 5)
- new /obj/item/firing_pin/paywall(src)
-
-/obj/item/storage/box/lasertagpins
- name = "box of laser tag firing pins"
- desc = "A box full of laser tag firing pins, to allow newly-developed firearms to require wearing brightly coloured plastic armor before being able to be used."
- illustration = "firingpin"
-
-/obj/item/storage/box/lasertagpins/PopulateContents()
- for(var/i in 1 to 3)
- new /obj/item/firing_pin/tag/red(src)
- new /obj/item/firing_pin/tag/blue(src)
-
/obj/item/storage/box/handcuffs
name = "box of spare handcuffs"
desc = "A box full of handcuffs."
@@ -893,6 +856,16 @@
for(var/i in 1 to 7)
new /obj/item/ammo_casing/shotgun/buckshot(src)
+/obj/item/storage/box/techshot
+ name = "box of unloaded shotgun tech shells"
+ desc = "A box full of unloaded tech shells, capable of producing a variety of effects once loaded."
+ icon_state = "techshot_box"
+ illustration = null
+
+/obj/item/storage/box/techshot/PopulateContents()
+ for(var/i in 1 to 7)
+ new /obj/item/ammo_casing/shotgun/techshell(src)
+
/obj/item/storage/box/beanbag
name = "box of beanbags"
desc = "A box full of beanbag shells."
@@ -1413,10 +1386,10 @@
/obj/item/stack/sheet/mineral/uranium=20,\
/obj/item/stack/sheet/mineral/diamond=50,\
/obj/item/stack/sheet/bluespace_crystal=50,\
- /obj/item/stack/sheet/mineral/bananium=50,\
+ /obj/item/stack/sheet/mineral/hidden/hellstone=50,\
/obj/item/stack/sheet/mineral/wood=50,\
/obj/item/stack/sheet/plastic/fifty=1,\
- /obj/item/stack/sheet/runed_metal/fifty=1
+ /obj/item/stack/sheet/mineral/hidden/hellstone/fifty=1
)
generate_items_inside(items_inside,src)
@@ -1563,53 +1536,3 @@
)
generate_items_inside(items_inside,src)
-/obj/item/storage/box/coffeepack
- icon_state = "arabica_beans"
- name = "arabica beans"
- desc = "A bag containing fresh, dry coffee arabica beans. Ethically sourced and packaged by Donk! Co."
- illustration = null
- icon = 'icons/obj/food/containers.dmi'
- var/beantype = /obj/item/reagent_containers/food/snacks/grown/coffee
-
-/obj/item/storage/box/cofeepack/Initialize(mapload)
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_items = 5
- STR.set_holdable(list(/obj/item/reagent_containers/food/snacks/grown/coffee))
-
-/obj/item/storage/box/coffeepack/PopulateContents()
- var/static/items_inside = list(
- /obj/item/reagent_containers/food/snacks/grown/coffee = 5,
- /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = 5)
- generate_items_inside(items_inside,src)
-
-/obj/item/storage/box/coffeepack/robusta
- icon_state = "robusta_beans"
- name = "robusta beans"
- desc = "A bag containing fresh, dry coffee robusta beans. Ethically sourced and packaged by Donk! Co."
- beantype = /obj/item/reagent_containers/food/snacks/grown/coffee/robusta
-
-
-/*
- * Coffee condiments display -- someone can make this fancy eventually, i cant fucking figure it out for the life of me -- it exists in TG
- */
-
-/obj/item/storage/box/coffee_condi_display
- name = "coffee condiments display"
- desc = "A neat small box, holding all your favorite coffee condiments."
-
-/obj/item/storage/box/coffee_condi_display/Initialize(mapload)
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_items = 14
- STR.set_holdable(list(
- /obj/item/reagent_containers/food/condiment/pack/sugar,
- /obj/item/reagent_containers/food/condiment/pack/creamer,
- /obj/item/reagent_containers/food/condiment/pack/astrotame,
- ))
-
-/obj/item/storage/box/coffee_condi_display/PopulateContents()
- for(var/i in 1 to 4)
- new /obj/item/reagent_containers/food/condiment/pack/sugar(src)
- new /obj/item/reagent_containers/food/condiment/pack/creamer(src)
- new /obj/item/reagent_containers/food/condiment/pack/astrotame(src)
diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm
index 895b94acf574..64a3a11cf327 100644
--- a/code/game/objects/items/storage/briefcase.dm
+++ b/code/game/objects/items/storage/briefcase.dm
@@ -42,10 +42,10 @@
/obj/item/storage/briefcase/sniperbundle/PopulateContents()
..() // in case you need any paperwork done after your rampage
- new /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate(src)
+ new /obj/item/gun/ballistic/automatic/marksman/sniper_rifle(src)
new /obj/item/clothing/neck/tie/red(src)
new /obj/item/clothing/under/syndicate/sniper(src)
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src)
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src)
- new /obj/item/suppressor/specialoffer(src)
+ new /obj/item/attachment/silencer(src)
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index 41f214998ffd..d6edfb29461a 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -133,6 +133,29 @@
STR.max_items = 12
STR.set_holdable(list(/obj/item/reagent_containers/food/snacks/egg))
+/obj/item/storage/fancy/egg_box/update_icon_state()
+ . = ..()
+ icon_state = "[base_icon_state][is_open ? "_open" : null]"
+
+/obj/item/storage/fancy/egg_box/update_overlays()
+ . = ..()
+ cut_overlays()
+ if(!is_open)
+ return
+ var/egg_count = 0
+ for(var/obj/item/reagent_containers/food/snacks/egg as anything in contents)
+ egg_count++
+ if(!egg)
+ return
+ var/image/current_huevo = image(icon = icon, icon_state = "eggbox_eggoverlay")
+ if(egg_count <= 6) //less than 6 eggs
+ current_huevo.pixel_x = (3*(egg_count-1))
+ else //if more than 6, make an extra row
+ current_huevo.pixel_x = (3*(egg_count-7)) //-7 to 'reset' it
+ current_huevo.pixel_y = -3
+ add_overlay(current_huevo)
+
+
/*
* Candle Box
*/
@@ -163,7 +186,7 @@
////////////
/obj/item/storage/fancy/cigarettes
name = "\improper Space Cigarettes packet"
- desc = "The most popular brand of cigarettes, sponsors of the Space Olympics."
+ desc = "The most popular brand of cigarettes on the Frontier."
icon = 'icons/obj/cigarettes.dmi'
base_icon_state = "cig"
icon_state = "cig"
@@ -273,14 +296,14 @@
/obj/item/storage/fancy/cigarettes/cigpack_carp
name = "\improper Carp Classic packet"
- desc = "Since 2313."
+ desc = "Since 207 FS."
icon_state = "carp"
base_icon_state = "carp"
spawn_type = /obj/item/clothing/mask/cigarette/carp
/obj/item/storage/fancy/cigarettes/cigpack_syndicate
name = "cigarette packet"
- desc = "An obscure brand of cigarettes."
+ desc = "A semi-obscure brand of cigarettes, favored by interstellar miners."
icon_state = "syndie"
base_icon_state = "syndie"
spawn_type = /obj/item/clothing/mask/cigarette/syndicate
@@ -322,7 +345,7 @@
/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker
name = "\improper Leary's Delight packet"
- desc = "Banned in over 36 galaxies."
+ desc = "Banned in over 36 Sectors."
icon_state = "shadyjim"
base_icon_state = "shadyjim"
spawn_type = /obj/item/clothing/mask/cigarette/rollie/mindbreaker
@@ -435,7 +458,7 @@
/obj/item/storage/fancy/cigarettes/cigars/havana
name = "\improper premium Havanian cigar case"
- desc = "A case of classy Havanian cigars."
+ desc = "Even after centuries of Solarian export, Havana smooth is only found in proper terran cigars."
icon_state = "cohibacase"
base_icon_state = "cohibacase"
spawn_type = /obj/item/clothing/mask/cigarette/cigar/havana
diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm
index 4505f596907f..bac896c0b8d5 100644
--- a/code/game/objects/items/storage/firstaid.dm
+++ b/code/game/objects/items/storage/firstaid.dm
@@ -306,7 +306,7 @@
name = "pill bottle"
desc = "It's an airtight container for storing medication."
icon_state = "pill_canister"
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/medicine.dmi'
item_state = "contsolid"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
diff --git a/code/game/objects/items/storage/guncases.dm b/code/game/objects/items/storage/guncases.dm
new file mode 100644
index 000000000000..9cda5ac27a39
--- /dev/null
+++ b/code/game/objects/items/storage/guncases.dm
@@ -0,0 +1,200 @@
+/obj/item/storage/guncase
+ name = "gun case"
+ desc = "A large box designed for holding firearms and magazines safely."
+ icon = 'icons/obj/guncase_48x32.dmi'
+ icon_state = "riflecase"
+ item_state = "infiltrator_case"
+ force = 12
+ throwforce = 12
+ throw_speed = 2
+ throw_range = 7
+ w_class = WEIGHT_CLASS_BULKY
+ attack_verb = list("robusted")
+ hitsound = 'sound/weapons/smash.ogg'
+ drop_sound = 'sound/items/handling/toolbox_drop.ogg'
+ pickup_sound = 'sound/items/handling/toolbox_pickup.ogg'
+
+
+/obj/item/storage/guncase/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_items = 10
+ STR.max_w_class = WEIGHT_CLASS_BULKY
+ STR.set_holdable(list(
+ /obj/item/gun,
+ /obj/item/ammo_box,
+ /obj/item/stock_parts/cell/gun
+ ))
+
+/obj/item/storage/guncase/winchester
+/obj/item/storage/guncase/winchester/PopulateContents()
+ new /obj/item/gun/ballistic/shotgun/flamingarrow/no_mag(src)
+
+/obj/item/storage/guncase/skm
+/obj/item/storage/guncase/skm/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/assault/skm/no_mag(src)
+ new /obj/item/ammo_box/magazine/skm_762_40/empty(src)
+ new /obj/item/ammo_box/magazine/skm_762_40/empty(src)
+
+/obj/item/storage/guncase/p16
+/obj/item/storage/guncase/p16/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/assault/p16/no_mag(src)
+ new /obj/item/ammo_box/magazine/p16/empty(src)
+ new /obj/item/ammo_box/magazine/p16/empty(src)
+
+/obj/item/storage/guncase/beacon
+/obj/item/storage/guncase/beacon/PopulateContents()
+ new /obj/item/gun/ballistic/shotgun/doublebarrel/beacon/no_mag(src)
+
+/obj/item/storage/guncase/scout
+/obj/item/storage/guncase/scout/PopulateContents()
+ new /obj/item/gun/ballistic/rifle/scout/no_mag(src)
+ new /obj/item/ammo_box/a300/empty(src)
+ new /obj/item/ammo_box/a300/empty(src)
+
+/obj/item/storage/guncase/cobra
+/obj/item/storage/guncase/cobra/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/smg/c20r/cobra/no_mag(src)
+ new /obj/item/ammo_box/magazine/smgm45/empty(src)
+ new /obj/item/ammo_box/magazine/smgm45/empty(src)
+
+
+/obj/item/storage/guncase/hellfire
+/obj/item/storage/guncase/hellfire/PopulateContents()
+ new /obj/item/gun/ballistic/shotgun/hellfire/no_mag(src)
+
+/obj/item/storage/guncase/doublebarrel
+/obj/item/storage/guncase/doublebarrel/PopulateContents()
+ new /obj/item/gun/ballistic/shotgun/doublebarrel/no_mag(src)
+
+/obj/item/storage/guncase/brimstone
+/obj/item/storage/guncase/brimstone/PopulateContents()
+ new /obj/item/gun/ballistic/shotgun/brimstone/no_mag(src)
+
+/obj/item/storage/guncase/illestren
+/obj/item/storage/guncase/illestren/PopulateContents()
+ new /obj/item/gun/ballistic/rifle/illestren/empty(src)
+ new /obj/item/ammo_box/magazine/illestren_a850r/empty(src)
+ new /obj/item/ammo_box/magazine/illestren_a850r/empty(src)
+
+/obj/item/storage/guncase/wt550
+/obj/item/storage/guncase/wt550/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/smg/wt550/no_mag(src)
+ new /obj/item/ammo_box/magazine/wt550m9/empty(src)
+ new /obj/item/ammo_box/magazine/wt550m9/empty(src)
+
+/obj/item/storage/pistolcase
+ name = "pistol case"
+ desc = "A large box designed for holding pistols and magazines safely."
+ icon = 'icons/obj/guncase.dmi'
+ icon_state = "pistolcase"
+ item_state = "infiltrator_case"
+ force = 12
+ throwforce = 12
+ throw_speed = 2
+ w_class = WEIGHT_CLASS_BULKY
+ attack_verb = list("robusted")
+ hitsound = 'sound/weapons/smash.ogg'
+ drop_sound = 'sound/items/handling/toolbox_drop.ogg'
+ pickup_sound = 'sound/items/handling/toolbox_pickup.ogg'
+
+/obj/item/storage/pistolcase/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_items = 8
+ STR.max_w_class = WEIGHT_CLASS_NORMAL
+ STR.set_holdable(list(
+ /obj/item/gun,
+ /obj/item/ammo_box/,
+ /obj/item/stock_parts/cell/gun
+ ))
+
+/obj/item/storage/pistolcase/modelh
+/obj/item/storage/pistolcase/modelh/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/powered/gauss/modelh/no_mag(src)
+ new /obj/item/ammo_box/magazine/modelh/empty(src)
+ new /obj/item/ammo_box/magazine/modelh/empty(src)
+
+/obj/item/storage/pistolcase/stechkin
+/obj/item/storage/pistolcase/stechkin/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/pistol/syndicate/no_mag(src)
+ new /obj/item/ammo_box/magazine/m10mm/empty(src)
+ new /obj/item/ammo_box/magazine/m10mm/empty(src)
+
+/obj/item/storage/pistolcase/candor
+/obj/item/storage/pistolcase/candor/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/pistol/candor/no_mag(src)
+ new /obj/item/ammo_box/magazine/m45/empty(src)
+ new /obj/item/ammo_box/magazine/m45/empty(src)
+
+/obj/item/storage/pistolcase/detective
+/obj/item/storage/pistolcase/detective/PopulateContents()
+ new /obj/item/gun/ballistic/revolver/detective/no_mag(src)
+ new /obj/item/ammo_box/c38/empty(src)
+ new /obj/item/ammo_box/c38/empty(src)
+
+/obj/item/storage/pistolcase/shadow
+/obj/item/storage/pistolcase/shadow/PopulateContents()
+ new /obj/item/gun/ballistic/revolver/shadow/no_mag(src)
+
+/obj/item/storage/pistolcase/commander
+/obj/item/storage/pistolcase/commander/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/pistol/commander/no_mag(src)
+ new /obj/item/ammo_box/magazine/co9mm/empty(src)
+ new /obj/item/ammo_box/magazine/co9mm/empty(src)
+
+/obj/item/storage/pistolcase/firebrand
+/obj/item/storage/pistolcase/firebrand/PopulateContents()
+ new /obj/item/gun/ballistic/revolver/firebrand/no_mag(src)
+
+/obj/item/storage/pistolcase/derringer
+/obj/item/storage/pistolcase/derringer/PopulateContents()
+ new /obj/item/gun/ballistic/derringer/no_mag(src)
+
+/obj/item/storage/pistolcase/a357
+/obj/item/storage/pistolcase/a357/PopulateContents()
+ new /obj/item/gun/ballistic/revolver/syndicate/no_mag(src)
+ new /obj/item/ammo_box/a357/empty(src)
+ new /obj/item/ammo_box/a357/empty(src)
+
+/obj/item/storage/pistolcase/montagne
+/obj/item/storage/pistolcase/montagne/PopulateContents()
+ new /obj/item/gun/ballistic/revolver/montagne/no_mag(src)
+ new /obj/item/ammo_box/a44roum_speedloader/empty(src)
+ new /obj/item/ammo_box/a44roum_speedloader/empty(src)
+
+
+/obj/item/storage/pistolcase/disposable
+/obj/item/storage/pistolcase/disposable/PopulateContents()
+ new /obj/item/gun/ballistic/automatic/pistol/disposable(src)
+ new /obj/item/gun/ballistic/automatic/pistol/disposable(src)
+
+/obj/item/storage/pistolcase/laser
+/obj/item/storage/pistolcase/laser/PopulateContents()
+ new /obj/item/gun/energy/laser/empty_cell(src)
+ new /obj/item/stock_parts/cell/gun(src)
+
+/obj/item/storage/pistolcase/egun
+/obj/item/storage/pistolcase/egun/PopulateContents()
+ new /obj/item/gun/energy/laser/empty_cell(src)
+ new /obj/item/stock_parts/cell/gun(src)
+
+/obj/item/storage/pistolcase/kalixpistol
+/obj/item/storage/pistolcase/kalixpistol/PopulateContents()
+ new /obj/item/gun/energy/kalix/pistol/empty_cell(src)
+ new /obj/item/stock_parts/cell/gun/kalix(src)
+
+/obj/item/storage/guncase/kalixrifle
+/obj/item/storage/guncase/kalixrifle/PopulateContents()
+ new /obj/item/gun/energy/kalix/empty_cell(src)
+ new /obj/item/stock_parts/cell/gun/kalix(src)
+
+/obj/item/storage/pistolcase/miniegun
+/obj/item/storage/pistolcase/miniegun/PopulateContents()
+ new /obj/item/gun/energy/e_gun/empty_cell(src)
+ new /obj/item/stock_parts/cell/gun/mini(src)
+
+/obj/item/storage/pistolcase/iongun
+/obj/item/storage/pistolcase/iongun/PopulateContents()
+ new /obj/item/gun/energy/ionrifle/empty_cell(src)
+ new /obj/item/stock_parts/cell/gun(src)
diff --git a/code/game/objects/items/storage/holsters.dm b/code/game/objects/items/storage/holsters.dm
index 35e4899b090b..9000d5e4dbd0 100644
--- a/code/game/objects/items/storage/holsters.dm
+++ b/code/game/objects/items/storage/holsters.dm
@@ -24,7 +24,7 @@
STR.max_items = 1
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.set_holdable(list(
- /obj/item/gun/ballistic/automatic/pistol,
+ /obj/item/gun/ballistic/automatic/pistol/syndicate,
/obj/item/gun/ballistic/revolver,
/obj/item/gun/energy/e_gun/mini,
/obj/item/gun/energy/disabler,
@@ -90,7 +90,7 @@
STR.max_items = 2
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.set_holdable(list(
- /obj/item/gun/ballistic/automatic/pistol,
+ /obj/item/gun/ballistic/automatic/pistol/syndicate,
/obj/item/gun/ballistic/revolver,
/obj/item/gun/energy/e_gun/mini,
/obj/item/gun/energy/disabler,
diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm
index c1014716c323..238e39ce9318 100644
--- a/code/game/objects/items/storage/secure.dm
+++ b/code/game/objects/items/storage/secure.dm
@@ -200,6 +200,14 @@
/obj/item/storage/secure/safe/intel/stechkin/PopulateContents()
. = ..()
- new /obj/item/gun/ballistic/automatic/pistol/suppressed(src)
+ new /obj/item/gun/ballistic/automatic/pistol/syndicate(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/ammo_box/magazine/m10mm(src)
+
+/obj/item/storage/secure/safe/suns
+ name = "Captain's Secure Safe"
+ desc = "The most important part of a SUNS vessel is the spare dueling sword."
+
+/obj/item/storage/secure/safe/suns/PopulateContents()
+ . = ..()
+ new /obj/item/storage/belt/sabre/suns(src)
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index 7b02bd6b19d3..987aaa9933d5 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -10,7 +10,7 @@
throwforce = 12
throw_speed = 2
throw_range = 7
- w_class = WEIGHT_CLASS_BULKY
+ w_class = WEIGHT_CLASS_NORMAL
custom_materials = list(/datum/material/iron = 500)
attack_verb = list("robusted")
hitsound = 'sound/weapons/smash.ogg'
@@ -56,7 +56,7 @@
new /obj/item/flashlight/glowstick(src)
if(3)
new /obj/item/flashlight/flare(src)
- new /obj/item/radio/off(src)
+ new /obj/item/radio(src)
/obj/item/storage/toolbox/emergency/old
name = "rusty red toolbox"
@@ -299,7 +299,7 @@
/obj/item/clothing/gloves/color/latex/nitrile/infiltrator,
/obj/item/clothing/mask/infiltrator,
/obj/item/clothing/shoes/combat/sneakboots,
- /obj/item/gun/ballistic/automatic/pistol,
+ /obj/item/gun/ballistic/automatic/pistol/syndicate,
/obj/item/gun/ballistic/revolver,
/obj/item/ammo_box
))
@@ -312,6 +312,18 @@
new /obj/item/clothing/mask/infiltrator(src)
new /obj/item/clothing/shoes/combat/sneakboots(src)
+/obj/item/storage/toolbox/bounty
+ name = "defused explosives case"
+ desc = "Store defused landmines in here."
+ icon_state = "infiltrator_case"
+ item_state = "infiltrator_case"
+
+/obj/item/storage/toolbox/bounty/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_combined_w_class = 4
+ STR.max_items = 2
+
//floorbot assembly
/obj/item/storage/toolbox/attackby(obj/item/stack/tile/plasteel/T, mob/user, params)
var/list/allowed_toolbox = list(/obj/item/storage/toolbox/emergency, //which toolboxes can be made into floorbots
diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm
index 221cdf42d3f3..f34aae9e6f82 100644
--- a/code/game/objects/items/storage/uplink_kits.dm
+++ b/code/game/objects/items/storage/uplink_kits.dm
@@ -22,7 +22,7 @@
new /obj/item/multitool/ai_detect(src) // 1 tc
new /obj/item/encryptionkey/syndicate(src) // 2 tc
new /obj/item/reagent_containers/syringe/mulligan(src) // 4 tc
- new /obj/item/switchblade(src) //I'll count this as 2 tc
+ new /obj/item/kitchen/knife/switchblade(src) //I'll count this as 2 tc
new /obj/item/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals
new /obj/item/flashlight/emp(src) // 2 tc
new /obj/item/chameleon(src) // 7 tc
@@ -38,7 +38,7 @@
new /obj/item/jammer(src)
if("guns")
- new /obj/item/gun/ballistic/revolver(src)
+ new /obj/item/gun/ballistic/revolver/syndicate(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/card/emag(src)
@@ -99,7 +99,7 @@
new /obj/item/storage/box/syndie_kit/emp(src)
if("sniper") //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks
- new /obj/item/gun/ballistic/automatic/sniper_rifle(src) // 12 tc
+ new /obj/item/gun/ballistic/automatic/marksman/sniper_rifle(src) // 12 tc
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
@@ -108,7 +108,7 @@
if("metaops")
new /obj/item/clothing/suit/space/hardsuit/syndi(src) // 8 tc
- new /obj/item/gun/ballistic/shotgun/bulldog/unrestricted(src) // 8 tc
+ new /obj/item/gun/ballistic/shotgun/bulldog(src) // 8 tc
new /obj/item/implanter/explosive(src) // 2 tc
new /obj/item/ammo_box/magazine/m12g(src) // 2 tc
new /obj/item/ammo_box/magazine/m12g(src) // 2 tc
@@ -119,8 +119,8 @@
/obj/item/storage/box/syndicate/bundle_B/PopulateContents()
switch (pickweight(list( "bond" = 2, "ninja" = 1, "darklord" = 1, "white_whale_holy_grail" = 2, "mad_scientist" = 2, "bee" = 1, "mr_freeze" = 2, "made_man"= 1)))
if("bond")
- new /obj/item/gun/ballistic/automatic/pistol(src)
- new /obj/item/suppressor(src)
+ new /obj/item/gun/ballistic/automatic/pistol/syndicate(src)
+ new /obj/item/attachment/silencer(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/clothing/under/chameleon(src)
@@ -165,7 +165,7 @@
new /obj/item/assembly/signaler(src) // 0 tc
new /obj/item/storage/toolbox/syndicate(src) // 1 tc
new /obj/item/pen/edagger(src)
- new /obj/item/gun/energy/decloner/unrestricted(src)
+ new /obj/item/gun/energy/decloner(src)
if("bee")
new /obj/item/paper/fluff/bee_objectives(src) // 0 tc (motivation)
@@ -195,7 +195,7 @@
if("made_man")
new /obj/effect/spawner/lootdrop/mafia_outfit(src) // 0 TC, just an outfit for the new 'don of this family
new /obj/item/gun/ballistic/automatic/smg/firestorm/pan(src) // 20 TC, a gun with 50 .45 bullets on a three round burst is kinda outstanding
- new /obj/item/switchblade(src) // 3 TC? It's nice, but it's really a stealth/oh fuck I'm out of ammo weapon
+ new /obj/item/kitchen/knife/switchblade(src) // 3 TC? It's nice, but it's really a stealth/oh fuck I'm out of ammo weapon
new /obj/item/reagent_containers/food/drinks/bottle/vodka (src) // 5 TC, free molotov assemblies
new /obj/item/reagent_containers/food/drinks/bottle/vodka (src)
new /obj/item/reagent_containers/food/drinks/bottle/vodka (src)
@@ -306,7 +306,7 @@
/obj/item/storage/box/syndie_kit/imp_radio,
/obj/item/storage/box/syndie_kit/imp_uplink,
/obj/item/clothing/gloves/krav_maga/combatglovesplus,
- /obj/item/gun/ballistic/automatic/smg/c20r/toy/unrestricted/riot,
+ /obj/item/gun/ballistic/automatic/smg/c20r/toy/riot,
/obj/item/reagent_containers/hypospray/medipen/stimulants,
/obj/item/storage/box/syndie_kit/imp_freedom,
/obj/item/toy/eightball/haunted
@@ -370,13 +370,6 @@
for(var/i in 1 to 7)
new /obj/item/reagent_containers/syringe/bioterror(src)
-/obj/item/storage/box/syndie_kit/clownpins
- name = "ultra hilarious firing pin box"
-
-/obj/item/storage/box/syndie_kit/clownpins/PopulateContents()
- for(var/i in 1 to 7)
- new /obj/item/firing_pin/clown/ultra(src)
-
/obj/item/storage/box/syndie_kit/imp_adrenal
name = "adrenal implant box"
@@ -526,9 +519,6 @@
for(var/i in 1 to 3)
new/obj/item/grenade/chem_grenade/ez_clean(src)
-/obj/item/storage/box/hug/reverse_revolver/PopulateContents()
- new /obj/item/gun/ballistic/revolver/reverse(src)
-
/obj/item/storage/box/syndie_kit/mimery/PopulateContents()
new /obj/item/book/granter/spell/mimery_blockade(src)
new /obj/item/book/granter/spell/mimery_guns(src)
diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm
index 91f47f56cdd5..002b72633294 100644
--- a/code/game/objects/items/storage/wallets.dm
+++ b/code/game/objects/items/storage/wallets.dm
@@ -42,9 +42,10 @@
/obj/item/storage/wallet/Exited(atom/movable/AM)
. = ..()
- refreshID()
+ UnregisterSignal(AM, COSMIG_ACCESS_UPDATED)
+ refresh_id()
-/obj/item/storage/wallet/proc/refreshID()
+/obj/item/storage/wallet/proc/refresh_id()
LAZYCLEARLIST(combined_access)
if(!(front_id in src))
front_id = null
@@ -61,7 +62,8 @@
/obj/item/storage/wallet/Entered(atom/movable/AM)
. = ..()
- refreshID()
+ RegisterSignal(AM, COSMIG_ACCESS_UPDATED, PROC_REF(refresh_id))
+ refresh_id()
/obj/item/storage/wallet/update_overlays()
. = ..()
@@ -117,6 +119,11 @@
else
return ..()
+/obj/item/storage/wallet/GetBankCard()
+ for(var/obj/item/card/I in contents)
+ if(istype(I, /obj/item/card/bank))
+ return I
+
/obj/item/storage/wallet/random
icon_state = "random_wallet"
diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm
index e1ad81e21413..3265b36a3b41 100644
--- a/code/game/objects/items/stunbaton.dm
+++ b/code/game/objects/items/stunbaton.dm
@@ -300,8 +300,8 @@
preload_cell_type = /obj/item/stock_parts/cell/high
/obj/item/melee/baton/boomerang
- name = "\improper OZtek Boomerang"
- desc = "A device invented in 2486 for the great Space Emu War by the confederacy of Australicus, these high-tech boomerangs also work exceptionally well at stunning crewmembers. Just be careful to catch it when thrown!"
+ name = "\improper baton boomerang"
+ desc = "Apparently, someone thought that attaching the stunning part of a baton to a boomerang was a good idea. Just be careful to catch it when thrown!"
throw_speed = 1
icon_state = "boomerang"
item_state = "boomerang"
diff --git a/code/game/objects/items/survery_handheld.dm b/code/game/objects/items/survery_handheld.dm
index 79523b574030..a10097031485 100644
--- a/code/game/objects/items/survery_handheld.dm
+++ b/code/game/objects/items/survery_handheld.dm
@@ -51,7 +51,7 @@
src_turf.visible_message("Warning: unable to locate valuable information in current sector.")
break
- if(!do_after_mob(user, list(src), survey_delay / penalty))
+ if(!do_after(user, survey_delay / penalty, src))
flick(icon_state + "-corrupted", src)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20)
src_turf.visible_message("Warning: results corrupted. Please try again.")
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 00c619da8353..5ce082d79dc9 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -187,8 +187,8 @@
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "revolver"
item_state = "gun"
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_NORMAL
@@ -562,7 +562,6 @@
var/datum/fakeDevil/devil = new
var/list/messages = list()
messages += "Some fun facts about: [devil.truename]"
- messages += "[GLOB.lawlorify[LORE][devil.bane]]"
messages += "[GLOB.lawlorify[LORE][devil.obligation]]"
messages += "[GLOB.lawlorify[LORE][devil.ban]]"
messages += "[GLOB.lawlorify[LORE][devil.banish]]"
@@ -1404,7 +1403,7 @@
say(message, language)
return NOPASS
-/obj/item/toy/dummy/GetVoice()
+/obj/item/toy/dummy/GetVoice(if_no_voice = "Unknown")
return doll_name
/obj/item/toy/seashell
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 9e8d1e3c17b9..a76334a0b7ea 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -350,44 +350,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
attack_verb = list("stabbed", "ripped", "gored", "impaled")
embedding = list("pain_mult" = 8, "embed_chance" = 100, "fall_chance" = 0, "impact_pain_mult" = 15) //55 damage+embed on hit
-/obj/item/switchblade
- name = "switchblade"
- icon_state = "switchblade"
- lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
- desc = "A sharp, concealable, spring-loaded knife."
- flags_1 = CONDUCT_1
- force = 3
- w_class = WEIGHT_CLASS_SMALL
- throwforce = 5
- throw_speed = 3
- throw_range = 6
- custom_materials = list(/datum/material/iron=12000)
- hitsound = 'sound/weapons/genhit.ogg'
- attack_verb = list("stubbed", "poked")
- resistance_flags = FIRE_PROOF
- var/extended = 0
-
-/obj/item/switchblade/attack_self(mob/user)
- extended = !extended
- playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
- if(extended)
- force = 20
- w_class = WEIGHT_CLASS_NORMAL
- throwforce = 23
- icon_state = "switchblade_ext"
- attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
- hitsound = 'sound/weapons/bladeslice.ogg'
- sharpness = IS_SHARP
- else
- force = 3
- w_class = WEIGHT_CLASS_SMALL
- throwforce = 5
- icon_state = "switchblade"
- attack_verb = list("stubbed", "poked")
- hitsound = 'sound/weapons/genhit.ogg'
- sharpness = IS_BLUNT
-
/obj/item/phone
name = "red phone"
desc = "Should anything ever go wrong..."
@@ -775,35 +737,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
return 1
return 0
-/obj/item/legion_staff
- icon_state = "legion_staff"
- lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
- name = "legionnaire staff"
- desc = "The remnants of a legionnaire, reconstructed around a pole of bone. The skulls it produces are loyal to the wielder, seeming to recognize them as their host body."
- icon = 'icons/obj/guns/magic.dmi'
- block_chance = 20
- force = 20
- throwforce = 10
- throw_speed = 4
- attack_verb = list("bit", "gnawed", "chomped")
- w_class = WEIGHT_CLASS_NORMAL
- slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT
- hitsound = 'sound/weapons/bite.ogg'
- var/next_use_time
-
-/obj/item/legion_staff/attack_self(mob/user)
- if(next_use_time > world.time)
- user.visible_message("[src] rattles in [user]'s hands, but nothing happens...")
- to_chat(user, "You need to wait longer to use this again.")
- return
- user.visible_message("[user] raises the [src] and summons a legion skull!")
- for(var/i in 1 to 3)
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/staff/LegionSkull = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/staff(user.loc)
- LegionSkull.faction = user.faction.Copy()
- LegionSkull.friends += user
- next_use_time = world.time + 6 SECONDS
-
/obj/item/claymore/bone
name = "Bone Sword"
desc = "Jagged pieces of bone are tied to what looks like a goliaths femur."
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 69efcd42af15..971ba3cbedce 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -93,7 +93,7 @@
if(HAS_TRAIT(user, TRAIT_FREERUNNING)) //do you have any idea how fast I am???
adjusted_climb_time *= 0.8
structureclimber = user
- if(do_mob(user, user, adjusted_climb_time))
+ if(do_after(user, adjusted_climb_time))
if(src.loc) //Checking if structure has been destroyed
if(do_climb(user))
user.visible_message("[user] climbs onto [src].", \
diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm
index 532b4385f2cf..4f132b11af99 100644
--- a/code/game/objects/structures/beds_chairs/alien_nest.dm
+++ b/code/game/objects/structures/beds_chairs/alien_nest.dm
@@ -34,7 +34,7 @@
M.visible_message("[M.name] struggles to break free from the gelatinous resin!",\
"You struggle to break free from the gelatinous resin... (Stay still for two minutes.)",\
"You hear squelching...")
- if(!do_after(M, 1200, target = src))
+ if(!do_after(M, 1200, target = src, hidden = TRUE))
if(M && M.buckled)
to_chat(M, "You fail to unbuckle yourself!")
return
diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm
index 3c7d1ac0f01c..6c5f46e94a3b 100644
--- a/code/game/objects/structures/beds_chairs/bed.dm
+++ b/code/game/objects/structures/beds_chairs/bed.dm
@@ -167,7 +167,7 @@
name = "dog bed"
icon_state = "dogbed"
desc = "A comfy-looking dog bed. You can even strap your pet in, in case the gravity turns off."
- anchored = FALSE
+ anchored = TRUE
buildstacktype = /obj/item/stack/sheet/mineral/wood
buildstackamount = 10
var/mob/living/owner = null
@@ -175,22 +175,18 @@
/obj/structure/bed/dogbed/ian
desc = "Ian's bed! Looks comfy."
name = "Ian's bed"
- anchored = TRUE
/obj/structure/bed/dogbed/cayenne
desc = "Seems kind of... fishy."
name = "Cayenne's bed"
- anchored = TRUE
/obj/structure/bed/dogbed/renault
desc = "Renault's bed! Looks comfy. A foxy person needs a foxy pet."
name = "Renault's bed"
- anchored = TRUE
/obj/structure/bed/dogbed/runtime
desc = "A comfy-looking cat bed. You can even strap your pet in, in case the gravity turns off."
name = "Runtime's bed"
- anchored = TRUE
/obj/structure/bed/dogbed/proc/update_owner(mob/living/M)
if(owner)
@@ -210,11 +206,6 @@
. = ..()
update_owner(M)
-/obj/structure/bed/alien
- name = "resting contraption"
- desc = "This looks similar to contraptions from Earth. Could aliens be stealing our technology?"
- icon_state = "abed"
-
//Double Beds, for luxurious sleeping, i.e. the captain and maybe heads - no quirky refrence here. Move along
/obj/structure/bed/double
name = "double bed"
diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm
index a8d560796f7e..045bf39ae9b6 100644
--- a/code/game/objects/structures/beds_chairs/chair.dm
+++ b/code/game/objects/structures/beds_chairs/chair.dm
@@ -134,67 +134,6 @@
icon_state = "wooden_chair_wings"
item_chair = /obj/item/chair/wood/wings
-/obj/structure/chair/comfy
- name = "comfy chair"
- desc = "It looks comfy."
- icon_state = "comfychair"
- color = rgb(255,255,255)
- resistance_flags = FLAMMABLE
- max_integrity = 70
- buildstackamount = 2
- item_chair = null
- var/mutable_appearance/armrest
-
-/obj/structure/chair/comfy/Initialize()
- armrest = GetArmrest()
- armrest.layer = ABOVE_MOB_LAYER
- return ..()
-
-/obj/structure/chair/comfy/proc/GetArmrest()
- return mutable_appearance(icon, "[icon_state]_armrest")
-
-/obj/structure/chair/comfy/Destroy()
- QDEL_NULL(armrest)
- return ..()
-
-/obj/structure/chair/comfy/post_buckle_mob(mob/living/M)
- . = ..()
- update_armrest()
-
-/obj/structure/chair/comfy/proc/update_armrest()
- if(has_buckled_mobs())
- add_overlay(armrest)
- else
- cut_overlay(armrest)
-
-/obj/structure/chair/comfy/post_unbuckle_mob()
- . = ..()
- update_armrest()
-
-/obj/structure/chair/comfy/brown
- color = rgb(255,113,0)
-
-/obj/structure/chair/comfy/beige
- color = rgb(255,253,195)
-
-/obj/structure/chair/comfy/teal
- color = rgb(0,255,255)
-
-/obj/structure/chair/comfy/black
- color = rgb(167,164,153)
-
-/obj/structure/chair/comfy/lime
- color = rgb(255,251,0)
-
-/obj/structure/chair/comfy/shuttle
- name = "shuttle seat"
- desc = "A comfortable, secure seat. It has a more sturdy looking buckling system, for smoother flights."
- icon_state = "shuttle_chair"
- buildstacktype = /obj/item/stack/sheet/mineral/titanium
-
-/obj/structure/chair/comfy/shuttle/GetArmrest()
- return mutable_appearance('icons/obj/chairs.dmi', "shuttle_chair_armrest")
-
/obj/structure/chair/office
anchored = FALSE
buildstackamount = 5
@@ -367,48 +306,6 @@
icon_state = "wooden_chair_wings_toppled"
origin_type = /obj/structure/chair/wood/wings
-/obj/structure/chair/comfy/shuttle/bronze
- name = "brass chair"
- desc = "A spinny chair made of bronze. It has little cogs for wheels!"
- anchored = FALSE
- icon_state = "brass_chair"
- buildstacktype = /obj/item/stack/tile/bronze
- buildstackamount = 1
- item_chair = null
- var/turns = 0
-
-/obj/structure/chair/comfy/shuttle/bronze/GetArmrest()
- return mutable_appearance('icons/obj/chairs.dmi', "brass_chair_armrest")
-
-/obj/structure/chair/comfy/shuttle/bronze/Destroy()
- STOP_PROCESSING(SSfastprocess, src)
- . = ..()
-
-/obj/structure/chair/comfy/shuttle/bronze/process()
- setDir(turn(dir,-90))
- playsound(src, 'sound/effects/servostep.ogg', 50, FALSE)
- turns++
- if(turns >= 8)
- STOP_PROCESSING(SSfastprocess, src)
-
-/obj/structure/chair/comfy/shuttle/bronze/Moved()
- . = ..()
- if(has_gravity())
- playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
-
-/obj/structure/chair/comfy/shuttle/bronze/AltClick(mob/living/user)
- turns = 0
- if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
- return
- if(!(datum_flags & DF_ISPROCESSING))
- user.visible_message("[user] spins [src] around, and the last vestiges of Ratvarian technology keeps it spinning FOREVER.", \
- "Automated spinny chairs. The pinnacle of ancient Ratvarian technology.")
- START_PROCESSING(SSfastprocess, src)
- else
- user.visible_message("[user] stops [src]'s uncontrollable spinning.", \
- "You grab [src] and stop its wild spinning.")
- STOP_PROCESSING(SSfastprocess, src)
-
/obj/structure/chair/mime
name = "invisible chair"
desc = "The mime needs to sit down and shut up."
@@ -458,3 +355,12 @@
custom_materials = list(/datum/material/plastic = 2000)
break_chance = 25
origin_type = /obj/structure/chair/plastic
+
+/obj/structure/chair/handrail
+ name = "handrail"
+ icon = 'icons/obj/structures/handrail.dmi'
+ icon_state = "handrail"
+ desc = "A safety railing with buckles to secure yourself to when floor isn't stable enough."
+ item_chair = null
+ buildstackamount = 4
+ buildstacktype = /obj/item/stack/rods
diff --git a/code/game/objects/structures/beds_chairs/comfy.dm b/code/game/objects/structures/beds_chairs/comfy.dm
new file mode 100644
index 000000000000..b3d7f38e9a90
--- /dev/null
+++ b/code/game/objects/structures/beds_chairs/comfy.dm
@@ -0,0 +1,270 @@
+// Base type - DO NOT USE!
+/obj/structure/chair/comfy
+ name = "comfy chair"
+ desc = "It looks comfy."
+ icon_state = null
+ icon = 'icons/obj/structures/chairs/comfychair.dmi'
+ resistance_flags = FLAMMABLE
+ max_integrity = 70
+ buildstackamount = 2
+ item_chair = null
+
+ ///Armrest sprite to overlay over mobs
+ var/mutable_appearance/armrest
+
+/obj/structure/chair/comfy/Initialize()
+ armrest = get_armrest()
+ armrest.layer = ABOVE_MOB_LAYER
+ return ..()
+
+/obj/structure/chair/comfy/proc/get_armrest()
+ return mutable_appearance(icon, "overlay_[icon_state]")
+
+/obj/structure/chair/comfy/Destroy()
+ QDEL_NULL(armrest)
+ return ..()
+
+/obj/structure/chair/comfy/post_buckle_mob(mob/living/M)
+ . = ..()
+ update_armrest()
+
+/obj/structure/chair/comfy/proc/update_armrest()
+ if(has_buckled_mobs())
+ add_overlay(armrest)
+ else
+ cut_overlay(armrest)
+
+/obj/structure/chair/comfy/post_unbuckle_mob()
+ . = ..()
+ update_armrest()
+
+// Update this along with brass chair
+/obj/structure/chair/comfy/shuttle
+ name = "shuttle seat"
+ desc = "A comfortable, secure seat. It has a more sturdy looking buckling system, for smoother flights."
+ icon_state = "shuttle_chair"
+ icon = 'icons/obj/chairs.dmi'
+ buildstacktype = /obj/item/stack/sheet/mineral/titanium
+
+/obj/structure/chair/comfy/shuttle/get_armrest()
+ return mutable_appearance('icons/obj/chairs.dmi', "shuttle_chair_armrest")
+
+/obj/structure/chair/comfy/shuttle/bronze
+ name = "brass chair"
+ desc = "A spinny chair made of bronze. It has little cogs for wheels!"
+ anchored = FALSE
+ icon_state = "brass_chair"
+ buildstacktype = /obj/item/stack/tile/bronze
+ buildstackamount = 1
+ item_chair = null
+ var/turns = 0
+
+/obj/structure/chair/comfy/shuttle/bronze/get_armrest()
+ return mutable_appearance('icons/obj/chairs.dmi', "brass_chair_armrest")
+
+/obj/structure/chair/comfy/shuttle/bronze/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ . = ..()
+
+/obj/structure/chair/comfy/shuttle/bronze/process()
+ setDir(turn(dir,-90))
+ playsound(src, 'sound/effects/servostep.ogg', 50, FALSE)
+ turns++
+ if(turns >= 8)
+ STOP_PROCESSING(SSfastprocess, src)
+
+/obj/structure/chair/comfy/shuttle/bronze/Moved()
+ . = ..()
+ if(has_gravity())
+ playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
+
+/obj/structure/chair/comfy/shuttle/bronze/AltClick(mob/living/user)
+ turns = 0
+ if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+ return
+ if(!(datum_flags & DF_ISPROCESSING))
+ user.visible_message("[user] spins [src] around, and the last vestiges of Ratvarian technology keeps it spinning FOREVER.", \
+ "Automated spinny chairs. The pinnacle of ancient Ratvarian technology.")
+ START_PROCESSING(SSfastprocess, src)
+ else
+ user.visible_message("[user] stops [src]'s uncontrollable spinning.", \
+ "You grab [src] and stop its wild spinning.")
+ STOP_PROCESSING(SSfastprocess, src)
+
+// Purple
+/obj/structure/chair/comfy/purple
+ icon_state = "imaginos_purple"
+
+/obj/structure/chair/comfy/purple/old
+ icon_state = "old_purple"
+
+/obj/structure/chair/comfy/purple/old/alt
+ icon_state = "old_purple_alt"
+
+/obj/structure/chair/comfy/purple/corpo
+ icon_state = "corp_purple"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/purple, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/purple/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/purple/old/alt, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/purple/corpo, 0)
+
+// Beige
+/obj/structure/chair/comfy/beige
+ icon_state = "imaginos_beige"
+
+/obj/structure/chair/comfy/beige/old
+ icon_state = "old_beige"
+
+/obj/structure/chair/comfy/beige/old/alt
+ icon_state = "old_beige_alt"
+
+/obj/structure/chair/comfy/beige/corpo
+ icon_state = "corp_beige"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/beige, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/beige/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/beige/old/alt, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/beige/corpo, 0)
+
+// Grey
+/obj/structure/chair/comfy/grey
+ icon_state = "imaginos_grey"
+
+/obj/structure/chair/comfy/grey/old
+ icon_state = "old_grey"
+
+/obj/structure/chair/comfy/grey/old/alt
+ icon_state = "old_grey_alt"
+
+/obj/structure/chair/comfy/grey/corpo
+ icon_state = "corp_grey"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/grey, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/grey/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/grey/old/alt, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/grey/corpo, 0)
+
+// Orange
+
+/obj/structure/chair/comfy/orange
+ icon_state = "imaginos_orange"
+
+/obj/structure/chair/comfy/orange/old
+ icon_state = "old_orange"
+
+/obj/structure/chair/comfy/orange/old/alt
+ icon_state = "old_orange_alt"
+
+/obj/structure/chair/comfy/orange/corpo
+ icon_state = "corp_orange"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/orange, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/orange/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/orange/old/alt, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/orange/corpo, 0)
+
+// Blue
+
+/obj/structure/chair/comfy/blue
+ icon_state = "imaginos_blue"
+
+/obj/structure/chair/comfy/blue/old
+ icon_state = "old_blue"
+
+/obj/structure/chair/comfy/blue/old/alt
+ icon_state = "old_blue_alt"
+
+/obj/structure/chair/comfy/blue/corpo
+ icon_state = "corp_blue"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/blue, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/blue/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/blue/old/alt, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/blue/corpo, 0)
+
+// Red
+
+/obj/structure/chair/comfy/red
+ icon_state = "imaginos_red"
+
+/obj/structure/chair/comfy/red/old
+ icon_state = "old_red"
+
+/obj/structure/chair/comfy/red/old/alt
+ icon_state = "old_red_alt"
+
+/obj/structure/chair/comfy/red/corpo
+ icon_state = "corp_red"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/red, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/red/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/red/old/alt, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/red/corpo, 0)
+
+// Olive
+
+/obj/structure/chair/comfy/olive
+ icon_state = "imaginos_olive"
+
+/obj/structure/chair/comfy/olive/old
+ icon_state = "old_olive"
+
+/obj/structure/chair/comfy/olive/old/alt
+ icon_state = "old_olive_alt"
+
+/obj/structure/chair/comfy/olive/corpo
+ icon_state = "corp_olive"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/olive, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/olive/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/olive/old/alt, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/comfy/olive/corpo, 0)
+
+// Benches - No armrests
+
+// Base type - DO NOT USE!
+/obj/structure/chair/bench
+ name = "comfy bench"
+ desc = "It looks comfy."
+ icon_state = null
+ icon = 'icons/obj/structures/chairs/comfychair.dmi'
+ resistance_flags = FLAMMABLE
+ max_integrity = 70
+ buildstackamount = 2
+ item_chair = null
+
+/obj/structure/chair/bench/purple
+ icon_state = "bench_purple"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/bench/purple, 0)
+
+/obj/structure/chair/bench/beige
+ icon_state = "bench_beige"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/bench/beige, 0)
+
+/obj/structure/chair/bench/grey
+ icon_state = "bench_grey"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/bench/grey, 0)
+
+/obj/structure/chair/bench/orange
+ icon_state = "bench_orange"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/bench/orange, 0)
+
+/obj/structure/chair/bench/blue
+ icon_state = "bench_blue"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/bench/blue, 0)
+
+/obj/structure/chair/bench/red
+ icon_state = "bench_red"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/bench/red, 0)
+
+/obj/structure/chair/bench/olive
+ icon_state = "bench_olive"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/bench/olive, 0)
diff --git a/code/game/objects/structures/beds_chairs/pew.dm b/code/game/objects/structures/beds_chairs/pew.dm
index 8e5cf9a19493..87f02c41240e 100644
--- a/code/game/objects/structures/beds_chairs/pew.dm
+++ b/code/game/objects/structures/beds_chairs/pew.dm
@@ -1,7 +1,7 @@
/obj/structure/chair/pew
name = "wooden pew"
desc = "Kneel here and pray."
- icon = 'icons/obj/sofa.dmi'
+ icon = 'icons/obj/structures/chairs/sofa.dmi'
icon_state = "pewmiddle"
resistance_flags = FLAMMABLE
max_integrity = 70
@@ -22,7 +22,7 @@
return ..()
/obj/structure/chair/pew/left/proc/GetLeftPewArmrest()
- return mutable_appearance('icons/obj/sofa.dmi', "pewend_left_armrest")
+ return mutable_appearance('icons/obj/structures/chairs/sofa.dmi', "pewend_left_armrest")
/obj/structure/chair/pew/left/Destroy()
QDEL_NULL(leftpewarmrest)
@@ -53,7 +53,7 @@
return ..()
/obj/structure/chair/pew/right/proc/GetRightPewArmrest()
- return mutable_appearance('icons/obj/sofa.dmi', "pewend_right_armrest")
+ return mutable_appearance('icons/obj/structures/chairs/sofa.dmi', "pewend_right_armrest")
/obj/structure/chair/pew/right/Destroy()
QDEL_NULL(rightpewarmrest)
diff --git a/code/game/objects/structures/beds_chairs/sofa.dm b/code/game/objects/structures/beds_chairs/sofa.dm
index 8ba787920546..0c69a2335f2c 100644
--- a/code/game/objects/structures/beds_chairs/sofa.dm
+++ b/code/game/objects/structures/beds_chairs/sofa.dm
@@ -1,31 +1,433 @@
+// Base type - DO NOT USE!
/obj/structure/chair/sofa
name = "sofa"
- icon_state = "sofamiddle"
- icon = 'icons/obj/sofa.dmi'
+ icon_state = null
+ icon = 'icons/obj/structures/chairs/sofa.dmi'
buildstackamount = 1
item_chair = null
-/obj/structure/chair/sofa/left
- icon_state = "sofaend_left"
+// brown, new
-/obj/structure/chair/sofa/right
- icon_state = "sofaend_right"
+/obj/structure/chair/sofa/brown
+ icon_state = "brown_sofa_middle"
-/obj/structure/chair/sofa/corner
- icon_state = "sofacorner"
+/obj/structure/chair/sofa/brown/left
+ icon_state = "brown_sofa_end_left"
+
+/obj/structure/chair/sofa/brown/right
+ icon_state = "brown_sofa_end_right"
+
+/obj/structure/chair/sofa/brown/corner
+ icon_state = "brown_sofa_corner"
+
+/obj/structure/chair/sofa/brown/internal_corner
+ icon_state = "brown_sofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/internal_corner, 0)
+
+// brown, old
+
+/obj/structure/chair/sofa/brown/old
+ name = "old ratty sofa"
+ icon_state = "brown_oldsofa_middle"
+
+/obj/structure/chair/sofa/brown/old/left
+ icon_state = "brown_oldsofa_end_left"
+
+/obj/structure/chair/sofa/brown/old/right
+ icon_state = "brown_oldsofa_end_right"
+
+/obj/structure/chair/sofa/brown/old/corner
+ icon_state = "brown_oldsofa_corner"
+
+/obj/structure/chair/sofa/brown/old/internal_corner
+ icon_state = "brown_oldsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/old/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/old/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/old/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/old/internal_corner, 0)
+
+// brown, corpo
+
+/obj/structure/chair/sofa/brown/corpo
+ name = "corporate sofa"
+ icon_state = "brown_corpsofa_middle"
+
+/obj/structure/chair/sofa/brown/corpo/left
+ icon_state = "brown_corpsofa_end_left"
+
+/obj/structure/chair/sofa/brown/corpo/right
+ icon_state = "brown_corpsofa_end_right"
+
+/obj/structure/chair/sofa/brown/corpo/corner
+ icon_state = "brown_corpsofa_corner"
+
+/obj/structure/chair/sofa/brown/corpo/internal_corner
+ icon_state = "brown_corpsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/corpo, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/corpo/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/corpo/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/corpo/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/brown/corpo/internal_corner, 0)
+
+// purple, new
+
+/obj/structure/chair/sofa/purple
+ icon_state = "purple_sofa_middle"
+
+/obj/structure/chair/sofa/purple/left
+ icon_state = "purple_sofa_end_left"
+
+/obj/structure/chair/sofa/purple/right
+ icon_state = "purple_sofa_end_right"
+
+/obj/structure/chair/sofa/purple/corner
+ icon_state = "purple_sofa_corner"
+
+/obj/structure/chair/sofa/purple/internal_corner
+ icon_state = "purple_sofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/internal_corner, 0)
+
+// purple, old
+
+/obj/structure/chair/sofa/purple/old
+ name = "old ratty sofa"
+ icon_state = "purple_oldsofa_middle"
+
+/obj/structure/chair/sofa/purple/old/left
+ icon_state = "purple_oldsofa_end_left"
+
+/obj/structure/chair/sofa/purple/old/right
+ icon_state = "purple_oldsofa_end_right"
+
+/obj/structure/chair/sofa/purple/old/corner
+ icon_state = "purple_oldsofa_corner"
+
+/obj/structure/chair/sofa/purple/old/internal_corner
+ icon_state = "purple_oldsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/old/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/old/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/old/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/old/internal_corner, 0)
+
+// purple, corpo
+
+/obj/structure/chair/sofa/purple/corpo
+ name = "corporate sofa"
+ icon_state = "purple_corpsofa_middle"
+
+/obj/structure/chair/sofa/purple/corpo/left
+ icon_state = "purple_corpsofa_end_left"
+
+/obj/structure/chair/sofa/purple/corpo/right
+ icon_state = "purple_corpsofa_end_right"
+
+/obj/structure/chair/sofa/purple/corpo/corner
+ icon_state = "purple_corpsofa_corner"
+
+/obj/structure/chair/sofa/purple/corpo/internal_corner
+ icon_state = "purple_corpsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/corpo, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/corpo/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/corpo/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/corpo/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/purple/corpo/internal_corner, 0)
+
+// blue, new
+
+/obj/structure/chair/sofa/blue
+ icon_state = "blue_sofa_middle"
+
+/obj/structure/chair/sofa/blue/left
+ icon_state = "blue_sofa_end_left"
+
+/obj/structure/chair/sofa/blue/right
+ icon_state = "blue_sofa_end_right"
+
+/obj/structure/chair/sofa/blue/corner
+ icon_state = "blue_sofa_corner"
+
+/obj/structure/chair/sofa/blue/internal_corner
+ icon_state = "blue_sofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/internal_corner, 0)
+
+// blue, old
+
+/obj/structure/chair/sofa/blue/old
+ name = "old ratty sofa"
+ icon_state = "blue_oldsofa_middle"
+
+/obj/structure/chair/sofa/blue/old/left
+ icon_state = "blue_oldsofa_end_left"
+
+/obj/structure/chair/sofa/blue/old/right
+ icon_state = "blue_oldsofa_end_right"
+
+/obj/structure/chair/sofa/blue/old/corner
+ icon_state = "blue_oldsofa_corner"
+
+/obj/structure/chair/sofa/blue/old/internal_corner
+ icon_state = "blue_oldsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/old/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/old/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/old/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/old/internal_corner, 0)
+
+// blue, corpo
+
+/obj/structure/chair/sofa/blue/corpo
+ name = "corporate sofa"
+ icon_state = "blue_corpsofa_middle"
+
+/obj/structure/chair/sofa/blue/corpo/left
+ icon_state = "blue_corpsofa_end_left"
+
+/obj/structure/chair/sofa/blue/corpo/right
+ icon_state = "blue_corpsofa_end_right"
+
+/obj/structure/chair/sofa/blue/corpo/corner
+ icon_state = "blue_corpsofa_corner"
+
+/obj/structure/chair/sofa/blue/corpo/internal_corner
+ icon_state = "blue_corpsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/corpo, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/corpo/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/corpo/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/corpo/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/blue/corpo/internal_corner, 0)
+
+// red, new
/obj/structure/chair/sofa/red
- name = "comfortable sofa"
- icon_state = "sofamiddle_red"
+ icon_state = "red_sofa_middle"
/obj/structure/chair/sofa/red/left
- icon_state = "sofaend_left_red"
+ icon_state = "red_sofa_end_left"
/obj/structure/chair/sofa/red/right
- icon_state = "sofaend_right_red"
+ icon_state = "red_sofa_end_right"
/obj/structure/chair/sofa/red/corner
- icon_state = "sofacorner_red"
+ icon_state = "red_sofa_corner"
/obj/structure/chair/sofa/red/internal_corner
- icon_state = "sofainternalcorner_red"
+ icon_state = "red_sofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/internal_corner, 0)
+
+// red, old
+
+/obj/structure/chair/sofa/red/old
+ name = "old ratty sofa"
+ icon_state = "red_oldsofa_middle"
+
+/obj/structure/chair/sofa/red/old/left
+ icon_state = "red_oldsofa_end_left"
+
+/obj/structure/chair/sofa/red/old/right
+ icon_state = "red_oldsofa_end_right"
+
+/obj/structure/chair/sofa/red/old/corner
+ icon_state = "red_oldsofa_corner"
+
+/obj/structure/chair/sofa/red/old/internal_corner
+ icon_state = "red_oldsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/old/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/old/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/old/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/old/internal_corner, 0)
+
+// red, corpo
+
+/obj/structure/chair/sofa/red/corpo
+ name = "corporate sofa"
+ icon_state = "red_corpsofa_middle"
+
+/obj/structure/chair/sofa/red/corpo/left
+ icon_state = "red_corpsofa_end_left"
+
+/obj/structure/chair/sofa/red/corpo/right
+ icon_state = "red_corpsofa_end_right"
+
+/obj/structure/chair/sofa/red/corpo/corner
+ icon_state = "red_corpsofa_corner"
+
+/obj/structure/chair/sofa/red/corpo/internal_corner
+ icon_state = "red_corpsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/corpo, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/corpo/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/corpo/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/corpo/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/red/corpo/internal_corner, 0)
+
+// grey, new
+
+/obj/structure/chair/sofa/grey
+ icon_state = "grey_sofa_middle"
+
+/obj/structure/chair/sofa/grey/left
+ icon_state = "grey_sofa_end_left"
+
+/obj/structure/chair/sofa/grey/right
+ icon_state = "grey_sofa_end_right"
+
+/obj/structure/chair/sofa/grey/corner
+ icon_state = "grey_sofa_corner"
+
+/obj/structure/chair/sofa/grey/internal_corner
+ icon_state = "grey_sofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/internal_corner, 0)
+
+// grey, old
+
+/obj/structure/chair/sofa/grey/old
+ name = "old ratty sofa"
+ icon_state = "grey_oldsofa_middle"
+
+/obj/structure/chair/sofa/grey/old/left
+ icon_state = "grey_oldsofa_end_left"
+
+/obj/structure/chair/sofa/grey/old/right
+ icon_state = "grey_oldsofa_end_right"
+
+/obj/structure/chair/sofa/grey/old/corner
+ icon_state = "grey_oldsofa_corner"
+
+/obj/structure/chair/sofa/grey/old/internal_corner
+ icon_state = "grey_oldsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/old/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/old/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/old/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/old/internal_corner, 0)
+
+// grey, corpo
+
+/obj/structure/chair/sofa/grey/corpo
+ name = "corporate sofa"
+ icon_state = "grey_corpsofa_middle"
+
+/obj/structure/chair/sofa/grey/corpo/left
+ icon_state = "grey_corpsofa_end_left"
+
+/obj/structure/chair/sofa/grey/corpo/right
+ icon_state = "grey_corpsofa_end_right"
+
+/obj/structure/chair/sofa/grey/corpo/corner
+ icon_state = "grey_corpsofa_corner"
+
+/obj/structure/chair/sofa/grey/corpo/internal_corner
+ icon_state = "grey_corpsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/corpo, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/corpo/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/corpo/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/corpo/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/grey/corpo/internal_corner, 0)
+
+// olive, new
+
+/obj/structure/chair/sofa/olive
+ icon_state = "olive_sofa_middle"
+
+/obj/structure/chair/sofa/olive/left
+ icon_state = "olive_sofa_end_left"
+
+/obj/structure/chair/sofa/olive/right
+ icon_state = "olive_sofa_end_right"
+
+/obj/structure/chair/sofa/olive/corner
+ icon_state = "olive_sofa_corner"
+
+/obj/structure/chair/sofa/olive/internal_corner
+ icon_state = "olive_sofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/internal_corner, 0)
+
+// olive, old
+
+/obj/structure/chair/sofa/olive/old
+ name = "old ratty sofa"
+ icon_state = "olive_oldsofa_middle"
+
+/obj/structure/chair/sofa/olive/old/left
+ icon_state = "olive_oldsofa_end_left"
+
+/obj/structure/chair/sofa/olive/old/right
+ icon_state = "olive_oldsofa_end_right"
+
+/obj/structure/chair/sofa/olive/old/corner
+ icon_state = "olive_oldsofa_corner"
+
+/obj/structure/chair/sofa/olive/old/internal_corner
+ icon_state = "olive_oldsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/old, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/old/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/old/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/old/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/old/internal_corner, 0)
+
+// olive, corpo
+
+/obj/structure/chair/sofa/olive/corpo
+ name = "corporate sofa"
+ icon_state = "olive_corpsofa_middle"
+
+/obj/structure/chair/sofa/olive/corpo/left
+ icon_state = "olive_corpsofa_end_left"
+
+/obj/structure/chair/sofa/olive/corpo/right
+ icon_state = "olive_corpsofa_end_right"
+
+/obj/structure/chair/sofa/olive/corpo/corner
+ icon_state = "olive_corpsofa_corner"
+
+/obj/structure/chair/sofa/olive/corpo/internal_corner
+ icon_state = "olive_corpsofa_internalcorner"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/corpo, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/corpo/left, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/corpo/right, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/corpo/corner, 0)
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/sofa/olive/corpo/internal_corner, 0)
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 35b7663ca05e..d57e31ce9514 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -235,6 +235,13 @@ LINEN BINS
item_state = "sheetsolgov"
dream_messages = list("bureaucracy", "laws", "papers", "writing")
+/obj/item/bedsheet/suns
+ name = "\improper SUNS bedsheet"
+ desc = "A gold and purple bedsheet with the SUNS icon on it."
+ icon_state = "sheetsuns"
+ item_state = "sheetsuns"
+ dream_messages = list("learning", "science", "geology", "studying a day before an exam")
+
/obj/item/bedsheet/ian
icon_state = "sheetian"
item_state = "sheetian"
@@ -356,6 +363,13 @@ LINEN BINS
dream_messages = list("bureaucracy", "laws", "papers", "writing")
desc = "It has the emblem of the Solar Confederation emblazoned upon it!"
+/obj/item/bedsheet/double/suns
+ name = "double SUNS bedsheet"
+ desc = "A large gold and purple bedsheet with the SUNS icon on it."
+ icon_state = "double_sheetsuns"
+ item_state = "double_sheetsuns"
+ dream_messages = list("learning", "science", "geology", "studying a day before an exam")
+
/obj/item/bedsheet/random/Initialize()
..()
var/type = pick(typesof(/obj/item/bedsheet) - (typesof(/obj/item/bedsheet/double) + /obj/item/bedsheet/random))
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 417a1f8d86a6..714129498e4c 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -343,7 +343,7 @@
"You [actuallyismob ? "try to ":""]stuff [O] into [src].", \
"You hear clanging.")
if(actuallyismob)
- if(do_after_mob(user, targets, 40))
+ if(do_after(user, 40, targets))
user.visible_message(
"[user] stuffs [O] into [src].", \
"You stuff [O] into [src].", \
diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
index 0e65a5aeb760..dac919bb428c 100644
--- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
@@ -98,7 +98,7 @@
icon_door = "black"
/obj/structure/closet/wardrobe/chaplain_black/PopulateContents()
- new /obj/item/choice_beacon/holy(src)
+ new /obj/item/storage/box/holy(src)
new /obj/item/clothing/accessory/pocketprotector/cosmetology(src)
new /obj/item/clothing/under/rank/civilian/chaplain(src)
new /obj/item/clothing/shoes/sneakers/black(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index a11e647a706d..f3aca3e96a98 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -5,11 +5,9 @@
/obj/structure/closet/secure_closet/engineering_chief/PopulateContents()
..()
- //WS Begin
new /obj/item/clothing/head/beret/ce(src) //Berets
new /obj/item/clothing/under/rank/command(src) //Better command uniforms
new /obj/item/stack/tape/industrial/pro(src) //Better tape
- //WS End
new /obj/item/clothing/neck/cloak/ce(src)
new /obj/item/clothing/under/rank/engineering/chief_engineer(src)
new /obj/item/clothing/under/rank/engineering/chief_engineer/skirt(src)
@@ -40,9 +38,7 @@
/obj/structure/closet/secure_closet/engineering_electrical/PopulateContents()
..()
var/static/items_inside = list(
- //WS Begin
/obj/item/stack/tape/industrial/electrical = 1, // Better tape
- //WS End
/obj/item/clothing/gloves/color/yellow = 2,
/obj/item/storage/toolbox/electrical = 3,
/obj/item/electronics/apc = 3,
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
index cfdcca348b14..6c01be326e7a 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -79,13 +79,11 @@
/obj/structure/closet/secure_closet/CMO/PopulateContents()
..()
- //WS Begin
new /obj/item/storage/belt/medical(src) //Gives the CMO a belt
new /obj/item/storage/bag/medical(src) //Medibags
new /obj/item/clothing/head/beret/cmo(src) //Berets
new /obj/item/clothing/under/rank/command(src) //Better command uniforms
new /obj/item/storage/box/hypospray/CMO(src) //Hypo mk. 2s
- //WS End
new /obj/item/clothing/neck/cloak/cmo(src)
new /obj/item/clothing/suit/bio_suit/cmo(src)
new /obj/item/clothing/head/bio_hood/cmo(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/misc.dm b/code/game/objects/structures/crates_lockers/closets/secure/misc.dm
index 165dac720c04..e05bd4524230 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/misc.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/misc.dm
@@ -65,3 +65,7 @@
new /obj/item/storage/box/smart_metal_foam(src)
for(var/i in 1 to 3)
new /obj/item/rcd_ammo/large(src)
+
+/obj/structure/closet/secure_closet/suns
+ name = "SUNS locker"
+ icon_state = "suns"
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index f94a5d5de585..8ccc632dbac5 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -23,8 +23,6 @@
new /obj/item/clothing/under/rank/command/captain/skirt(src)
new /obj/item/clothing/suit/armor/vest/capcarapace(src)
new /obj/item/clothing/head/caphat(src)
- new /obj/item/clothing/under/rank/command/captain/parade(src)
- new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src)
new /obj/item/clothing/head/caphat/parade(src)
new /obj/item/clothing/suit/armor/vest/capcarapace/captunic(src)
new /obj/item/clothing/head/crown/fancy(src)
@@ -296,7 +294,6 @@
/obj/structure/closet/secure_closet/armory2/PopulateContents()
..()
- new /obj/item/storage/box/firingpins(src)
for(var/i in 1 to 3)
new /obj/item/storage/box/rubbershot(src)
for(var/i in 1 to 3)
@@ -309,7 +306,6 @@
/obj/structure/closet/secure_closet/armory3/PopulateContents()
..()
- new /obj/item/storage/box/firingpins(src)
new /obj/item/gun/energy/ionrifle(src)
for(var/i in 1 to 3)
new /obj/item/gun/energy/e_gun(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
index ee9a29945aa0..fc0aae860782 100644
--- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm
+++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
@@ -105,7 +105,7 @@
/obj/item/stack/sheet/mineral/plasma,
/obj/item/stack/sheet/mineral/uranium,
/obj/item/stack/sheet/mineral/diamond,
- /obj/item/stack/sheet/mineral/bananium,
+ /obj/item/stack/sheet/mineral/hidden/hellstone,
/obj/item/stack/sheet/plasteel,
/obj/item/stack/sheet/mineral/titanium,
/obj/item/stack/sheet/mineral/plastitanium,
diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm
index 63d9b6552c16..77d75164b185 100644
--- a/code/game/objects/structures/crates_lockers/crates/secure.dm
+++ b/code/game/objects/structures/crates_lockers/crates/secure.dm
@@ -83,10 +83,10 @@
/obj/structure/closet/crate/secure/owned/togglelock(mob/living/user, silent)
if(privacy_lock)
if(!broken)
- var/obj/item/card/id/id_card = user.get_idcard(TRUE)
- if(id_card)
- if(id_card.registered_account)
- if(id_card.registered_account == buyer_account)
+ var/obj/item/card/bank/bank_card = user.get_bankcard()
+ if(bank_card)
+ if(bank_card.registered_account)
+ if(bank_card.registered_account == buyer_account)
if(iscarbon(user))
add_fingerprint(user)
locked = !locked
@@ -105,7 +105,7 @@
else ..()
/obj/structure/closet/crate/secure/exo
- desc = "A lock-enabled crate used to carry EXOCON merchandise destined for export to potential buyers."
- name = "EXOCON storage crate"
+ desc = "A lock-enabled crate used to carry EXOCOM merchandise destined for export to potential buyers."
+ name = "EXOCOM storage crate"
icon = 'icons/obj/crates.dmi'
icon_state = "exocrate"
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index 37c816335977..4e95b5558842 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -422,7 +422,7 @@
. = ..()
if(.)
return
- var/obj/item/card/id/potential_acc = usr.get_idcard(hand_first = TRUE)
+ var/obj/item/card/bank/potential_acc = usr.get_bankcard()
switch(action)
if("Buy")
if(!showpiece)
@@ -497,9 +497,9 @@
return TRUE
. = TRUE
/obj/structure/displaycase/forsale/attackby(obj/item/I, mob/living/user, params)
- if(isidcard(I))
+ if(isbankcard(I))
//Card Registration
- var/obj/item/card/id/potential_acc = I
+ var/obj/item/card/bank/potential_acc = I
if(!potential_acc.registered_account)
to_chat(user, "This ID card has no account registered!")
return
diff --git a/code/game/objects/structures/door_assembly_types.dm b/code/game/objects/structures/door_assembly_types.dm
index 2558993a5278..d2bcf77cfda7 100644
--- a/code/game/objects/structures/door_assembly_types.dm
+++ b/code/game/objects/structures/door_assembly_types.dm
@@ -214,14 +214,6 @@
mineral = "plasma"
glass_type = /obj/machinery/door/airlock/plasma/glass
-/obj/structure/door_assembly/door_assembly_bananium
- name = "bananium airlock assembly"
- desc = "Honk."
- icon = 'icons/obj/doors/airlocks/station/bananium.dmi'
- base_name = "bananium airlock"
- airlock_type = /obj/machinery/door/airlock/bananium
- mineral = "bananium"
- glass_type = /obj/machinery/door/airlock/bananium/glass
/obj/structure/door_assembly/door_assembly_sandstone
name = "sandstone airlock assembly"
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index a0097504c1d3..d5a8c3e496c1 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -269,19 +269,6 @@
if(exposed_temperature > 300)
burnbabyburn()
-/obj/structure/falsewall/bananium
- name = "bananium wall"
- desc = "A wall with bananium plating. Honk!"
- icon = 'icons/turf/walls/bananium_wall.dmi'
- icon_state = "bananium_wall-0"
- base_icon_state = "bananium_wall"
- mineral = /obj/item/stack/sheet/mineral/bananium
- walltype = /turf/closed/wall/mineral/bananium
- smoothing_flags = SMOOTH_BITMASK
- smoothing_groups = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_BANANIUM_WALLS)
- canSmoothWith = list(SMOOTH_GROUP_BANANIUM_WALLS)
-
-
/obj/structure/falsewall/sandstone
name = "sandstone wall"
desc = "A wall with sandstone plating. Rough."
diff --git a/code/game/objects/structures/fugitive_role_spawners.dm b/code/game/objects/structures/fugitive_role_spawners.dm
deleted file mode 100644
index 4f98e919ffc5..000000000000
--- a/code/game/objects/structures/fugitive_role_spawners.dm
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-/obj/effect/mob_spawn/human/fugitive
- assignedrole = "Fugitive Hunter"
- flavour_text = "" //the flavor text will be the backstory argument called on the antagonist's greet, see hunter.dm for details
- roundstart = FALSE
- death = FALSE
- random = TRUE
- show_flavour = FALSE
- density = TRUE
- var/back_story = "error"
-
-/obj/effect/mob_spawn/human/fugitive/Initialize(mapload)
- . = ..()
- notify_ghosts("Hunters are waking up looking for refugees!", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_FUGITIVE)
-
-/obj/effect/mob_spawn/human/fugitive/spacepol
- name = "police pod"
- desc = "A small sleeper typically used to put people to sleep for briefing on the mission."
- mob_name = "a spacepol officer"
- flavour_text = "Justice has arrived. I am a member of the Spacepol!"
- back_story = "space cop"
- outfit = /datum/outfit/spacepol
- icon = 'icons/obj/machines/sleeper.dmi'
- icon_state = "sleeper"
-
-/obj/effect/mob_spawn/human/fugitive/russian
- name = "russian pod"
- flavour_text = "Ay blyat. I am a space-russian smuggler! We were mid-flight when our cargo was beamed off our ship!"
- back_story = "russian"
- desc = "A small sleeper typically used to make long distance travel a bit more bearable."
- mob_name = "russian"
- outfit = /datum/outfit/frontier/hunter
- icon = 'icons/obj/machines/sleeper.dmi'
- icon_state = "sleeper"
-
-/obj/effect/mob_spawn/human/fugitive/bounty
- name = "bounty hunter pod"
- flavour_text = "We got a new bounty on some fugitives, dead or alive."
- back_story = "bounty hunters"
- desc = "A small sleeper typically used to make long distance travel a bit more bearable."
- mob_name = "bounty hunter"
- icon = 'icons/obj/machines/sleeper.dmi'
- icon_state = "sleeper"
-
-/obj/effect/mob_spawn/human/fugitive/bounty/Destroy()
- var/obj/structure/fluff/empty_sleeper/S = new(drop_location())
- S.setDir(dir)
- return ..()
-
-/obj/effect/mob_spawn/human/fugitive/bounty/armor
- outfit = /datum/outfit/bountyarmor
-
-/obj/effect/mob_spawn/human/fugitive/bounty/hook
- outfit = /datum/outfit/bountyhook
-
-/obj/effect/mob_spawn/human/fugitive/bounty/synth
- outfit = /datum/outfit/bountysynth
diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/geyser.dm
similarity index 77%
rename from code/game/objects/structures/lavaland/geyser.dm
rename to code/game/objects/structures/geyser.dm
index ed177c72d34e..af536d2e8c1c 100644
--- a/code/game/objects/structures/lavaland/geyser.dm
+++ b/code/game/objects/structures/geyser.dm
@@ -35,7 +35,7 @@
to_chat(user, "The [name] is already active!")
return
- to_chat(user, "You start vigorously plunging [src]!")
+ to_chat(user, span_notice("You start vigorously plunging [src]!"))
if(do_after(user, 50 * P.plunge_mod, target = src) && !activated)
start_chemming()
@@ -51,6 +51,8 @@
name = "plunger"
desc = "It's a plunger for plunging."
icon = 'icons/obj/watercloset.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
+ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
icon_state = "plunger"
slot_flags = ITEM_SLOT_MASK
@@ -59,6 +61,15 @@
var/plunge_mod = 1 //time*plunge_mod = total time we take to plunge an object
+
+/obj/item/plunger/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!. && user.zone_selected == BODY_ZONE_HEAD && iscarbon(target))
+ var/mob/living/carbon/H = target
+ if(!H.wear_mask)
+ H.equip_to_slot_if_possible(src, ITEM_SLOT_MASK)
+ H.visible_message(span_warning("[user] slaps [src] onto [H]'s face!"), span_warning("[user] slaps [src] onto your face!"), span_hear("You hear violent plumbing."))
+
/obj/item/plunger/attack_obj(obj/O, mob/living/user)
if(!O.plunger_act(src, user))
return ..()
@@ -71,5 +82,5 @@
var/mob/living/carbon/H = hit_atom
if(!H.wear_mask)
H.equip_to_slot_if_possible(src, ITEM_SLOT_MASK)
- H.visible_message("The plunger slams into [H]'s face!", "The plunger suctions to your face!")
+ H.visible_message(span_warning("[src] slams into [H]'s face!"), span_warning("[src] suctions to your face!"), span_hear("You hear violent plumbing."))
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index abc67e252d52..aed3ae724c59 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -149,7 +149,7 @@
name = "Demonic Friend"
uniform = /obj/item/clothing/under/misc/assistantformal
shoes = /obj/item/clothing/shoes/laceup
- r_pocket = /obj/item/radio/off
+ r_pocket = /obj/item/radio
back = /obj/item/storage/backpack
implants = list(/obj/item/implant/mindshield) //No revolutionaries, he's MY friend.
id = /obj/item/card/id
@@ -211,37 +211,3 @@
/obj/effect/mob_spawn/human/pirate/gunner
rank = "Gunner"
-
-/datum/outfit/syndicatespace
- name = "Syndicate Spacer"
- uniform = /obj/item/clothing/under/syndicate/combat
- mask = /obj/item/clothing/mask/gas/syndicate
-
-/datum/outfit/syndicatespace/syndicrew
- name = "Syndicate Ship Crew Member"
- glasses = /obj/item/clothing/glasses/night
- ears = /obj/item/radio/headset/syndicate/alt
- shoes = /obj/item/clothing/shoes/combat
- gloves = /obj/item/clothing/gloves/combat
- back = /obj/item/storage/backpack
- l_pocket = /obj/item/gun/ballistic/automatic/pistol
- r_pocket = /obj/item/kitchen/knife/combat/survival
- belt = /obj/item/storage/belt/military/assault
- id = /obj/item/card/id/syndicate_command/crew_id
- implants = list(/obj/item/implant/weapons_auth)
-
-/datum/outfit/syndicatespace/syndicaptain
- name = "Syndicate Ship Captain"
- suit = /obj/item/clothing/suit/armor/vest/capcarapace/syndicate
- glasses = /obj/item/clothing/glasses/night
- head = /obj/item/clothing/head/HoS/beret/syndicate
- ears = /obj/item/radio/headset/syndicate/alt/captain
- shoes = /obj/item/clothing/shoes/combat
- gloves = /obj/item/clothing/gloves/combat
- back = /obj/item/storage/backpack
- l_pocket = /obj/item/gun/ballistic/automatic/pistol/APS
- r_pocket = /obj/item/kitchen/knife/combat/survival
- belt = /obj/item/storage/belt/military/assault
- id = /obj/item/card/id/syndicate_command/captain_id
- backpack_contents = list(/obj/item/documents/syndicate/red, /obj/item/paper/fluff/ruins/forgottenship/password)
- implants = list(/obj/item/implant/weapons_auth)
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 25822d69ff00..6463282eb6df 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -364,7 +364,7 @@
add_fingerprint(user)
if(istype(W, /obj/item/melee/cultblade/dagger) && iscultist(user)) //Cultists can demolish cult girders instantly with their tomes
user.visible_message("[user] strikes [src] with [W]!", "You demolish [src].")
- new /obj/item/stack/sheet/runed_metal(drop_location(), 1)
+ new /obj/item/stack/sheet/mineral/hidden/hellstone(drop_location(), 1)
qdel(src)
else if(W.tool_behaviour == TOOL_WELDER)
@@ -374,19 +374,19 @@
to_chat(user, "You start slicing apart the girder...")
if(W.use_tool(src, user, 40, volume=50))
to_chat(user, "You slice apart the girder.")
- var/obj/item/stack/sheet/runed_metal/R = new(drop_location(), 1)
+ var/obj/item/stack/sheet/mineral/hidden/hellstone/R = new(drop_location(), 1)
transfer_fingerprints_to(R)
qdel(src)
else if(istype(W, /obj/item/pickaxe/drill/jackhammer))
to_chat(user, "Your jackhammer smashes through the girder!")
- var/obj/item/stack/sheet/runed_metal/R = new(drop_location(), 2)
+ var/obj/item/stack/sheet/mineral/hidden/hellstone/R = new(drop_location(), 2)
transfer_fingerprints_to(R)
W.play_tool_sound(src)
qdel(src)
- else if(istype(W, /obj/item/stack/sheet/runed_metal))
- var/obj/item/stack/sheet/runed_metal/R = W
+ else if(istype(W, /obj/item/stack/sheet/mineral/hidden/hellstone))
+ var/obj/item/stack/sheet/mineral/hidden/hellstone/R = W
if(R.get_amount() < 1)
to_chat(user, "You need at least one sheet of runed metal to construct a runed wall!")
return 0
@@ -408,7 +408,7 @@
/obj/structure/girder/cult/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
- new /obj/item/stack/sheet/runed_metal(drop_location(), 1)
+ new /obj/item/stack/sheet/mineral/hidden/hellstone(drop_location(), 1)
qdel(src)
/obj/structure/girder/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm
index cf0d6957e69c..ddcb59466deb 100644
--- a/code/game/objects/structures/guncase.dm
+++ b/code/game/objects/structures/guncase.dm
@@ -1,5 +1,5 @@
//GUNCASES//
-/obj/structure/guncase
+/obj/structure/guncloset
name = "gun locker"
desc = "A locker that holds guns."
icon = 'icons/obj/closet.dmi'
@@ -12,7 +12,7 @@
var/open = TRUE
var/capacity = 4
-/obj/structure/guncase/Initialize(mapload)
+/obj/structure/guncloset/Initialize(mapload)
. = ..()
if(mapload)
for(var/obj/item/I in loc.contents)
@@ -22,7 +22,7 @@
break
update_appearance()
-/obj/structure/guncase/update_overlays()
+/obj/structure/guncloset/update_overlays()
. = ..()
if(case_type && LAZYLEN(contents))
var/mutable_appearance/gun_overlay = mutable_appearance(icon, case_type)
@@ -31,7 +31,7 @@
. += new /mutable_appearance(gun_overlay)
. += "[icon_state]_[open ? "open" : "door"]"
-/obj/structure/guncase/attackby(obj/item/I, mob/user, params)
+/obj/structure/guncloset/attackby(obj/item/I, mob/user, params)
if(iscyborg(user) || isalien(user))
return
if(istype(I, gun_category) && open)
@@ -50,7 +50,7 @@
else
return ..()
-/obj/structure/guncase/attack_hand(mob/user)
+/obj/structure/guncloset/attack_hand(mob/user)
. = ..()
if(.)
return
@@ -68,7 +68,7 @@
* Arguments:
* * user The mob to which we are showing the radial menu
*/
-/obj/structure/guncase/proc/show_menu(mob/user)
+/obj/structure/guncloset/proc/show_menu(mob/user)
if(!LAZYLEN(contents))
return
@@ -100,7 +100,7 @@
* Arguments:
* * user The mob interacting with a menu
*/
-/obj/structure/guncase/proc/check_menu(mob/living/carbon/human/user)
+/obj/structure/guncloset/proc/check_menu(mob/living/carbon/human/user)
if(!open)
return FALSE
if(!istype(user))
@@ -109,10 +109,10 @@
return FALSE
return TRUE
-/obj/structure/guncase/handle_atom_del(atom/A)
+/obj/structure/guncloset/handle_atom_del(atom/A)
update_appearance()
-/obj/structure/guncase/contents_explosion(severity, target)
+/obj/structure/guncloset/contents_explosion(severity, target)
for(var/atom/A in contents)
switch(severity)
if(EXPLODE_DEVASTATE)
@@ -122,13 +122,13 @@
if(EXPLODE_LIGHT)
SSexplosions.lowobj += A
-/obj/structure/guncase/shotgun
+/obj/structure/guncloset/shotgun
name = "shotgun locker"
desc = "A locker that holds shotguns."
case_type = "shotgun"
gun_category = /obj/item/gun/ballistic/shotgun
-/obj/structure/guncase/ecase
+/obj/structure/guncloset/ecase
name = "energy gun locker"
desc = "A locker that holds energy guns."
icon_state = "ecase"
diff --git a/code/game/objects/structures/hivebot.dm b/code/game/objects/structures/hivebot.dm
deleted file mode 100644
index 00124d781d80..000000000000
--- a/code/game/objects/structures/hivebot.dm
+++ /dev/null
@@ -1,112 +0,0 @@
-/obj/structure/hivebot_beacon
- name = "beacon"
- desc = "Some odd beacon thing."
- icon = 'icons/mob/hivebot.dmi'
- icon_state = "def_radar-off"
- anchored = TRUE
- density = TRUE
- var/bot_type = "norm"
- var/bot_amt = 10
- var/spawn_time_min
- var/spawn_time_max
-
-/obj/structure/hivebot_beacon/Initialize()
- . = ..()
- var/datum/effect_system/smoke_spread/smoke = new
- smoke.set_up(2, loc)
- smoke.start()
- visible_message("[src] warps in!")
- playsound(src.loc, 'sound/effects/empulse.ogg', 25, TRUE)
- addtimer(CALLBACK(src, PROC_REF(warpbots)), rand(spawn_time_min, spawn_time_max))
-
-/obj/structure/hivebot_beacon/proc/warpbots()
- icon_state = "def_radar"
- visible_message("[src] turns on!")
- while(bot_amt > 0)
- bot_amt--
- switch(bot_type)
- if("norm")
- new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
- if("range")
- new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
- if("rapid")
- new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
-
- sleep(100)
- visible_message("[src] warps out!")
- playsound(src.loc, 'sound/effects/empulse.ogg', 25, TRUE)
- qdel(src)
- return
-
-/obj/structure/spawner/wasteplanet/hivebot
- name = "hivebot fabricator"
- desc = "An active fabricator, creating hivebots out of resources from below the surface."
-
- icon = 'icons/obj/machines/bsm.dmi'
- icon_state = "bsm_on"
-
- faction = list("mining")
- max_mobs = 5
- max_integrity = 250
- mob_types = list(
- /mob/living/simple_animal/hostile/hivebot/wasteplanet = 40,
- /mob/living/simple_animal/hostile/hivebot/wasteplanet/ranged = 40,
- /mob/living/simple_animal/hostile/hivebot/wasteplanet/ranged/rapid = 10,
- /mob/living/simple_animal/hostile/hivebot/wasteplanet/strong = 5,
- /mob/living/simple_animal/hostile/hivebot/mechanic = 5
- )
- spawn_text = "crawls out of"
- spawn_sound = list('sound/effects/suitstep2.ogg')
- move_resist = INFINITY
- anchored = TRUE
- resistance_flags = FIRE_PROOF | LAVA_PROOF
- var/obj/effect/light_emitter/hivespawner/emitted_light
-
-/obj/structure/spawner/wasteplanet/hivebot/Initialize()
- . = ..()
- emitted_light = new(loc)
-
-/obj/structure/spawner/wasteplanet/hivebot/deconstruct(disassembled)
- destroy_effect()
- drop_loot()
- return ..()
-
-/obj/structure/spawner/wasteplanet/hivebot/Destroy()
- QDEL_NULL(emitted_light)
- return ..()
-
-/obj/structure/spawner/wasteplanet/hivebot/proc/destroy_effect()
- playsound(loc,'sound/effects/explosionfar.ogg', 200, TRUE)
- visible_message("[src] begins to rattle and shake, sparks flying off of it!")
-
-
-/obj/structure/spawner/wasteplanet/hivebot/proc/drop_loot()
- var/datum/effect_system/smoke_spread/smoke = new
- smoke.set_up(2, loc)
- smoke.start()
- new /obj/effect/particle_effect/sparks(loc)
- new /obj/effect/spawner/lootdrop/waste/hivebot/beacon(loc)
-
-/obj/effect/light_emitter/hivespawner
- set_luminosity = 4
- set_cap = 2.5
- light_color = COLOR_RED_LIGHT
-
-
-/obj/structure/spawner/wasteplanet/hivebot/low_threat
- max_mobs = 4
- spawn_time = 300
-
-/obj/structure/spawner/wasteplanet/hivebot/medium_threat
- max_mobs = 5
- spawn_time = 250
-
-/obj/structure/spawner/wasteplanet/hivebot/high_threat
- max_mobs = 7
- spawn_time = 200
-
-/obj/structure/spawner/wasteplanet/hivebot/extreme_threat
- max_mobs = 10
- spawn_time = 150
-
-
diff --git a/code/game/objects/structures/icemoon/cave_entrance.dm b/code/game/objects/structures/icemoon/cave_entrance.dm
deleted file mode 100644
index 07ecef04afac..000000000000
--- a/code/game/objects/structures/icemoon/cave_entrance.dm
+++ /dev/null
@@ -1,1060 +0,0 @@
-GLOBAL_LIST_INIT(ore_probability, list(
- /obj/item/stack/ore/uranium = 50,
- /obj/item/stack/ore/iron = 50,
- /obj/item/stack/ore/plasma = 75,
- /obj/item/stack/ore/silver = 50,
- /obj/item/stack/ore/gold = 50,
- /obj/item/stack/ore/diamond = 25,
- /obj/item/stack/ore/bananium = 5,
- /obj/item/stack/ore/titanium = 75,
- /obj/item/pickaxe/diamond = 15,
- /obj/item/borg/upgrade/modkit/cooldown = 5,
- /obj/item/borg/upgrade/modkit/damage = 5,
- /obj/item/borg/upgrade/modkit/range = 5,
- /obj/item/t_scanner/adv_mining_scanner/lesser = 15,
- /obj/item/kinetic_crusher = 15,
- /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25,
- /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25,
- /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25,
- /obj/item/tank/jetpack/suit = 10,
- /obj/item/survivalcapsule = 15,
- /obj/item/reagent_containers/hypospray/medipen/survival = 15,
- /obj/item/gps/mining = 10,
- /obj/item/extraction_pack = 10,
- /obj/item/reagent_containers/food/drinks/beer = 15,
- ))
-
-/obj/structure/spawner/ice_moon
- name = "cave entrance"
- desc = "A hole in the ground, filled with monsters ready to defend it."
- faction = list("mining")
- max_mobs = 3
- max_integrity = 250
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/wolf)
- move_resist = INFINITY
- anchored = TRUE
-
-/obj/structure/spawner/ice_moon/Initialize()
- . = ..()
- clear_rock()
-
-/**
- * Clears rocks around the spawner when it is created
- *
- */
-/obj/structure/spawner/ice_moon/proc/clear_rock()
- for(var/turf/F in RANGE_TURFS(2, src))
- if(abs(src.x - F.x) + abs(src.y - F.y) > 3)
- continue
- if(ismineralturf(F))
- var/turf/closed/mineral/M = F
- M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
-
-/obj/structure/spawner/ice_moon/deconstruct(disassembled)
- destroy_effect()
- drop_loot()
- return ..()
-
-/**
- * Effects and messages created when the spawner is destroyed
- *
- */
-/obj/structure/spawner/ice_moon/proc/destroy_effect()
- playsound(loc,'sound/effects/explosionfar.ogg', 200, TRUE)
- visible_message("[src] collapses, sealing everything inside!\nOres fall out of the cave as it is destroyed!")
-
-/**
- * Drops items after the spawner is destroyed
- *
- */
-/obj/structure/spawner/ice_moon/proc/drop_loot()
- for(var/type in GLOB.ore_probability)
- var/chance = GLOB.ore_probability[type]
- if(!prob(chance))
- continue
- new type(loc, rand(5, 10))
-
-/obj/structure/spawner/ice_moon/polarbear
- max_mobs = 1
- spawn_time = 60 SECONDS
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/polarbear)
-
-/obj/structure/spawner/ice_moon/polarbear/clear_rock()
- for(var/turf/F in RANGE_TURFS(1, src))
- if(ismineralturf(F))
- var/turf/closed/mineral/M = F
- M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
-
-/obj/structure/spawner/ice_moon/demonic_portal
- name = "demonic portal"
- desc = "A portal that goes to another world, normal creatures couldn't survive there. When it collapses, who knows where it will go?"
- icon_state = "nether"
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/ice_demon)
- light_range = 1
- light_color = COLOR_SOFT_RED
- spawn_time = 300
-
-/obj/structure/spawner/ice_moon/demonic_portal/clear_rock()
- for(var/turf/F in RANGE_TURFS(3, src))
- if(abs(src.x - F.x) + abs(src.y - F.y) > 5)
- continue
- if(ismineralturf(F))
- var/turf/closed/mineral/M = F
- M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
-
-/obj/structure/spawner/ice_moon/demonic_portal/Initialize()
- . = ..()
-
-/obj/structure/spawner/ice_moon/demonic_portal/destroy_effect()
- new /obj/effect/collapsing_demonic_portal(loc)
-
-/obj/structure/spawner/ice_moon/demonic_portal/drop_loot()
- return
-
-/obj/structure/spawner/ice_moon/rockplanet
- name = "gruboid den"
- desc = "Though gruboid are typically nomadic creatures, they gather in small surface caves to reproduce. They're unlikely to be happy about being disturbed."
- max_mobs = 3
- spawn_time = 60 SECONDS
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/rockplanet, /mob/living/simple_animal/hostile/asteroid/elite/broodmother_child/rockplanet)
-
-/obj/structure/spawner/ice_moon/rockplanet/clear_rock()
- for(var/turf/F in RANGE_TURFS(1, src))
- if(ismineralturf(F))
- var/turf/closed/mineral/M = F
- M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
-
-/obj/effect/collapsing_demonic_portal
- name = "collapsing demonic portal"
- desc = "It's slowly fading! Get ready to fight whatever comes through!"
- layer = TABLE_LAYER
- icon = 'icons/mob/nest.dmi'
- icon_state = "nether"
- anchored = TRUE
- density = TRUE
-
-/obj/effect/collapsing_demonic_portal/Initialize()
- . = ..()
- playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, FALSE, 50, TRUE, TRUE)
- visible_message("[src] begins to collapse! As it fails, it connects to a random dimensional point and pulls through what it finds!")
- animate(src, transform = matrix().Scale(0, 1), alpha = 50, time = 5 SECONDS)
- addtimer(CALLBACK(src, PROC_REF(collapse)), 5 SECONDS)
-
-/**
- * Handles portal deletion
- *
- */
-/obj/effect/collapsing_demonic_portal/proc/collapse()
- drop_loot()
- qdel(src)
-
-//portal types go here
-
-/obj/structure/spawner/ice_moon/demonic_portal/brimdemon
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/brimdemon)
-
-/obj/structure/spawner/ice_moon/demonic_portal/ice_whelp
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/ice_whelp)
-
-/obj/structure/spawner/ice_moon/demonic_portal/snowlegion
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril)
-
-/obj/structure/spawner/ice_moon/demonic_portal/low_threat
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 35,
- /mob/living/simple_animal/hostile/asteroid/ice_whelp = 15,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril = 35,
- /mob/living/simple_animal/hostile/asteroid/ice_demon = 15
- )
- max_mobs = 5
- spawn_time = 300
-
-/obj/structure/spawner/ice_moon/demonic_portal/medium_threat
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 25,
- /mob/living/simple_animal/hostile/asteroid/ice_whelp = 25,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril = 25,
- /mob/living/simple_animal/hostile/asteroid/ice_demon = 25
- )
- max_mobs = 7
- spawn_time = 300
-/obj/structure/spawner/ice_moon/demonic_portal/high_threat
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 15,
- /mob/living/simple_animal/hostile/asteroid/ice_whelp = 35,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril = 15,
- /mob/living/simple_animal/hostile/asteroid/ice_demon = 35
- )
- max_mobs = 7
- spawn_time = 200
-
-/obj/structure/spawner/ice_moon/demonic_portal/extreme_threat
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 10,
- /mob/living/simple_animal/hostile/asteroid/ice_whelp = 25,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril = 15,
- /mob/living/simple_animal/hostile/asteroid/ice_demon = 50
- )
- max_mobs = 10
- spawn_time = 200
-
-//I think there's room to make portal types drop loot/spawn monsters based on the loot list but that's out of scope for what I'm doing
-
-/**
- * Drops loot from the portal. Uses variable difficulty based on drops- more valulable rewards will also add additional enemies to the attack wave.
- * If you manage to win big and get a bunch of major rich loot, you will also be faced with a big mob of angries.
- * Absolutely deranged use of probability code below, trigger warning
- */
-/obj/effect/collapsing_demonic_portal/proc/drop_loot()
- visible_message("Something slips out of [src]!")
- var/loot = rand(1, 23)
- switch(loot)
- if(1)//Clown hell. God help you if you roll this.
- visible_message("You can hear screaming and joyful honking.")//now THIS is what we call a critical failure
- playsound(loc,'sound/spookoween/ghosty_wind.ogg', 100, FALSE, 50, TRUE, TRUE)
- playsound(loc,'sound/spookoween/scary_horn3.ogg', 100, FALSE, 50, TRUE, TRUE)
- if(prob(15))
- new /mob/living/simple_animal/hostile/clown/clownhulk(loc)
- new /mob/living/simple_animal/hostile/clown/longface(loc)
- new /mob/living/simple_animal/hostile/clown/clownhulk/chlown(loc)
- new /obj/item/shield/energy/bananium(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/clown/banana(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/clown/fleshclown(loc)
- new /mob/living/simple_animal/hostile/clown/clownhulk/chlown
- new /mob/living/simple_animal/hostile/clown/honkling(loc)
- if(prob(25))
- new /obj/item/grenade/spawnergrenade/clown(loc)
- new /obj/item/grenade/spawnergrenade/clown(loc)
- new /mob/living/simple_animal/hostile/clown/clownhulk(loc)
- if(prob(10))
- new /mob/living/simple_animal/hostile/clown/mutant/blob(loc)//oh god oh fuck
- new /obj/machinery/syndicatebomb/badmin/clown(loc)
- if(prob(35))
- new /obj/item/storage/backpack/duffelbag/clown/syndie(loc)
- new /mob/living/simple_animal/hostile/clown/fleshclown(loc)
- new /mob/living/simple_animal/hostile/clown/honkling(loc)
- else
- new /obj/item/storage/backpack/duffelbag/clown/cream_pie(loc)
- new /mob/living/simple_animal/hostile/clown/honkling(loc)
- if(prob(25))
- new /obj/item/borg/upgrade/transform/clown(loc)
- new /mob/living/simple_animal/hostile/clown/stacked(loc)
- if(prob(35))
- new /obj/item/megaphone/clown(loc)
- new /mob/living/simple_animal/hostile/clown/stacked(loc)
- if(prob(25))
- new /obj/item/reagent_containers/spray/waterflower/lube(loc)
- new /mob/living/simple_animal/hostile/clown/fleshclown(loc)
- new /mob/living/simple_animal/hostile/clown/fleshclown(loc)
- if(prob(35))
- new /obj/item/clothing/suit/space/hardsuit/clown(loc)
- new /mob/living/simple_animal/hostile/clown/fleshclown(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/clown/fleshclown(loc)
- if(prob(25))
- new /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat(loc)
- new /mob/living/simple_animal/hostile/clown/fleshclown(loc)
- if(prob(25))//you lost
- new /obj/item/circlegame(loc)
- new /obj/item/stack/sheet/mineral/bananium(loc)
- new /turf/open/floor/mineral/bananium(loc)
- if(2)//basic demonic incursion
- visible_message("You glimpse an indescribable abyss in the portal. Horrifying monsters appear in a gout of flame.")
- playsound(loc,'sound/hallucinations/wail.ogg', 200, FALSE, 50, TRUE, TRUE)
- if(prob(35))
- new /obj/item/clothing/glasses/godeye(loc)
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- if(prob(45))
- new /obj/item/pickaxe/drill/jackhammer/demonic(loc)
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- if(prob(45))
- new /obj/item/wisp_lantern(loc)
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- new /mob/living/simple_animal/hostile/netherworld(loc)
- if(prob(25))
- new /mob/living/simple_animal/hostile/netherworld(loc)
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- if(prob(5))
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- if(prob(45))
- new /obj/item/nullrod/staff(loc)
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- if(prob(30))
- new /obj/item/clothing/suit/space/hardsuit/quixote/dimensional(loc)
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- else
- new /obj/item/immortality_talisman(loc)
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- if(prob(30))
- new /obj/item/shared_storage/red(loc)
- new /mob/living/simple_animal/hostile/netherworld(loc)
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- if(prob(30))
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- if(prob(30))
- new /obj/item/book/granter/spell/traps(loc)
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- if(prob(30))
- new /mob/living/simple_animal/hostile/netherworld/blankbody(loc)
- new /mob/living/simple_animal/hostile/netherworld(loc)
- new /mob/living/simple_animal/hostile/netherworld/migo(loc)
- new /mob/living/simple_animal/hostile/netherworld(loc)
- new /turf/open/indestructible/necropolis(loc)
- if(3)//skeleton/religion association, now accepting YOUR BONES
- visible_message("Bones rattle and strained voices chant a forgotten god's name.")
- playsound(loc,'sound/ambience/ambiholy.ogg', 100, FALSE, 50, TRUE, TRUE)
- if(prob(30))
- new /obj/item/reagent_containers/glass/bottle/potion/flight(loc)
- new /mob/living/simple_animal/hostile/skeleton/templar(loc)
- else
- new /obj/item/clothing/neck/memento_mori(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- new /mob/living/simple_animal/hostile/skeleton/templar(loc)
- if(prob(35))
- new /obj/item/storage/box/holy_grenades(loc)
- new /mob/living/simple_animal/hostile/skeleton/templar(loc)
- new /mob/living/simple_animal/hostile/skeleton/templar(loc)
- if(prob(40))
- new /obj/item/claymore(loc)
- new /mob/living/simple_animal/hostile/skeleton/templar(loc)
- if(prob(45))
- new /obj/item/gun/ballistic/bow(loc)
- new /obj/item/storage/bag/quiver(loc)
- new /obj/item/ammo_casing/caseless/arrow/bronze(loc)
- new /obj/item/ammo_casing/caseless/arrow/bronze(loc)
- new /obj/item/ammo_casing/caseless/arrow/bronze(loc)
- new /obj/item/ammo_casing/caseless/arrow/bronze(loc)
- new /obj/item/ammo_casing/caseless/arrow/bronze(loc)
- new /mob/living/simple_animal/hostile/skeleton/templar(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- if(prob(30))
- new /obj/item/stack/sheet/mineral/wood/fifty(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- if(prob(35))
- new /obj/item/staff/bostaff(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- if(prob(45))
- new /obj/item/disk/design_disk/adv/cleric_mace(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- if(prob(25))
- new /obj/item/shield/riot/roman(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- if(prob(55))
- new /obj/item/clothing/suit/armor/riot/knight/blue(loc)
- new /obj/item/clothing/head/helmet/knight/blue(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- if(prob(35))
- new /obj/item/disk/design_disk/adv/knight_gear(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- new /mob/living/simple_animal/hostile/skeleton(loc)
- new /obj/item/instrument/trombone(loc)
- new /obj/item/stack/sheet/bone(loc)
- new /obj/item/stack/sheet/bone(loc)
- new /obj/item/stack/sheet/bone(loc)
- new /obj/item/stack/sheet/bone(loc)
- new /mob/living/simple_animal/hostile/skeleton/templar(loc)
- new /turf/open/floor/mineral/silver(loc)
- if(4)//syndicate incursion. Again, high-quality loot at low chances, this time with excessive levels of danger
- visible_message("Radio chatter echoes out from the portal. Red-garbed figures step through, weapons raised.")
- playsound(loc,'sound/effects/radiohiss.ogg', 200, FALSE, 50, TRUE, TRUE)
- playsound(loc,'sound/ambience/antag/tatoralert.ogg', 75, FALSE, 50, TRUE, TRUE)
- if(prob(35))
- if(prob(15))
- new /obj/item/clothing/suit/space/hardsuit/syndi/elite(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- else
- if(prob(50))
- new /obj/item/clothing/suit/space/hardsuit/syndi(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- else
- new /obj/item/clothing/suit/space/hardsuit/syndi(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- if(prob(25))//the real prize
- new /obj/effect/spawner/lootdrop/donkpockets(loc)
- new /obj/effect/spawner/lootdrop/donkpockets(loc)
- new /obj/effect/spawner/lootdrop/donkpockets(loc)
- if(prob(35))
- new /obj/item/clothing/shoes/magboots/syndie(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- if(prob(25))
- new /obj/item/gun/ballistic/automatic/pistol/suppressed(loc)
- new /obj/item/ammo_box/magazine/
- new /mob/living/simple_animal/hostile/syndicate/melee/sword(loc)
- if(prob(25))
- new /obj/item/gun/ballistic/automatic/pistol/tec9(loc)
- new /obj/item/ammo_box/magazine/tec9(loc)
- new /obj/item/ammo_box/magazine/tec9(loc)
- new /mob/living/simple_animal/hostile/syndicate/melee/sword(loc)
- if(prob(35))
- new /obj/item/clothing/gloves/rapid(loc)
- new /mob/living/simple_animal/hostile/syndicate/melee/sword/space(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- if(prob(35))
- new /obj/item/wrench/combat(loc)
- new /obj/item/storage/toolbox/syndicate(loc)
- new /mob/living/simple_animal/hostile/syndicate/melee/sword/space(loc)
- if(prob(35))
- new /obj/item/storage/fancy/cigarettes/cigpack_syndicate(loc)
- if(prob(35))
- new /obj/item/borg/upgrade/transform/assault(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg(loc)
- if(prob(25))
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- if(prob(25))
- new /mob/living/simple_animal/hostile/syndicate/melee/sword/space(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- if(prob(25))
- new /mob/living/simple_animal/hostile/syndicate/melee/sword(loc)
- new /obj/item/storage/backpack/duffelbag/syndie/c4(loc)
- if(prob(35))
- new /obj/item/storage/belt/military(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg(loc)
- if(prob(35))
- new /obj/item/kinetic_crusher/syndie_crusher(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- if(prob(25))
- new /obj/item/card/id/syndicate/anyone(loc)
- if(prob(35))
- new /obj/item/clothing/glasses/thermal/syndi(loc)
- new /mob/living/simple_animal/hostile/syndicate/melee/sword(loc)
- if(prob(35))
- new /obj/item/reagent_containers/hypospray(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/shotgun(loc)
- new /mob/living/simple_animal/hostile/syndicate/melee/sword(loc)
- if(prob(25))
- new /obj/item/card/emag(loc)
- new /mob/living/simple_animal/hostile/syndicate/melee/sword(loc)
- new /mob/living/simple_animal/hostile/syndicate/ranged/smg/space(loc)
- new /mob/living/simple_animal/hostile/syndicate/melee/sword/space(loc)
- new /turf/open/floor/mineral/plastitanium/red(loc)
- if(5)//;HELP BLOB IN MEDICAL
- visible_message("You hear a robotic voice saying something about a \"Delta-level biohazard\".")
- playsound(loc,'sound/ai/outbreak5.ogg', 100, FALSE, 50, TRUE, TRUE)
- playsound(loc,'sound/misc/bloblarm.ogg', 50, FALSE, 50, TRUE, TRUE)
- if(prob(35))
- new /obj/item/circuitboard/machine/chem_dispenser(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(35))
- new /obj/item/storage/box/hypospray/CMO(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(15))
- new /mob/living/simple_animal/hostile/blob/blobbernaut/independent(loc)
- if(prob(45))
- new /obj/item/defibrillator(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(45))
- new /obj/item/circuitboard/machine/stasis(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(45))
- new /obj/item/stack/medical/suture/medicated(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(45))
- new /obj/item/stack/medical/mesh/advanced(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(35))
- new /obj/item/gun/syringe/syndicate(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(25))
- new /obj/item/healthanalyzer/advanced(loc)
- if(prob(35))
- new /obj/item/storage/firstaid/advanced(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(35))
- new /obj/item/storage/firstaid/tactical(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- new /mob/living/simple_animal/hostile/blob/blobbernaut/independent(loc)
- else
- new /obj/item/storage/firstaid/regular(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(prob(35))
- new /obj/effect/mob_spawn/human/corpse/solgov/sonnensoldner(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- else
- new /obj/effect/mob_spawn/human/doctor(loc)
- if(prob(35))
- new /obj/effect/mob_spawn/human/corpse/solgov/sonnensoldner(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- else
- new /obj/effect/mob_spawn/human/doctor(loc)
- if(prob(35))
- new /obj/effect/mob_spawn/human/corpse/solgov/sonnensoldner(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- else
- new /obj/effect/mob_spawn/human/doctor(loc)
- new /obj/item/healthanalyzer(loc)
- new /turf/open/floor/carpet/nanoweave/beige(loc)
- new /mob/living/simple_animal/hostile/blob/blobbernaut/independent(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- new /mob/living/simple_animal/hostile/blob/blobspore/weak(loc)
- if(6)//teleporty ice world. Incomplete.
- visible_message("You glimpse a frozen, empty plane. Something stirs in the fractal abyss.")
- playsound(loc,'sound/ambience/ambisin3.ogg', 150, FALSE, 50, TRUE, TRUE)
- if(prob(45))
- new /obj/item/warp_cube/red(loc)
- new /mob/living/simple_animal/hostile/asteroid/ice_demon(loc)
- if(prob(45))
- new /obj/item/clothing/suit/drfreeze_coat(loc)
- new /obj/item/clothing/under/costume/drfreeze(loc)
- new /mob/living/simple_animal/hostile/asteroid/ice_demon(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/asteroid/ice_demon(loc)
- new /mob/living/simple_animal/hostile/bear/snow(loc)
- if(prob(45))
- new /obj/item/freeze_cube(loc)
- new /mob/living/simple_animal/hostile/asteroid/ice_demon(loc)
- if(prob(55))
- new /obj/item/clothing/shoes/winterboots/ice_boots(loc)
- new /mob/living/simple_animal/hostile/bear/snow(loc)
- new /obj/effect/decal/remains/human(loc)
- new /mob/living/simple_animal/hostile/asteroid/ice_demon(loc)
- new /turf/open/floor/plating/ice/smooth(loc)
- if(7)//FUCK FUCK HELP SWARMERS IN VAULT
- visible_message("Something beeps. Small, glowing forms spill out of the portal en masse!")
- playsound(loc,'sound/ambience/ambitech.ogg', 150, FALSE, 50, TRUE, TRUE)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(45))
- new /obj/item/construction/rcd/loaded(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(35))
- new /obj/item/holosign_creator/atmos(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/vendor(loc)
- new /obj/item/vending_refill/engivend(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(45))
- new /obj/item/tank/jetpack/oxygen(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(25))
- new /obj/item/stack/sheet/metal/fifty(loc)
- new /obj/item/grenade/chem_grenade/smart_metal_foam(loc)
- new /obj/item/grenade/chem_grenade/smart_metal_foam(loc)
- new /obj/item/grenade/chem_grenade/smart_metal_foam(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(35))
- new /obj/item/stack/sheet/metal/fifty(loc)
- new /obj/item/clothing/glasses/meson/engine(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(25))
- new /obj/item/stack/sheet/metal/twenty(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(25))
- new /obj/item/storage/toolbox/infiltrator(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(25))
- new /obj/machinery/portable_atmospherics/canister/oxygen(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- new /obj/item/clothing/gloves/color/latex/engineering(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/swarmer/ai(loc)
- new /obj/item/clothing/gloves/color/latex/engineering(loc)
- new /obj/effect/mob_spawn/human/engineer(loc)
- new /turf/open/floor/circuit/telecomms(loc)
- if(8)//Literally blood-drunk.
- visible_message("Blood sprays from the portal. An ichor-drenched figure steps through!")
- playsound(loc,'sound/magic/enter_blood.ogg', 150, FALSE, 50, TRUE, TRUE)
- new /obj/effect/gibspawner/human(loc)
- new /obj/effect/gibspawner/human(loc)
- new /obj/effect/gibspawner/human(loc)
- new /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/doom(loc)
- if(prob(50))
- new /obj/item/gem/bloodstone(loc)
- if(prob(25))
- new /obj/item/seeds/tomato/blood(loc)
- new /turf/open/floor/plating/asteroid/basalt(loc)
- if(9)//Now's your chance to be a [[BIG SHOT]]
- visible_message("You hear the sound of big money and bigger avarice.")
- playsound(loc,'sound/lavaland/cursed_slot_machine_jackpot.ogg', 150, FALSE, 50, TRUE, TRUE)
- new /obj/structure/cursed_slot_machine(loc)
- if(prob(35))
- new /obj/item/spacecash/bundle/mediumrand(loc)
- new /obj/item/spacecash/bundle/mediumrand(loc)
- new /obj/item/coin/gold(loc)
- new /mob/living/simple_animal/hostile/faithless(loc)
- if(prob(35))
- new /obj/item/clothing/mask/spamton(loc)
- new /mob/living/simple_animal/hostile/faithless(loc)
- if(prob(35))
- new /obj/item/gem/fdiamond(loc)
- new /mob/living/simple_animal/hostile/faithless(loc)
- else
- new /obj/item/gem/rupee(loc)
- if(prob(35))
- new /obj/item/coin/gold(loc)
- new /obj/item/coin/gold(loc)
- new /obj/item/stack/sheet/mineral/gold/twenty(loc)
- new /mob/living/simple_animal/hostile/faithless(loc)
- if(prob(35))
- new /obj/item/storage/fancy/cigarettes/cigpack_robustgold(loc)
- new /mob/living/simple_animal/hostile/faithless(loc)
- if(prob(35))
- new /obj/item/clothing/head/collectable/petehat(loc)
- new /mob/living/simple_animal/hostile/faithless(loc)
- new /mob/living/simple_animal/hostile/faithless(loc)
- new /mob/living/simple_animal/hostile/faithless(loc)
- new /turf/open/floor/mineral/gold(loc)
- if(10)//hivebot factory
- visible_message("You catch a brief glimpse of a vast production complex. One of the assembly lines outputs through the portal!")
- playsound(loc,'sound/ambience/antag/clockcultalr.ogg', 100, FALSE, 50, TRUE, TRUE)
- if(prob(45))
- new /obj/item/stack/sheet/mineral/adamantine/ten(loc)
- new /obj/item/stack/sheet/mineral/runite/ten(loc)
- new /obj/item/stack/sheet/mineral/mythril/ten(loc)
- new /mob/living/simple_animal/hostile/hivebot(loc)
- if(prob(35))
- new /obj/item/stack/sheet/mineral/adamantine/ten(loc)
- new /obj/item/stack/sheet/mineral/runite/ten(loc)
- new /obj/item/stack/sheet/mineral/mythril/ten(loc)
- new /mob/living/simple_animal/hostile/hivebot(loc)
- if(prob(25))
- new /obj/item/stack/sheet/mineral/adamantine/ten(loc)
- new /obj/item/stack/sheet/mineral/runite/ten(loc)
- new /obj/item/stack/sheet/mineral/mythril/ten(loc)
- new /mob/living/simple_animal/hostile/hivebot/strong(loc)
- if(prob(35))
- new /obj/item/stack/sheet/mineral/silver/twenty(loc)
- new /obj/item/stack/sheet/mineral/titanium/twenty(loc)
- new /obj/item/stack/sheet/mineral/gold/twenty(loc)
- new /mob/living/simple_animal/hostile/hivebot/strong(loc)
- if(prob(35))
- new /obj/item/circuitboard/computer/solar_control(loc)
- new /obj/item/electronics/tracker(loc)
- new /obj/item/solar_assembly(loc)
- new /obj/item/solar_assembly(loc)
- new /obj/item/solar_assembly(loc)
- new /obj/item/solar_assembly(loc)
- if(prob(45))
- new /obj/item/stack/circuit_stack(loc)
- new /mob/living/simple_animal/hostile/hivebot/mechanic(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/hivebot/range(loc)
- if(prob(45))
- new /obj/item/circuitboard/machine/dna_vault(loc)
- new /mob/living/simple_animal/hostile/hivebot/mechanic(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/recycler(loc)
- new /mob/living/simple_animal/hostile/hivebot/mechanic(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/recharger(loc)
- new /mob/living/simple_animal/hostile/hivebot/mechanic(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/smoke_machine(loc)
- new /mob/living/simple_animal/hostile/hivebot/mechanic(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/ore_silo(loc)
- new /mob/living/simple_animal/hostile/hivebot/mechanic(loc)
- if(prob(35))
- new /obj/item/stack/sheet/mineral/adamantine/ten(loc)
- new /obj/item/stack/sheet/mineral/runite/ten(loc)
- new /obj/item/stack/sheet/mineral/mythril/ten(loc)
- new /mob/living/simple_animal/hostile/hivebot/strong(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/medipen_refiller(loc)
- new /mob/living/simple_animal/hostile/hivebot(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/stasis(loc)
- new /mob/living/simple_animal/hostile/hivebot(loc)
- if(prob(50))
- new /obj/item/stack/sheet/metal/fifty(loc)
- new /obj/item/stack/sheet/glass/fifty(loc)
- new /obj/item/stack/cable_coil/yellow(loc)
- new /obj/item/storage/box/lights/bulbs(loc)
- new /mob/living/simple_animal/hostile/hivebot(loc)
- new /mob/living/simple_animal/hostile/hivebot(loc)
- new /mob/living/simple_animal/hostile/hivebot/strong(loc)
- new /obj/machinery/conveyor(loc)
- new /turf/open/floor/circuit/red(loc)
- if(11)//miner's last moments
- visible_message("The familiar sound of an ash storm greets you. A miner steps through the portal, stumbles, and collapses.")
- playsound(loc,'sound/weather/ashstorm/outside/weak_end.ogg', 150, FALSE, 50, TRUE, TRUE)
- if(prob(35))
- new /obj/item/disk/design_disk/modkit_disc/resonator_blast(loc)
- if(prob(25))
- new /obj/item/disk/design_disk/modkit_disc/rapid_repeater(loc)
- if(prob(25))
- new /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe(loc)
- if(prob(25))
- new /obj/item/disk/design_disk/modkit_disc/bounty(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/vending/mining_equipment(loc)
- if(prob(45))
- new /obj/item/vending_refill/mining_equipment(loc)
- new /mob/living/simple_animal/hostile/asteroid/goliath/beast(loc)
- if(prob(35))
- new /obj/item/reagent_containers/hypospray/medipen/survival(loc)
- if(prob(35))
- new /obj/item/fulton_core(loc)
- new /obj/item/extraction_pack(loc)
- new /mob/living/simple_animal/hostile/asteroid/goliath/beast(loc)
- if(prob(45))
- new /obj/item/t_scanner/adv_mining_scanner/lesser(loc)
- new /mob/living/simple_animal/hostile/asteroid/goliath/beast(loc)
- if(prob(45))
- new /obj/item/gibtonite(loc)
- new /mob/living/simple_animal/hostile/asteroid/goliath/beast(loc)
- if(prob(45))
- new /obj/item/clothing/glasses/meson/night(loc)
- new /mob/living/simple_animal/hostile/asteroid/goliath/beast(loc)
- if(prob(50))
- new /obj/item/kinetic_crusher(loc)
- else
- new /obj/item/gun/energy/kinetic_accelerator(loc)
- new /mob/living/simple_animal/hostile/asteroid/goliath/beast(loc)
- new /mob/living/simple_animal/hostile/asteroid/goliath/beast(loc)
- new /mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient(loc)
- new /obj/effect/mob_spawn/human/miner(loc)
- new /turf/open/floor/plating/asteroid/basalt(loc)
- if(12)//sailing the ocean blue
- visible_message("Water pours out of the portal, followed by a strange vessel. It's occupied.")
- playsound(loc,'sound/ambience/shore.ogg', 150, FALSE, 50, TRUE, TRUE)
- new /obj/vehicle/ridden/lavaboat/dragon(loc)
- new /obj/item/oar(loc)
- if(prob(50))
- new /obj/item/clothing/under/costume/sailor(loc)
- if(prob(50))
- new /obj/item/pneumatic_cannon/speargun(loc)
- new /obj/item/storage/backpack/magspear_quiver(loc)
- new /obj/item/throwing_star/magspear(loc)
- new /obj/item/throwing_star/magspear(loc)
- new /obj/item/throwing_star/magspear(loc)
- new /obj/item/throwing_star/magspear(loc)
- new /obj/item/throwing_star/magspear(loc)
- new /mob/living/simple_animal/hostile/carp(loc)
- if(prob(45))
- new /obj/item/clothing/suit/space/hardsuit/carp(loc)
- new /mob/living/simple_animal/hostile/carp(loc)
- if(prob(45))
- new /obj/item/gun/magic/hook(loc)
- new /mob/living/simple_animal/hostile/carp(loc)
- if(prob(45))
- new /obj/item/reagent_containers/food/snacks/fishmeat/carp(loc)
- new /obj/item/reagent_containers/food/snacks/fishmeat/carp(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/carp/megacarp(loc)
- if(prob(25))
- new /obj/item/book/granter/martial/carp(loc)
- new /mob/living/simple_animal/hostile/carp/megacarp(loc)
- if(prob(35))
- new /obj/item/grenade/spawnergrenade/spesscarp(loc)
- new /mob/living/simple_animal/hostile/carp/megacarp(loc)
- new /mob/living/simple_animal/hostile/carp/megacarp(loc)
- new /mob/living/simple_animal/hostile/carp(loc)
- new /turf/open/water(loc)
- if(13)//hydroponics forest
- visible_message("You catch a glimpse of a strange forest. Smells like weed and bad choices.")
- playsound(loc,'sound/ambience/shore.ogg', 150, FALSE, 50, TRUE, TRUE)
- if(prob(45))
- new /obj/item/circuitboard/machine/biogenerator(loc)
- new /mob/living/simple_animal/hostile/venus_human_trap(loc)
- if(prob(35))
- new /obj/item/gun/energy/floragun(loc)
- new /mob/living/simple_animal/hostile/venus_human_trap(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/seed_extractor(loc)
- new /mob/living/simple_animal/hostile/venus_human_trap(loc)
- if(prob(45))
- new /obj/item/circuitboard/machine/plantgenes(loc)
- else
- new /obj/item/circuitboard/machine/hydroponics(loc)
- if(prob(15))
- new /obj/item/circuitboard/machine/hydroponics(loc)
- new /mob/living/simple_animal/hostile/venus_human_trap(loc)
- if(prob(15))
- new /obj/item/circuitboard/machine/hydroponics(loc)
- if(prob(5))
- new /obj/item/seeds/gatfruit(loc)
- new /mob/living/simple_animal/hostile/venus_human_trap(loc)
- if(prob(45))
- new /obj/item/seeds/random(loc)
- if(prob(45))
- new /obj/item/seeds/random(loc)
- new /mob/living/simple_animal/hostile/venus_human_trap(loc)
- if(prob(45))
- new /obj/item/seeds/random(loc)
- if(prob(45))
- new /obj/item/seeds/random(loc)
- new /mob/living/simple_animal/hostile/venus_human_trap(loc)
- if(prob(50))
- new /obj/item/seeds/random(loc)
- if(prob(45))
- new /obj/item/seeds/cannabis(loc)
- new /obj/item/clothing/gloves/botanic_leather(loc)
- new /obj/item/cultivator/rake(loc)
- new /obj/structure/spacevine(loc)
- new /mob/living/simple_animal/hostile/venus_human_trap(loc)
- new /turf/open/floor/plating/grass(loc)
- if(14)//fallout ss13
- visible_message("You hear a geiger counter click and smell ash.")
- playsound(loc,'sound/items/radiostatic.ogg', 100, FALSE, 50, TRUE, TRUE)
- if(prob(50))
- new /obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola(loc)
- new /obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola(loc)
- new /obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola(loc)
- new /mob/living/simple_animal/hostile/cockroach/glockroach(loc)
- if(prob(50))
- new /obj/structure/radioactive/stack(loc)
- new /mob/living/simple_animal/hostile/cockroach/glockroach(loc)
- if(prob(45))
- new /obj/item/stack/sheet/mineral/uranium/twenty(loc)
- new /mob/living/simple_animal/hostile/cockroach/glockroach(loc)
- if(prob(35))
- new /obj/item/clothing/head/radiation(loc)
- new /obj/item/clothing/suit/radiation(loc)
- if(prob(45))
- new /obj/item/gun/energy/decloner(loc)
- new /mob/living/simple_animal/hostile/cockroach/glockroach(loc)
- new /obj/item/geiger_counter(loc)
- new /mob/living/simple_animal/hostile/cockroach/glockroach(loc)
- new /turf/open/floor/plating/dirt(loc)
-
- if(15)//the cultists amoung us
- visible_message("Chanting and a hateful red glow spill through the portal.")
- playsound(loc,'sound/spookoween/ghost_whisper.ogg', 100, FALSE, 50, TRUE, TRUE)
- if(prob(50))
- new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
- if(prob(45))
- new /obj/item/borg/upgrade/modkit/lifesteal(loc)
- new /obj/item/bedsheet/cult(loc)
- new /mob/living/simple_animal/hostile/construct/wraith/hostile(loc)
- if(prob(50))
- new /obj/item/stack/sheet/runed_metal/ten(loc)
- if(prob(35))
- new /obj/item/sharpener/cult(loc)
- new /mob/living/simple_animal/hostile/construct/artificer/hostile(loc)
- if(prob(15))
- new /obj/item/cult_bastard(loc)
- new /mob/living/simple_animal/hostile/construct/juggernaut/hostile(loc)
- if(prob(35))
- new /obj/item/cult_shift(loc)
- new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
- if(prob(45))
- new /obj/item/gem/bloodstone(loc)
- new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
- if(prob(35))
- new /obj/item/nullrod/scythe/talking/necro(loc)
- new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
- if(prob(35))
- new /obj/item/clothing/suit/space/hardsuit/cult/(loc)
- new /mob/living/simple_animal/hostile/construct/artificer/hostile(loc)
- new /mob/living/simple_animal/hostile/construct/juggernaut/hostile(loc)
- new /mob/living/simple_animal/hostile/construct/wraith/hostile(loc)
- new /obj/structure/destructible/cult/pylon(loc)
- new /turf/open/floor/plasteel/cult(loc)
- if(16)//the backroom freezer
- visible_message("The faint hallogen glow of a faraway kitchen greets you.")
- if(prob(45))
- new /obj/item/kitchen/knife/bloodletter(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(55))
- new /obj/item/clothing/gloves/butchering(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(45))
- new /obj/item/reagent_containers/food/snacks/store/bread/meat(loc)
- new /obj/item/reagent_containers/food/snacks/store/bread/meat(loc)
- new /obj/item/reagent_containers/food/snacks/store/bread/meat(loc)
- if(prob(55))
- new /obj/item/reagent_containers/food/snacks/store/cake/trumpet(loc)
- if(prob(35))
- new /obj/item/reagent_containers/food/snacks/pizza/dank(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(25))
- new /obj/item/reagent_containers/food/snacks/meat/steak/gondola(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(35))
- new /obj/item/reagent_containers/food/snacks/burger/roburgerbig(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(35))
- new /obj/item/kitchen/knife/butcher(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(35))
- new /obj/item/flamethrower/full(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(45))
- new /obj/item/sharpener(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(25))
- new /obj/item/sharpener/super(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/gibber(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/chem_master/condi(loc)
- new /mob/living/simple_animal/hostile/killertomato(loc)
- new /mob/living/simple_animal/hostile/alien/maid(loc)
- new /turf/open/floor/plasteel/kitchen_coldroom/freezerfloor(loc)
- if(17)//legion miniboss
- visible_message("The ground quakes. An immense figure reaches through the portal, crouching to squeeze through.")
- playsound(loc,'sound/magic/knock.ogg', 100, FALSE, 50, TRUE, TRUE)
- new /mob/living/simple_animal/hostile/big_legion(loc)
- if(prob(75))
- new /obj/structure/closet/crate/necropolis/tendril/greater(loc)
- new /turf/open/indestructible/necropolis(loc)
- if(18)//xenobiologist's hubris
- visible_message("You catch a glimpse of a wobbling sea of slimy friends. An abused-looking keeper slips through the portal.")
- playsound(loc,'sound/effects/footstep/slime1.ogg', 100, FALSE, 50, TRUE, TRUE)
- if(prob(25))
- new /obj/item/slime_extract/adamantine(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(35))
- new /obj/item/slime_extract/gold(loc)
- if(prob(25))
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(45))
- new /obj/item/extinguisher/advanced(loc)
- if(prob(25))
- new /obj/item/slimepotion/slime/renaming(loc)
- new /mob/living/simple_animal/slime/random(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(25))
- new /obj/item/slimepotion/slime/sentience(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(25))
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(45))
- new /obj/item/circuitboard/computer/xenobiology(loc)
- new /obj/item/slime_extract/grey(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(45))
- new /obj/item/circuitboard/machine/processor/slime(loc)
- new /mob/living/simple_animal/slime/random(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(25))
- new /obj/item/shield/adamantineshield(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(45))
- new /obj/item/slime_cookie/purple(loc)
- new /obj/item/slime_cookie/purple(loc)
- new /obj/item/slime_cookie/purple(loc)
- if(prob(45))
- new /obj/item/storage/box/monkeycubes(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(35))
- new /obj/item/slimepotion/speed(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(45))
- new /obj/item/slimepotion/slime/slimeradio(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(prob(35))
- new /mob/living/simple_animal/pet/dog/corgi/puppy/slime(loc)
- new /obj/effect/mob_spawn/human/scientist(loc)
- new /turf/open/floor/mineral/titanium/purple(loc)
- new /mob/living/simple_animal/slime/random(loc)
- if(19)//hey, free elite tumor!
- visible_message("A large, pulsating structure falls through the portal and crashes to the floor.")
- playsound(loc,'sound/effects/break_stone.ogg', 100, FALSE, 50, TRUE, TRUE)
- new /obj/structure/elite_tumor(loc)
- new /turf/open/floor/plating/asteroid/basalt(loc)
- if(20)//*you flush the toilet.*
- visible_message("You hear the faint noise of a long flush.")
- new /obj/structure/toilet(loc)
- new /obj/effect/decal/remains(loc)
- new /obj/item/newspaper(loc)
- new /turf/open/floor/plastic(loc)
- new /obj/item/clothing/head/papersack/smiley(loc) //welcome to the bathroom
- if(21)//Research & Zombies
- visible_message("Flashing lights and quarantine alarms echo through the portal. You smell rotting flesh and plasma.")
- playsound(loc,'sound/misc/bloblarm.ogg', 120, FALSE, 50, TRUE, TRUE)
- if(prob(35))
- new /obj/item/storage/box/rndboards(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(prob(35))
- new /obj/item/storage/box/stockparts/deluxe(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(prob(15))
- new /obj/effect/spawner/lootdrop/stockparts(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(prob(15))
- new /obj/effect/spawner/lootdrop/stockparts(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(prob(15))
- new /obj/effect/spawner/lootdrop/stockparts(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(prob(15))
- new /obj/effect/spawner/lootdrop/stockparts(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(prob(30))
- new /obj/item/circuitboard/machine/rdserver(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(prob(35))
- new /obj/item/research_notes/loot/big(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- else
- new /obj/item/research_notes/loot/medium(loc)
- if(prob(35))
- new /obj/item/research_notes/loot/medium(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- else
- new /obj/item/research_notes/loot/small(loc)
- if(prob(35))
- new /obj/item/pneumatic_cannon(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(prob(45))
- new /obj/item/research_notes/loot/medium(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- else
- new /obj/item/research_notes/loot/small(loc)
- new/turf/open/floor/mineral/titanium/purple(loc)
- new /mob/living/simple_animal/hostile/zombie(loc)
- if(22)//Silverback's locker room
- visible_message("You catch a glimpse of verdant green. Smells like a locker room.")
- playsound(loc,'sound/creatures/gorilla.ogg', 75, FALSE, 50, TRUE, TRUE)
- new /mob/living/simple_animal/hostile/gorilla(loc)
- new /mob/living/simple_animal/hostile/gorilla(loc)
- if(prob(35))
- new /obj/item/circuitboard/machine/dnascanner(loc)
- if(prob(35))
- new /obj/item/circuitboard/computer/scan_consolenew(loc)
- if(prob(25))
- new /obj/item/reagent_containers/hypospray/medipen/magillitis(loc)
- new /mob/living/simple_animal/hostile/gorilla(loc)
- if(prob(35))
- new /obj/item/dnainjector/thermal(loc)
- new /mob/living/simple_animal/hostile/gorilla(loc)
- if(prob(35))
- new /obj/item/storage/box/gorillacubes(loc)
- new /mob/living/simple_animal/hostile/gorilla(loc)
- if(prob(35))
- new /obj/item/dnainjector/hulkmut(loc)
- new /mob/living/simple_animal/hostile/gorilla(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/gorilla(loc)
- if(prob(35))
- new /obj/item/dnainjector/gigantism(loc)
- if(prob(45))
- new /obj/item/dnainjector/dwarf(loc)
- if(prob(35))
- new /obj/item/dnainjector/firebreath(loc)
- new /mob/living/simple_animal/hostile/gorilla(loc)
- if(prob(35))
- new /mob/living/simple_animal/hostile/gorilla(loc)
- new /obj/item/dnainjector/telemut/darkbundle(loc)
- if(prob(35))
- new /obj/item/dnainjector/insulated(loc)
- new /mob/living/simple_animal/hostile/gorilla(loc)
- new /obj/item/sequence_scanner(loc)
- new /obj/structure/flora/grass/jungle(loc)
- new /turf/open/floor/plating/grass/jungle(loc)
diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm
index 65479f171334..6512a0683947 100644
--- a/code/game/objects/structures/kitchen_spike.dm
+++ b/code/game/objects/structures/kitchen_spike.dm
@@ -64,7 +64,7 @@
/obj/structure/kitchenspike/attack_hand(mob/user)
if(VIABLE_MOB_CHECK(user.pulling) && user.a_intent == INTENT_GRAB && !has_buckled_mobs())
var/mob/living/L = user.pulling
- if(do_mob(user, src, 120))
+ if(do_after(user, 12 SECONDS, src))
if(has_buckled_mobs()) //to prevent spam/queing up attacks
return
if(L.buckled)
@@ -112,7 +112,7 @@
"You struggle to break free from [src], exacerbating your wounds! (Stay still for two minutes.)",\
"You hear a wet squishing noise..")
M.adjustBruteLoss(30)
- if(!do_after(M, 1200, target = src))
+ if(!do_after(M, 1200, target = src, hidden = TRUE))
if(M && M.buckled)
to_chat(M, "You fail to free yourself!")
return
diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm
deleted file mode 100644
index b3c9a8cbf230..000000000000
--- a/code/game/objects/structures/lavaland/necropolis_tendril.dm
+++ /dev/null
@@ -1,187 +0,0 @@
-//Necropolis Tendrils, which spawn lavaland monsters and break into a chasm when killed
-/obj/structure/spawner/lavaland
- name = "necropolis tendril"
- desc = "A vile tendril of corruption, originating deep underground. Terrible monsters are pouring out of it."
-
- icon_state = "tendril"
-
- faction = list("mining")
- max_mobs = 5
- max_integrity = 450
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril)
-
- move_resist = INFINITY // just killing it tears a massive hole in the ground, let's not move it
- anchored = TRUE
- resistance_flags = FIRE_PROOF | LAVA_PROOF
-
- hitsound_type = PROJECTILE_HITSOUND_FLESH
-
- var/gps = null
- var/obj/effect/light_emitter/tendril/emitted_light
-
-GLOBAL_LIST_INIT(tendrils, list())
-/obj/structure/spawner/lavaland/Initialize()
- . = ..()
- emitted_light = new(loc)
- for(var/F in RANGE_TURFS(1, src))
- if(ismineralturf(F))
- var/turf/closed/mineral/M = F
- M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
- GLOB.tendrils += src
-
-/obj/structure/spawner/lavaland/deconstruct(disassembled)
- new /obj/effect/collapse(loc)
- new /obj/structure/closet/crate/necropolis/tendril(loc)
- return ..()
-
-
-/obj/structure/spawner/lavaland/Destroy()
- var/last_tendril = TRUE
- if(GLOB.tendrils.len>1)
- last_tendril = FALSE
-
- if(last_tendril && !(flags_1 & ADMIN_SPAWNED_1))
- if(SSachievements.achievements_enabled)
- for(var/mob/living/L in view(7,src))
- if(L.stat || !L.client)
- continue
- L.client.give_award(/datum/award/achievement/boss/tendril_exterminator, L)
- L.client.give_award(/datum/award/score/tendril_score, L) //Progresses score by one
- GLOB.tendrils -= src
- QDEL_NULL(emitted_light)
- return ..()
-
-/obj/effect/light_emitter/tendril
- set_luminosity = 4
- set_cap = 2.5
- light_color = LIGHT_COLOR_LAVA
-
-/obj/effect/collapse
- name = "collapsing necropolis tendril"
- desc = "Get clear!"
- layer = TABLE_LAYER
- icon = 'icons/mob/nest.dmi'
- icon_state = "tendril"
- anchored = TRUE
- density = TRUE
- var/obj/effect/light_emitter/tendril/emitted_light
-
-/obj/effect/collapse/Initialize()
- . = ..()
- emitted_light = new(loc)
- visible_message("The tendril writhes in fury as the earth around it begins to crack and break apart! Get back!")
- visible_message("Something falls free of the tendril!")
- playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, FALSE, 50, TRUE, TRUE)
- addtimer(CALLBACK(src, PROC_REF(collapse)), 50)
-
-/obj/effect/collapse/Destroy()
- QDEL_NULL(emitted_light)
- return ..()
-
-/obj/effect/collapse/proc/collapse()
- for(var/mob/M in range(7,src))
- shake_camera(M, 15, 1)
- playsound(get_turf(src),'sound/effects/explosionfar.ogg', 200, TRUE)
- visible_message("The tendril falls inward, the ground around it erupting into bubbling lava!") //WS edit.
- for(var/turf/T in range(2,src))
- if(!T.density)
- T.TerraformTurf(/turf/open/lava/smooth/lava_land_surface, /turf/open/lava/smooth/lava_land_surface, flags = CHANGETURF_INHERIT_AIR) //WS edit, instead of chasms this produces lava instead.
- qdel(src)
-
- //these are good for mappers and already see use in some maps.
-
-/obj/structure/spawner/lavaland/goliath
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril)
-
-/obj/structure/spawner/lavaland/legion
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
-
-/obj/structure/spawner/lavaland/icewatcher
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing)
-
-/obj/structure/spawner/lavaland/whitesandsbasilisk
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/whitesands)
-
- //these are ones that we want to see spawning on worlds.
-
-/obj/structure/spawner/lavaland/low_threat //this is the most common one, it shouldn't be a huge issue for most players.
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 27,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 26,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril = 26,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing = 1,
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 20
- )
- max_mobs = 4
- spawn_time = 300
-
-/obj/structure/spawner/lavaland/medium_threat //this is less common. It starts getting dangerous here.
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 27,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 26,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril = 26,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing = 1,
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 20
- )
- max_mobs = 6
- spawn_time = 200 //they spawn a little faster
-
-/obj/structure/spawner/lavaland/high_threat //this should be rare. People will have trouble with this.
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 27,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 26,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril = 26,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing = 1,
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 20
- )
- max_mobs = 9
- spawn_time = 200
-
-/obj/structure/spawner/lavaland/extreme_threat //extremely rare
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 27,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 26,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril = 26,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing = 1,
- /mob/living/simple_animal/hostile/asteroid/brimdemon = 20
- )
- max_mobs = 12
- spawn_time = 150 //bring a friend and some automatic weapons
-
-//and sand world ones. More legions, no brimdemons, no icewings.
-
-/obj/structure/spawner/lavaland/sand_world/low_threat
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 20,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 40,
- /mob/living/simple_animal/hostile/asteroid/basilisk/whitesands = 40
- )
- max_mobs = 5
- spawn_time = 300
-
-/obj/structure/spawner/lavaland/sand_world/medium_threat
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 20,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 40,
- /mob/living/simple_animal/hostile/asteroid/basilisk/whitesands = 40
- )
- max_mobs = 7
- spawn_time = 200
-
-/obj/structure/spawner/lavaland/sand_world/high_threat
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 20,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 40,
- /mob/living/simple_animal/hostile/asteroid/basilisk/whitesands = 40
- )
- max_mobs = 10
- spawn_time = 200
-
-/obj/structure/spawner/lavaland/sand_world/extreme_threat
- mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 20,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 40,
- /mob/living/simple_animal/hostile/asteroid/basilisk/whitesands = 40
- )
- max_mobs = 12
- spawn_time = 150
diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm
index 28ff5a8de732..e2c3b8909913 100644
--- a/code/game/objects/structures/loom.dm
+++ b/code/game/objects/structures/loom.dm
@@ -31,11 +31,9 @@
user.show_message("You need at least [FABRIC_PER_SHEET] units of fabric before using this.", MSG_VISUAL)
return FALSE
user.show_message("You start weaving \the [W.name] through the loom..", MSG_VISUAL)
- if(W.use_tool(src, user, W.pull_effort))
- if(W.amount >= FABRIC_PER_SHEET)
- new W.loom_result(drop_location())
- W.use(FABRIC_PER_SHEET)
- user.show_message("You weave \the [W.name] into a workable fabric.", MSG_VISUAL)
+ while(W.use_tool(src, user, W.pull_effort) && W.use(FABRIC_PER_SHEET))
+ new W.loom_result(drop_location())
+ user.show_message("You weave \the [W.name] into a workable fabric.", MSG_VISUAL)
return TRUE
#undef FABRIC_PER_SHEET
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index fa964a55619b..ffd4e021086a 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -336,7 +336,7 @@
if((user.a_intent != INTENT_HARM) && istype(I, /obj/item/paper) && (obj_integrity < max_integrity))
user.visible_message("[user] starts to patch the holes in [src].", "You start patching some of the holes in [src]!")
- if(do_after(user, 20, TRUE, src))
+ if(do_after(user, 20, src))
obj_integrity = min(obj_integrity+4,max_integrity)
qdel(I)
user.visible_message("[user] patches some of the holes in [src].", "You patch some of the holes in [src]!")
diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm
index c8b804469255..1be0a2517bd6 100644
--- a/code/game/objects/structures/petrified_statue.dm
+++ b/code/game/objects/structures/petrified_statue.dm
@@ -58,6 +58,9 @@
if(petrified_mob)
petrified_mob.status_flags &= ~GODMODE
+ if(ishuman(petrified_mob))
+ var/mob/living/carbon/human/H = petrified_mob
+ H.bleedsuppress = FALSE
petrified_mob.forceMove(loc)
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE)
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
@@ -80,7 +83,7 @@
return 0
var/obj/structure/statue/petrified/S = new(loc, src, statue_timer)
S.name = "statue of [name]"
- bleedsuppress = 1
+ bleedsuppress = TRUE
S.copy_overlays(src)
var/newcolor = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
S.add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index 89ec5a384320..4efc9f895ab0 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -1,13 +1,12 @@
/obj/structure/plasticflaps
- name = "airtight plastic flaps"
- desc = "Heavy duty, airtight, plastic flaps. Definitely can't get past those. No way."
+ name = "plastic flaps"
+ desc = "Heavy duty plastic flaps. Definitely can't get past those. No way."
gender = PLURAL
icon = 'icons/obj/stationobjs.dmi'
icon_state = "plasticflaps"
armor = list("melee" = 100, "bullet" = 80, "laser" = 80, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 50, "acid" = 50)
density = FALSE
anchored = TRUE
- CanAtmosPass = ATMOS_PASS_NO
/obj/structure/plasticflaps/opaque
opacity = TRUE
diff --git a/code/game/objects/structures/salvaging.dm b/code/game/objects/structures/salvaging.dm
index fa5c49260738..d373f8eb94a9 100644
--- a/code/game/objects/structures/salvaging.dm
+++ b/code/game/objects/structures/salvaging.dm
@@ -577,8 +577,8 @@
)
/obj/effect/spawner/lootdrop/random_gun_protolathe_lootdrop
loot = list(
- /obj/item/gun/energy/lasercannon/unrestricted = 1,
- /obj/item/gun/ballistic/automatic/smg/proto/unrestricted = 1,
+ /obj/item/gun/energy/lasercannon = 1,
+ /obj/item/gun/ballistic/automatic/smg/skm_carbine/inteq/proto = 1,
/obj/item/gun/energy/temperature/security = 1,
)
/obj/effect/spawner/lootdrop/random_ammo_protolathe_lootdrop
@@ -673,7 +673,7 @@
/obj/effect/spawner/lootdrop/random_computer_circuit_rare
loot = list(
- /obj/item/circuitboard/computer/cargo/express = 5,
+ /obj/item/circuitboard/computer/cargo = 5,
/obj/item/circuitboard/computer/communications = 5,
/obj/item/circuitboard/computer/shuttle/helm = 5,
/obj/item/circuitboard/computer/med_data = 5,
@@ -683,7 +683,7 @@
/obj/effect/spawner/lootdrop/destructive_anal_loot //what do people usually put in these things anayways
loot = list(
/obj/item/storage/toolbox/syndicate/empty = 650,
- /obj/item/gun/ballistic/automatic/pistol = 500,
+ /obj/item/gun/ballistic/automatic/pistol/syndicate = 500,
/obj/item/camera_bug = 500,
/obj/item/clothing/gloves/combat = 200,
/obj/item/clothing/head/chameleon = 200,
diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm
index 48a26493ae29..f96d11703943 100644
--- a/code/game/objects/structures/signs/_signs.dm
+++ b/code/game/objects/structures/signs/_signs.dm
@@ -212,9 +212,24 @@
name = "\improper Nanotrasen logo sign"
sign_change_name = "Corporate Logo - Nanotrasen"
desc = "A sign with the Nanotrasen logo on it. Glory to Nanotrasen!"
+ icon = 'icons/obj/nanotrasen_logos.dmi'
icon_state = "nanotrasen"
is_editable = TRUE
+/obj/structure/sign/nanotrasen/ns
+ name = "\improper N+S Logistics logo sign"
+ sign_change_name = "Corporate Logo - N+S Logistics"
+ desc = "A sign with the N+S Logistics compass rose on it."
+ icon_state = "ns"
+ is_editable = TRUE
+
+/obj/structure/sign/nanotrasen/vigilitas
+ name = "\improper Vigilitas Interstellar logo sign"
+ sign_change_name = "Corporate Logo - Vigilitas Interstellar"
+ desc = "A sign with Vigilitas Interstellar's VI logo on it."
+ icon_state = "vigilitas"
+ is_editable = TRUE
+
/obj/structure/sign/logo
name = "\improper Nanotrasen logo sign"
desc = "The Nanotrasen corporate logo."
@@ -237,18 +252,24 @@
// some solgov stuff
/obj/structure/sign/solgov_seal
- name = "Seal of the solarian government"
- desc = "A seal emblazened with a gold trim depicting the star, sol."
+ name = "seal of the solarian government"
+ desc = "A seal emblazened with a gold trim depicting Sol."
icon = 'icons/obj/solgov_logos.dmi'
icon_state = "solgovseal"
pixel_y = 27
/obj/structure/sign/solgov_flag
name = "solgov banner"
- desc = "A large flag displaying the logo of solgov, the local government of the sol system."
+ desc = "A large flag displaying the logo of solgov, the government of the Sol system."
icon = 'icons/obj/solgov_logos.dmi'
icon_state = "solgovflag-left"
+// suns seal
+/obj/structure/sign/suns
+ name = "emblem of the Student-Union Association of Naturalistic Sciences"
+ desc = "A large emblem showcasing the icon of SUNS."
+ icon_state = "suns"
+
// clip seal
/obj/structure/sign/clip
name = "Banner of the Confederated League of Independent Planets"
@@ -260,7 +281,7 @@
/obj/structure/sign/number
name = "zero"
desc = "A numeral sign."
- icon = 'icons/turf/decals.dmi'
+ icon = 'icons/turf/decals/decals.dmi'
icon_state = "0"
/obj/structure/sign/number/one
diff --git a/code/game/objects/structures/signs/signs_flags.dm b/code/game/objects/structures/signs/signs_flags.dm
index a8652f130806..415bce3bf6f5 100644
--- a/code/game/objects/structures/signs/signs_flags.dm
+++ b/code/game/objects/structures/signs/signs_flags.dm
@@ -37,6 +37,12 @@
icon_state = "flag_gezena"
item_flag = /obj/item/sign/flag/gezena
+/obj/structure/sign/flag/suns
+ name = "\improper SUNS flag"
+ desc = "A flag featuring the iconography of the Student-Union Association of Naturalistic Sciences. Something about the flag reminds you of books."
+ icon_state = "flag_suns"
+ item_flag = /obj/item/sign/flag/suns
+
// ITEM FLAGS - THE THINGS YOU HOLD AND PLACE
/obj/item/sign/flag
@@ -51,3 +57,9 @@
desc = "A folded up Gezenan Flag. Something about this flag makes you think of plants."
icon_state = "folded_gezena"
sign_path = /obj/structure/sign/flag/gezena
+
+/obj/item/sign/flag/suns
+ name = "folded SUNS flag"
+ desc = "A folded up purple Flag. Something about this flag makes you think of chemistry."
+ icon_state = "folded_suns"
+ sign_path = /obj/structure/sign/flag/suns
diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm
deleted file mode 100644
index 9773221f0c22..000000000000
--- a/code/game/objects/structures/spawner.dm
+++ /dev/null
@@ -1,153 +0,0 @@
-GLOBAL_LIST_INIT(astroloot, list(
- /obj/item/stack/ore/uranium = 50,
- /obj/item/stack/ore/iron = 50,
- /obj/item/stack/ore/plasma = 75,
- /obj/item/stack/ore/silver = 50,
- /obj/item/stack/ore/gold = 50,
- /obj/item/stack/ore/diamond = 25,
- /obj/item/stack/ore/bananium = 5,
- /obj/item/stack/ore/titanium = 75,
- /obj/item/pickaxe/diamond = 15,
- /obj/item/borg/upgrade/modkit/cooldown = 5,
- /obj/item/borg/upgrade/modkit/damage = 5,
- /obj/item/borg/upgrade/modkit/range = 5,
- /obj/item/t_scanner/adv_mining_scanner/lesser = 15,
- /obj/item/kinetic_crusher = 15,
- /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25,
- /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25,
- /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25,
- /obj/item/tank/jetpack/suit = 10,
- /obj/item/survivalcapsule = 15,
- /obj/item/reagent_containers/hypospray/medipen/survival = 15,
- /obj/item/gps/mining = 10,
- /obj/item/extraction_pack = 10,
- /obj/item/reagent_containers/food/drinks/beer = 15,
- ))
-
-/obj/structure/spawner
- name = "monster nest"
- icon = 'icons/mob/nest.dmi'
- icon_state = "hole"
- max_integrity = 100
-
- move_resist = MOVE_FORCE_EXTREMELY_STRONG
- anchored = TRUE
- density = TRUE
-
- var/max_mobs = 5
- var/spawn_time = 300 //30 seconds default
- var/mob_types = list(/mob/living/simple_animal/hostile/carp)
- var/spawn_text = "emerges from"
- var/faction = list("hostile")
- var/spawn_sound = list('sound/effects/break_stone.ogg')
- var/spawner_type = /datum/component/spawner
- var/spawn_distance_min = 1
- var/spawn_distance_max = 1
-
-/obj/structure/spawner/Initialize()
- . = ..()
- AddComponent(spawner_type, mob_types, spawn_time, faction, spawn_text, max_mobs, spawn_sound, spawn_distance_min, spawn_distance_max)
-
-/obj/structure/spawner/attack_animal(mob/living/simple_animal/M)
- if(faction_check(faction, M.faction, FALSE)&&!M.client)
- return
- ..()
-
-
-/obj/structure/spawner/syndicate
- name = "warp beacon"
- icon = 'icons/obj/device.dmi'
- icon_state = "syndbeacon"
- spawn_text = "warps in from"
- mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged)
- faction = list(ROLE_SYNDICATE)
-
-/obj/structure/spawner/skeleton
- name = "bone pit"
- desc = "A pit full of bones, and some still seem to be moving..."
- max_integrity = 150
- max_mobs = 15
- spawn_time = 150
- mob_types = list(/mob/living/simple_animal/hostile/skeleton)
- spawn_text = "climbs out of"
- faction = list("skeleton")
-
-/obj/structure/spawner/clown
- name = "Laughing Larry"
- desc = "A laughing, jovial figure. Something seems stuck in his throat."
- icon_state = "clownbeacon"
- icon = 'icons/obj/device.dmi'
- max_integrity = 200
- max_mobs = 15
- spawn_time = 150
- mob_types = list(/mob/living/simple_animal/hostile/retaliate/clown, /mob/living/simple_animal/hostile/retaliate/clown/fleshclown, /mob/living/simple_animal/hostile/retaliate/clown/clownhulk, /mob/living/simple_animal/hostile/retaliate/clown/longface, /mob/living/simple_animal/hostile/retaliate/clown/clownhulk/chlown, /mob/living/simple_animal/hostile/retaliate/clown/clownhulk/honcmunculus, /mob/living/simple_animal/hostile/retaliate/clown/mutant/blob, /mob/living/simple_animal/hostile/retaliate/clown/banana, /mob/living/simple_animal/hostile/retaliate/clown/honkling, /mob/living/simple_animal/hostile/retaliate/clown/lube)
- spawn_text = "climbs out of"
- faction = list("clown")
-
-/obj/structure/spawner/carp
- name = "carp spawn" //the non game spawn meaning
- desc = "A puddle, which appears to be full of carp"
- icon_state = "puddle"
- icon = 'icons/obj/watercloset.dmi'
- max_integrity = 150
- max_mobs = 5
- spawn_time = 1200
- mob_types = list(/mob/living/simple_animal/hostile/carp)
- spawn_text = "climbs out of"
- faction = list("carp")
-
-/obj/structure/spawner/mining/proc/adestroy_effect()
- playsound(loc,'sound/effects/explosionfar.ogg', 200, TRUE)
- visible_message("[src] collapses, sealing everything inside!\nOres fall out of the cave as it is destroyed!")
-
-/obj/structure/spawner/mining
- name = "monster den"
- desc = "A hole dug into the ground, harboring all kinds of monsters found within most caves or mining asteroids."
- max_mobs = 3
- spawn_text = "crawls out of"
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub, /mob/living/simple_animal/hostile/asteroid/goliath, /mob/living/simple_animal/hostile/asteroid/hivelord, /mob/living/simple_animal/hostile/asteroid/basilisk, /mob/living/simple_animal/hostile/asteroid/fugu)
- faction = list("mining")
- density = 0
-
-/obj/structure/spawner/mining/deconstruct(disassembled)
- adestroy_effect()
- drop_astroloot()
- return ..()
-
-/obj/structure/spawner/mining/proc/drop_astroloot()
- for(var/type in GLOB.astroloot)
- var/chance = GLOB.astroloot[type]
- if(!prob(chance))
- continue
- new type(loc, rand(5, 17))
-
-/obj/structure/spawner/mining/goldgrub
- name = "goldgrub den"
- desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest."
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub)
-
-/obj/structure/spawner/mining/goliath
- name = "goliath den"
- desc = "A den housing a nest of goliaths, oh god why?"
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath)
-
-/obj/structure/spawner/mining/hivelord
- name = "hivelord den"
- desc = "A den housing a nest of hivelords."
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord)
-
-/obj/structure/spawner/mining/basilisk
- name = "basilisk den"
- desc = "A den housing a nest of basilisks, bring a coat."
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk)
-
-/obj/structure/spawner/mining/wumborian
- name = "wumborian fugu den"
- desc = "A den housing a nest of wumborian fugus, how do they all even fit in there?"
- mob_types = list(/mob/living/simple_animal/hostile/asteroid/fugu)
-
-/obj/structure/spawner/mining/carp
- name = "carp den"
- desc = "A den housing a nest of space carp, seems fishy!"
- mob_types = list(/mob/living/simple_animal/hostile/carp)
- spawn_text = "emerges from"
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index 642c2c2efdd4..9f51ba34476a 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -224,7 +224,7 @@
/obj/structure/statue/bananium
max_integrity = 300
- material_drop_type = /obj/item/stack/sheet/mineral/bananium
+ material_drop_type = /obj/item/stack/sheet/mineral/hidden/hellstone
impressiveness = 50
desc = "A bananium statue with a small engraving:'HOOOOOOONK'."
var/spam_flag = 0
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 2257a3c10c3a..4ebd416675b8 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -106,6 +106,8 @@
return TRUE
if(locate(/obj/structure/table) in get_turf(mover))
return TRUE
+ if(mover.movement_type & FLOATING)
+ return TRUE
/obj/structure/table/CanAStarPass(ID, dir, caller)
. = !density
@@ -372,7 +374,7 @@
check_break(M)
/obj/structure/table/glass/proc/check_break(mob/living/M)
- if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL && !(M.movement_type & FLYING))
+ if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL && !(M.movement_type & (FLYING || FLOATING)))
table_shatter(M)
/obj/structure/table/glass/proc/table_shatter(mob/living/L)
@@ -746,7 +748,7 @@
return
building = TRUE
to_chat(user, "You start assembling [src]...")
- if(do_after(user, 50, target = user, progress=TRUE))
+ if(do_after(user, 50, target = user))
if(!user.temporarilyRemoveItemFromInventory(src))
return
var/obj/structure/R = new construction_type(user.loc)
diff --git a/code/game/objects/structures/traps.dm b/code/game/objects/structures/traps.dm
index f56cfae9a5b8..4c6c3173cded 100644
--- a/code/game/objects/structures/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -144,16 +144,3 @@
/obj/structure/trap/ward/Initialize()
. = ..()
QDEL_IN(src, time_between_triggers)
-
-/obj/structure/trap/cult
- name = "unholy trap"
- desc = "A trap that rings with unholy energy. You think you hear... chittering?"
- icon_state = "trap-cult"
-
-/obj/structure/trap/cult/trap_effect(mob/living/L)
- to_chat(L, "With a crack, the hostile constructs come out of hiding, stunning you!")
- L.electrocute_act(10, src, flags = SHOCK_NOGLOVES) // electrocute act does a message.
- L.Paralyze(20)
- new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
- new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
- QDEL_IN(src, 30)
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 377c40d4e7ce..c22858ea591d 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -40,7 +40,7 @@
GM.visible_message("[user] starts to give [GM] a swirlie!", "[user] starts to give you a swirlie...")
swirlie = GM
var/was_alive = (swirlie.stat != DEAD)
- if(do_after(user, 30, 0, target = src))
+ if(do_after(user, 30, target = src, timed_action_flags = IGNORE_HELD_ITEM))
GM.visible_message("[user] gives [GM] a swirlie!", "[user] gives you a swirlie!", "You hear a toilet flushing.")
if(iscarbon(GM))
var/mob/living/carbon/C = GM
diff --git a/code/game/say.dm b/code/game/say.dm
index c3c8dca852f8..2d53eea65e75 100644
--- a/code/game/say.dm
+++ b/code/game/say.dm
@@ -52,10 +52,28 @@ GLOBAL_LIST_INIT(freqcolor, list())
//Radio freq/name display
var/freqpart = radio_freq ? "\[[get_radio_name(radio_freq)]\] " : ""
//Speaker name
- var/namepart = "[speaker.GetVoice()][speaker.get_alt_name()]"
- if(face_name && ishuman(speaker))
- var/mob/living/carbon/human/H = speaker
- namepart = "[H.get_face_name()]" //So "fake" speaking like in hallucinations does not give the speaker away if disguised
+
+ var/namepart = speaker.GetVoice()
+ var/atom/movable/reliable_narrator = speaker
+ if(istype(speaker, /atom/movable/virtualspeaker)) //ugh
+ var/atom/movable/virtualspeaker/fakespeaker = speaker
+ reliable_narrator = fakespeaker.source
+ if(ishuman(reliable_narrator))
+ //So "fake" speaking like in hallucinations does not give the speaker away if disguised
+ if(face_name)
+ var/mob/living/carbon/human/human_narrator = reliable_narrator
+ namepart = human_narrator.name
+ //otherwise, do guestbook handling
+ else if(ismob(src))
+ var/mob/mob_source = src
+ if(mob_source.mind?.guestbook)
+ var/known_name = mob_source.mind.guestbook.get_known_name(src, reliable_narrator, namepart)
+ if(known_name)
+ namepart = "[known_name]"
+ else
+ var/mob/living/carbon/human/human_narrator = reliable_narrator
+ namepart = "[human_narrator.get_generic_name(prefixed = TRUE, lowercase = FALSE)]"
+
//End name span.
var/endspanpart = ""
@@ -67,9 +85,9 @@ GLOBAL_LIST_INIT(freqcolor, list())
else
messagepart = lang_treat(speaker, message_language, raw_message, spans, message_mods)
- var/datum/language/D = GLOB.language_datum_instances[message_language]
- if(istype(D) && D.display_icon(src))
- languageicon = "[D.get_icon()] "
+ var/datum/language/language = GLOB.language_datum_instances[message_language]
+ if(istype(language) && language.display_icon(src))
+ languageicon = "[language.get_icon()] "
messagepart = " [say_emphasis(messagepart)]"
@@ -177,7 +195,7 @@ GLOBAL_LIST_INIT(freqcolor, list())
return "2"
return "0"
-/atom/movable/proc/GetVoice()
+/atom/movable/proc/GetVoice(if_no_voice = "Unknown")
return "[src]" //Returns the atom's name, prepended with 'The' if it's not a proper noun
/atom/movable/proc/IsVocal()
diff --git a/code/game/turfs/closed/_closed.dm b/code/game/turfs/closed/_closed.dm
index cfede10541d4..2b7d93ae2590 100644
--- a/code/game/turfs/closed/_closed.dm
+++ b/code/game/turfs/closed/_closed.dm
@@ -77,6 +77,16 @@
smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_AIRLOCK)
canSmoothWith = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_AIRLOCK)
+/turf/closed/indestructible/titanium
+ name = "wall"
+ desc = "A light-weight titanium wall used in shuttles. Effectively impervious to conventional methods of destruction."
+ icon = 'icons/turf/walls/shuttle_wall.dmi'
+ icon_state = "shuttle_wall-0"
+ base_icon_state = "shuttle_wall"
+ flags_ricochet = RICOCHET_SHINY | RICOCHET_HARD
+ smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS
+ smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_TITANIUM_WALLS)
+ canSmoothWith = list(SMOOTH_GROUP_TITANIUM_WALLS, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_SHUTTLE_PARTS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_WINDOW_FULLTILE)
/turf/closed/indestructible/riveted
icon = 'icons/turf/walls/riveted.dmi'
@@ -86,47 +96,6 @@
smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS)
canSmoothWith = list(SMOOTH_GROUP_CLOSED_TURFS)
-/turf/closed/indestructible/riveted/supermatter
- name = "wall"
- desc = "A wall made out of a strange metal. The squares on it pulse in a predictable pattern."
- icon = 'icons/turf/walls/bananium_wall.dmi'
- icon_state = "bananium_wall-0"
- base_icon_state = "bananium_wall"
- smoothing_flags = SMOOTH_BITMASK
- smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_BANANIUM_WALLS)
- canSmoothWith = list(SMOOTH_GROUP_BANANIUM_WALLS)
-
-/turf/closed/indestructible/riveted/supermatter/Bumped(atom/movable/AM)
- if(isliving(AM))
- AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [AM.p_their()] body starts to glow and burst into flames before flashing into dust!",\
- "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\
- "You hear an unearthly noise as a wave of heat washes over you.")
- else if(isobj(AM) && !iseffect(AM))
- AM.visible_message("\The [AM] smacks into \the [src] and rapidly flashes to ash.", null,\
- "You hear a loud crack as you are washed with a wave of heat.")
- else
- return
-
- playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE)
- Consume(AM)
-
-/turf/closed/indestructible/riveted/supermatter/proc/Consume(atom/movable/AM)
- if(isliving(AM))
- var/mob/living/user = AM
- if(user.status_flags & GODMODE)
- return
- message_admins("[src] has consumed [key_name_admin(user)] [ADMIN_JMP(src)].")
- investigate_log("has consumed [key_name(user)].", INVESTIGATE_SUPERMATTER)
- user.dust(force = TRUE)
- else if(isobj(AM))
- if(!iseffect(AM))
- var/suspicion = ""
- if(AM.fingerprintslast)
- suspicion = "last touched by [AM.fingerprintslast]"
- message_admins("[src] has consumed [AM], [suspicion] [ADMIN_JMP(src)].")
- investigate_log("has consumed [AM] - [suspicion].", INVESTIGATE_SUPERMATTER)
- qdel(AM)
-
/turf/closed/indestructible/syndicate
icon = 'icons/turf/walls/plastitanium_wall.dmi'
icon_state = "plastitanium_wall-0"
@@ -280,7 +249,7 @@
return TRUE
/turf/closed/indestructible/riveted/boss
- name = "necropolis wall"
+ name = "thick stone wall"
desc = "A thick, seemingly indestructible stone wall."
icon = 'icons/turf/walls/boss_wall.dmi'
icon_state = "boss_wall-0"
diff --git a/code/game/turfs/closed/minerals.dm b/code/game/turfs/closed/minerals.dm
index b5eddacd3e41..33fcf315fc52 100644
--- a/code/game/turfs/closed/minerals.dm
+++ b/code/game/turfs/closed/minerals.dm
@@ -161,6 +161,10 @@
//Currently, Adamantine won't spawn as it has no uses. -Durandan
var/mineralChance = 5
+/turf/closed/mineral/ship
+ baseturfs = /turf/open/floor/plating/asteroid/ship
+ turf_type = /turf/open/floor/plating/asteroid/ship
+
/turf/closed/mineral/random/Initialize(mapload, inherited_virtual_z)
@@ -204,12 +208,6 @@
/obj/item/stack/ore/uranium = 35, /obj/item/stack/ore/diamond = 30, /obj/item/stack/ore/gold = 45, /obj/item/stack/ore/titanium = 45,
/obj/item/stack/ore/silver = 50, /obj/item/stack/ore/plasma = 50, /obj/item/stack/ore/bluespace_crystal)
-/turf/closed/mineral/random/high_chance/volcanic/icecropolis
- environment_type = "basalt"
- turf_type = /turf/open/indestructible/necropolis/air
- baseturfs = /turf/open/indestructible/necropolis/air
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
-
/turf/closed/mineral/random/low_chance
mineralChance = 3
mineralSpawnChanceList = list(
@@ -234,12 +232,6 @@
/obj/item/stack/ore/silver = 12, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 40,
/turf/closed/mineral/gibtonite/volcanic = 4, /obj/item/stack/ore/bluespace_crystal = 1)
-/turf/closed/mineral/random/volcanic/icecropolis
- environment_type = "basalt"
- turf_type = /turf/open/indestructible/necropolis/air
- baseturfs = /turf/open/indestructible/necropolis/air
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
-
/turf/closed/mineral/random/snow
name = "schist"
desc = "Say it fives times fast."
@@ -276,7 +268,7 @@
opacity = FALSE
light_range = 2
light_power = 1
-
+ mineralType = /obj/item/stack/ore/ice
/turf/closed/mineral/random/snow/underground
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
@@ -284,7 +276,7 @@
mineralChance = 10
mineralSpawnChanceList = list(
/obj/item/stack/ore/uranium = 10, /obj/item/stack/ore/diamond = 4, /obj/item/stack/ore/gold = 20, /obj/item/stack/ore/titanium = 22,
- /obj/item/stack/ore/silver = 24, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 20, /obj/item/stack/ore/bananium = 1,
+ /obj/item/stack/ore/silver = 24, /obj/item/stack/ore/plasma = 20, /obj/item/stack/ore/iron = 20,
/turf/closed/mineral/gibtonite/ice/icemoon = 8, /obj/item/stack/ore/bluespace_crystal = 2)
/turf/closed/mineral/random/snow/high_chance
@@ -400,11 +392,6 @@
initial_gas_mix = FROZEN_ATMOS
defer_change = TRUE
-/turf/closed/mineral/bananium
- mineralType = /obj/item/stack/ore/bananium
- mineralAmt = 3
- scan_state = "rock_Bananium"
-
/turf/closed/mineral/bscrystal
mineralType = /obj/item/stack/ore/bluespace_crystal
mineralAmt = 1
@@ -646,10 +633,7 @@
H.mind.adjust_experience(/datum/skill/mining, 100) //yay!
/turf/closed/mineral/strong/proc/drop_ores()
- if(prob(10))
- new /obj/item/stack/sheet/mineral/mythril(src, 5)
- else
- new /obj/item/stack/sheet/mineral/adamantine(src, 5)
+ new /obj/item/stack/sheet/mineral/hidden/hellstone(src, 5)
/turf/closed/mineral/strong/acid_melt()
return
diff --git a/code/game/turfs/closed/wall/mineral_walls.dm b/code/game/turfs/closed/wall/mineral_walls.dm
index 720a95afd0e1..53dbb9479f3b 100644
--- a/code/game/turfs/closed/wall/mineral_walls.dm
+++ b/code/game/turfs/closed/wall/mineral_walls.dm
@@ -68,24 +68,6 @@
icon_state = "diamond_wall-255"
smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS
-/turf/closed/wall/mineral/bananium
- name = "bananium wall"
- desc = "A wall with bananium plating. Honk!"
- icon = 'icons/turf/walls/bananium_wall.dmi'
- icon_state = "bananium_wall-0"
- base_icon_state = "bananium_wall"
- sheet_type = /obj/item/stack/sheet/mineral/bananium
- smoothing_flags = SMOOTH_BITMASK | SMOOTH_CONNECTORS
- smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_BANANIUM_WALLS)
- canSmoothWith = list(SMOOTH_GROUP_BANANIUM_WALLS, SMOOTH_GROUP_WALLS,SMOOTH_GROUP_AIRLOCK)
- connector_icon = 'icons/turf/connectors/bananium_wall_connector.dmi'
- connector_icon_state = "bananium_wall_connector"
- no_connector_typecache = list(/turf/closed/wall/mineral/bananium, /obj/structure/falsewall/bananium)
-
-/turf/closed/wall/mineral_bananium/yesdiag
- icon_state = "bananium_wall-255"
- smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS
-
/turf/closed/wall/mineral/sandstone
name = "sandstone wall"
desc = "A wall with sandstone plating. Rough."
@@ -244,8 +226,6 @@
icon_state = "wood_wall-255"
smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS | SMOOTH_CONNECTORS
-/turf/closed/wall/mineral/wood/nonmetal/icecropolis
- baseturfs = /turf/open/indestructible/necropolis/air
/turf/closed/wall/mineral/wood/attackby(obj/item/W, mob/user)
if(W.get_sharpness() && W.force)
@@ -284,9 +264,6 @@
icon_state = "iron_wall-255"
smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS
-/turf/closed/wall/mineral/iron/icecropolis
- baseturfs = /turf/open/indestructible/necropolis/air
-
/turf/closed/wall/mineral/snow
name = "packed snow wall"
desc = "A wall made of densely packed snow blocks."
diff --git a/code/game/turfs/closed/wall/misc_walls.dm b/code/game/turfs/closed/wall/misc_walls.dm
index e6e5c8f0c557..7fbcab55504a 100644
--- a/code/game/turfs/closed/wall/misc_walls.dm
+++ b/code/game/turfs/closed/wall/misc_walls.dm
@@ -6,7 +6,7 @@
base_icon_state = "cult_wall"
smoothing_flags = SMOOTH_BITMASK
canSmoothWith = null
- sheet_type = /obj/item/stack/sheet/runed_metal
+ sheet_type = /obj/item/stack/sheet/mineral/hidden/hellstone
sheet_amount = 1
girder_type = /obj/structure/girder/cult
@@ -63,10 +63,6 @@
icon_state = "rusty_wall-255"
smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS
-/turf/closed/wall/rust/icecropolis
- baseturfs = /turf/open/indestructible/necropolis/air
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
-
/turf/closed/wall/r_wall/rust
name = "rusted reinforced wall"
desc = "A huge chunk of rusted reinforced metal."
diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm
index 27a3225dbb03..44acbe06f6bf 100644
--- a/code/game/turfs/open/_open.dm
+++ b/code/game/turfs/open/_open.dm
@@ -99,9 +99,6 @@
heavyfootstep = FOOTSTEP_LAVA
tiled_dirt = FALSE
-/turf/open/indestructible/necropolis/icecropolis
- initial_gas_mix = ICEMOON_DEFAULT_ATMOS
-
/turf/open/indestructible/necropolis/Initialize(mapload, inherited_virtual_z)
. = ..()
if(prob(12))
diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm
index f4bfa034fa12..d74edb27a658 100644
--- a/code/game/turfs/open/floor.dm
+++ b/code/game/turfs/open/floor.dm
@@ -62,27 +62,15 @@
if(1)
ScrapeAway(2, flags = CHANGETURF_INHERIT_AIR)
if(2)
- switch(rand(1, 3))
- if(1)
- if(!length(baseturfs) || !ispath(baseturfs[baseturfs.len-1], /turf/open/floor))
- ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
- ReplaceWithLattice()
- else
- ScrapeAway(2, flags = CHANGETURF_INHERIT_AIR)
- if(prob(33))
- new /obj/item/stack/sheet/metal(src)
- if(2)
- ScrapeAway(2, flags = CHANGETURF_INHERIT_AIR)
- if(3)
- if(prob(80))
- ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
- else
- break_tile()
- hotspot_expose(1000,CELL_VOLUME)
- if(prob(33))
- new /obj/item/stack/sheet/metal(src)
+ if(prob(60))
+ ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
+ else
+ break_tile()
+ hotspot_expose(1000,CELL_VOLUME)
+ if(prob(33))
+ new /obj/item/stack/sheet/metal(src)
if(3)
- if (prob(50))
+ if(prob(50))
src.break_tile()
src.hotspot_expose(1000,CELL_VOLUME)
diff --git a/code/game/turfs/open/floor/fancy_floor.dm b/code/game/turfs/open/floor/fancy_floor.dm
index 37c369a3d8c9..3a0184849450 100644
--- a/code/game/turfs/open/floor/fancy_floor.dm
+++ b/code/game/turfs/open/floor/fancy_floor.dm
@@ -41,9 +41,6 @@
/turf/open/floor/wood/yew
color = WOOD_COLOR_YELLOW
-/turf/open/floor/wood/icecropolis
- baseturfs = /turf/open/indestructible/necropolis/air
-
/turf/open/floor/wood/examine(mob/user)
. = ..()
. += "There's a few screws and a small crack visible."
diff --git a/code/game/turfs/open/floor/mineral_floor.dm b/code/game/turfs/open/floor/mineral_floor.dm
index 476a69fa468d..5d53a162b087 100644
--- a/code/game/turfs/open/floor/mineral_floor.dm
+++ b/code/game/turfs/open/floor/mineral_floor.dm
@@ -172,48 +172,6 @@
/turf/open/floor/mineral/plastitanium/red/brig
name = "brig floor"
-//BANANIUM
-
-/turf/open/floor/mineral/bananium
- name = "bananium floor"
- icon_state = "bananium"
- floor_tile = /obj/item/stack/tile/mineral/bananium
- icons = list("bananium","bananium_dam")
- var/spam_flag = 0
-
-/turf/open/floor/mineral/bananium/Entered(atom/movable/AM)
- .=..()
- if(!.)
- if(isliving(AM))
- squeak()
-
-/turf/open/floor/mineral/bananium/attackby(obj/item/W, mob/user, params)
- .=..()
- if(!.)
- honk()
-
-/turf/open/floor/mineral/bananium/attack_hand(mob/user)
- .=..()
- if(!.)
- honk()
-
-/turf/open/floor/mineral/bananium/attack_paw(mob/user)
- .=..()
- if(!.)
- honk()
-
-/turf/open/floor/mineral/bananium/proc/honk()
- if(spam_flag < world.time)
- playsound(src, 'sound/items/bikehorn.ogg', 50, TRUE)
- spam_flag = world.time + 20
-
-/turf/open/floor/mineral/bananium/proc/squeak()
- if(spam_flag < world.time)
- playsound(src, "clownstep", 50, TRUE)
- spam_flag = world.time + 10
-
-/turf/open/floor/mineral/bananium/airless
- initial_gas_mix = AIRLESS_ATMOS
//DIAMOND
diff --git a/code/game/turfs/open/floor/plasteel_floor.dm b/code/game/turfs/open/floor/plasteel_floor.dm
index 10760b3af5cf..61a90ff0da86 100644
--- a/code/game/turfs/open/floor/plasteel_floor.dm
+++ b/code/game/turfs/open/floor/plasteel_floor.dm
@@ -157,7 +157,6 @@
/turf/open/floor/plasteel/cult/airless
initial_gas_mix = AIRLESS_ATMOS
-
/turf/open/floor/plasteel/stairs //considering removal
icon = 'icons/turf/floors.dmi'
icon_state = "stairs"
@@ -169,7 +168,7 @@
icon_state = "stairs-l"
base_icon_state = "stairs-l"
-/turf/open/floor/plasteel/stairs/medium
+/turf/open/floor/plasteel/stairs/mid
icon_state = "stairs-m"
base_icon_state = "stairs-m"
@@ -182,9 +181,128 @@
base_icon_state = "stairs-old"
/turf/open/floor/plasteel/stairs/wood
- color = "#A47449"
- barefootstep = "wood"
- footstep = "wood"
+ color = "#5B3E1D"
+ icon_state = "stairs-wood"
+ base_icon_state = "stairs-wood"
+ barefootstep = FOOTSTEP_WOOD_BAREFOOT
+ footstep = FOOTSTEP_WOOD_CLAW
+
+/turf/open/floor/plasteel/stairs/wood/left
+ icon_state = "stairs-wood-l"
+ base_icon_state = "stairs-wood-l"
+
+/turf/open/floor/plasteel/stairs/wood/mid
+ icon_state = "stairs-wood-m"
+ base_icon_state = "stairs-wood-m"
+
+/turf/open/floor/plasteel/stairs/wood/right
+ icon_state = "stairs-wood-r"
+ base_icon_state = "stairs-wood-r"
+
+/turf/open/floor/plasteel/stairs/wood/mahogany
+ color = WOOD_COLOR_RICH
+
+/turf/open/floor/plasteel/stairs/wood/mahogany/left
+ icon_state = "stairs-wood-l"
+ base_icon_state = "stairs-wood-l"
+
+/turf/open/floor/plasteel/stairs/wood/mahogany/mid
+ icon_state = "stairs-wood-m"
+ base_icon_state = "stairs-wood-m"
+
+/turf/open/floor/plasteel/stairs/wood/mahogany/right
+ icon_state = "stairs-wood-r"
+ base_icon_state = "stairs-wood-r"
+
+/turf/open/floor/plasteel/stairs/wood/maple
+ color = WOOD_COLOR_PALE
+
+/turf/open/floor/plasteel/stairs/wood/maple/left
+ icon_state = "stairs-wood-l"
+ base_icon_state = "stairs-wood-l"
+
+/turf/open/floor/plasteel/stairs/wood/maple/mid
+ icon_state = "stairs-wood-m"
+ base_icon_state = "stairs-wood-m"
+
+/turf/open/floor/plasteel/stairs/wood/maple/right
+ icon_state = "stairs-wood-r"
+ base_icon_state = "stairs-wood-r"
+
+/turf/open/floor/plasteel/stairs/wood/ebony
+ color = WOOD_COLOR_BLACK
+
+/turf/open/floor/plasteel/stairs/wood/ebony/left
+ icon_state = "stairs-wood-l"
+ base_icon_state = "stairs-wood-l"
+
+/turf/open/floor/plasteel/stairs/wood/ebony/mid
+ icon_state = "stairs-wood-m"
+ base_icon_state = "stairs-wood-m"
+
+/turf/open/floor/plasteel/stairs/wood/ebony/right
+ icon_state = "stairs-wood-r"
+ base_icon_state = "stairs-wood-r"
+
+/turf/open/floor/plasteel/stairs/wood/walnut
+ color = WOOD_COLOR_CHOCOLATE
+
+/turf/open/floor/plasteel/stairs/wood/walnut/left
+ icon_state = "stairs-wood-l"
+ base_icon_state = "stairs-wood-l"
+
+/turf/open/floor/plasteel/stairs/wood/walnut/mid
+ icon_state = "stairs-wood-m"
+ base_icon_state = "stairs-wood-m"
+
+/turf/open/floor/plasteel/stairs/wood/walnut/right
+ icon_state = "stairs-wood-r"
+ base_icon_state = "stairs-wood-r"
+
+/turf/open/floor/plasteel/stairs/wood/bamboo
+ color = WOOD_COLOR_PALE2
+
+/turf/open/floor/plasteel/stairs/wood/bamboo/left
+ icon_state = "stairs-wood-l"
+ base_icon_state = "stairs-wood-l"
+
+/turf/open/floor/plasteel/stairs/wood/bamboo/mid
+ icon_state = "stairs-wood-m"
+ base_icon_state = "stairs-wood-m"
+
+/turf/open/floor/plasteel/stairs/wood/bamboo/right
+ icon_state = "stairs-wood-r"
+ base_icon_state = "stairs-wood-r"
+
+/turf/open/floor/plasteel/stairs/wood/birch
+ color = WOOD_COLOR_PALE3
+
+/turf/open/floor/plasteel/stairs/wood/birch/left
+ icon_state = "stairs-wood-l"
+ base_icon_state = "stairs-wood-l"
+
+/turf/open/floor/plasteel/stairs/wood/birch/mid
+ icon_state = "stairs-wood-m"
+ base_icon_state = "stairs-wood-m"
+
+/turf/open/floor/plasteel/stairs/wood/birch/right
+ icon_state = "stairs-wood-r"
+ base_icon_state = "stairs-wood-r"
+
+/turf/open/floor/plasteel/stairs/wood/yew
+ color = WOOD_COLOR_YELLOW
+
+/turf/open/floor/plasteel/stairs/wood/yew/left
+ icon_state = "stairs-wood-l"
+ base_icon_state = "stairs-wood-l"
+
+/turf/open/floor/plasteel/stairs/wood/yew/mid
+ icon_state = "stairs-wood-m"
+ base_icon_state = "stairs-wood-m"
+
+/turf/open/floor/plasteel/stairs/wood/yew/right
+ icon_state = "stairs-wood-r"
+ base_icon_state = "stairs-wood-r"
/turf/open/floor/plasteel/rockvault
icon_state = "rockvault"
@@ -214,6 +332,3 @@
icon_state = "tiled_light"
base_icon_state = "tiled_light"
color = "#938170"
-
-/turf/open/floor/plasteel/icecropolis
- baseturfs = /turf/open/indestructible/necropolis/air
diff --git a/code/game/turfs/open/floor/plating/asteroid.dm b/code/game/turfs/open/floor/plating/asteroid.dm
index ee311f747d82..996d122a4ac9 100644
--- a/code/game/turfs/open/floor/plating/asteroid.dm
+++ b/code/game/turfs/open/floor/plating/asteroid.dm
@@ -101,7 +101,7 @@
to_chat(user, "There is already a grave there!")
return
to_chat(user, "You start piling the dirt...")
- if(do_after(user,30, target = src))
+ if(do_after(user, 30, target = src))
if(locate(/obj/structure/closet/crate/grave) in dest_turf)
return
if(istype(W, /obj/item/stack/sheet/mineral/wood))
@@ -126,3 +126,5 @@
baseturfs = /turf/open/floor/plating/asteroid/airless
turf_type = /turf/open/floor/plating/asteroid/airless
+/turf/open/floor/plating/asteroid/ship
+ baseturfs = /turf/open/floor/plating
diff --git a/code/game/turfs/open/floor/plating/lavaland.dm b/code/game/turfs/open/floor/plating/lavaland.dm
index 1dd8d49d746d..84e0173819b7 100644
--- a/code/game/turfs/open/floor/plating/lavaland.dm
+++ b/code/game/turfs/open/floor/plating/lavaland.dm
@@ -37,15 +37,6 @@
planetary_atmos = TRUE
baseturfs = /turf/open/lava/smooth/lava_land_surface
-/turf/open/floor/plating/asteroid/basalt/lava_land_surface/icecropolis
- initial_gas_mix = ICEMOON_DEFAULT_ATMOS
- baseturfs = /turf/open/indestructible/necropolis/icecropolis
-
-/turf/open/floor/plating/asteroid/basalt/lava_land_surface/icecropolis/inside
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
- planetary_atmos = FALSE
- baseturfs = /turf/open/indestructible/necropolis/air
-
/turf/open/floor/plating/asteroid/basalt/purple
icon = 'icons/turf/lavaland_purple.dmi'
baseturfs = /turf/open/floor/plating/asteroid/basalt/purple
@@ -102,3 +93,39 @@
light_range = 2
light_power = 0.6
light_color = LIGHT_COLOR_FIRE
+
+/turf/open/floor/concrete/lava
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
+ light_range = 2
+ light_power = 0.6
+ light_color = LIGHT_COLOR_FIRE
+
+/turf/open/floor/concrete/slab_1/lava
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
+ light_range = 2
+ light_power = 0.6
+ light_color = LIGHT_COLOR_FIRE
+
+/turf/open/floor/plating/lava
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
+ light_range = 2
+ light_power = 0.6
+ light_color = LIGHT_COLOR_FIRE
+
+/turf/open/floor/plating/rust/lava
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
+ light_range = 2
+ light_power = 0.6
+ light_color = LIGHT_COLOR_FIRE
+
+/turf/open/floor/plasteel/white/lava
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
+ light_range = 2
+ light_power = 0.6
+ light_color = LIGHT_COLOR_FIRE
+
+/turf/open/floor/plasteel/dark/lava
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
+ light_range = 2
+ light_power = 0.6
+ light_color = LIGHT_COLOR_FIRE
diff --git a/code/game/turfs/open/floor/plating/misc_plating.dm b/code/game/turfs/open/floor/plating/misc_plating.dm
index e9b28fb4a613..84a49d1a0038 100644
--- a/code/game/turfs/open/floor/plating/misc_plating.dm
+++ b/code/game/turfs/open/floor/plating/misc_plating.dm
@@ -11,11 +11,6 @@
icon_state = "plating"
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
-/turf/open/floor/plating/icecropolis
- icon_state = "plating"
- baseturfs = /turf/open/indestructible/necropolis/air
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
-
/turf/open/floor/plating/abductor
name = "alien floor"
icon_state = "alienpod1"
diff --git a/code/game/turfs/open/floor/reinf_floor.dm b/code/game/turfs/open/floor/reinf_floor.dm
index a164b159d6f6..7fb94e541bda 100644
--- a/code/game/turfs/open/floor/reinf_floor.dm
+++ b/code/game/turfs/open/floor/reinf_floor.dm
@@ -133,6 +133,13 @@
name = "fuel mix floor"
initial_gas_mix = ATMOS_TANK_FUEL
+/turf/open/floor/engine/hydrogen
+ name = "\improper hydrogen floor"
+ initial_gas_mix = ATMOS_TANK_HYDROGEN
+
+/turf/open/floor/engine/hydrogen_fuel
+ name = "hydrogen mix floor"
+ initial_gas_mix = ATMOS_TANK_HYDROGEN_FUEL
/turf/open/floor/engine/cult
name = "engraved floor"
diff --git a/code/game/turfs/open/floor/suns_floor.dm b/code/game/turfs/open/floor/suns_floor.dm
new file mode 100644
index 000000000000..efa1aa91a61a
--- /dev/null
+++ b/code/game/turfs/open/floor/suns_floor.dm
@@ -0,0 +1,45 @@
+/turf/open/floor/suns
+ name = "white marble floor"
+ icon = 'icons/turf/floors/suns.dmi'
+ icon_state = "light"
+ floor_tile = /obj/item/stack/tile/suns
+
+/turf/open/floor/suns/plain
+ name = "white plain marble floor"
+ icon_state = "lightplain"
+ floor_tile = /obj/item/stack/tile/suns/plain
+
+/turf/open/floor/suns/pattern
+ name = "patterned white marble floor"
+ icon_state = "lightpattern"
+ floor_tile = /obj/item/stack/tile/suns/pattern
+
+/turf/open/floor/suns/hatch
+ name = "hatched wooden floor"
+ icon_state = "lighthatched"
+ floor_tile = /obj/item/stack/tile/suns/hatch
+
+/turf/open/floor/suns/diagonal
+ name = "diagonal wooden floor"
+ icon_state = "lightdiag"
+ floor_tile = /obj/item/stack/tile/suns/diagonal
+
+/turf/open/floor/suns/grid
+ name = "dark grid floor"
+ icon_state = "darkchunky"
+ floor_tile = /obj/item/stack/tile/suns/grid
+
+/turf/open/floor/suns/dark
+ name = "black marble floor"
+ icon_state = "dark"
+ floor_tile = /obj/item/stack/tile/suns/dark
+
+/turf/open/floor/suns/dark/plain
+ name = "black plain marble floor"
+ icon_state = "darkplain"
+ floor_tile = /obj/item/stack/tile/suns/dark/plain
+
+/turf/open/floor/suns/dark/pattern
+ name = "patterned black marble floor"
+ icon_state = "darkpattern"
+ floor_tile = /obj/item/stack/tile/suns/dark/pattern
diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm
index 99f1d590c05a..eb2132940bd9 100644
--- a/code/game/turfs/open/lava.dm
+++ b/code/game/turfs/open/lava.dm
@@ -18,6 +18,8 @@
heavyfootstep = FOOTSTEP_LAVA
var/particle_emitter = /obj/effect/particle_emitter/lava
+ /// Whether the lava has been dug with hellstone found successfully
+ var/is_mined = FALSE
/turf/open/lava/Initialize(mapload)
. = ..()
@@ -100,10 +102,10 @@
/turf/open/lava/TakeTemperature(temp)
-/turf/open/lava/attackby(obj/item/C, mob/user, params)
+/turf/open/lava/attackby(obj/item/attacking_item, mob/user, params)
..()
- if(istype(C, /obj/item/stack/rods/lava))
- var/obj/item/stack/rods/lava/R = C
+ if(istype(attacking_item, /obj/item/stack/rods/lava))
+ var/obj/item/stack/rods/lava/R = attacking_item
var/obj/structure/lattice/lava/H = locate(/obj/structure/lattice/lava, src)
if(H)
to_chat(user, "There is already a lattice here!")
@@ -115,6 +117,19 @@
else
to_chat(user, "You need one rod to build a heatproof lattice.")
return
+ if(attacking_item.tool_behaviour == TOOL_MINING && (attacking_item.custom_materials[SSmaterials.GetMaterialRef(/datum/material/diamond)]))
+ if(is_mined)
+ to_chat(user, span_notice("This has already been cleared out of hellstone..."))
+ return FALSE
+ to_chat(user, span_notice("You start parting away [src]..."))
+ if(attacking_item.use_tool(src, user, 175, volume=30))
+ to_chat(user, span_notice("You part away [src]."))
+ playsound(src, 'sound/effects/break_stone.ogg', 30, TRUE)
+ if (prob(10))
+ new /obj/item/stack/ore/hellstone(src)
+ is_mined = TRUE
+ return TRUE
+ return FALSE
/turf/open/lava/proc/is_safe()
//if anything matching this typecache is found in the lava, we don't burn things
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 4ed4b47297a2..e5cc9709559c 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -461,12 +461,12 @@ GLOBAL_LIST_EMPTY(created_baseturf_lists)
return
if(length(src_object.contents()))
to_chat(usr, "You start dumping out the contents...")
- if(!do_after(usr,20,target=src_object.parent))
+ if(!do_after(usr, 20, target=src_object.parent))
return FALSE
var/list/things = src_object.contents()
var/datum/progressbar/progress = new(user, things.len, src)
- while (do_after(usr, 10, TRUE, src, FALSE, CALLBACK(src_object, TYPE_PROC_REF(/datum/component/storage, mass_remove_from_storage), src, things, progress)))
+ while (do_after(usr, 10, src, TRUE, FALSE, CALLBACK(src_object, TYPE_PROC_REF(/datum/component/storage, mass_remove_from_storage), src, things, progress)))
stoplag(1)
progress.end_progress()
diff --git a/code/modules/NTNet/relays.dm b/code/modules/NTNet/relays.dm
index 9a1b01403eda..f161eced8060 100644
--- a/code/modules/NTNet/relays.dm
+++ b/code/modules/NTNet/relays.dm
@@ -3,8 +3,8 @@
name = "NTNet Quantum Relay"
desc = "A very complex router and transmitter capable of connecting electronic devices together. Looks fragile."
use_power = ACTIVE_POWER_USE
- active_power_usage = 10000 //10kW, apropriate for machine that keeps massive cross-Zlevel wireless network operational. Used to be 20 but that actually drained the smes one round
- idle_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_EXTREME //Since NTnet is barely used, this has been lowered by half.
icon = 'icons/obj/machines/telecomms.dmi'
icon_state = "bus"
density = TRUE
@@ -64,9 +64,9 @@
/obj/machinery/ntnet_relay/process()
if(is_operational)
- use_power = ACTIVE_POWER_USE
+ set_active_power()
else
- use_power = IDLE_POWER_USE
+ set_idle_power()
update_appearance()
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 82cb857576c1..82e75d63b30e 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -39,7 +39,7 @@
return
var/body = "Options for [M.key]"
- body += "Options panel for [M]"
+ body += "Options panel for [M.real_name]"
if(M.client)
body += " played by [M.client] "
body += "[M.client.holder ? M.client.holder.rank : "Player"]"
@@ -215,7 +215,7 @@
/datum/admins/proc/access_news_network() //MARKER
- set category = "Admin.Events"
+ set category = "Event"
set name = "Access Newscaster Network"
set desc = "Allows you to view, add and edit news feeds."
@@ -700,7 +700,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
/datum/admins/proc/spawn_atom(object as text)
- set category = "Debug"
+ set category = "Event.Spawning"
set desc = "(atom path) Spawn an atom"
set name = "Spawn"
@@ -729,7 +729,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/podspawn_atom(object as text)
- set category = "Debug"
+ set category = "Event.Spawning"
set desc = "(atom path) Spawn an atom via supply drop"
set name = "Podspawn"
@@ -753,7 +753,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Podspawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/spawn_cargo(object as text)
- set category = "Debug"
+ set category = "Event.Spawning"
set desc = "(atom path) Spawn a cargo crate"
set name = "Spawn Cargo"
@@ -1018,3 +1018,14 @@
dat += "Disable footsteps: [SSlag_switch.measures[DISABLE_FOOTSTEPS] ? "On" : "Off"] - trait applies to character "
dat += ""
usr << browse(dat.Join(), "window=lag_switch_panel;size=420x480")
+
+/datum/admins/proc/view_manifest()
+ set category = "Admin.Game"
+ set name = "View Manifest"
+ set desc = "Opens the Manifest UI."
+
+ if(!GLOB.crew_manifest_tgui)
+ GLOB.crew_manifest_tgui = new /datum/crew_manifest(src)
+
+ if(ismob(usr))
+ GLOB.crew_manifest_tgui.ui_interact(usr)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 0539dca13e25..9c4f15b9d460 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -81,6 +81,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
/client/proc/overmap_datum_token_manager,
/datum/admins/proc/open_borgopanel,
/client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/
+ /datum/admins/proc/view_manifest
)
GLOBAL_LIST_INIT(admin_verbs_ban, list(
@@ -121,7 +122,6 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
/client/proc/polymorph_all,
/client/proc/show_tip,
/client/proc/smite,
- /client/proc/spawn_ruin,
))
GLOBAL_PROTECT(admin_verbs_fun)
GLOBAL_LIST_INIT(admin_verbs_spawn, list(
@@ -130,7 +130,9 @@ GLOBAL_LIST_INIT(admin_verbs_spawn, list(
/datum/admins/proc/spawn_cargo,
/datum/admins/proc/spawn_objasmob,
/datum/admins/proc/beaker_panel,
- /datum/admins/proc/gift
+ /datum/admins/proc/gift,
+ /client/proc/spawn_ruin,
+ /client/proc/spawn_outpost /* Allows admins to spawn a new outpost. */
))
GLOBAL_PROTECT(admin_verbs_spawn)
GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer())
@@ -205,12 +207,10 @@ GLOBAL_PROTECT(admin_verbs_debug)
#endif
/datum/admins/proc/create_or_modify_area,
/datum/admins/proc/open_shuttlepanel, /* Opens shuttle manipulator UI */
- /client/proc/spawn_outpost, /* Allows admins to spawn a new outpost. */
/datum/admins/proc/open_borgopanel,
/datum/admins/proc/overmap_view, /* Opens HTML overmap viewer UI */
/client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/
/client/proc/toggle_cdn,
- /client/proc/check_timer_sources
)
GLOBAL_LIST_INIT(admin_verbs_possess, list(/proc/possess, /proc/release))
GLOBAL_PROTECT(admin_verbs_possess)
@@ -269,7 +269,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
/client/proc/Debug2,
/client/proc/reload_admins,
/client/proc/cmd_debug_make_powernets,
- /client/proc/startSinglo,
/client/proc/cmd_debug_mob_lists,
/client/proc/cmd_debug_del_all,
/client/proc/enable_debug_verbs,
@@ -338,8 +337,8 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/play_web_sound,
GLOB.admin_verbs_spawn,
/*Debug verbs added by "show debug verbs"*/
- GLOB.admin_verbs_debug_mapping,
- /client/proc/disable_debug_verbs,
+ GLOB.admin_verbs_debug_extra,
+ /client/proc/enable_debug_verbs,
/client/proc/readmin
))
@@ -403,11 +402,13 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set category = "Admin.Game"
set desc = "Toggles ghost-like invisibility (Don't abuse this)"
if(holder && mob)
- if(mob.invisibility == INVISIBILITY_OBSERVER)
+ if(mob.invisibility == INVISIBILITY_INVINISMIN)
mob.invisibility = initial(mob.invisibility)
+ mob.remove_from_all_data_huds()
to_chat(mob, "Invisimin off. Invisibility reset.", confidential = TRUE)
else
- mob.invisibility = INVISIBILITY_OBSERVER
+ mob.invisibility = INVISIBILITY_INVINISMIN
+ mob.add_to_all_human_data_huds()
to_chat(mob, "Invisimin on. You are now as invisible as a ghost.", confidential = TRUE)
/client/proc/check_antagonists()
@@ -503,7 +504,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Stealth Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_bomb()
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Drop Bomb"
set desc = "Cause an explosion of varying strength at your location."
@@ -545,7 +546,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_dynex_bomb()
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Drop DynEx Bomb"
set desc = "Cause an explosion of varying strength at your location."
@@ -592,7 +593,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("[key_name_admin(usr)] has modified Dynamic Explosion Scale: [ex_scale]")
/client/proc/give_spell(mob/T in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Give Spell"
set desc = "Gives a spell to a mob."
@@ -616,7 +617,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("Spells given to mindless mobs will not be transferred in mindswap or cloning!")
/client/proc/remove_spell(mob/T in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Remove Spell"
set desc = "Remove a spell from the selected mob."
@@ -629,7 +630,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Spell") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/give_disease(mob/living/T in GLOB.mob_living_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Give Disease"
set desc = "Gives a Disease to a mob."
if(!istype(T))
@@ -644,7 +645,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("[key_name_admin(usr)] gave [key_name_admin(T)] the disease [D].")
/client/proc/object_say(obj/O in world)
- set category = "Admin.Events"
+ set category = "Event"
set name = "OSay"
set desc = "Makes an object say something."
var/message = input(usr, "What do you want the message to be?", "Make Sound") as text | null
@@ -654,9 +655,10 @@ GLOBAL_PROTECT(admin_verbs_hideable)
log_admin("[key_name(usr)] made [O] at [AREACOORD(O)] say \"[message]\"")
message_admins("[key_name_admin(usr)] made [O] at [AREACOORD(O)]. say \"[message]\"")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Object Say") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
/client/proc/togglebuildmodeself()
set name = "Toggle Build Mode Self"
- set category = "Admin.Events"
+ set category = "Event"
if (!(holder.rank.rights & R_BUILD))
return
if(src.mob)
diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm
index c1845945485f..3b8c5191c9b6 100644
--- a/code/modules/admin/create_mob.dm
+++ b/code/modules/admin/create_mob.dm
@@ -23,6 +23,7 @@
H.facial_hair_color = H.hair_color
H.eye_color = random_eye_color()
H.dna.blood_type = random_blood_type()
+ H.generic_adjective = pick_species_adjective(H)
// Mutant randomizing, doesn't affect the mob appearance unless it's the specific mutant.
H.dna.features["mcolor"] = random_short_color()
@@ -41,6 +42,7 @@
H.dna.features["squid_face"] = pick(GLOB.squid_face_list)
H.dna.features["kepori_feathers"] = pick(GLOB.kepori_feathers_list)
H.dna.features["kepori_body_feathers"] = pick(GLOB.kepori_body_feathers_list)
+ H.dna.features["kepori_head_feathers"] = pick(GLOB.kepori_head_feathers_list)
H.dna.features["vox_head_quills"] = pick(GLOB.vox_head_quills_list)
H.dna.features["vox_neck_quills"] = pick(GLOB.vox_neck_quills_list)
H.dna.features["elzu_horns"] = pick(GLOB.elzu_horns_list)
diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm
index 99e7b1692ecc..04e84097f6d1 100644
--- a/code/modules/admin/fun_balloon.dm
+++ b/code/modules/admin/fun_balloon.dm
@@ -134,8 +134,8 @@
INVOKE_ASYNC(src, PROC_REF(do_bloodbath), M)
/obj/effect/forcefield/arena_shuttle_entrance/proc/do_bloodbath(mob/living/L)
- var/obj/effect/mine/pickup/bloodbath/B = new (L)
- B.mineEffect(L)
+ var/obj/item/mine/pressure/pickup/bloodbath/B = new (L)
+ B.mine_effect(L)
/area/shuttle_arena
name = "arena"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index b917501d0bb8..2e4b1c60acdd 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1239,7 +1239,7 @@
cookiealt = /obj/item/reagent_containers/food/condiment/milk
else if(isplasmaman(H))
cookiealt = /obj/item/reagent_containers/food/condiment/milk
- else if(isethereal(H))
+ else if(iselzuose(H))
cookiealt = /obj/item/reagent_containers/food/snacks/energybar
// WS - More fun with cookies - Start
else if(islizard(H))
@@ -2227,6 +2227,15 @@
return
paper_to_show.ui_interact(usr)
+ else if(href_list["show_photo"])
+ if(!check_rights(R_ADMIN))
+ return
+
+ var/obj/item/photo/photo_to_show = locate(href_list["show_photo"])
+ if(!istype(photo_to_show))
+ return
+ photo_to_show.show(usr)
+
/datum/admins/proc/HandleCMode()
if(!check_rights(R_ADMIN))
return
diff --git a/code/modules/admin/verbs/anonymousnames.dm b/code/modules/admin/verbs/anonymousnames.dm
index 62c48149af52..c880a74ba6f6 100644
--- a/code/modules/admin/verbs/anonymousnames.dm
+++ b/code/modules/admin/verbs/anonymousnames.dm
@@ -1,5 +1,5 @@
/client/proc/anon_names()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Setup Anonymous Names"
diff --git a/code/modules/admin/verbs/atmosdebug.dm b/code/modules/admin/verbs/atmosdebug.dm
index 6fc5f8a4c709..56da851fdfd9 100644
--- a/code/modules/admin/verbs/atmosdebug.dm
+++ b/code/modules/admin/verbs/atmosdebug.dm
@@ -19,7 +19,7 @@
return list(y + 1 - min(bounds[2], bounds[4]), -(x - 1 - max(bounds[1], bounds[3])))
/client/proc/check_atmos()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Check Atmospherics Piping"
if(!check_rights_for(src, R_DEBUG))
to_chat(src, "Only administrators may use this command.", confidential = TRUE)
@@ -54,7 +54,7 @@
return results
/client/proc/check_wiring()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Check Power"
if(!check_rights_for(src, R_DEBUG))
to_chat(src, "Only administrators may use this command.", confidential = TRUE)
diff --git a/code/modules/admin/verbs/beakerpanel.dm b/code/modules/admin/verbs/beakerpanel.dm
index 1f523c9e4627..3ba2a51b2fe8 100644
--- a/code/modules/admin/verbs/beakerpanel.dm
+++ b/code/modules/admin/verbs/beakerpanel.dm
@@ -61,7 +61,7 @@
return container
/datum/admins/proc/beaker_panel()
- set category = "Admin.Events"
+ set category = "Event.Spawning"
set name = "Spawn reagent container"
if(!check_rights())
return
diff --git a/code/modules/admin/verbs/cinematic.dm b/code/modules/admin/verbs/cinematic.dm
index 722440e11b93..a8549c635966 100644
--- a/code/modules/admin/verbs/cinematic.dm
+++ b/code/modules/admin/verbs/cinematic.dm
@@ -1,6 +1,6 @@
/client/proc/cinematic()
- set name = "cinematic"
- set category = "Fun"
+ set name = "Cinematic"
+ set category = "Event.Fun"
set desc = "Shows a cinematic." // Intended for testing but I thought it might be nice for events on the rare occasion Feel free to comment it out if it's not wanted.
set hidden = TRUE
if(!SSticker)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 19ac8a0514d3..9a226bbcb617 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -26,8 +26,8 @@ Because if you select a player mob as owner it tries to do the proc for
But you can call procs that are of type /mob/living/carbon/human/proc/ for that player.
*/
-/client/proc/Cell()
- set category = "Debug"
+/client/proc/air_status_loc()
+ set category = "Debug.Debug"
set name = "Air Status in Location"
if(!mob)
return
@@ -38,7 +38,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
SSblackbox.record_feedback("tally", "admin_verb", 1, "Air Status In Location") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_robotize(mob/M in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Make Robot"
if(!SSticker.HasRoundStarted())
@@ -53,7 +53,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
alert("Invalid mob")
/client/proc/cmd_admin_blobize(mob/M in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Make Blob"
if(!SSticker.HasRoundStarted())
@@ -68,7 +68,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
/client/proc/cmd_admin_animalize(mob/M in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Make Simple Animal"
if(!SSticker.HasRoundStarted())
@@ -88,7 +88,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
/client/proc/makepAI(turf/T in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Make pAI"
set desc = "Specify a location to spawn a pAI device, then specify a key to play that pAI"
@@ -121,7 +121,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make pAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_alienize(mob/M in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Make Alien"
if(!SSticker.HasRoundStarted())
@@ -136,7 +136,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
alert("Invalid mob")
/client/proc/cmd_admin_slimeize(mob/M in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Make slime"
if(!SSticker.HasRoundStarted())
@@ -185,7 +185,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Powernets") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_grantfullaccess(mob/M in GLOB.mob_list)
- set category = "Debug"
+ set category = "Debug.Debug"
set name = "Grant Full Access"
if(!SSticker.HasRoundStarted())
@@ -228,7 +228,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
message_admins("[key_name_admin(usr)] has granted [M.key] full access.")
/client/proc/cmd_assume_direct_control(mob/M in GLOB.mob_list)
- set category = "Admin.Game"
+ set category = "Debug.Debug"
set name = "Assume direct control"
set desc = "Direct intervention"
@@ -249,7 +249,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
SSblackbox.record_feedback("tally", "admin_verb", 1, "Assume Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_give_direct_control(mob/M in GLOB.mob_list)
- set category = "Admin.Game"
+ set category = "Debug.Debug"
set name = "Give direct control"
if(!M)
@@ -275,7 +275,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_test_atmos_controllers()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Test Atmos Monitoring Consoles"
var/list/dat = list()
@@ -311,7 +311,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
popup.open()
/client/proc/cmd_admin_areatest()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Test Areas"
var/list/dat = list()
@@ -465,12 +465,12 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
/client/proc/cmd_admin_areatest_station()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Test Areas (STATION Z)"
cmd_admin_areatest(TRUE)
/client/proc/cmd_admin_areatest_all()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Test Areas (ALL)"
cmd_admin_areatest(FALSE)
@@ -529,9 +529,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
return dresscode
-/client/proc/startSinglo()
-
- set category = "Debug"
+/client/proc/start_singlo()
+ set category = "Debug.Debug"
set name = "Start Singularity"
set desc = "Sets up the singularity and all machines to get power flowing through the station"
@@ -692,11 +691,11 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
to_chat(usr, "[template.description]", confidential = TRUE)
/client/proc/fucky_wucky()
- set category = "Debug"
+ set category = "Event.Fun"
set name = "Fucky Wucky"
set desc = "Inform the players that the code monkeys at our headquarters are working very hard to fix this."
- if(!check_rights(R_DEBUG))
+ if(!check_rights(R_FUN))
return
remove_verb(/client/proc/fucky_wucky)
message_admins("[key_name_admin(src)] did a fucky wucky.")
@@ -750,7 +749,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
log_admin("[key_name(src)] pumped a random event.")
/client/proc/start_line_profiling()
- set category = "Profile"
+ set category = "Debug.Profile"
set name = "Start Line Profiling"
set desc = "Starts tracking line by line profiling for code lines that support it"
@@ -761,7 +760,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
log_admin("[key_name(src)] started line by line profiling.")
/client/proc/stop_line_profiling()
- set category = "Profile"
+ set category = "Debug.Profile"
set name = "Stops Line Profiling"
set desc = "Stops tracking line by line profiling for code lines that support it"
@@ -772,7 +771,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
log_admin("[key_name(src)] stopped line by line profiling.")
/client/proc/show_line_profiling()
- set category = "Profile"
+ set category = "Debug.Profile"
set name = "Show Line Profiling"
set desc = "Shows tracked profiling info from code lines that support it"
@@ -798,7 +797,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
/// A debug verb to check the sources of currently running timers
/client/proc/check_timer_sources()
- set category = "Debug"
+ set category = "Debug.Debug"
set name = "Check Timer Sources"
set desc = "Checks the sources of the running timers"
if (!check_rights(R_DEBUG))
diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm
index 7e89d542eb2b..469c0cda08f3 100644
--- a/code/modules/admin/verbs/diagnostics.dm
+++ b/code/modules/admin/verbs/diagnostics.dm
@@ -1,5 +1,5 @@
/client/proc/air_status(turf/target)
- set category = "Debug"
+ set category = "Debug.Debug"
set name = "Display Air Status"
if(!isturf(target))
diff --git a/code/modules/admin/verbs/fps.dm b/code/modules/admin/verbs/fps.dm
index a3e7c5f5df0b..8ac8d6b91d44 100644
--- a/code/modules/admin/verbs/fps.dm
+++ b/code/modules/admin/verbs/fps.dm
@@ -1,6 +1,6 @@
//replaces the old Ticklag verb, fps is easier to understand
/client/proc/set_server_fps()
- set category = "Debug"
+ set category = "Debug.Debug"
set name = "Set Server FPS"
set desc = "Sets game speed in frames-per-second. Can potentially break the game"
diff --git a/code/modules/admin/verbs/manipulate_organs.dm b/code/modules/admin/verbs/manipulate_organs.dm
index 0695777a6897..42873241b71b 100644
--- a/code/modules/admin/verbs/manipulate_organs.dm
+++ b/code/modules/admin/verbs/manipulate_organs.dm
@@ -1,6 +1,6 @@
/client/proc/manipulate_organs(mob/living/carbon/C in world)
set name = "Manipulate Organs"
- set category = "Debug"
+ set category = "Debug.Debug"
var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") as null|anything in list("add organ", "add implant", "drop organ/implant", "remove organ/implant", "cancel")
if (!operation)
return
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 305cce363c8d..8f1b69bc831d 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -19,42 +19,41 @@
//- Identify how hard it is to break into the area and where the weak points are
//- Check if the area has too much empty space. If so, make it smaller and replace the rest with maintenance tunnels.
-GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
+GLOBAL_LIST_INIT(admin_verbs_debug_extra, list(
/client/proc/camera_view, //-errorage
- /client/proc/sec_camera_report, //-errorage
- /client/proc/intercom_view, //-errorage
- /client/proc/air_status, //Air things
- /client/proc/Cell, //More air things
/client/proc/check_atmos,
/client/proc/check_wiring,
- /client/proc/count_objects_on_z_level,
- /client/proc/count_objects_all,
- /client/proc/cmd_assume_direct_control, //-errorage
- /client/proc/cmd_give_direct_control,
- /client/proc/startSinglo,
- /client/proc/set_server_fps, //allows you to set the ticklag.
- /client/proc/cmd_admin_grantfullaccess,
/client/proc/cmd_admin_areatest_all,
/client/proc/cmd_admin_areatest_station,
- #ifdef TESTING
- /client/proc/see_dirty_varedits,
- #endif
/client/proc/cmd_admin_test_atmos_controllers,
- /client/proc/cmd_admin_rejuvenate,
- /datum/admins/proc/show_traitor_panel,
- /client/proc/disable_communication,
/client/proc/cmd_show_at_list,
/client/proc/cmd_show_at_markers,
- /client/proc/manipulate_organs,
- /client/proc/start_line_profiling,
- /client/proc/stop_line_profiling,
- /client/proc/show_line_profiling,
+ /client/proc/count_objects_all,
+ /client/proc/count_objects_on_z_level,
/client/proc/create_mapping_job_icons,
/client/proc/debug_z_levels,
+ /client/proc/disable_communication,
+ /client/proc/export_map,
+ /client/proc/intercom_view, //-errorage
/client/proc/map_zones_info,
- /client/proc/export_map
+ /client/proc/sec_camera_report, //-errorage
+ #ifdef TESTING
+ /client/proc/see_dirty_varedits,
+ #endif
+ /client/proc/show_line_profiling,
+ /client/proc/start_line_profiling,
+ /client/proc/stop_line_profiling,
+ /client/proc/check_timer_sources,
+ /client/proc/air_status, //Air things
+ /client/proc/air_status_loc, //More air things
+ /client/proc/manipulate_organs,
+ /client/proc/set_server_fps, //allows you to set the ticklag.
+ /client/proc/start_singlo,
+ /client/proc/cmd_admin_grantfullaccess,
+ /client/proc/cmd_assume_direct_control, //-errorage
+ /client/proc/cmd_give_direct_control,
))
-GLOBAL_PROTECT(admin_verbs_debug_mapping)
+GLOBAL_PROTECT(admin_verbs_debug_extra)
/obj/effect/debugging/mapfix_marker
name = "map fix marker"
@@ -70,7 +69,7 @@ GLOBAL_PROTECT(admin_verbs_debug_mapping)
return 0
/client/proc/camera_view()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Camera Range Display"
var/on = FALSE
@@ -93,7 +92,7 @@ GLOBAL_PROTECT(admin_verbs_debug_mapping)
GLOBAL_LIST_EMPTY(dirty_vars)
/client/proc/see_dirty_varedits()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Dirty Varedits"
var/list/dat = list()
@@ -107,7 +106,7 @@ GLOBAL_LIST_EMPTY(dirty_vars)
#endif
/client/proc/sec_camera_report()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Camera Report"
if(!Master)
@@ -147,7 +146,7 @@ GLOBAL_LIST_EMPTY(dirty_vars)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/intercom_view()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Intercom Range Display"
var/static/intercom_range_display_status = FALSE
@@ -165,7 +164,7 @@ GLOBAL_LIST_EMPTY(dirty_vars)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Intercom Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_show_at_list()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Show roundstart AT list"
set desc = "Displays a list of active turfs coordinates at roundstart"
@@ -182,7 +181,7 @@ GLOBAL_LIST_EMPTY(dirty_vars)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Roundstart Active Turfs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_show_at_markers()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Show roundstart AT markers"
set desc = "Places a marker on all active-at-roundstart turfs"
@@ -207,18 +206,18 @@ GLOBAL_LIST_EMPTY(dirty_vars)
if(!check_rights(R_DEBUG))
return
remove_verb(src, /client/proc/enable_debug_verbs)
- add_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
+ add_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_extra))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/disable_debug_verbs()
set category = "Debug"
set name = "Debug verbs - Disable"
- remove_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
+ remove_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_extra))
add_verb(src, /client/proc/enable_debug_verbs)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/count_objects_on_z_level()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Count Objects On Level"
var/level = input("Which z-level?","Level?") as text|null
if(!level)
@@ -257,7 +256,7 @@ GLOBAL_LIST_EMPTY(dirty_vars)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Count Objects Zlevel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/count_objects_all()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Count Objects All"
var/type_text = input("Which type path?","") as text|null
@@ -280,7 +279,7 @@ GLOBAL_LIST_EMPTY(dirty_vars)
//This proc is intended to detect lag problems relating to communication procs
GLOBAL_VAR_INIT(say_disabled, FALSE)
/client/proc/disable_communication()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Disable all communication verbs"
GLOB.say_disabled = !GLOB.say_disabled
@@ -292,7 +291,7 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
//This generates the icon states for job starting location landmarks.
/client/proc/create_mapping_job_icons()
set name = "Generate job landmarks icons"
- set category = "Mapping"
+ set category = "Debug.Mapping"
var/icon/final = icon()
var/mob/living/carbon/human/dummy/D = new(locate(1,1,1)) //spawn on 1,1,1 so we don't have runtimes when items are deleted
D.setDir(SOUTH)
@@ -319,7 +318,7 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
/client/proc/debug_z_levels()
set name = "Debug Z-Levels"
- set category = "Mapping"
+ set category = "Debug.Mapping"
var/list/z_list = SSmapping.z_list
var/list/messages = list()
@@ -350,7 +349,7 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
/client/proc/map_zones_info()
set name = "Map-Zones Info"
- set category = "Mapping"
+ set category = "Debug.Mapping"
var/list/dat = list()
for(var/datum/map_zone/map_zone as anything in SSmapping.map_zones)
@@ -405,7 +404,7 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
#undef MAP_ZONE_INFO
/client/proc/export_map()
- set category = "Mapping"
+ set category = "Debug.Mapping"
set name = "Export Map"
var/z_level = input("Export Which Z-Level?", "Map Exporter", 2) as num
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index ac05c3afdd4f..028c9729131a 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -4,7 +4,7 @@
/client/proc/one_click_antag()
set name = "Create Antagonist"
set desc = "Auto-create an antagonist of your choice"
- set category = "Admin.Events"
+ set category = "Event"
if(holder)
holder.one_click_antag()
@@ -493,6 +493,16 @@
teamSpawned++
if(teamSpawned)
+ // guestbook
+ for(var/datum/mind/member in ert_team.members)
+ var/member_mob = member.current
+ for(var/datum/mind/other_member in ert_team.members)
+ // skip yourself
+ if(other_member.name == member.name)
+ continue
+ var/mob/living/carbon/human/other_member_mob = other_member.current
+ member.guestbook.add_guest(member_mob, other_member_mob, other_member_mob.real_name, other_member_mob.real_name, TRUE)
+
message_admins("[ertemplate.rename_team] has spawned with the mission: [ertemplate.mission]")
//Open the Armory doors
diff --git a/code/modules/admin/verbs/outpost.dm b/code/modules/admin/verbs/outpost.dm
index 358da03d2844..25632838f45f 100644
--- a/code/modules/admin/verbs/outpost.dm
+++ b/code/modules/admin/verbs/outpost.dm
@@ -19,7 +19,7 @@
/client/proc/spawn_outpost()
set name = "Spawn Outpost"
- set category = "Admin.Events"
+ set category = "Event.Spawning"
set desc = "Spawns the selected /datum/overmap/outpost subtype."
if(!holder)
diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm
index 131dd55ad82b..e3e5bc8c1ede 100644
--- a/code/modules/admin/verbs/playsound.dm
+++ b/code/modules/admin/verbs/playsound.dm
@@ -1,5 +1,5 @@
/client/proc/play_sound(S as sound)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Play Global Sound"
if(!check_rights(R_SOUND))
return
@@ -40,7 +40,7 @@
/client/proc/play_local_sound(S as sound)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Play Local Sound"
if(!check_rights(R_SOUND))
return
@@ -52,7 +52,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Local Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_direct_mob_sound(S as sound, mob/M)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Play Direct Mob Sound"
if(!check_rights(R_SOUND))
return
@@ -67,7 +67,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Direct Mob Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_web_sound()
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Play Internet Sound"
if(!check_rights(R_SOUND))
return
@@ -151,7 +151,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Internet Sound")
/client/proc/set_round_end_sound(S as sound)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Set Round End Sound"
if(!check_rights(R_SOUND))
return
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index ae621e17d479..f189fdf6106d 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -20,7 +20,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list)
- set category = "Admin.Events"
+ set category = "Event"
set name = "Subtle Message"
if(!ismob(M))
@@ -46,7 +46,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_headset_message(mob/M in GLOB.mob_list)
- set category = "Admin.Events"
+ set category = "Event"
set name = "Headset Message"
admin_headset_message(M)
@@ -92,7 +92,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Headset Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_world_narrate()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Global Narrate"
if(!check_rights(R_ADMIN))
@@ -108,7 +108,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_direct_narrate(mob/M)
- set category = "Admin.Events"
+ set category = "Event"
set name = "Direct Narrate"
if(!check_rights(R_ADMIN))
@@ -133,7 +133,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_local_narrate(atom/A)
- set category = "Admin.Events"
+ set category = "Event"
set name = "Local Narrate"
if(!check_rights(R_ADMIN))
@@ -295,7 +295,7 @@
return 1
/client/proc/cmd_admin_add_freeform_ai_law()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Add Custom AI law"
if(!check_rights(R_ADMIN))
@@ -318,7 +318,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_create_centcom_report()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Create Command Report"
if(!check_rights(R_FUN))
@@ -347,7 +347,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_change_command_name()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Change Command Name"
if(!check_rights(R_FUN))
@@ -370,7 +370,7 @@
admin_delete(A)
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Explosion"
if(!check_rights(R_ADMIN))
@@ -406,7 +406,7 @@
return
/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "EM Pulse"
if(!check_rights(R_ADMIN))
@@ -431,7 +431,7 @@
return
/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list)
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Gib"
if(!check_rights(R_ADMIN))
@@ -458,7 +458,7 @@
/client/proc/cmd_admin_gib_self()
set name = "Gibself"
- set category = "Fun"
+ set category = "Event.Fun"
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm == "Yes")
@@ -492,7 +492,7 @@
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Change View Range", "[view]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/admin_initiate_jump()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Initiate Jump"
if(!check_rights(R_ADMIN))
return
@@ -510,7 +510,7 @@
message_admins("[key_name_admin(usr)] admin-initiated a bluespace jump.")
/client/proc/admin_cancel_jump()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Cancel Jump"
if(!check_rights(0))
return
@@ -528,7 +528,7 @@
message_admins("[key_name_admin(usr)] admin-cancelled a bluespace jump.")
/client/proc/everyone_random()
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Make Everyone Random"
set desc = "Make everyone have a random appearance. You can only use this before rounds!"
@@ -576,7 +576,7 @@
/client/proc/admin_change_sec_level()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Set Security Level"
set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke"
@@ -593,7 +593,7 @@
/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list)
set name = "Toggle Nuke"
- set category = "Admin.Events"
+ set category = "Event"
set popup_menu = 0
if(!check_rights(R_DEBUG))
return
@@ -646,7 +646,7 @@
/client/proc/run_weather()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Run Weather"
set desc = "Triggers a weather on the z-level you choose."
@@ -669,7 +669,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Run Weather")
/client/proc/mass_zombie_infection()
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Mass Zombie Infection"
set desc = "Infects all humans with a latent organ that will zombify \
them on death."
@@ -690,7 +690,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Mass Zombie Infection")
/client/proc/mass_zombie_cure()
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Mass Zombie Cure"
set desc = "Removes the zombie infection from all humans, returning them to normal."
if(!check_rights(R_ADMIN))
@@ -708,7 +708,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Mass Zombie Cure")
/client/proc/polymorph_all()
- set category = "Fun"
+ set category = "Event.Fun"
set name = "Polymorph All"
set desc = "Applies the effects of the bolt of change to every single mob."
@@ -735,8 +735,6 @@
M.audible_message("...wabbajack...wabbajack...")
playsound(M.loc, 'sound/magic/staff_change.ogg', 50, TRUE, -1)
- wabbajack(M)
-
message_admins("Mass polymorph started by [who_did_it] is complete.")
@@ -819,7 +817,7 @@
/client/proc/spawn_ruin()
set name = "Spawn Planet/Ruin"
- set category = "Fun"
+ set category = "Event.Spawning"
if(!check_rights(R_ADMIN) || !check_rights(R_SPAWN))
return
@@ -880,7 +878,7 @@
/client/proc/smite(mob/living/target as mob)
set name = "Smite"
- set category = "Fun"
+ set category = "Event.Fun"
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
return
@@ -1068,8 +1066,8 @@
REMOVE_TRAIT(D,chosen_trait,source)
/datum/admins/proc/gift(mob/living/carbon/human/target as mob, object as text)
- set name = "Gift"
- set category = "Fun"
+ set name = "Gift a mob"
+ set category = "Event.Spawning"
set desc = "Give a mob an item directly."
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
return
diff --git a/code/modules/admin/verbs/selectequipment.dm b/code/modules/admin/verbs/selectequipment.dm
index 9bc6ab3dcea9..03a560d5e712 100644
--- a/code/modules/admin/verbs/selectequipment.dm
+++ b/code/modules/admin/verbs/selectequipment.dm
@@ -1,5 +1,5 @@
/client/proc/cmd_select_equipment(mob/target in GLOB.mob_list)
- set category = "Admin.Events"
+ set category = "Event"
set name = "Select equipment"
diff --git a/code/modules/admin/verbs/shuttlepanel.dm b/code/modules/admin/verbs/shuttlepanel.dm
index b4e374f41cb8..bb3bd11b7f42 100644
--- a/code/modules/admin/verbs/shuttlepanel.dm
+++ b/code/modules/admin/verbs/shuttlepanel.dm
@@ -1,5 +1,5 @@
/datum/admins/proc/open_shuttlepanel()
- set category = "Admin.Events"
+ set category = "Event"
set name = "Shuttle Manipulator"
set desc = "Opens the shuttle manipulator UI."
@@ -8,7 +8,6 @@
SSshuttle.ui_interact(usr)
-
/obj/docking_port/mobile/proc/admin_fly_shuttle(mob/user)
var/list/options = list()
diff --git a/code/modules/admin/verbs/spawnobjasmob.dm b/code/modules/admin/verbs/spawnobjasmob.dm
index f840516d49f1..e787ecfde664 100644
--- a/code/modules/admin/verbs/spawnobjasmob.dm
+++ b/code/modules/admin/verbs/spawnobjasmob.dm
@@ -1,7 +1,7 @@
/datum/admins/proc/spawn_objasmob(object as text)
- set category = "Debug"
- set desc = "(obj path) Spawn object-mob"
- set name = "Spawn object-mob"
+ set category = "Event.Spawning"
+ set desc = "(obj path) Spawn object-mob from Object"
+ set name = "Spawn Living Mob"
if(!check_rights(R_SPAWN))
return
diff --git a/code/modules/admin/view_variables/get_variables.dm b/code/modules/admin/view_variables/get_variables.dm
index 3f90002edc05..75892a87e2c1 100644
--- a/code/modules/admin/view_variables/get_variables.dm
+++ b/code/modules/admin/view_variables/get_variables.dm
@@ -62,6 +62,7 @@
VV_DATUM_TYPE,
VV_TYPE,
VV_FILE,
+ VV_COLOR,
VV_NEW_ATOM,
VV_NEW_DATUM,
VV_NEW_TYPE,
@@ -190,6 +191,12 @@
.["class"] = null
return
+ if(VV_COLOR)
+ .["value"] = input("Pick color:", "Color", current_value) as null|color
+ if(.["value"] == null)
+ .["class"] = null
+ return
+
if(VV_ICON)
.["value"] = input("Pick icon:", "Icon") as null|icon
if(.["value"] == null)
diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm
index 537afd8d4ff5..4b4ca9bd96ec 100644
--- a/code/modules/antagonists/_common/antag_spawner.dm
+++ b/code/modules/antagonists/_common/antag_spawner.dm
@@ -292,7 +292,7 @@
/obj/item/antag_spawner/syndi_borer
name = "syndicate brain-slug container"
desc = "Releases a modified cortical borer to assist the user."
- icon = 'icons/obj/chemical.dmi' //Temporary? //The most permanent type of solution lol
+ icon = 'icons/obj/chemical/hypovial.dmi'
icon_state = "hypoviallarge-b"
var/polling = FALSE
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
index 9a5b95d21184..5bce8014babe 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
@@ -369,21 +369,10 @@
to_chat(user, "You send the message to your target.")
log_directed_talk(user, L, message, LOG_SAY, "abductor whisper")
-
-/obj/item/firing_pin/abductor
- name = "alien firing pin"
- icon_state = "firing_pin_ayy"
- desc = "This firing pin is slimy and warm; you can swear you feel it constantly trying to mentally probe you."
- fail_message = "Firing error, please contact Command."
-
-/obj/item/firing_pin/abductor/pin_auth(mob/living/user)
- . = isabductor(user)
-
/obj/item/gun/energy/alien
name = "alien pistol"
desc = "A complicated gun that fires bursts of high-intensity radiation."
ammo_type = list(/obj/item/ammo_casing/energy/declone)
- pin = /obj/item/firing_pin/abductor
icon_state = "alienpistol"
item_state = "alienpistol"
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
@@ -395,7 +384,7 @@
ammo_type = list(/obj/item/ammo_casing/energy/shrink)
item_state = "shrink_ray"
icon_state = "shrink_ray"
- fire_delay = 30
+ fire_delay = 3 SECONDS
selfcharge = 1//shot costs 200 energy, has a max capacity of 1000 for 5 shots. self charge returns 25 energy every couple ticks, so about 1 shot charged every 12~ seconds
trigger_guard = TRIGGER_GUARD_ALLOW_ALL// variable-size trigger, get it? (abductors need this to be set so the gun is usable for them)
@@ -588,9 +577,11 @@ Congratulations! You are now trained for invasive xenobiology research!"}
if(!C.handcuffed)
if(C.canBeHandcuffed())
playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
- C.visible_message("[user] begins restraining [C] with [src]!", \
- "[user] begins shaping an energy field around your hands!")
- if(do_mob(user, C, time_to_cuff) && C.canBeHandcuffed())
+ C.visible_message(
+ "[user] begins restraining [C] with [src]!", \
+ "[user] begins shaping an energy field around your hands!"
+ )
+ if(do_after(user, time_to_cuff, C) && C.canBeHandcuffed())
if(!C.handcuffed)
C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(C))
C.update_handcuffed()
diff --git a/code/modules/antagonists/blood_contract/blood_contract.dm b/code/modules/antagonists/blood_contract/blood_contract.dm
index 01039a77623d..edd8aba60422 100644
--- a/code/modules/antagonists/blood_contract/blood_contract.dm
+++ b/code/modules/antagonists/blood_contract/blood_contract.dm
@@ -26,10 +26,10 @@
H.add_atom_colour("#FF0000", ADMIN_COLOUR_PRIORITY)
- var/obj/effect/mine/pickup/bloodbath/B = new(H)
+ var/obj/item/mine/pressure/pickup/bloodbath/B = new(H)
B.duration = duration
- INVOKE_ASYNC(B, TYPE_PROC_REF(/obj/effect/mine/pickup/bloodbath, mineEffect), H) //could use moving out from the mine
+ INVOKE_ASYNC(B, TYPE_PROC_REF(/obj/item/mine/pressure/pickup/bloodbath, mine_effect), H) //could use moving out from the mine
for(var/mob/living/carbon/human/P in GLOB.player_list)
if(P == H)
diff --git a/code/modules/antagonists/borer/borer.dm b/code/modules/antagonists/borer/borer.dm
index d4af47670412..92a1e728dc8b 100644
--- a/code/modules/antagonists/borer/borer.dm
+++ b/code/modules/antagonists/borer/borer.dm
@@ -422,7 +422,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 3)
"[src] tears [H.ears] off of your ear!") //coz, you know, they go in the ear holes
to_chat(src, "You slither up [H] and begin probing at their ear canal...")
- if(!do_mob(src, H, 30))
+ if(!do_after(src, 3 SECONDS, H))
to_chat(src, "As [H] moves away, you are dislodged and fall to the ground.")
return
@@ -1053,7 +1053,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 3)
/datum/action/innate/borer/make_chems
name = "Secrete Chemicals"
desc = "Push some chemicals into your host's bloodstream."
- icon_icon = 'icons/obj/chemical.dmi'
+ icon_icon = 'icons/obj/chemical/chem_machines.dmi'
button_icon_state = "minidispenser"
/datum/action/innate/borer/make_chems/Activate()
diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm
index 33e0a8f75d48..a54cdc4cd09c 100644
--- a/code/modules/antagonists/changeling/powers/absorb.dm
+++ b/code/modules/antagonists/changeling/powers/absorb.dm
@@ -43,7 +43,7 @@
target.take_overall_damage(40)
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("Absorb DNA", "[i]"))
- if(!do_mob(user, target, 150))
+ if(!do_after(user, 15 SECONDS, target))
to_chat(user, "Our absorption of [target] has been interrupted!")
changeling.isabsorbing = 0
return
diff --git a/code/modules/antagonists/changeling/powers/linglink.dm b/code/modules/antagonists/changeling/powers/linglink.dm
index a0008dec26de..f158499d8b0f 100644
--- a/code/modules/antagonists/changeling/powers/linglink.dm
+++ b/code/modules/antagonists/changeling/powers/linglink.dm
@@ -58,7 +58,7 @@
target.say("[MODE_TOKEN_CHANGELING] AAAAARRRRGGGGGHHHHH!!")
to_chat(target, "You can now communicate in the changeling hivemind, say \"[MODE_TOKEN_CHANGELING] message\" to communicate!")
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]", "[i]"))
- if(!do_mob(user, target, 20))
+ if(!do_after(user, 2 SECONDS, target))
to_chat(user, "Our link with [target] has ended!")
changeling.islinking = 0
target.mind.linglink = 0
@@ -67,7 +67,7 @@
to_chat(user, "We must keep holding on to [target] to sustain the link. ")
while(user.pulling && user.grab_state >= GRAB_NECK)
target.reagents.add_reagent(/datum/reagent/medicine/salbutamol, 0.5) // So they don't choke to death while you interrogate them
- do_mob(user, target, 100, TRUE)
+ do_after(user, 10 SECONDS, target, hidden = TRUE)
changeling.islinking = 0
target.mind.linglink = 0
diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm
index d77c4ef6ff3c..28a4ae06d16b 100644
--- a/code/modules/antagonists/changeling/powers/mutations.dm
+++ b/code/modules/antagonists/changeling/powers/mutations.dm
@@ -211,185 +211,6 @@
if(can_drop)
new /obj/item/melee/synthetic_arm_blade(get_turf(user))
-/***************************************\
-|***********COMBAT TENTACLES*************|
-\***************************************/
-
-/datum/action/changeling/weapon/tentacle
- name = "Tentacle"
- desc = "We ready a tentacle to grab items or victims with. Costs 10 chemicals."
- helptext = "We can use it once to retrieve a distant item. If used on living creatures, the effect depends on the intent: \
- Help will simply drag them closer, Disarm will grab whatever they're holding instead of them, Grab will put the victim in our hold after catching it, \
- and Harm will pull it in and stab it if we're also holding a sharp weapon. Cannot be used while in lesser form."
- button_icon_state = "tentacle"
- chemical_cost = 10
- dna_cost = 2
- req_human = 1
- weapon_type = /obj/item/gun/magic/tentacle
- weapon_name_simple = "tentacle"
- silent = TRUE
-
-/obj/item/gun/magic/tentacle
- name = "tentacle"
- desc = "A fleshy tentacle that can stretch out and grab things or people."
- icon = 'icons/obj/changeling_items.dmi'
- icon_state = "tentacle"
- item_state = "tentacle"
- lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
- item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL | NOBLUDGEON
- flags_1 = NONE
- w_class = WEIGHT_CLASS_HUGE
- slot_flags = NONE
- ammo_type = /obj/item/ammo_casing/magic/tentacle
- fire_sound = 'sound/effects/splat.ogg'
- force = 0
- max_charges = 1
- fire_delay = 1
- throwforce = 0 //Just to be on the safe side
- throw_range = 0
- throw_speed = 0
-
-/obj/item/gun/magic/tentacle/Initialize(mapload, silent)
- . = ..()
- ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
- if(ismob(loc))
- if(!silent)
- loc.visible_message("[loc.name]\'s arm starts stretching inhumanly!", "Our arm twists and mutates, transforming it into a tentacle.", "You hear organic matter ripping and tearing!")
- else
- to_chat(loc, "You prepare to extend a tentacle.")
-
-
-/obj/item/gun/magic/tentacle/shoot_with_empty_chamber(mob/living/user as mob|obj)
- to_chat(user, "The [name] is not ready yet.")
-
-/obj/item/gun/magic/tentacle/process_fire()
- . = ..()
- if(charges == 0)
- qdel(src)
-
-/obj/item/ammo_casing/magic/tentacle
- name = "tentacle"
- desc = "A tentacle."
- projectile_type = /obj/projectile/tentacle
- caliber = "tentacle"
- icon_state = "arrow"
- firing_effect_type = null
- var/obj/item/gun/magic/tentacle/gun //the item that shot it
-
-/obj/item/ammo_casing/magic/tentacle/Initialize()
- gun = loc
- . = ..()
-
-/obj/item/ammo_casing/magic/tentacle/Destroy()
- gun = null
- return ..()
-
-/obj/projectile/tentacle
- name = "tentacle"
- icon_state = "tentacle_end"
- pass_flags = PASSTABLE
- damage = 0
- damage_type = BRUTE
- range = 8
- hitsound = 'sound/weapons/thudswoosh.ogg'
- var/chain
- var/obj/item/ammo_casing/magic/tentacle/source //the item that shot it
-
-/obj/projectile/tentacle/Initialize()
- source = loc
- . = ..()
-
-/obj/projectile/tentacle/fire(setAngle)
- if(firer)
- chain = firer.Beam(src, icon_state = "tentacle", emissive = FALSE)
- ..()
-
-/obj/projectile/tentacle/proc/reset_throw(mob/living/carbon/human/H)
- if(H.throw_mode)
- H.throw_mode_off() //Don't annoy the changeling if he doesn't catch the item
-
-/obj/projectile/tentacle/proc/tentacle_grab(mob/living/carbon/human/H, mob/living/carbon/C)
- if(H.Adjacent(C))
- if(H.get_active_held_item() && !H.get_inactive_held_item())
- H.swap_hand()
- if(H.get_active_held_item())
- return
- C.grabbedby(H)
- C.grippedby(H, instant = TRUE) //instant aggro grab
-
-/obj/projectile/tentacle/proc/tentacle_stab(mob/living/carbon/human/H, mob/living/carbon/C)
- if(H.Adjacent(C))
- for(var/obj/item/I in H.held_items)
- if(I.get_sharpness())
- C.visible_message("[H] impales [C] with [H.p_their()] [I.name]!", "[H] impales you with [H.p_their()] [I.name]!")
- C.apply_damage(I.force, BRUTE, BODY_ZONE_CHEST)
- H.do_item_attack_animation(C, used_item = I)
- H.add_mob_blood(C)
- playsound(get_turf(H),I.hitsound,75,TRUE)
- return
-
-/obj/projectile/tentacle/on_hit(atom/target, blocked = FALSE)
- var/mob/living/carbon/human/H = firer
- if(blocked >= 100)
- return BULLET_ACT_BLOCK
- if(isitem(target))
- var/obj/item/I = target
- if(!I.anchored)
- to_chat(firer, "You pull [I] towards yourself.")
- H.throw_mode_on()
- I.throw_at(H, 10, 2)
- . = BULLET_ACT_HIT
-
- else if(isliving(target))
- var/mob/living/L = target
- if(!L.anchored && !L.throwing)//avoid double hits
- if(iscarbon(L))
- var/mob/living/carbon/C = L
- var/firer_intent = INTENT_HARM
- var/mob/M = firer
- if(istype(M))
- firer_intent = M.a_intent
- switch(firer_intent)
- if(INTENT_HELP)
- C.visible_message("[L] is pulled by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
- C.throw_at(get_step_towards(H,C), 8, 2)
- return BULLET_ACT_HIT
-
- if(INTENT_DISARM)
- var/obj/item/I = C.get_active_held_item()
- if(I)
- if(C.dropItemToGround(I))
- C.visible_message("[I] is yanked off [C]'s hand by [src]!","A tentacle pulls [I] away from you!")
- on_hit(I) //grab the item as if you had hit it directly with the tentacle
- return BULLET_ACT_HIT
- else
- to_chat(firer, "You can't seem to pry [I] off [C]'s hands!")
- return BULLET_ACT_BLOCK
- else
- to_chat(firer, "[C] has nothing in hand to disarm!")
- return BULLET_ACT_HIT
-
- if(INTENT_GRAB)
- C.visible_message("[L] is grabbed by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
- C.throw_at(get_step_towards(H,C), 8, 2, H, TRUE, TRUE, callback=CALLBACK(src, PROC_REF(tentacle_grab), H, C))
- return BULLET_ACT_HIT
-
- if(INTENT_HARM)
- C.visible_message("[L] is thrown towards [H] by a tentacle!","A tentacle grabs you and throws you towards [H]!")
- C.throw_at(get_step_towards(H,C), 8, 2, H, TRUE, TRUE, callback=CALLBACK(src, PROC_REF(tentacle_stab), H, C))
- return BULLET_ACT_HIT
- else
- L.visible_message("[L] is pulled by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
- L.throw_at(get_step_towards(H,L), 8, 2)
- . = BULLET_ACT_HIT
-
-/obj/projectile/tentacle/Destroy()
- qdel(chain)
- source = null
- return ..()
-
-
/***************************************\
|****************SHIELD*****************|
\***************************************/
@@ -488,6 +309,8 @@
name = "flesh mass"
icon_state = "lingspacehelmet"
desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front."
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
item_flags = DROPDEL
clothing_flags = STOPSPRESSUREDAMAGE
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm
index 003abfd42991..c9232857a547 100644
--- a/code/modules/antagonists/cult/blood_magic.dm
+++ b/code/modules/antagonists/cult/blood_magic.dm
@@ -535,7 +535,7 @@
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
C.visible_message("[user] begins restraining [C] with dark magic!", \
"[user] begins shaping dark magic shackles around your wrists!")
- if(do_mob(user, C, 30))
+ if(do_after(user, 3 SECONDS, C))
if(!C.handcuffed)
C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/cult/used(C))
C.update_handcuffed()
@@ -601,7 +601,7 @@
var/quantity = candidate.amount
if(candidate.use(quantity))
uses --
- new /obj/item/stack/sheet/runed_metal(T,quantity)
+ new /obj/item/stack/sheet/mineral/hidden/hellstone(T,quantity)
to_chat(user, "A dark cloud emanates from you hand and swirls around the plasteel, transforming it into runed metal!")
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
else if(istype(target,/mob/living/silicon/robot))
@@ -812,7 +812,7 @@
/obj/item/melee/blood_magic/manipulator/attack_self(mob/living/user)
if(iscultist(user))
- var/list/options = list("Blood Spear (150)", "Blood Bolt Barrage (300)", "Blood Beam (500)")
+ var/list/options = list("Blood Spear (150)", "Blood Beam (500)")
var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options
if(!choice)
to_chat(user, "You decide against conducting a greater blood rite.")
@@ -835,18 +835,6 @@
user.visible_message(
"A [rite.name] appears at [user]'s feet!", \
"A [rite.name] materializes at your feet.")
- if("Blood Bolt Barrage (300)")
- if(uses < BLOOD_BARRAGE_COST)
- to_chat(user, "You need [BLOOD_BARRAGE_COST] charges to perform this rite.")
- else
- var/obj/rite = new /obj/item/gun/ballistic/rifle/illestren/enchanted/arcane_barrage/blood()
- uses -= BLOOD_BARRAGE_COST
- qdel(src)
- if(user.put_in_hands(rite))
- to_chat(user, "Your hands glow with power!")
- else
- to_chat(user, "You need a free hand for this rite!")
- qdel(rite)
if("Blood Beam (500)")
if(uses < BLOOD_BEAM_COST)
to_chat(user, "You need [BLOOD_BEAM_COST] charges to perform this rite.")
diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm
index e7f37d37f4a6..406c51956035 100644
--- a/code/modules/antagonists/cult/cult.dm
+++ b/code/modules/antagonists/cult/cult.dm
@@ -61,7 +61,7 @@
var/mob/living/current = owner.current
add_objectives()
if(give_equipment)
- equip_cultist(TRUE)
+ equip_cultist()
SSticker.mode.cult += owner // Only add after they've been given objectives
current.log_message("has been converted to the cult of Nar'Sie!", LOG_ATTACK, color="#960000")
@@ -69,13 +69,11 @@
current.client.images += cult_team.blood_target_image
-/datum/antagonist/cult/proc/equip_cultist(metal=TRUE)
+/datum/antagonist/cult/proc/equip_cultist()
var/mob/living/carbon/H = owner.current
if(!istype(H))
return
. += cult_give_item(/obj/item/melee/cultblade/dagger, H)
- if(metal)
- . += cult_give_item(/obj/item/stack/sheet/runed_metal/ten, H)
to_chat(owner, "These will help you jumpstart a cult of your own in this sector. Use them well, and remember - you are not the only one.")
@@ -163,21 +161,16 @@
/datum/antagonist/cult/get_admin_commands()
. = ..()
.["Dagger"] = CALLBACK(src, PROC_REF(admin_give_dagger))
- .["Dagger and Metal"] = CALLBACK(src, PROC_REF(admin_give_metal))
- .["Remove Dagger and Metal"] = CALLBACK(src, PROC_REF(admin_take_all))
+ .["Metal"] = CALLBACK(src, PROC_REF(admin_take_all))
/datum/antagonist/cult/proc/admin_give_dagger(mob/admin)
- if(!equip_cultist(metal=FALSE))
+ if(!equip_cultist())
to_chat(admin, "Spawning dagger failed!")
-/datum/antagonist/cult/proc/admin_give_metal(mob/admin)
- if (!equip_cultist(metal=TRUE))
- to_chat(admin, "Spawning runed metal failed!")
-
/datum/antagonist/cult/proc/admin_take_all(mob/admin)
var/mob/living/current = owner.current
for(var/o in current.GetAllContents())
- if(istype(o, /obj/item/melee/cultblade/dagger) || istype(o, /obj/item/stack/sheet/runed_metal))
+ if(istype(o, /obj/item/melee/cultblade/dagger))
qdel(o)
/datum/antagonist/cult/master
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index 6eed283b02f1..53d17bf325aa 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -703,47 +703,6 @@
L.visible_message("An unseen force pulls the blood spear from [L]'s hands!")
spear.throw_at(owner, 10, 2, owner)
-
-/obj/item/gun/ballistic/rifle/illestren/enchanted/arcane_barrage/blood
- name = "blood bolt barrage"
- desc = "Blood for blood."
- color = "#ff0000"
- guns_left = 24
- mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage/blood
- fire_sound = 'sound/magic/wand_teleport.ogg'
-
-
-/obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage/blood
- ammo_type = /obj/item/ammo_casing/magic/arcane_barrage/blood
-
-/obj/item/ammo_casing/magic/arcane_barrage/blood
- projectile_type = /obj/projectile/magic/arcane_barrage/blood
- firing_effect_type = /obj/effect/temp_visual/cult/sparks
-
-/obj/projectile/magic/arcane_barrage/blood
- name = "blood bolt"
- icon_state = "mini_leaper"
- nondirectional_sprite = TRUE
- damage_type = BRUTE
- impact_effect_type = /obj/effect/temp_visual/dir_setting/bloodsplatter
-
-/obj/projectile/magic/arcane_barrage/blood/Bump(atom/target)
- var/turf/T = get_turf(target)
- playsound(T, 'sound/effects/splat.ogg', 50, TRUE)
- if(iscultist(target))
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- if(H.stat != DEAD)
- H.reagents.add_reagent(/datum/reagent/fuel/unholywater, 4)
- if(isshade(target) || isconstruct(target))
- var/mob/living/simple_animal/M = target
- if(M.health+5 < M.maxHealth)
- M.adjustHealth(-5)
- new /obj/effect/temp_visual/cult/sparks(T)
- qdel(src)
- else
- ..()
-
/obj/item/blood_beam
name = "\improper magical aura"
desc = "Sinister looking aura that distorts the flow of reality around it."
diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm
index 66526d96a34f..60816a90d45d 100644
--- a/code/modules/antagonists/cult/cult_structures.dm
+++ b/code/modules/antagonists/cult/cult_structures.dm
@@ -5,7 +5,7 @@
light_power = 2
var/cooldowntime = 0
break_sound = 'sound/hallucinations/veryfar_noise.ogg'
- debris = list(/obj/item/stack/sheet/runed_metal = 1)
+ debris = list(/obj/item/stack/sheet/mineral/hidden/hellstone = 1)
/obj/structure/destructible/cult/proc/conceal() //for spells that hide cult presence
density = FALSE
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index 7355880e6da1..5058dc73f081 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -61,10 +61,6 @@ Runes can either be invoked by one's self or with many different cultists. Each
if(do_after(user, 15, target = src))
to_chat(user, "You carefully erase the [lowertext(cultist_name)] rune.")
qdel(src)
- else if(istype(I, /obj/item/nullrod))
- user.say("BEGONE FOUL MAGIKS!!", forced = "nullrod")
- to_chat(user, "You disrupt the magic of [src] with [I].")
- qdel(src)
/obj/effect/rune/attack_hand(mob/living/user)
. = ..()
@@ -502,9 +498,6 @@ structure_check() searches for nearby cultist structures required for the invoca
if(do_after(user, 50, target = src)) //Prevents accidental erasures.
log_game("Summon Narsie rune erased by [key_name(user)] with [I.name]")
message_admins("[ADMIN_LOOKUPFLW(user)] erased a Narsie rune with [I.name]")
- else if(istype(I, /obj/item/nullrod)) //Begone foul magiks. You cannot hinder me.
- log_game("Summon Narsie rune erased by [key_name(user)] using a null rod")
- message_admins("[ADMIN_LOOKUPFLW(user)] erased a Narsie rune with a null rod")
else
..()
diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm
index 9b9ba7c4d69d..ace534f94dfa 100644
--- a/code/modules/antagonists/devil/devil.dm
+++ b/code/modules/antagonists/devil/devil.dm
@@ -24,13 +24,6 @@ GLOBAL_LIST_INIT(lawlorify, list (
OBLIGATION_SAYNAME = "He will always chant his name upon killing someone.",
OBLIGATION_ANNOUNCEKILL = "This devil always loudly announces his kills for the world to hear.",
OBLIGATION_ANSWERTONAME = "This devil always responds to his truename.",
- BANE_SILVER = "Silver seems to gravely injure this devil.",
- BANE_SALT = "Throwing salt at this devil will hinder his ability to use infernal powers temporarily.",
- BANE_LIGHT = "Bright flashes will disorient the devil, likely causing him to flee.",
- BANE_IRON = "Cold iron will slowly injure him, until he can purge it from his system.",
- BANE_WHITECLOTHES = "Wearing clean white clothing will help ward off this devil.",
- BANE_HARVEST = "Presenting the labors of a harvest will disrupt the devil.",
- BANE_TOOLBOX = "That which holds the means of creation also holds the means of the devil's undoing.",
BAN_HURTWOMAN = "This devil seems to prefer hunting men.",
BAN_CHAPEL = "This devil avoids holy ground.",
BAN_HURTPRIEST = "The annointed clergy appear to be immune to his powers.",
@@ -62,13 +55,6 @@ GLOBAL_LIST_INIT(lawlorify, list (
BAN_STRIKEUNCONSCIOUS = "You must never strike an unconscious person.",
BAN_HURTlizard = "You must never harm a lizardman outside of self defense.",
BAN_HURTANIMAL = "You must never harm a non-sentient creature or robot outside of self defense.",
- BANE_SILVER = "Silver, in all of its forms shall be your downfall.",
- BANE_SALT = "Salt will disrupt your magical abilities.",
- BANE_LIGHT = "Blinding lights will prevent you from using offensive powers for a time.",
- BANE_IRON = "Cold wrought iron shall act as poison to you.",
- BANE_WHITECLOTHES = "Those clad in pristine white garments will strike you true.",
- BANE_HARVEST = "The fruits of the harvest shall be your downfall.",
- BANE_TOOLBOX = "Toolboxes are bad news for you, for some reason.",
BANISH_WATER = "If your corpse is filled with holy water, you will be unable to resurrect.",
BANISH_COFFIN = "If your corpse is in a coffin, you will be unable to resurrect.",
BANISH_FORMALDYHIDE = "If your corpse is embalmed, you will be unable to resurrect.",
@@ -94,7 +80,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
show_to_ghosts = TRUE
var/obligation
var/ban
- var/bane
var/banish
var/truename
var/list/datum/mind/soulsOwned = new
@@ -171,9 +156,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/proc/randomdevilban()
return pick(BAN_HURTWOMAN, BAN_CHAPEL, BAN_HURTPRIEST, BAN_AVOIDWATER, BAN_STRIKEUNCONSCIOUS, BAN_HURTLIZARD, BAN_HURTANIMAL)
-/proc/randomdevilbane()
- return pick(BANE_SALT, BANE_LIGHT, BANE_IRON, BANE_WHITECLOTHES, BANE_SILVER, BANE_HARVEST, BANE_TOOLBOX)
-
/proc/randomdevilbanish()
return pick(BANISH_WATER, BANISH_COFFIN, BANISH_FORMALDYHIDE, BANISH_RUNES, BANISH_CANDLES, BANISH_DESTRUCTION, BANISH_FUNERAL_GARB)
@@ -489,7 +471,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
to_chat(owner.current, "However, your infernal form is not without weaknesses.")
to_chat(owner.current, "You may not use violence to coerce someone into selling their soul.")
to_chat(owner.current, "You may not directly and knowingly physically harm a devil, other than yourself.")
- to_chat(owner.current, GLOB.lawlorify[LAW][bane])
to_chat(owner.current, GLOB.lawlorify[LAW][ban])
to_chat(owner.current, GLOB.lawlorify[LAW][obligation])
to_chat(owner.current, GLOB.lawlorify[LAW][banish])
@@ -499,12 +480,11 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/antagonist/devil/on_gain()
truename = randomDevilName()
ban = randomdevilban()
- bane = randomdevilbane()
obligation = randomdevilobligation()
banish = randomdevilbanish()
GLOB.allDevils[lowertext(truename)] = src
- antag_memory += "Your devilic true name is [truename] [GLOB.lawlorify[LAW][ban]] You may not use violence to coerce someone into selling their soul. You may not directly and knowingly physically harm a devil, other than yourself. [GLOB.lawlorify[LAW][bane]] [GLOB.lawlorify[LAW][obligation]] [GLOB.lawlorify[LAW][banish]] "
+ antag_memory += "Your devilic true name is [truename] [GLOB.lawlorify[LAW][ban]] You may not use violence to coerce someone into selling their soul. You may not directly and knowingly physically harm a devil, other than yourself. [GLOB.lawlorify[LAW][obligation]] [GLOB.lawlorify[LAW][banish]] "
if(issilicon(owner.current))
var/mob/living/silicon/robot_devil = owner.current
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
@@ -541,7 +521,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
parts += "The devil's true name is: [truename]"
parts += "The devil's bans were:"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][ban]]"
- parts += "[FOURSPACES][GLOB.lawlorify[LORE][bane]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][obligation]]"
parts += "[FOURSPACES][GLOB.lawlorify[LORE][banish]]"
return parts.Join(" ")
@@ -556,7 +535,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
//A simple super light weight datum for the codex gigas.
/datum/fakeDevil
var/truename
- var/bane
var/obligation
var/ban
var/banish
@@ -564,7 +542,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/fakeDevil/New(name = randomDevilName())
truename = name
- bane = randomdevilbane()
obligation = randomdevilobligation()
ban = randomdevilban()
banish = randomdevilbanish()
diff --git a/code/modules/antagonists/devil/devil_helpers.dm b/code/modules/antagonists/devil/devil_helpers.dm
deleted file mode 100644
index 3be8320a001f..000000000000
--- a/code/modules/antagonists/devil/devil_helpers.dm
+++ /dev/null
@@ -1,37 +0,0 @@
-/mob/living/proc/check_devil_bane_multiplier(obj/item/weapon, mob/living/attacker)
- var/datum/antagonist/devil/devilInfo = mind.has_antag_datum(/datum/antagonist/devil)
- switch(devilInfo.bane)
- if(BANE_WHITECLOTHES)
- if(ishuman(attacker))
- var/mob/living/carbon/human/H = attacker
- if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under))
- var/obj/item/clothing/under/U = H.w_uniform
- var/static/list/whiteness = list (
- /obj/item/clothing/under/color/white = 2,
- /obj/item/clothing/under/rank/civilian/bartender = 1,
- /obj/item/clothing/under/rank/civilian/chef = 1,
- /obj/item/clothing/under/rank/engineering/chief_engineer = 1,
- /obj/item/clothing/under/rank/rnd/scientist = 1,
- /obj/item/clothing/under/rank/medical/chemist = 1,
- /obj/item/clothing/under/rank/medical/chief_medical_officer = 1,
- /obj/item/clothing/under/rank/medical/geneticist = 1,
- /obj/item/clothing/under/rank/medical/virologist = 1,
- /obj/item/clothing/under/rank/medical/doctor/nurse = 1,
- /obj/item/clothing/under/rank/medical/doctor = 1,
- /obj/item/clothing/under/rank/security/detective = 1,
- /obj/item/clothing/under/suit/white = 0.5,
- )
- if(U && whiteness[U.type])
- src.visible_message("[src] seems to have been harmed by the purity of [attacker]'s clothes.", "Unsullied white clothing is disrupting your form.")
- return whiteness[U.type] + 1
- if(BANE_TOOLBOX)
- if(istype(weapon, /obj/item/storage/toolbox))
- src.visible_message("The [weapon] seems unusually robust this time.", "The [weapon] is your unmaking!")
- return 2.5 // Will take four hits with a normal toolbox to crit.
- if(BANE_HARVEST)
- if(istype(weapon, /obj/item/reagent_containers/food/snacks/grown/))
- visible_message("The spirits of the harvest aid in the exorcism.", "The harvest spirits are harming you.")
- Paralyze(40)
- qdel(weapon)
- return 2
- return 1
diff --git a/code/modules/antagonists/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm
index 0faab8e003cf..4703f95263f7 100644
--- a/code/modules/antagonists/devil/true_devil/_true_devil.dm
+++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm
@@ -113,11 +113,6 @@
/mob/living/carbon/true_devil/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null)
return 666
-/mob/living/carbon/true_devil/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
- if(mind && has_bane(BANE_LIGHT))
- mind.disrupt_spells(-500)
- return ..() //flashes don't stop devils UNLESS it's their bane.
-
/mob/living/carbon/true_devil/soundbang_act()
return 0
@@ -126,8 +121,7 @@
/mob/living/carbon/true_devil/attacked_by(obj/item/I, mob/living/user, def_zone)
- var/weakness = check_weakness(I, user)
- apply_damage(I.force * weakness, I.damtype, def_zone)
+ apply_damage(I.force, I.damtype, def_zone)
var/message_verb = ""
if(I.attack_verb && I.attack_verb.len)
message_verb = "[pick(I.attack_verb)]"
@@ -213,8 +207,6 @@
b_loss = 150
if (EXPLODE_LIGHT)
b_loss = 30
- if(has_bane(BANE_LIGHT))
- b_loss *=2
adjustBruteLoss(b_loss)
return ..()
diff --git a/code/modules/antagonists/ert/frontiersmen.dm b/code/modules/antagonists/ert/frontiersmen.dm
index 3c76dcebed9c..d6a1a5182cf0 100644
--- a/code/modules/antagonists/ert/frontiersmen.dm
+++ b/code/modules/antagonists/ert/frontiersmen.dm
@@ -26,6 +26,9 @@
outfit = /datum/outfit/job/frontiersmen/ert/leader
role = "Officer"
+/datum/antagonist/ert/frontier/leader/unnarmed
+ outfit = /datum/outfit/job/frontiersmen/ert/leader/unnarmed
+
/datum/antagonist/ert/frontier/medic
name = "Frontiersmen Medic"
outfit = /datum/outfit/job/frontiersmen/ert/medic
@@ -35,3 +38,11 @@
name = "Frontiersmen Engineer"
outfit = /datum/outfit/job/frontiersmen/ert/engineer
role = "Sapper"
+
+/datum/antagonist/ert/frontier/better
+ name = "Frontiersmen Grunt"
+ outfit = /datum/outfit/job/frontiersmen/ert/grunt/skm
+
+/datum/antagonist/ert/frontier/unnarmed
+ name = "Frontiersmen Grunt"
+ outfit = /datum/outfit/job/frontiersmen/ert/grunt
diff --git a/code/modules/antagonists/ert/inteq.dm b/code/modules/antagonists/ert/inteq.dm
index 591ad684cc1d..f4636487da5f 100644
--- a/code/modules/antagonists/ert/inteq.dm
+++ b/code/modules/antagonists/ert/inteq.dm
@@ -20,5 +20,5 @@
/datum/antagonist/ert/inteq/leader
name = "Inteq Mercenary Leader"
- outfit = /datum/outfit/job/inteq/captain
+ outfit = /datum/outfit/job/inteq/captain/empty
role = "Vanguard"
diff --git a/code/modules/antagonists/fugitive/fugitive_outfits.dm b/code/modules/antagonists/fugitive/fugitive_outfits.dm
deleted file mode 100644
index df784813df40..000000000000
--- a/code/modules/antagonists/fugitive/fugitive_outfits.dm
+++ /dev/null
@@ -1,154 +0,0 @@
-/datum/outfit/prisoner
- name = "Prison Escapee"
- uniform = /obj/item/clothing/under/rank/prisoner
- shoes = /obj/item/clothing/shoes/sneakers/orange
- r_pocket = /obj/item/kitchen/knife/shiv
-
-/datum/outfit/prisoner/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
- if(visualsOnly)
- return
- H.fully_replace_character_name(null,"NTP #CC-0[rand(111,999)]") //same as the lavaland prisoner transport, but this time they are from CC, or CentCom
-
-/datum/outfit/yalp_cultist
- name = "Cultist of Yalp Elor"
- uniform = /obj/item/clothing/under/rank/civilian/chaplain
- suit = /obj/item/clothing/suit/chaplainsuit/holidaypriest
- gloves = /obj/item/clothing/gloves/color/red
- shoes = /obj/item/clothing/shoes/sneakers/black
- mask = /obj/item/clothing/mask/gas/tiki_mask/yalp_elor
-
-/datum/outfit/waldo
- name = "Waldo"
- uniform = /obj/item/clothing/under/pants/jeans
- suit = /obj/item/clothing/suit/striped_sweater
- head = /obj/item/clothing/head/beanie/waldo
- shoes = /obj/item/clothing/shoes/sneakers/brown
- ears = /obj/item/radio/headset
- glasses = /obj/item/clothing/glasses/regular/circle
-
-/datum/outfit/waldo/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
- if(visualsOnly)
- return
- H.fully_replace_character_name(null,"Waldo")
- H.eye_color = "000"
- H.gender = MALE
- H.skin_tone = "caucasian3"
- H.hairstyle = "Business Hair 3"
- H.facial_hairstyle = "Shaved"
- H.hair_color = "000"
- H.facial_hair_color = H.hair_color
- H.update_body()
- if(H.mind)
- H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
- var/list/no_drops = list()
- no_drops += H.get_item_by_slot(ITEM_SLOT_FEET)
- no_drops += H.get_item_by_slot(ITEM_SLOT_ICLOTHING)
- no_drops += H.get_item_by_slot(ITEM_SLOT_OCLOTHING)
- no_drops += H.get_item_by_slot(ITEM_SLOT_HEAD)
- no_drops += H.get_item_by_slot(ITEM_SLOT_EYES)
- for(var/i in no_drops)
- var/obj/item/I = i
- ADD_TRAIT(I, TRAIT_NODROP, CURSED_ITEM_TRAIT)
-
-/datum/outfit/synthetic
- name = "Factory Error Synth"
- uniform = /obj/item/clothing/under/color/white
- ears = /obj/item/radio/headset
-
-/datum/outfit/synthetic/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
- return
- var/obj/item/organ/eyes/robotic/glow/eyes = new()
- eyes.Insert(src, drop_if_replaced = FALSE)
-
-/datum/outfit/spacepol
- name = "Spacepol Officer"
- uniform = /obj/item/clothing/under/rank/security/officer/beatcop
- suit = /obj/item/clothing/suit/armor/vest/blueshirt
- belt = /obj/item/gun/ballistic/automatic/pistol/candor
- head = /obj/item/clothing/head/helmet/police
- gloves = /obj/item/clothing/gloves/tackler/combat
- shoes = /obj/item/clothing/shoes/jackboots
- mask = /obj/item/clothing/mask/gas/sechailer/swat/spacepol
- glasses = /obj/item/clothing/glasses/sunglasses
- ears = /obj/item/radio/headset
- l_pocket = /obj/item/ammo_box/magazine/m45
- r_pocket = /obj/item/restraints/handcuffs
- id = /obj/item/card/id
-
-/datum/outfit/spacepol/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
- return
- var/obj/item/card/id/W = H.wear_id
- W.assignment = "Police Officer"
- W.registered_name = H.real_name
- W.update_label()
-
-/datum/outfit/frontier/hunter
- name = "Frontiersman Corpse (Hunter)"
- ears = /obj/item/radio/headset
- r_hand = /obj/item/gun/ballistic/rifle/illestren
-
-/datum/outfit/frontier/hunter/pre_equip(mob/living/carbon/human/H)
- if(prob(50))
- head = /obj/item/clothing/head/trapper
-
-/datum/outfit/bountyarmor
- name = "Bounty Hunter - Armored"
- uniform = /obj/item/clothing/under/rank/prisoner
- head = /obj/item/clothing/head/hunter
- suit = /obj/item/clothing/suit/space/hunter
- gloves = /obj/item/clothing/gloves/tackler/combat
- shoes = /obj/item/clothing/shoes/jackboots
- mask = /obj/item/clothing/mask/gas/hunter
- glasses = /obj/item/clothing/glasses/sunglasses/garb
- ears = /obj/item/radio/headset
- l_pocket = /obj/item/tank/internals/emergency_oxygen
- r_pocket = /obj/item/restraints/handcuffs/cable
- id = /obj/item/card/id
- r_hand = /obj/item/flamethrower/full/tank
-
-/datum/outfit/bountyarmor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
- return
- var/obj/item/card/id/W = H.wear_id
- W.assignment = "Bounty Hunter"
- W.registered_name = H.real_name
- W.update_label()
-
-/datum/outfit/bountyhook
- name = "Bounty Hunter - Hook"
- uniform = /obj/item/clothing/under/rank/prisoner
- back = /obj/item/storage/backpack
- head = /obj/item/clothing/head/scarecrow_hat
- gloves = /obj/item/clothing/gloves/botanic_leather
- ears = /obj/item/radio/headset
- shoes = /obj/item/clothing/shoes/jackboots
- mask = /obj/item/clothing/mask/scarecrow
- r_pocket = /obj/item/restraints/handcuffs/cable
- id = /obj/item/card/id
- r_hand = /obj/item/gun/ballistic/shotgun/doublebarrel/hook
-
- backpack_contents = list(
- /obj/item/ammo_casing/shotgun/incapacitate = 6
- )
-
-/datum/outfit/bountyhook/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
- return
- var/obj/item/card/id/W = H.wear_id
- W.assignment = "Bounty Hunter"
- W.registered_name = H.real_name
- W.update_label()
-
-/datum/outfit/bountysynth
- name = "Bounty Hunter - Synth"
- uniform = /obj/item/clothing/under/rank/prisoner
- back = /obj/item/storage/backpack
- suit = /obj/item/clothing/suit/armor/riot
- shoes = /obj/item/clothing/shoes/jackboots
- glasses = /obj/item/clothing/glasses/eyepatch
- r_pocket = /obj/item/restraints/handcuffs/cable
- ears = /obj/item/radio/headset
- id = /obj/item/card/id
- r_hand = /obj/item/storage/firstaid/regular
diff --git a/code/modules/antagonists/nukeop/equipment/borgchameleon.dm b/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
index ddc895060b0c..17cd8fd99bff 100644
--- a/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
+++ b/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
@@ -65,7 +65,7 @@
to_chat(user, "You activate \the [src].")
playsound(src, 'sound/effects/seedling_chargeup.ogg', 100, TRUE, -6)
apply_wibbly_filters(user)
- if (do_after(user, 50, target=user) && user.cell.use(activationCost))
+ if (do_after(user, 50, target=user, hidden = TRUE) && user.cell.use(activationCost))
playsound(src, 'sound/effects/bamf.ogg', 100, TRUE, -6)
to_chat(user, "You are now disguised as the Nanotrasen engineering borg \"[friendlyName]\".")
activate(user)
diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
index d0019eb19cc2..648803185661 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
@@ -126,7 +126,7 @@
if(istype(I, /obj/item/nuke_core_container))
var/obj/item/nuke_core_container/core_box = I
to_chat(user, "You start loading the plutonium core into [core_box]...")
- if(do_after(user,50,target=src))
+ if(do_after(user, 50, target = src, hidden = TRUE))
if(core_box.load(core, user))
to_chat(user, "You load the plutonium core into [core_box].")
deconstruction_state = NUKESTATE_CORE_REMOVED
diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm
index 76da8304df09..084176f4b8c4 100644
--- a/code/modules/antagonists/revenant/revenant.dm
+++ b/code/modules/antagonists/revenant/revenant.dm
@@ -190,17 +190,6 @@
return BULLET_ACT_FORCE_PIERCE
return ..()
-//damage, gibbing, and dying
-/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
- . = ..()
- if(istype(W, /obj/item/nullrod))
- visible_message("[src] violently flinches!", \
- "As \the [W] passes through you, you feel your essence draining away!")
- adjustBruteLoss(25) //hella effective
- inhibited = TRUE
- update_action_buttons_icon()
- addtimer(CALLBACK(src, PROC_REF(reset_inhibit)), 30)
-
/mob/living/simple_animal/revenant/proc/reset_inhibit()
inhibited = FALSE
update_action_buttons_icon()
diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm
index b235199ed750..ca568bce6316 100644
--- a/code/modules/antagonists/revenant/revenant_abilities.dm
+++ b/code/modules/antagonists/revenant/revenant_abilities.dm
@@ -34,7 +34,7 @@
draining = TRUE
essence_drained += rand(15, 20)
to_chat(src, "You search for the soul of [target].")
- if(do_after(src, rand(10, 20), 0, target)) //did they get deleted in that second?
+ if(do_after(src, rand(10, 20), target, timed_action_flags = IGNORE_HELD_ITEM)) //did they get deleted in that second?
if(target.ckey)
to_chat(src, "[target.p_their(TRUE)] soul burns with intelligence.")
essence_drained += rand(20, 30)
@@ -43,7 +43,7 @@
essence_drained += rand(40, 50)
else
to_chat(src, "[target.p_their(TRUE)] soul is weak and faltering.")
- if(do_after(src, rand(15, 20), 0, target)) //did they get deleted NOW?
+ if(do_after(src, rand(15, 20), target, timed_action_flags = IGNORE_HELD_ITEM)) //did they get deleted NOW?
switch(essence_drained)
if(1 to 30)
to_chat(src, "[target] will not yield much essence. Still, every bit counts.")
@@ -53,7 +53,7 @@
to_chat(src, "Such a feast! [target] will yield much essence to you.")
if(90 to INFINITY)
to_chat(src, "Ah, the perfect soul. [target] will yield massive amounts of essence to you.")
- if(do_after(src, rand(15, 25), 0, target)) //how about now
+ if(do_after(src, rand(15, 25), target, timed_action_flags = IGNORE_HELD_ITEM)) //how about now
if(!target.stat)
to_chat(src, "[target.p_theyre(TRUE)] now powerful enough to fight off your draining.")
to_chat(target, "You feel something tugging across your body before subsiding.")
@@ -76,7 +76,7 @@
draining = FALSE
return
var/datum/beam/B = Beam(target,icon_state="drain_life",time=INFINITY)
- if(do_after(src, 46, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
+ if(do_after(src, 46, target, timed_action_flags = IGNORE_HELD_ITEM)) //As one cannot prove the existence of ghosts, ghosts cannot prove the existence of the target they were draining.
change_essence_amount(essence_drained, FALSE, target)
if(essence_drained <= 90 && target.stat != DEAD)
essence_regen_cap += 5
diff --git a/code/modules/antagonists/survivalist/survivalist.dm b/code/modules/antagonists/survivalist/survivalist.dm
index 0e38dc57105d..1fb457eea64b 100644
--- a/code/modules/antagonists/survivalist/survivalist.dm
+++ b/code/modules/antagonists/survivalist/survivalist.dm
@@ -26,17 +26,3 @@
guns.owner = owner
objectives += guns
..()
-
-/datum/antagonist/survivalist/magic
- name = "Amateur Magician"
- greet_message = "Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way."
-
-/datum/antagonist/survivalist/magic/greet()
- ..()
- to_chat(owner, "As a wonderful magician, you should remember that spellbooks don't mean anything if they are used up.")
-
-/datum/antagonist/survivalist/magic/forge_objectives()
- var/datum/objective/steal_five_of_type/summon_magic/magic = new
- magic.owner = owner
- objectives += magic
- ..()
diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm
index 6fec09373797..ea6fe83c8a07 100644
--- a/code/modules/antagonists/swarmer/swarmer.dm
+++ b/code/modules/antagonists/swarmer/swarmer.dm
@@ -456,7 +456,7 @@
to_chat(src, "Attempting to remove this being from our presence.")
- if(!do_mob(src, target, 30))
+ if(!do_after(src, 3 SECONDS, target))
return
var/turf/open/floor/F
@@ -491,7 +491,7 @@
D.pixel_x = target.pixel_x
D.pixel_y = target.pixel_y
D.pixel_z = target.pixel_z
- if(do_mob(src, target, 100))
+ if(do_after(src, 10 SECONDS, target))
to_chat(src, "Dismantling complete.")
var/atom/Tsec = target.drop_location()
new /obj/item/stack/sheet/metal(Tsec, 5)
@@ -604,7 +604,7 @@
if(resources < 5)
to_chat(src, "We do not have the resources for this!")
return
- if(do_mob(src, src, 10))
+ if(do_after(src, 1 SECONDS))
Fabricate(/obj/structure/swarmer/blockade, 5)
@@ -633,7 +633,7 @@
if(!isturf(loc))
to_chat(src, "This is not a suitable location for replicating ourselves. We need more room.")
return
- if(do_mob(src, src, 100))
+ if(do_after(src, 10 SECONDS))
var/createtype = SwarmerTypeToCreate()
if(createtype && Fabricate(createtype, 50))
playsound(loc,'sound/items/poster_being_created.ogg',50, TRUE, -1)
@@ -650,7 +650,7 @@
if(!isturf(loc))
return
to_chat(src, "Attempting to repair damage to our body, stand by...")
- if(do_mob(src, src, 100))
+ if(do_after(src, 10 SECONDS))
adjustHealth(-100)
to_chat(src, "We successfully repaired ourselves.")
diff --git a/code/modules/antagonists/traitor/syndicate_contract.dm b/code/modules/antagonists/traitor/syndicate_contract.dm
index a6edcb075361..d6bbba359303 100644
--- a/code/modules/antagonists/traitor/syndicate_contract.dm
+++ b/code/modules/antagonists/traitor/syndicate_contract.dm
@@ -143,10 +143,10 @@
// Pay contractor their portion of ransom
if (status == CONTRACT_STATUS_COMPLETE)
var/mob/living/carbon/human/H
- var/obj/item/card/id/C
+ var/obj/item/card/bank/C
if(ishuman(contract.owner.current))
H = contract.owner.current
- C = H.get_idcard(TRUE)
+ C = H.get_bankcard()
if(C && C.registered_account)
C.registered_account.adjust_money(ransom * 0.35, "syndicate_contract")
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index a95ef0d1b579..a20b905b590d 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -58,14 +58,6 @@
if(spawn_amt_left <= 0)
qdel(src)
-/obj/effect/rend/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/nullrod))
- user.visible_message("[user] seals \the [src] with \the [I].")
- qdel(src)
- return
- else
- return ..()
-
/obj/effect/rend/singularity_pull()
return
diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm
index 58e397a64d40..69ff4bcfc2f5 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook.dm
@@ -106,10 +106,6 @@
name = "Fireball"
spell_type = /obj/effect/proc_holder/spell/aimed/fireball
-/datum/spellbook_entry/spell_cards
- name = "Spell Cards"
- spell_type = /obj/effect/proc_holder/spell/aimed/spell_cards
-
/datum/spellbook_entry/rod_form
name = "Rod Form"
spell_type = /obj/effect/proc_holder/spell/targeted/rod_form
@@ -223,18 +219,6 @@
. = ..()
REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell")
-/datum/spellbook_entry/infinite_guns
- name = "Lesser Summon Guns"
- spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns/gun
- cost = 3
- no_coexistance_typecache = /obj/effect/proc_holder/spell/targeted/infinite_guns/arcane_barrage
-
-/datum/spellbook_entry/arcane_barrage
- name = "Arcane Barrage"
- spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns/arcane_barrage
- cost = 3
- no_coexistance_typecache = /obj/effect/proc_holder/spell/targeted/infinite_guns/gun
-
/datum/spellbook_entry/barnyard
name = "Barnyard Curse"
spell_type = /obj/effect/proc_holder/spell/pointed/barnyardcurse
@@ -291,47 +275,6 @@
dat += "[surplus] left. "
return dat
-/datum/spellbook_entry/item/staffchange
- name = "Staff of Change"
- desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
- item_path = /obj/item/gun/magic/staff/change
-
-/datum/spellbook_entry/item/staffanimation
- name = "Staff of Animation"
- desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines."
- item_path = /obj/item/gun/magic/staff/animate
- category = "Assistance"
-
-/datum/spellbook_entry/item/staffchaos
- name = "Staff of Chaos"
- desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended."
- item_path = /obj/item/gun/magic/staff/chaos
-
-/datum/spellbook_entry/item/spellblade
- name = "Spellblade"
- desc = "A sword capable of firing blasts of energy which rip targets limb from limb."
- item_path = /obj/item/gun/magic/staff/spellblade
-
-/datum/spellbook_entry/item/staffdoor
- name = "Staff of Door Creation"
- desc = "A particular staff that can mold solid walls into ornate doors. Useful for getting around in the absence of other transportation. Does not work on glass."
- item_path = /obj/item/gun/magic/staff/door
- cost = 1
- category = "Mobility"
-
-/datum/spellbook_entry/item/staffhealing
- name = "Staff of Healing"
- desc = "An altruistic staff that can heal the lame and raise the dead."
- item_path = /obj/item/gun/magic/staff/healing
- cost = 1
- category = "Defensive"
-
-/datum/spellbook_entry/item/lockerstaff
- name = "Staff of the Locker"
- desc = "A staff that shoots lockers. It eats anyone it hits on its way, leaving a welded locker with your victims behind."
- item_path = /obj/item/gun/magic/staff/locker
- category = "Defensive"
-
/datum/spellbook_entry/item/scryingorb
name = "Scrying Orb"
desc = "An incandescent orb of crackling energy. Using it will allow you to release your ghost while alive, allowing you to spy upon others and talk to the deceased. In addition, buying it will permanently grant you X-ray vision."
@@ -356,12 +299,6 @@
item_path = /obj/item/necromantic_stone
category = "Assistance"
-/datum/spellbook_entry/item/wands
- name = "Wand Assortment"
- desc = "A collection of wands that allow for a wide variety of utility. Wands have a limited number of charges, so be conservative with their use. Comes in a handy belt."
- item_path = /obj/item/storage/belt/wands/full
- category = "Defensive"
-
/datum/spellbook_entry/item/armor
name = "Mastercrafted Armor Set"
desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm
index 14cf56d51ae0..96a41b2ac07b 100644
--- a/code/modules/antagonists/wizard/wizard.dm
+++ b/code/modules/antagonists/wizard/wizard.dm
@@ -204,7 +204,6 @@
if(APPRENTICE_HEALING)
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null))
- H.put_in_hands(new /obj/item/gun/magic/staff/healing(H))
to_chat(owner, "Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned life-saving survival spells. You are able to cast charge and forcewall.")
if(APPRENTICE_ROBELESS)
owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm
index e128623f9cb8..fb0d7026a6d1 100644
--- a/code/modules/atmospherics/auxgm/gas_types.dm
+++ b/code/modules/atmospherics/auxgm/gas_types.dm
@@ -155,3 +155,15 @@
gas_overlay = "freon"
moles_visible = MOLES_GAS_VISIBLE *30
fusion_power = -5
+
+/datum/gas/hydrogen
+ id = GAS_HYDROGEN
+ specific_heat = 10
+ name = "Hydrogen"
+ flags = GAS_FLAG_DANGEROUS
+ moles_visible = MOLES_GAS_VISIBLE
+ color = "#ffe"
+ fusion_power = 0
+ fire_products = list(GAS_H2O = 1)
+ fire_burn_rate = 2
+ fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index bef2f277f7e1..e5a1be0294d6 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -65,8 +65,8 @@
icon = 'icons/obj/monitors.dmi'
icon_state = "alarm"
use_power = IDLE_POWER_USE
- idle_power_usage = 4
- active_power_usage = 1200
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
power_channel = AREA_USAGE_ENVIRON
//req_access = list(ACCESS_ATMOSPHERICS)
max_integrity = 250
@@ -121,7 +121,8 @@
GAS_STIMULUM = new/datum/tlv/dangerous,
GAS_NITRYL = new/datum/tlv/dangerous,
GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
- GAS_FREON = new/datum/tlv/dangerous
+ GAS_FREON = new/datum/tlv/dangerous,
+ GAS_HYDROGEN = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/server // No checks here.
@@ -140,7 +141,8 @@
GAS_STIMULUM = new/datum/tlv/no_checks,
GAS_NITRYL = new/datum/tlv/no_checks,
GAS_PLUOXIUM = new/datum/tlv/no_checks,
- GAS_FREON = new/datum/tlv/no_checks
+ GAS_FREON = new/datum/tlv/no_checks,
+ GAS_HYDROGEN = new/datum/tlv/no_checks
)
heating_manage = FALSE
@@ -160,7 +162,8 @@
GAS_STIMULUM = new/datum/tlv/dangerous,
GAS_NITRYL = new/datum/tlv/dangerous,
GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
- GAS_FREON = new/datum/tlv/dangerous
+ GAS_FREON = new/datum/tlv/dangerous,
+ GAS_HYDROGEN = new/datum/tlv/dangerous
)
heating_manage = FALSE
@@ -564,7 +567,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27)
GAS_BZ,
GAS_STIMULUM,
GAS_PLUOXIUM,
- GAS_FREON
+ GAS_FREON,
+ GAS_HYDROGEN
),
"scrubbing" = 1,
"widenet" = 1
@@ -753,14 +757,14 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27)
visible_message("The air alarm makes a quiet click as it stops heating the area")
playsound(src, 'sound/machines/terminal_off.ogg', 40)
heating_current_mode = "Idle"
- use_power = IDLE_POWER_USE
+ set_idle_power()
return
if(wanted_mode == "Heat" & heating_current_mode == "Idle")
visible_message("The air alarm makes a quiet click as it starts heating the area")
playsound(src, 'sound/machines/terminal_on.ogg', 40)
heating_current_mode = "Heat"
- use_power = ACTIVE_POWER_USE
+ set_active_power()
if(heating_current_mode == "Heat")
var/temperature = environment.return_temperature()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
index 9f2d582be256..30703b2f4a02 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
@@ -15,12 +15,19 @@
var/active = FALSE
var/last_pressure_delta = 0
- pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
+ pipe_flags = PIPING_ONE_PER_TURF
var/flipped = 0
var/mode = CIRCULATOR_HOT
var/obj/machinery/power/generator/generator
+/obj/machinery/atmospherics/components/unary/shuttle/heater/on_construction(obj_color, set_layer)
+ var/obj/item/circuitboard/machine/circulator/board = circuit
+ if(board)
+ piping_layer = board.pipe_layer
+ set_layer = piping_layer
+ ..()
+
//for mappers
/obj/machinery/atmospherics/components/binary/circulator/cold
mode = CIRCULATOR_COLD
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
index 8579d70a1165..8cd12ddf27cf 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
@@ -18,6 +18,10 @@
can_unwrench = TRUE
shift_underlay_only = FALSE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = 0
+ active_power_usage = ACTIVE_DRAW_MINIMAL
+
var/target_pressure = ONE_ATMOSPHERE
var/frequency = 0
@@ -30,6 +34,10 @@
/obj/machinery/atmospherics/components/binary/pump/CtrlClick(mob/user)
if(can_interact(user))
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS)
update_appearance()
return ..()
@@ -110,6 +118,10 @@
switch(action)
if("power")
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
if("pressure")
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
index 020570f34785..24ef0997406d 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
@@ -73,6 +73,9 @@ It's like a regular ol' straight pipe, but you can turn it on and off.
return
..()
+/obj/machinery/atmospherics/components/binary/valve/digital/toggle()
+ use_power(ACTIVE_DRAW_MINIMAL)
+ . = ..()
/obj/machinery/atmospherics/components/binary/valve/layer2
piping_layer = 2
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
index 03b41df05e32..7416014ee463 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
@@ -18,6 +18,10 @@
can_unwrench = TRUE
shift_underlay_only = FALSE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = 0
+ active_power_usage = ACTIVE_DRAW_MINIMAL
+
var/transfer_rate = MAX_TRANSFER_RATE
var/overclocked = FALSE
@@ -31,6 +35,10 @@
/obj/machinery/atmospherics/components/binary/volume_pump/CtrlClick(mob/user)
if(can_interact(user))
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS)
update_appearance()
return ..()
@@ -130,6 +138,10 @@
switch(action)
if("power")
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
if("rate")
@@ -192,18 +204,18 @@
piping_layer = 2
icon_state = "volpump_map-2"
-/obj/machinery/atmospherics/components/binary/volume_pump/layer2
- piping_layer = 2
- icon_state = "volpump_map-2"
+/obj/machinery/atmospherics/components/binary/volume_pump/layer4
+ piping_layer = 4
+ icon_state = "volpump_map-4"
/obj/machinery/atmospherics/components/binary/volume_pump/on
on = TRUE
- icon_state = "volpump_map-2"
+ icon_state = "volpump_on_map-3"
/obj/machinery/atmospherics/components/binary/volume_pump/on/layer2
piping_layer = 2
- icon_state = "volpump_map-2"
+ icon_state = "volpump_on_map-2"
/obj/machinery/atmospherics/components/binary/volume_pump/on/layer4
piping_layer = 4
- icon_state = "volpump_map-4"
+ icon_state = "volpump_on_map-4"
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
index 404ecbf46eb2..d196bca1c3b3 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
@@ -5,6 +5,10 @@
name = "gas filter"
desc = "Very useful for filtering gasses."
+ use_power = IDLE_POWER_USE
+ idle_power_usage = 0
+ active_power_usage = ACTIVE_DRAW_MINIMAL
+
can_unwrench = TRUE
var/transfer_rate = MAX_TRANSFER_RATE
var/filter_type = null
@@ -17,6 +21,10 @@
/obj/machinery/atmospherics/components/trinary/filter/CtrlClick(mob/user)
if(can_interact(user))
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS)
update_appearance()
return ..()
@@ -114,6 +122,10 @@
switch(action)
if("power")
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
if("rate")
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index c1ce88286b4c..9ea52bd847be 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -5,6 +5,10 @@
name = "gas mixer"
desc = "Very useful for mixing gasses."
+ use_power = IDLE_POWER_USE
+ idle_power_usage = 0
+ active_power_usage = ACTIVE_DRAW_MINIMAL
+
can_unwrench = TRUE
var/target_pressure = ONE_ATMOSPHERE
@@ -19,6 +23,10 @@
/obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user)
if(can_interact(user))
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS)
update_appearance()
return ..()
@@ -137,6 +145,10 @@
switch(action)
if("power")
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
if("pressure")
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 8f547335e9e0..5ff6b2e396b5 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -273,7 +273,7 @@
user.visible_message("You see [user] kicking against the glass of [src]!", \
"You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(breakout_time)].)", \
"You hear a thump from [src].")
- if(do_after(user, breakout_time, target = src))
+ if(do_after(user, breakout_time, target = src, hidden = TRUE))
if(!user || user.stat != CONSCIOUS || user.loc != src)
return
user.visible_message("[user] successfully broke out of [src]!", \
@@ -299,7 +299,7 @@
close_machine(target)
else
user.visible_message("[user] starts shoving [target] inside [src].", "You start shoving [target] inside [src].")
- if (do_after(user, 25, target=target))
+ if (do_after(user, 25, target = target))
close_machine(target)
/obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
index 1b6df20c721e..bcb46dedf147 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
@@ -6,6 +6,7 @@
desc = "Heats or cools gas in connected pipes."
density = TRUE
+ idle_power_usage = IDLE_DRAW_LOW
max_integrity = 300
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30)
layer = OBJ_LAYER
@@ -83,7 +84,7 @@
var/temperature_delta= abs(old_temperature - air_contents.return_temperature())
if(temperature_delta > 1)
- active_power_usage = (heat_capacity * temperature_delta) / 10 + idle_power_usage
+ active_power_usage = (heat_capacity * temperature_delta) / 5 + idle_power_usage
update_parents()
else
active_power_usage = idle_power_usage
@@ -152,7 +153,10 @@
switch(action)
if("power")
on = !on
- use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
if("target")
@@ -182,6 +186,10 @@
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
on = !on
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS)
update_appearance()
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index c55b8da80436..dc8b278959f6 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -48,8 +48,8 @@
radio_connection = null
adjacent_turfs.Cut()
return ..()
-
-/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power()
+/*
+/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power() //auto_use_power no longer called
if(!on || welded || !is_operational || !powered(power_channel))
return FALSE
@@ -64,7 +64,7 @@
amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2))
use_power(amount, power_channel)
return TRUE
-
+*/
/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes()
cut_overlays()
if(showpipe)
@@ -138,13 +138,20 @@
..()
if(welded || !on || !is_operational)
+ if(use_static_power != NO_POWER_USE)
+ set_no_power()
return FALSE
if(!nodes[1])
return FALSE
scrub(loc)
if(widenet)
+ if(use_static_power != ACTIVE_POWER_USE)
+ set_active_power()
for(var/turf/tile in adjacent_turfs)
scrub(tile)
+ else
+ if(use_static_power != IDLE_POWER_USE)
+ set_idle_power()
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(turf/tile)
diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm
index 811979dd4c39..07aca0757568 100644
--- a/code/modules/atmospherics/machinery/other/meter.dm
+++ b/code/modules/atmospherics/machinery/other/meter.dm
@@ -6,8 +6,8 @@
layer = GAS_PUMP_LAYER
power_channel = AREA_USAGE_ENVIRON
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 4
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = IDLE_DRAW_MINIMAL
max_integrity = 150
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 40, "acid" = 0)
var/frequency = 0
diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm
index 37045635cf1a..9f5a6a9aa6db 100644
--- a/code/modules/atmospherics/machinery/other/miner.dm
+++ b/code/modules/atmospherics/machinery/other/miner.dm
@@ -26,8 +26,8 @@
var/power_draw_dynamic_kpa_coeff = 0.5
var/broken = FALSE
var/broken_message = "ERROR"
- idle_power_usage = 150
- active_power_usage = 2000
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_HIGH
/obj/machinery/atmospherics/miner/Initialize()
. = ..()
@@ -178,3 +178,8 @@
name = "\improper Water Vapor Gas Miner"
overlay_color = "#99928E"
spawn_id = GAS_H2O
+
+/obj/machinery/atmospherics/miner/hydrogen
+ name = "\improper Hydrogen Gas Miner"
+ overlay_color = "#ffffffda"
+ spawn_id = GAS_HYDROGEN
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index 6b0f025b6b89..f2e563c07b5e 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -52,7 +52,9 @@
"stimulum" = /obj/machinery/portable_atmospherics/canister/stimulum,
"pluoxium" = /obj/machinery/portable_atmospherics/canister/pluoxium,
"caution" = /obj/machinery/portable_atmospherics/canister,
- "freon" = /obj/machinery/portable_atmospherics/canister/freon
+ "freon" = /obj/machinery/portable_atmospherics/canister/freon,
+ "hydrogen" = /obj/machinery/portable_atmospherics/canister/hydrogen,
+ "fuel mix" = /obj/machinery/portable_atmospherics/canister/fuel
)
/obj/machinery/portable_atmospherics/canister/interact(mob/user)
@@ -147,6 +149,27 @@
gas_type = GAS_FREON
filled = 1
+/obj/machinery/portable_atmospherics/canister/hydrogen
+ name = "hydrogen canister"
+ desc = "Hydrogen. Used in thruster fuel."
+ icon_state = "orangews"
+ gas_type = GAS_HYDROGEN
+
+/obj/machinery/portable_atmospherics/canister/fuel
+ name = "fuel canister"
+ desc = "A highly volatile mix of hydrogen and oxygen."
+ icon_state = "orangewshaz"
+
+/obj/machinery/portable_atmospherics/canister/fuel_test
+ name = "test canister"
+ desc = "Hydrogen. Used in thruster fuel."
+ icon_state = "orangewshaz"
+
+/obj/machinery/portable_atmospherics/canister/fuel_test/create_gas()
+ air_contents.set_moles(GAS_O2, 500)
+ air_contents.set_moles(GAS_HYDROGEN, 1000)
+ air_contents.set_temperature(T20C)
+
/obj/machinery/portable_atmospherics/canister/fusion_test
name = "fusion test canister"
desc = "Don't be a badmin."
@@ -216,6 +239,11 @@
air_contents.set_moles(GAS_O2, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
air_contents.set_moles(GAS_N2, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
+/obj/machinery/portable_atmospherics/canister/fuel/create_gas()
+ air_contents.set_temperature(starter_temp)
+ air_contents.set_moles(GAS_HYDROGEN, (2/3 * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
+ air_contents.set_moles((GAS_O2), (1/3 * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
+
/obj/machinery/portable_atmospherics/canister/update_icon_state()
if(machine_stat & BROKEN)
icon_state = "[icon_state]-1"
diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm
index b608d5849e38..7505d2b8789e 100644
--- a/code/modules/atmospherics/machinery/portable/scrubber.dm
+++ b/code/modules/atmospherics/machinery/portable/scrubber.dm
@@ -8,7 +8,7 @@
var/volume_rate = 1000
var/overpressure_m = 80
var/use_overlays = TRUE
- var/list/scrubbing = list(GAS_PLASMA, GAS_CO2, GAS_NITROUS, GAS_BZ, GAS_NITRYL, GAS_TRITIUM, GAS_HYPERNOB, GAS_H2O, GAS_FREON)
+ var/list/scrubbing = list(GAS_PLASMA, GAS_CO2, GAS_NITROUS, GAS_BZ, GAS_NITRYL, GAS_TRITIUM, GAS_HYPERNOB, GAS_H2O, GAS_FREON, GAS_HYDROGEN)
/obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src)
@@ -113,8 +113,8 @@
name = "huge air scrubber"
icon_state = "scrubber:0"
anchored = TRUE
- active_power_usage = 500
- idle_power_usage = 10
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
overpressure_m = 200
volume_rate = 1500
@@ -137,8 +137,10 @@
if((!anchored && !movable) || !is_operational)
on = FALSE
update_appearance()
- use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE
- if(!on)
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
return
..()
diff --git a/code/modules/autowiki/pages/reactions.dm b/code/modules/autowiki/pages/reactions.dm
new file mode 100644
index 000000000000..2e1a07b806e4
--- /dev/null
+++ b/code/modules/autowiki/pages/reactions.dm
@@ -0,0 +1,65 @@
+/*
+Templates:
+
+Autowiki/Reaction
+{{{chems|ERROR}}} {{#if: {{{temperature|}}} | Temperature {{{temperature}}} | }} {{#if: {{{container|}}} | Needs container "{{{container}}}" | }} Makes {{{volume|1}}}u
+
+Autowiki/Reagent
+{{#if: {{{tooltip|}}} | {{Tooltip|{{{volume}}} part [[#{{{name}}}|{{{name}}}]]|{{{tooltip}}}|FEF6E7}} | {{{volume}}} part {{{name}}} }}
+
+*/
+
+/datum/autowiki/reactions
+ page = "Template:Autowiki/Content/Reactions"
+
+/datum/autowiki/reactions/generate()
+ var/list/output = list()
+
+ var/list/mixable_reagents = list()
+ var/list/all_reactions = list()
+ for(var/type in subtypesof(/datum/chemical_reaction))
+ var/datum/chemical_reaction/reaction = new type
+ all_reactions += reaction
+ mixable_reagents |= reaction.results
+
+ for(var/datum/chemical_reaction/reaction as anything in all_reactions)
+ var/required_chems = ""
+ for(var/datum/reagent/required_chem_type as anything in reaction.required_reagents)
+ var/has_tooltip = (required_chem_type in mixable_reagents) && !(required_chem_type in reaction.results) && !(required_chem_type in GLOB.base_reagents)
+ required_chems += format_required_reagent(required_chem_type, reaction.required_reagents[required_chem_type], has_tooltip)
+
+ for(var/datum/reagent/required_catalyst_type as anything in reaction.required_catalysts)
+ var/has_tooltip = (required_catalyst_type in mixable_reagents) && !(required_catalyst_type in reaction.results) && !(required_catalyst_type in GLOB.base_reagents)
+ required_chems += format_required_reagent(required_catalyst_type, reaction.required_catalysts[required_catalyst_type], has_tooltip, "Catalyst")
+
+ for(var/datum/reagent/result_chem_type as anything in reaction.results)
+ var/result_name = escape_value(initial(result_chem_type.name))
+ var/list/details = list("volume" = reaction.results[result_chem_type], "chems" = required_chems, "name" = result_name)
+
+ if(reaction.required_temp > 0)
+ details["temperature"] = "[reaction.is_cold_recipe ? "below" : "above"] [reaction.required_temp]K"
+
+ if(reaction.required_container)
+ details["container"] = "[escape_value(initial(reaction.required_container.name))]"
+
+ var/description = include_template("Autowiki/Reaction", details)
+ if(result_name in output)
+ output[result_name] += " OR [description]"
+ else
+ output[result_name] = description
+
+ return output
+
+/datum/autowiki/reactions/proc/format_required_reagent(datum/reagent/required_reagent_type, volume, has_tooltip = FALSE, type)
+ var/list/details = list(
+ "volume" = volume,
+ "name" = escape_value(initial(required_reagent_type.name))
+ )
+
+ if(has_tooltip)
+ details["tooltip"] = include_template("Autowiki/Content/Reactions/[initial(required_reagent_type.name)]")
+
+ if(type)
+ details["type"] = type
+
+ return include_template("Autowiki/Reagent", details)
diff --git a/code/modules/autowiki/pages/reagents.dm b/code/modules/autowiki/pages/reagents.dm
index d10137d07f53..885c64665c20 100644
--- a/code/modules/autowiki/pages/reagents.dm
+++ b/code/modules/autowiki/pages/reagents.dm
@@ -1,65 +1,52 @@
-/*
-Templates:
-
-Autowiki/Reaction
-{{{chems|ERROR}}} {{#if: {{{temperature|}}} | Temperature {{{temperature}}} | }} {{#if: {{{container|}}} | Needs container "{{{container}}}" | }} Makes {{{volume|1}}}u
-
-Autowiki/Reagent
-{{#if: {{{tooltip|}}} | {{Tooltip|{{{volume}}} part [[#{{{name}}}|{{{name}}}]]|{{{tooltip}}}|FEF6E7}} | {{{volume}}} part {{{name}}} }}
-
-*/
-
/datum/autowiki/reagents
- page = "Template:Autowiki/Content/Reactions"
+ page = "Template:Autowiki/Content/Reagents"
/datum/autowiki/reagents/generate()
- var/list/output = list()
+ var/output = ""
var/list/mixable_reagents = list()
- var/list/all_reactions = list()
for(var/type in subtypesof(/datum/chemical_reaction))
var/datum/chemical_reaction/reaction = new type
- all_reactions += reaction
mixable_reagents |= reaction.results
+ qdel(reaction)
- for(var/datum/chemical_reaction/reaction as anything in all_reactions)
- var/required_chems = ""
- for(var/datum/reagent/required_chem_type as anything in reaction.required_reagents)
- var/has_tooltip = (required_chem_type in mixable_reagents) && !(required_chem_type in reaction.results) && !(required_chem_type in GLOB.base_reagents)
- required_chems += format_required_reagent(required_chem_type, reaction.required_reagents[required_chem_type], has_tooltip)
+ var/list/categories = list()
- for(var/datum/reagent/required_catalyst_type as anything in reaction.required_catalysts)
- var/has_tooltip = (required_catalyst_type in mixable_reagents) && !(required_catalyst_type in reaction.results) && !(required_catalyst_type in GLOB.base_reagents)
- required_chems += format_required_reagent(required_catalyst_type, reaction.required_catalysts[required_catalyst_type], has_tooltip, "Catalyst")
+ for(var/reagent in mixable_reagents)
+ var/datum/reagent/chem = new reagent
- for(var/datum/reagent/result_chem_type as anything in reaction.results)
- var/result_name = escape_value(initial(result_chem_type.name))
- var/list/details = list("volume" = reaction.results[result_chem_type], "chems" = required_chems, "name" = result_name)
+ LAZYINITLIST(categories[chem.category])
+ categories[chem.category] += list(chem)
- if(reaction.required_temp > 0)
- details["temperature"] = "[reaction.is_cold_recipe ? "below" : "above"] [reaction.required_temp]K"
+ for(var/category in sortList(categories))
+ output += "\n"
+ output += generate_category(category, categories[category])
- if(reaction.required_container)
- details["container"] = "[escape_value(initial(reaction.required_container.name))]"
+ return output
- var/description = include_template("Autowiki/Reaction", details)
- if(result_name in output)
- output[result_name] += " OR [description]"
- else
- output[result_name] = description
+/datum/autowiki/reagents/proc/generate_category(name, list/datum/reagent/reagents)
+ var/output = "== [escape_value(name)] ==\n"
- return output
+ output += "{| class='wikitable sortable' style=width:100%; text-align:left; border: 3px solid #FFDD66; cellspacing=0; cellpadding=2; background-color:white;'\n"
+ output += "! scope='col' style='width:150px; background-color:#FFDD66;' |Name\n"
+ output += "! class='unsortable' scope='col' style='width:150px; background-color:#FFDD66;' |Recipe\n"
+ output += "! class='unsortable' scope='col' style='background-color:#FFDD66;' |Description\n"
+ output += "! scope='col' | Metabolization Rate\n"
+ output += "! scope='col' | Overdose Threshold\n"
+ output += "! scope='col' | Addiction Threshold\n"
+ output += "|-\n"
-/datum/autowiki/reagents/proc/format_required_reagent(datum/reagent/required_reagent_type, volume, has_tooltip = FALSE, type)
- var/list/details = list(
- "volume" = volume,
- "name" = escape_value(initial(required_reagent_type.name))
- )
+ reagents = sortList(reagents, /proc/cmp_typepaths_asc)
- if(has_tooltip)
- details["tooltip"] = include_template("Autowiki/Content/Reactions/[initial(required_reagent_type.name)]")
+ for(var/datum/reagent/reagent as anything in reagents)
+ output += "! style='background-color: #FFEE88;' | [include_template("anchor", list("1" = escape_value(reagent.name)))][escape_value(reagent.name)] _\n"
+ output += "|[include_template("Autowiki/Content/Reactions/[escape_value(reagent.name)]")]\n"
+ output += "|[escape_value(reagent.description)]\n"
+ output += "|data-sort-value=[reagent.metabolization_rate]|[reagent.metabolization_rate] units per tick\n"
+ output += "|[reagent.overdose_threshold || "data-sort-value=0|N/A"]\n"
+ output += "|[reagent.addiction_threshold || "data-sort-value=0|N/A"]\n"
+ output += "|-\n"
- if(type)
- details["type"] = type
+ output += "|}\n"
- return include_template("Autowiki/Reagent", details)
+ return output
diff --git a/code/modules/autowiki/pages/ships.dm b/code/modules/autowiki/pages/ships.dm
index 8a444cd33896..c59a321942b6 100644
--- a/code/modules/autowiki/pages/ships.dm
+++ b/code/modules/autowiki/pages/ships.dm
@@ -75,7 +75,7 @@
/datum/autowiki/ship/proc/get_dummy_image(datum/job/to_equip)
//Controlled randomisation
- wiki_dummy.seeded_randomization("[to_equip.outfit]", list(/datum/species/ethereal, /datum/species/human, /datum/species/ipc, /datum/species/lizard, /datum/species/moth, /datum/species/spider))
+ wiki_dummy.seeded_randomization("[to_equip.outfit]", list(/datum/species/elzuose, /datum/species/human, /datum/species/ipc, /datum/species/lizard, /datum/species/moth, /datum/species/spider))
//Delete all the old stuff they had
wiki_dummy.wipe_state()
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 8e8739a5acb0..0bf0b74c715a 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -30,8 +30,10 @@
var/mob_color //Change the mob's color
var/assignedrole
var/show_flavour = TRUE
- var/banType = ROLE_LAVALAND
+ var/ban_type = ROLE_LAVALAND
var/ghost_usable = TRUE
+ /// Weakref to the mob this spawner created - just if you needed to do something with it.
+ var/datum/weakref/spawned_mob_ref
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/effect/mob_spawn/attack_ghost(mob/user)
@@ -40,7 +42,7 @@
if(!uses)
to_chat(user, "This spawner is out of charges!")
return
- if(is_banned_from(user.key, banType))
+ if(is_banned_from(user.key, ban_type))
to_chat(user, "You are jobanned!")
return
if(!allow_spawn(user))
@@ -128,6 +130,7 @@
MM.name = M.real_name
if(uses > 0)
uses--
+ spawned_mob_ref = WEAKREF(M)
if(!permanent && !uses)
qdel(src)
return M
@@ -220,7 +223,8 @@
if(istype(C))
C.sensor_mode = NO_SENSORS
- var/obj/item/card/id/W = H.wear_id
+
+ var/obj/item/card/id/W = H.get_idcard()
if(W)
if(H.age)
W.registered_age = H.age
@@ -433,7 +437,7 @@
/datum/outfit/spacebartender/post_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
- var/obj/item/card/id/W = H.wear_id
+ var/obj/item/card/id/W = H.get_idcard()
if(H.age < AGE_MINOR)
W.registered_age = AGE_MINOR
to_chat(H, "You're not technically old enough to access or serve alcohol, but your ID has been discreetly modified to display your age as [AGE_MINOR]. Try to keep that a secret!")
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm
index a643be115aab..51ab76479657 100644
--- a/code/modules/awaymissions/gateway.dm
+++ b/code/modules/awaymissions/gateway.dm
@@ -157,8 +157,8 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 100
- active_power_usage = 5000
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_EXTREME
var/calibrated = TRUE
/// Type of instanced gateway destination, needs to be subtype of /datum/gateway_destination/gateway
@@ -198,7 +198,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
target = null
dest.deactivate(src)
QDEL_NULL(portal)
- use_power = IDLE_POWER_USE
+ set_idle_power()
update_appearance()
portal_visuals.reset_visuals()
@@ -221,7 +221,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
target.activate(destination)
portal_visuals.setup_visuals(target)
generate_bumper()
- use_power = ACTIVE_POWER_USE
+ set_active_power()
update_appearance()
/obj/machinery/gateway/proc/Transfer(atom/movable/AM)
diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm
index dec456b8ef2f..f2dbb91f3f0f 100644
--- a/code/modules/awaymissions/mission_code/snowdin.dm
+++ b/code/modules/awaymissions/mission_code/snowdin.dm
@@ -487,7 +487,6 @@
/obj/item/shield/energy = 6,
/obj/item/shield/riot/tele = 12,
/obj/item/dnainjector/lasereyesmut = 7,
- /obj/item/gun/magic/wand/fireball/inert = 3,
/obj/item/pneumatic_cannon = 15,
/obj/item/melee/transforming/energy/sword = 7,
/obj/item/book/granter/spell/knock = 15,
@@ -514,9 +513,7 @@
/obj/item/organ/brain/alien = 17,
/obj/item/dualsaber = 15,
/obj/item/organ/heart/demon = 7,
- /obj/item/gun/ballistic/automatic/smg/c20r/unrestricted = 16,
- /obj/item/gun/magic/wand/resurrection/inert = 15,
- /obj/item/gun/magic/wand/resurrection = 10,
+ /obj/item/gun/ballistic/automatic/smg/c20r = 16,
/obj/item/uplink/old = 2,
/obj/item/book/granter/spell/charge = 12,
/obj/item/grenade/clusterbuster/spawner_manhacks = 15,
@@ -556,16 +553,6 @@
desc = "High speed, low drag combat boots, now with an added layer of insulation."
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
-/obj/item/gun/magic/wand/fireball/inert
- name = "weakened wand of fireball"
- desc = "This wand shoots scorching balls of fire that explode into destructive flames. The years of the cold have weakened the magic inside the wand."
- max_charges = 4
-
-/obj/item/gun/magic/wand/resurrection/inert
- name = "weakened wand of healing"
- desc = "This wand uses healing magics to heal and revive. The years of the cold have weakened the magic inside the wand."
- max_charges = 5
-
/obj/effect/mob_spawn/human/syndicatesoldier/coldres
name = "Syndicate Snow Operative"
outfit = /datum/outfit/snowsyndie/corpse
@@ -592,7 +579,7 @@
uniform = /obj/item/clothing/under/syndicate/coldres
shoes = /obj/item/clothing/shoes/combat/coldres
ears = /obj/item/radio/headset/syndicate/alt
- r_pocket = /obj/item/gun/ballistic/automatic/pistol
+ r_pocket = /obj/item/gun/ballistic/automatic/pistol/syndicate
id = /obj/item/card/id/syndicate
implants = list(/obj/item/implant/exile)
diff --git a/code/modules/awaymissions/mission_code/spacebattle.dm b/code/modules/awaymissions/mission_code/spacebattle.dm
index dee4def256b0..efe429b86b73 100644
--- a/code/modules/awaymissions/mission_code/spacebattle.dm
+++ b/code/modules/awaymissions/mission_code/spacebattle.dm
@@ -41,11 +41,11 @@
name = "Hidden Chamber"
icon_state = "awaycontent10"
-/mob/living/simple_animal/hostile/syndicate/ranged/spacebattle
+/mob/living/simple_animal/hostile/human/syndicate/ranged/spacebattle
loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier,
/obj/item/gun/ballistic/automatic/smg/c20r,
/obj/item/shield/energy)
-/mob/living/simple_animal/hostile/syndicate/melee/spacebattle
+/mob/living/simple_animal/hostile/human/syndicate/melee/spacebattle
deathmessage = "falls limp as they release their grip from the energy weapons, activating their self-destruct function!"
loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier)
diff --git a/code/modules/awaymissions/mission_code/stationCollision.dm b/code/modules/awaymissions/mission_code/stationCollision.dm
index 4312d2f89f48..063966c86d63 100644
--- a/code/modules/awaymissions/mission_code/stationCollision.dm
+++ b/code/modules/awaymissions/mission_code/stationCollision.dm
@@ -44,7 +44,6 @@
icon_state = "retro"
desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces."
// projectile_type = "/obj/projectile/practice"
- clumsy_check = 0 //No sense in having a harmless gun blow up in the clowns face
//Syndicate sub-machine guns.
/obj/item/gun/ballistic/automatic/smg/c20r/sc_c20r
@@ -68,7 +67,6 @@
/obj/item/gun/energy/laser/practice/sc_laser
name = "Old laser"
desc = "A once potent weapon, years of dust have collected in the chamber and lens of this weapon, weakening the beam significantly."
- clumsy_check = 0
/*
* Safe code hints
diff --git a/code/modules/buildmode/buildmode.dm b/code/modules/buildmode/buildmode.dm
index 700485eb1d7f..d85929daa0a8 100644
--- a/code/modules/buildmode/buildmode.dm
+++ b/code/modules/buildmode/buildmode.dm
@@ -26,7 +26,7 @@
var/atom/movable/screen/buildmode/preview_item/preview
/datum/buildmode/New(client/c)
- mode = new /datum/buildmode_mode/basic(src)
+ mode = new /datum/buildmode_mode/advanced(src)
holder = c
buttons = list()
li_cb = CALLBACK(src, PROC_REF(post_login))
@@ -36,6 +36,7 @@
holder.screen += buttons
holder.click_intercept = src
mode.enter_mode(src)
+ modebutton.update_appearance()
/datum/buildmode/proc/quit()
mode.exit_mode(src)
@@ -181,9 +182,6 @@
return TRUE // no doing underlying actions
/proc/togglebuildmode(mob/M as mob in GLOB.player_list)
- set name = "Toggle Build Mode"
- set category = "Event"
-
if(M.client)
if(istype(M.client.click_intercept,/datum/buildmode))
var/datum/buildmode/B = M.client.click_intercept
diff --git a/code/modules/buildmode/submodes/lightmaker.dm b/code/modules/buildmode/submodes/lightmaker.dm
new file mode 100644
index 000000000000..2b50343c641a
--- /dev/null
+++ b/code/modules/buildmode/submodes/lightmaker.dm
@@ -0,0 +1,31 @@
+/datum/buildmode_mode/lightmaker
+ key = "lightmaker"
+
+ var/light_range = 3
+ var/light_power = 1
+ var/light_color = COLOR_WHITE
+
+/datum/buildmode_mode/lightmaker/show_help(client/target_client)
+ to_chat(target_client, span_purple(examine_block(
+ "[span_bold("Left Click")] -> Create light\n\
+ [span_bold("Right Click")] -> Delete light\n\
+ [span_bold("Right Click on Build Mode Button")] -> Change light properties"))
+ )
+
+/datum/buildmode_mode/lightmaker/change_settings(client/target_client)
+ var/choice = alert("Change the new light range, power or color?", "Light Maker", "Range", "Power", "Color", "Cancel")
+ switch(choice)
+ if("Range")
+ light_range = input(target_client, "Range of light", text("Input")) as num|null
+ if("Power")
+ light_power = input(target_client, "Power of light", text("Input")) as num|null
+ if("Color")
+ light_color = input(target_client, "Light color", text("Input")) as color|null
+
+/datum/buildmode_mode/lightmaker/handle_click(client/target_client, params, obj/object)
+ var/list/modifiers = params2list(params)
+
+ if(LAZYACCESS(modifiers, LEFT_CLICK))
+ object.set_light(light_range, light_power, light_color)
+ if(LAZYACCESS(modifiers, RIGHT_CLICK))
+ object.set_light(0,0,COLOR_WHITE)
diff --git a/code/modules/buildmode/submodes/relocate_to.dm b/code/modules/buildmode/submodes/relocate_to.dm
new file mode 100644
index 000000000000..3a2d52bc5d17
--- /dev/null
+++ b/code/modules/buildmode/submodes/relocate_to.dm
@@ -0,0 +1,28 @@
+/datum/buildmode_mode/relocate_to
+ key = "relocate_to"
+
+ var/atom/movable/relocate_atom = null
+
+/datum/buildmode_mode/relocate_to/Destroy()
+ relocate_atom = null
+ return ..()
+
+/datum/buildmode_mode/relocate_to/show_help(client/target_client)
+ to_chat(target_client, span_purple(examine_block(
+ "[span_bold("Select")] -> Left Mouse Button on obj/mob\n\
+ [span_bold("Relocate")] -> Right Mouse Button on turf/obj/mob"))
+ )
+
+/datum/buildmode_mode/relocate_to/handle_click(client/target_client, params, obj/object)
+ var/list/modifiers = params2list(params)
+
+ if(LAZYACCESS(modifiers, LEFT_CLICK))
+ if(isturf(object))
+ return
+ relocate_atom = object
+ to_chat(target_client, "Selected object '[relocate_atom]'")
+ if(LAZYACCESS(modifiers, RIGHT_CLICK))
+ if(relocate_atom)
+ var/atom/loc = get_turf(object)
+ relocate_atom.forceMove(loc)
+ log_admin("Build Mode: [key_name(target_client)] relocated [relocate_atom] at [object] ([AREACOORD(object)])")
diff --git a/code/modules/cargo/blackmarket/blackmarket_item.dm b/code/modules/cargo/blackmarket/blackmarket_item.dm
index fa09c3985de6..cbadddcf1221 100644
--- a/code/modules/cargo/blackmarket/blackmarket_item.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_item.dm
@@ -28,6 +28,8 @@
var/availability_prob = 0
// Should there be an unlimited stock of an item
var/unlimited = FALSE
+ /// Should another item spawn alongside this one in the catalogue?
+ var/datum/blackmarket_item/pair_item
/datum/blackmarket_item/New()
if(isnull(price))
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/clothing.dm b/code/modules/cargo/blackmarket/blackmarket_items/clothing.dm
index 95cb31d27a5e..a4c4195beca0 100644
--- a/code/modules/cargo/blackmarket/blackmarket_items/clothing.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_items/clothing.dm
@@ -1,15 +1,45 @@
/datum/blackmarket_item/clothing
category = "Clothing"
-/datum/blackmarket_item/clothing/ninja_mask
- name = "Space Ninja Mask"
- desc = "Apart from being acid, lava, fireproof and being hard to take off someone it does nothing special on it's own."
- item = /obj/item/clothing/mask/gas/space_ninja
+/datum/blackmarket_item/clothing/cloth
+ name = "Build Your Own Jumpsuit Special"
+ desc = "Ever wanted to learn how to sew? This lovely selection of cloth is perfect to get some practice with."
+ item = /obj/item/stack/sheet/cotton/cloth/ten
price_min = 200
- price_max = 500
- stock_max = 3
- availability_prob = 40
+ price_max = 400
+ stock_max = 5
+ availability_prob = 80
+
+/datum/blackmarket_item/clothing/crown
+ name = "Crown"
+ desc = "A beautiful golden crown, rich with history and pedigree. Better worn than left to collect dust in a museum, right?"
+ item = /obj/item/clothing/head/crown/fancy
+
+ price_min = 1000
+ price_max = 2000
+ stock_max = 1
+ availability_prob = 20
+
+/datum/blackmarket_item/clothing/galaxy_blue
+ name = "Blue Galaxy Suit"
+ desc = "A handsome silk suit, treated with a finish of bluespace dust for an out of this world sheen."
+ item = /obj/item/clothing/under/rank/civilian/lawyer/galaxy
+
+ price_min = 500
+ price_max = 2000
+ stock = 1
+ availability_prob = 20
+
+/datum/blackmarket_item/clothing/galaxy_red
+ name = "Red Galaxy Suit"
+ desc = "A handsome silk suit, treated with a finish of telecrystal dust. It cuts a menacing figure."
+ item = /obj/item/clothing/under/rank/civilian/lawyer/galaxy/red
+
+ price_min = 500
+ price_max = 2000
+ stock = 1
+ availability_prob = 20
/datum/blackmarket_item/clothing/durathread_vest
name = "Durathread Vest"
@@ -31,15 +61,73 @@
stock_max = 4
availability_prob = 50
+/datum/blackmarket_item/clothing/degraded_armor_set
+ name = "Clearance Bin Armor Set"
+ desc = "Looking to protect yourself, but on a tight budget? These previously used vest and helmets served their former owners well! (May they rest in peace.)"
+ item = /obj/item/storage/box
+
+ price_min = 100
+ price_max = 400
+ stock_min = 4
+ stock_max = 6
+ availability_prob = 80
+
+/datum/blackmarket_item/clothing/degraded_armor_set/spawn_item(loc)
+ var/obj/item/storage/box/B = ..()
+ B.name = "Used Armor Set Box"
+ B.desc = "It smells distinctly of iron."
+ new /obj/item/clothing/head/helmet/old(B)
+ new /obj/item/clothing/suit/armor/vest/old(B)
+ return B
+
+/datum/blackmarket_item/clothing/frontiersmen_armor_set
+ name = "X-11 Bulletproof Armor Set"
+ desc = "We got a good deal on some extra bulletproof armor from a Frontiersmen Quartermaster, and we're passing those savings onto you!"
+ item = /obj/item/storage/box
+
+ price_min = 1000
+ price_max = 1750
+ stock_max = 3
+ availability_prob = 50
+
+/datum/blackmarket_item/clothing/frontiersmen_armor_set/spawn_item(loc)
+ var/obj/item/storage/box/B = ..()
+ B.name = "Bulletproof Armor Set Box"
+ B.desc = "A beat up looking box with some armor inside."
+ new /obj/item/clothing/suit/armor/vest/bulletproof/frontier(B)
+ new /obj/item/clothing/head/helmet/bulletproof/x11/frontier(B)
+ return B
+
+/datum/blackmarket_item/clothing/gezena_armor
+ name = "Raksha-Plating vest"
+ desc = "Genuine armor vests used by the PGF Marine Corp. If a military guy in a cape comes by, play dumb."
+ item = /obj/item/clothing/suit/armor/gezena/marine
+ pair_item = /datum/blackmarket_item/clothing/gezena_helmet
+
+ price_min = 750
+ price_max = 1250
+ stock_max = 3
+ availability_prob = 20
+
+/datum/blackmarket_item/clothing/gezena_helmet
+ name = "Raksha-Helm"
+ desc = "A helmet used by the PGF Marine Corp. They won't miss it. Not like there's much to protect up there anyways."
+ item = /obj/item/clothing/head/helmet/gezena
+
+ price_min = 500
+ price_max = 600
+ stock_max = 3
+ availability_prob = 0
+
/datum/blackmarket_item/clothing/full_spacesuit_set
name = "\improper Nanotrasen Branded Spacesuit Box"
desc = "A few boxes of \"Old Style\" space suits fell off the back of a space truck."
item = /obj/item/storage/box
- price_min = 1500
- price_max = 4000
+ price_min = 250
+ price_max = 750
stock_max = 3
- availability_prob = 30
+ availability_prob = 70
/datum/blackmarket_item/clothing/full_spacesuit_set/spawn_item(loc)
var/obj/item/storage/box/B = ..()
@@ -60,11 +148,31 @@
availability_prob = 70
/datum/blackmarket_item/clothing/combatmedic_suit
- name = "Combat Medic hardsuit"
- desc = "A discarded combat medic hardsuit, found in the ruins of a carpet bombed xeno hive. Definately used, but as sturdy as an anchor."
+ name = "Combat Medic Hardsuit"
+ desc = "A discarded combat medic hardsuit, found in the ruins of a carpet bombed xeno hive. Definitely used, but as sturdy as an anchor."
item = /obj/item/clothing/suit/space/hardsuit/combatmedic
- price_min = 5500
- price_max = 7000
- stock_max = 1
- availability_prob = 10
+ price_min = 1000
+ price_max = 2500
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/clothing/ramzi_suit
+ name = "Rusted Red Hardsuit"
+ desc = "A vintage ICW Era Gorlex Maruader hardsuit. The previous owner said we could have it when we pried it off their cold dead hands. Dry cleaning not included."
+ item = /obj/item/clothing/suit/space/hardsuit/syndi/ramzi
+
+ price_min = 1500
+ price_max = 2500
+ stock = 1
+ availability_prob = 30
+
+/datum/blackmarket_item/clothing/frontiersmen_hardsuit
+ name = "Frontiersmen Hardsuit"
+ desc = "An old but durable hardsuit typically used by the Frontiersmen. We accept no liability if you're shot by CLIP while wearing this."
+ item = /obj/item/clothing/suit/space/hardsuit/security/independent/frontier
+
+ price_min = 1000
+ price_max = 2000
+ stock_max = 3
+ availability_prob = 40
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/consumables.dm b/code/modules/cargo/blackmarket/blackmarket_items/consumables.dm
index 00cfd456ea13..e3a20e0e8905 100644
--- a/code/modules/cargo/blackmarket/blackmarket_items/consumables.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_items/consumables.dm
@@ -1,20 +1,10 @@
/datum/blackmarket_item/consumable
category = "Consumables"
-/datum/blackmarket_item/consumable/clown_tears
- name = "Bowl of Clown's Tears"
- desc = "Guaranteed fresh from Weepy Boggins Tragic Kitchen"
- item = /obj/item/reagent_containers/food/snacks/soup/clownstears
- stock = 1
-
- price_min = 520
- price_max = 600
- availability_prob = 10
-
/datum/blackmarket_item/consumable/donk_pocket_box
name = "Box of Donk Pockets"
desc = "A well packaged box containing the favourite snack of every spacefarer."
- item = /obj/item/storage/box/donkpockets
+ item = /obj/effect/spawner/lootdrop/donkpockets
stock_min = 2
stock_max = 5
@@ -29,8 +19,8 @@
stock_min = 2
stock_max = 3
- price_min = 400
- price_max = 700
+ price_min = 200
+ price_max = 500
availability_prob = 50
/datum/blackmarket_item/consumable/suspicious_pills/spawn_item(loc)
@@ -52,12 +42,176 @@
price_max = 60
availability_prob = 50
+/datum/blackmarket_item/consumable/trickwine
+ name = "Trickwine"
+ desc = "The SRM keeps the recipes for their trickwines a closely guarded secret. The Hunters carrying those bottles? Less so."
+ item = /datum/reagent/consumable/ethanol/trickwine/ash_wine
+
+ price_min = 200
+ price_max = 600
+ stock_min = 3
+ stock_max = 7
+ availability_prob = 40
+
+/datum/blackmarket_item/consumable/trickwine/spawn_item(loc)
+ var/trickwine = pick(list(/obj/item/reagent_containers/food/drinks/breakawayflask/vintage/ashwine,
+ /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/icewine,
+ /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/shockwine,
+ /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/hearthwine,
+ /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/forcewine,
+ /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/prismwine))
+ return new trickwine(loc)
+
+
/datum/blackmarket_item/consumable/pumpup
name = "Maintenance Pump-Up"
- desc = "Resist any Baton stun with this handy device!"
+ desc = "Resist any Baton stun with this handy instant tetanus free injector!."
item = /obj/item/reagent_containers/hypospray/medipen/pumpup
stock_max = 3
price_min = 50
price_max = 150
availability_prob = 90
+
+/datum/blackmarket_item/consumable/morphine
+ name = "Morphine Bottle"
+ desc = "Medicinal? Recreational? You can decide with this 30u bottle of morphine!"
+ item = /obj/item/reagent_containers/glass/bottle/morphine
+
+ price_min = 50
+ price_max = 150
+ stock_max = 4
+ availability_prob = 50
+
+/datum/blackmarket_item/consumable/cyanide
+ name = "Cyanide Bottle"
+ desc = "Cyanide, a tried and true classic for all your poisoning needs."
+ item = /obj/item/reagent_containers/glass/bottle/cyanide
+
+ price_min = 300
+ price_max = 600
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/consumable/sodium_thiopental
+ name = "Sodium Thiopental Bottle"
+ desc = "Sodium Thiopental, a potent and fast acting sedative for any occasion."
+ item = /obj/item/reagent_containers/glass/bottle/sodium_thiopental
+
+ price_min = 300
+ price_max = 600
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/consumable/amanitin
+ name = "Amanitin bottle"
+ desc = "A slow acting, but nearly undetectable poison. For the dignified assassin."
+ item = /obj/item/reagent_containers/glass/bottle/amanitin
+
+ price_min = 300
+ price_max = 600
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/consumable/gumballs
+ name = "Gumball"
+ desc = "Looking for a sweet treat? These gumballs are sure to satisfy."
+ item = /obj/item/reagent_containers/food/snacks/gumball
+
+ price_min = 10
+ price_max = 20
+ stock_min = 10
+ stock_max = 20
+ availability_prob = 80
+
+/datum/blackmarket_item/consumable/xeno_meat
+ name = "Xenomorph steak"
+ desc = "The Frontier's most dangerous game, delivered right to your plate! May constitute a violation of your local BARD laws and regulations."
+ item = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
+
+ price_min = 300
+ price_max = 500
+ stock_max = 5
+ availability_prob = 20
+
+/datum/blackmarket_item/consumable/berries
+ name = "Berries"
+ desc = "Some fresh berries we found growing in the corner of our hangar. We're not 100% sure what species these are."
+ item = /obj/item/reagent_containers/food/snacks/grown/berries
+
+ price_min = 25
+ price_max = 100
+ stock_min = 10
+ stock_max = 20
+ availability_prob = 40
+
+/datum/blackmarket_item/consumable/berries/spawn_item(loc)
+ var/berries = pick(list(/obj/item/reagent_containers/food/snacks/grown/berries,
+ /obj/item/reagent_containers/food/snacks/grown/berries/poison/stealth,
+ /obj/item/reagent_containers/food/snacks/grown/berries/death/stealth))
+ return new berries(loc)
+
+/datum/blackmarket_item/consumable/ration
+ name = "Ration Pack"
+ desc = "PGF military surplus rations. What's in them? Who knows. Surprise is the spice of life after all."
+ item = /obj/effect/spawner/lootdrop/ration
+
+ price_min = 150
+ price_max = 400
+ availability_prob = 80
+ unlimited = TRUE
+
+/datum/blackmarket_item/consumable/vimukti
+ name = "Can of Vimukti"
+ desc = "This product was quietly discontinued after multiple health related incidents. But you aren't a coward, are you?"
+ item = /obj/item/reagent_containers/food/drinks/soda_cans/vimukti
+
+ price_min = 10
+ price_max = 50
+ stock_min = 10
+ stock_max = 20
+ availability_prob = 50
+
+/datum/blackmarket_item/consumable/sutures
+ name = "Sutures"
+ desc = "A bundle of sutures for stitching up your latest bullet wound."
+ item = /obj/item/stack/medical/suture
+
+ price_min = 200
+ price_max = 450
+ stock_min = 2
+ stock_max = 5
+ availability_prob = 40
+
+/datum/blackmarket_item/consumable/regen_mesh
+ name = "Regenerative Mesh"
+ desc = "A smoothing pack of regenerative mesh for your burns."
+ item = /obj/item/stack/medical/mesh
+
+ price_min = 200
+ price_max = 450
+ stock_min = 2
+ stock_max = 5
+ availability_prob = 40
+
+/datum/blackmarket_item/consumable/bruise_pack
+ name = "Bruise Packs"
+ desc = "A bundle of old bruise packs, for you guessed it, bruises. Any rumors of these containing hazardous chemicals are just that. Rumors."
+ item = /obj/item/stack/medical/bruise_pack
+
+ price_min = 300
+ price_max = 500
+ stock_min = 2
+ stock_max = 5
+ availability_prob = 30
+
+/datum/blackmarket_item/consumable/ointment
+ name = "Burn ointment"
+ desc = "A tube of burn ointment. It's past the expiry date, but those are only suggestions."
+ item = /obj/item/stack/medical/ointment
+
+ price_min = 300
+ price_max = 500
+ stock_min = 2
+ stock_max = 5
+ availability_prob = 30
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/emergency.dm b/code/modules/cargo/blackmarket/blackmarket_items/emergency.dm
new file mode 100644
index 000000000000..b609da87945d
--- /dev/null
+++ b/code/modules/cargo/blackmarket/blackmarket_items/emergency.dm
@@ -0,0 +1,52 @@
+/datum/blackmarket_item/emergency
+ category = "Emergency"
+
+/datum/blackmarket_item/emergency/plasma
+ name = "Ten Plasma Sheets"
+ desc = "Low on fuel? We can part with some plasma... for a reasonable price."
+ item = /obj/item/stack/sheet/mineral/plasma/ten
+
+ price_min = 1750
+ price_max = 2250
+ availability_prob = 100
+ unlimited = TRUE
+
+/datum/blackmarket_item/emergency/uranium
+ name = "Ten Uranium Sheets"
+ desc = "Fuel? Dirty Bomb? Fancy nightlight? Doesn't matter, we'll supply."
+ item = /obj/item/stack/sheet/mineral/uranium/ten
+
+ price_min = 1750
+ price_max = 2250
+ availability_prob = 100
+ unlimited = TRUE
+
+/datum/blackmarket_item/emergency/ion_thruster
+ name = "Ion Thruster"
+ desc = "Need a boost? We have a leftover engine board or two from a ship we happened to find. If you're lucky, you won't be the next."
+ item = /obj/item/circuitboard/machine/shuttle/engine/electric
+
+ price_min = 2000
+ price_max = 3000
+ stock_max = 5
+ availability_prob = 100
+
+/datum/blackmarket_item/emergency/oyxgen
+ name = "Oxygen Canister"
+ desc = "What keeps us all breathing. It'll keep you breathing too, if you know what's good for you."
+ item = /obj/machinery/portable_atmospherics/canister/oxygen
+
+ price_min = 2000
+ price_max = 3000
+ stock_max = 3
+ availability_prob = 100
+
+/datum/blackmarket_item/emergency/metal_foam
+ name = "Metal Foam Grenade"
+ desc = "Poor piloting blow a hole in the side of your hull? These metal foam grenades should keep everything important in."
+ item = /obj/item/grenade/chem_grenade/metalfoam
+
+ price_min = 300
+ price_max = 750
+ availability_prob = 100
+ unlimited = TRUE
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/explosives.dm b/code/modules/cargo/blackmarket/blackmarket_items/explosives.dm
new file mode 100644
index 000000000000..7fe78cdcd055
--- /dev/null
+++ b/code/modules/cargo/blackmarket/blackmarket_items/explosives.dm
@@ -0,0 +1,88 @@
+/datum/blackmarket_item/explosive
+ category = "Explosives"
+
+/datum/blackmarket_item/explosive/emp_grenade
+ name = "EMP Grenade"
+ desc = "Use this grenade for SHOCKING results!"
+ item = /obj/item/grenade/empgrenade
+
+ price_min = 100
+ price_max = 400
+ stock_max = 5
+ availability_prob = 50
+
+/datum/blackmarket_item/explosive/h_e
+ name = "HE Grenade"
+ desc = "These high explosive grenades are sure to get some bang for your buck."
+ item = /obj/item/grenade/syndieminibomb/concussion
+
+ price_min = 100
+ price_max = 500
+ stock_min = 2
+ stock_max = 5
+ availability_prob = 25
+
+/datum/blackmarket_item/explosive/frag
+ name = "Fragmentation Grenade"
+ desc = "Pull the pin, count to three, and throw for best results."
+ item = /obj/item/grenade/frag
+
+ price_min = 100
+ price_max = 500
+ stock_min = 3
+ stock_max = 5
+ availability_prob = 40
+
+/datum/blackmarket_item/explosive/c4
+ name = "C4"
+ desc = "Looking to make an explosive entrance? These plastic explosives are perfect for the job."
+ item = /obj/item/grenade/c4
+
+ price_min = 100
+ price_max = 400
+ stock_min = 5
+ stock_max = 10
+ availability_prob = 50
+
+/datum/blackmarket_item/explosive/x4
+ name = "X4"
+ desc = "X4 Plastic Explosives! Better than W4, worse than Y4."
+ item = /obj/item/grenade/c4/x4
+
+ price_min = 400
+ price_max = 700
+ stock_min = 2
+ stock_max = 4
+ availability_prob = 25
+
+/datum/blackmarket_item/explosive/slipocalypse
+ name = "Slipocalyse Cluster Bomb"
+ desc = "Wash away the opposition with sudstastic grenade!"
+ item = /obj/item/grenade/clusterbuster/soap
+
+ price_min = 500
+ price_max = 1500
+ stock = 1
+ availability_prob = 10
+
+/datum/blackmarket_item/explosive/rusted_mine
+ name = "Landmine"
+ desc = "Recovered from a decades old ICW battlefield by our best EOD tech, Nicky Nine Fingers."
+ item = /obj/item/mine/pressure/explosive/rusty
+
+ price_min = 250
+ price_max = 500
+ stock_max = 7
+ availability_prob = 50
+
+/datum/blackmarket_item/explosive/rpg
+ name = "PML-9 RPG"
+ desc = "Offically, it's an anti-armor RPG launcher. Technically, it's anti-everything. Most things don't enjoy being hit in the face with high explosives."
+ item = /obj/item/gun/ballistic/rocketlauncher
+
+ price_min = 3500
+ price_max = 6500
+ stock_min = 2
+ stock_max = 5
+ availability_prob = 20
+
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/misc.dm b/code/modules/cargo/blackmarket/blackmarket_items/misc.dm
index c9a165faaa2f..a5e2c67175af 100644
--- a/code/modules/cargo/blackmarket/blackmarket_items/misc.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_items/misc.dm
@@ -16,26 +16,11 @@
desc = "Yeehaw, hardboiled friends! This holster is the first step in your dream of becoming a detective and being allowed to shoot real guns!"
item = /obj/item/clothing/accessory/holster
- price_min = 400
+ price_min = 200
price_max = 800
stock_max = 8
availability_prob = 60
-/datum/blackmarket_item/misc/holywater
- name = "Flask of holy water"
- desc = "Father Lootius' own brand of ready-made holy water."
- item = /obj/item/reagent_containers/food/drinks/bottle/holywater
-
- price_min = 400
- price_max = 600
- stock_max = 3
- availability_prob = 40
-
-/datum/blackmarket_item/misc/holywater/spawn_item(loc)
- if (prob(6.66))
- return new /obj/item/reagent_containers/glass/beaker/unholywater(loc)
- return ..()
-
/datum/blackmarket_item/misc/strange_seed
name = "Strange Seeds"
desc = "An Exotic Variety of seed that can contain anything from glow to acid."
@@ -51,7 +36,74 @@
desc = "This easily hidden satchel can become a versatile tool to anybody with the desire to keep certain items out of sight and out of mind."
item = /obj/item/storage/backpack/satchel/flat/empty
- price_min = 750
+ price_min = 250
price_max = 1000
stock_max = 2
availability_prob = 30
+
+/datum/blackmarket_item/misc/organs
+ name = "Organ Freezer"
+ desc = "Need some fresh organs in a jiffy? We got you covered. Make good use of them, someone died to get these to you."
+ item = /obj/structure/closet/crate/freezer/surplus_limbs/organs
+
+ price_min = 1000
+ price_max = 2500
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/misc/abandoned_crate
+ name = "Abandoned Crate"
+ desc = "Why, it could be anything. Are you feeling lucky?"
+ item = /obj/structure/closet/crate/secure/loot
+
+ price_min = 250
+ price_max = 400
+ availability_prob = 100
+ unlimited = TRUE
+
+/datum/blackmarket_item/misc/spygass
+ name = "Spy Glass Kit"
+ desc = "A set of trick glasses and a linked camera. Suit and dashing shades not included."
+ item = /obj/item/storage/box/rxglasses/spyglasskit
+
+ price_min = 250
+ price_max = 1000
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/misc/ripley_mk_4
+ name = "Ripley Mk IV Upgrade Kit"
+ desc = "Pimp out your Ripley to the CLIP Mark IV Rogue Model today! Killjoy bureaucrats not included, thank god."
+ item = /obj/item/mecha_parts/mecha_equipment/conversion_kit/ripley/clip
+
+ price_min = 1500
+ price_max = 2500
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/misc/secret_docs
+ name = "Classified Documents"
+ desc = "Good people died to get these. Luckily, we aren't good people."
+ item = /obj/item/documents
+
+ price_min = 1000
+ price_max = 10000
+ stock = 1
+ availability_prob = 40
+
+/datum/blackmarket_item/misc/secret_docs/spawn_item(loc)
+ var/docs = pick(list(/obj/item/documents/nanotrasen,
+ /obj/item/documents/solgov,
+ /obj/item/documents/terragov,
+ /obj/item/documents/syndicate/red))
+ return new docs(loc)
+
+/datum/blackmarket_item/misc/black_box
+ name = "Blackbox"
+ desc = "Recorded in here is final moments of some poor souls who are no longer with us. We suggest watching it with friends and popcorn."
+ item = /obj/item/blackbox
+
+ price_min = 1000
+ price_max = 10000
+ stock = 1
+ availability_prob = 40
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/tools.dm b/code/modules/cargo/blackmarket/blackmarket_items/tools.dm
index 0b2cb16aa827..d24cbf68171d 100644
--- a/code/modules/cargo/blackmarket/blackmarket_items/tools.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_items/tools.dm
@@ -1,64 +1,45 @@
/datum/blackmarket_item/tool
category = "Tools"
-/datum/blackmarket_item/tool/caravan_wrench
- name = "Experimental Wrench"
- desc = "The extra fast and handy wrench you always wanted!"
- item = /obj/item/wrench/caravan
- stock = 1
-
- price_min = 400
- price_max = 800
- availability_prob = 20
+/datum/blackmarket_item/tool/combat_wrench
+ name = "Combat Wrench"
+ desc = "Under fire while doing repairs? With this dual purpose wrench, never be caught unprepared again!"
+ item = /obj/item/wrench/combat
-/datum/blackmarket_item/tool/caravan_wirecutters
- name = "Experimental Wirecutters"
- desc = "The extra fast and handy wirecutters you always wanted!"
- item = /obj/item/wirecutters/caravan
+ price_min = 500
+ price_max = 2500
stock = 1
-
- price_min = 400
- price_max = 800
availability_prob = 20
-/datum/blackmarket_item/tool/caravan_screwdriver
- name = "Experimental Screwdriver"
- desc = "The extra fast and handy screwdriver you always wanted!"
- item = /obj/item/screwdriver/caravan
- stock = 1
-
- price_min = 400
- price_max = 800
- availability_prob = 20
+/datum/blackmarket_item/tool/syndi_toolbox
+ name = "Syndicate Toolbox"
+ desc = "A set of specialized tools, built to precision perfection and certified by the GEC."
+ item = /obj/item/storage/toolbox/syndicate
-/datum/blackmarket_item/tool/caravan_crowbar
- name = "Experimental Crowbar"
- desc = "The extra fast and handy crowbar you always wanted!"
- item = /obj/item/crowbar/red/caravan
+ price_min = 500
+ price_max = 2000
stock = 1
-
- price_min = 400
- price_max = 800
- availability_prob = 20
+ availability_prob = 30
/datum/blackmarket_item/tool/binoculars
name = "Binoculars"
desc = "Increase your sight by 150% with this handy Tool!"
item = /obj/item/binoculars
- stock = 1
- price_min = 400
- price_max = 960
- availability_prob = 30
+ price_min = 50
+ price_max = 300
+ stock_min = 2
+ stock_max = 4
+ availability_prob = 70
/datum/blackmarket_item/tool/riot_shield
name = "Riot Shield"
desc = "Protect yourself from an unexpected Riot at your local Police department!"
item = /obj/item/shield/riot
- price_min = 450
- price_max = 650
- stock_max = 2
+ price_min = 300
+ price_max = 800
+ stock_max = 3
availability_prob = 50
/datum/blackmarket_item/tool/thermite_bottle
@@ -66,10 +47,20 @@
desc = "30u of Thermite to assist in creating a quick access point or get away!"
item = /obj/item/reagent_containers/glass/bottle/thermite
- price_min = 500
+ price_min = 100
+ price_max = 600
+ stock_max = 10
+ availability_prob = 50
+
+/datum/blackmarket_item/tool/thermite_jug
+ name = "Thermite Jug"
+ desc = "An extra large 150u jug of thermite. For those hard to reach places."
+ item = /obj/item/reagent_containers/glass/chem_jug/thermite
+
+ price_min = 400
price_max = 1500
stock_max = 3
- availability_prob = 30
+ availability_prob = 20
/datum/blackmarket_item/tool/science_goggles
name = "Science Goggles"
@@ -80,3 +71,105 @@
price_max = 200
stock_max = 3
availability_prob = 50
+
+/datum/blackmarket_item/tool/thermal_eyepatch
+ name = "Thermal Eyepatch"
+ desc = "A thermal eyepatch, capable of tracking the heat signatures of living beings through solid objects."
+ item = /obj/item/clothing/glasses/thermal/eyepatch
+
+ price_min = 1000
+ price_max = 3000
+ stock = 1
+ availability_prob = 20
+
+/datum/blackmarket_item/tool/jumpboots
+ name = "Jump Boots"
+ desc = "Jump ahead of the competition with these specialized mining boots!"
+ item = /obj/item/clothing/shoes/bhop
+
+ price_min = 100
+ price_max = 1000
+ stock = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/tool/rocket_gloves
+ name = "Rocket Gloves"
+ desc = "The pinacle of tackling technology, no one will be able to resist a tackle from these rocket propelled gloves. Make sure not to miss though, we don't sell wheelchairs."
+ item = /obj/item/clothing/gloves/tackler/rocket
+
+ price_min = 500
+ price_max = 2000
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/tool/chem_master
+ name = "Chem Master Board"
+ desc = "A Chem Master board, capable of seperating and packaging reagents. Perfect for any aspiring at home chemist."
+ item = /obj/item/circuitboard/machine/chem_master
+
+ price_min = 1000
+ price_max = 3000
+ stock = 1
+ availability_prob = 30
+
+/datum/blackmarket_item/tool/rcd
+ name = "Rapid Construction Device"
+ desc = "Borrowed from a GEC construction site, this handy device will make building a cinch."
+ item = /obj/item/construction/rcd
+
+ price_min = 1000
+ price_max = 3000
+ stock = 1
+ availability_prob = 30
+
+/datum/blackmarket_item/tool/suppressor
+ name = "Suppressor"
+ desc = "A suppressor, for when you to keep your murder on the down low."
+ item = /obj/item/attachment/silencer
+
+ price_min = 100
+ price_max = 700
+ stock_min = 3
+ stock_max = 6
+ availability_prob = 60
+
+/datum/blackmarket_item/tool/blastwave
+ name = "Blastwave Jackhammer"
+ desc = "We found a shipment of brand new hypersonic jackhammers in a cargo freighter. So we don't need these old ones anymore."
+ item = /obj/item/pickaxe/drill/jackhammer/old
+
+ price_min = 750
+ price_max = 1750
+ stock_max = 3
+ availability_prob = 40
+
+/datum/blackmarket_item/tool/impro_jetpack
+ name = "Improvised Jetpack"
+ desc = "A lovingly handcrafted jetpack built by our salvage techs. For the frugal space explorer."
+ item = /obj/item/tank/jetpack/improvised
+
+ price_min = 500
+ price_max = 1000
+ stock_min = 3
+ stock_max = 6
+ availability_prob = 70
+
+/datum/blackmarket_item/tool/jet_harness
+ name = "Jet Harness"
+ desc = "A compact oxygen filled jet harness for tactical EVA insertions and extractions."
+ item = /obj/item/tank/jetpack/oxygen/harness
+
+ price_min = 1250
+ price_max = 3500
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/tool/jetpack_upgrade
+ name = "Hardsuit Jetpack Upgrade"
+ desc = "A modular jetpack compatible with most hardsuits. If the screws feel a bit loose, it's because the last suit it was attached to was beyond recovery."
+ item = /obj/item/tank/jetpack/suit
+
+ price_min = 1750
+ price_max = 3000
+ stock = 1
+ availability_prob = 25
diff --git a/code/modules/cargo/blackmarket/blackmarket_items/weapons.dm b/code/modules/cargo/blackmarket/blackmarket_items/weapons.dm
index dea11a4c36d3..3d6b32a67569 100644
--- a/code/modules/cargo/blackmarket/blackmarket_items/weapons.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_items/weapons.dm
@@ -6,9 +6,10 @@
desc = "Get the janitor back at his own game with this affordable prank kit."
item = /obj/item/restraints/legcuffs/beartrap
- price_min = 300
- price_max = 550
- stock_max = 3
+ price_min = 150
+ price_max = 400
+ stock_min = 3
+ stock_max = 7
availability_prob = 40
/datum/blackmarket_item/weapon/shotgun_dart
@@ -34,30 +35,344 @@
stock_max = 3
availability_prob = 60
-/datum/blackmarket_item/weapon/emp_grenade
- name = "EMP Grenade"
- desc = "Use this grenade for SHOCKING results!"
- item = /obj/item/grenade/empgrenade
+/datum/blackmarket_item/weapon/switchblade
+ name = "Switchblade"
+ desc = "Extra shrap switchblades for intimidation AND style. Bandages not included if you cut yourself."
+ item = /obj/item/kitchen/knife/switchblade
- price_min = 100
- price_max = 400
- stock_max = 2
+ price_min = 500
+ price_max = 700
+ stock_max = 3
availability_prob = 50
+/datum/blackmarket_item/weapon/sabre
+ name = "SUNS Dueling Sabre"
+ desc = "A mastercrafted sabre formerly wielded by a SUNS academic. It's very sharp, we had to spend hours stitching our fingers back on after getting it."
+ item = /obj/item/storage/belt/sabre/suns
+
+ price_min = 1500
+ price_max = 3500
+ stock = 1
+ availability_prob = 25
+
/datum/blackmarket_item/weapon/derringer
name = "Derringer"
desc = "A concealable handgun small enough to hide nearly anywhere. Uses .38 revolver rounds."
item = /obj/item/gun/ballistic/derringer
- price_min = 400
- price_max = 600
+ price_min = 100
+ price_max = 500
stock_max = 6
availability_prob = 50
-/datum/blackmarket_item/weapon/derringer
+/datum/blackmarket_item/weapon/golden
name = "Golden Derringer"
desc = "A rare custom-made concealable weapon designed to fire illegal .357 rounds."
item = /obj/item/gun/ballistic/derringer/gold
price_min = 1000
price_max = 3000
- stock_max = 1
- availability_prob = 5
+ stock = 1
+ availability_prob = 10
+
+/datum/blackmarket_item/weapon/himehabu
+ name = "Himehabu Pistol"
+ desc = "Great things come in small packages. The Himehabu is perfect for all your espionage needs. Chambered in .22lr."
+ item = /obj/item/gun/ballistic/automatic/pistol/himehabu
+ pair_item = /datum/blackmarket_item/weapon/himehabu_mag
+
+ price_min = 100
+ price_max = 600
+ stock_max = 6
+ availability_prob = 50
+
+/datum/blackmarket_item/weapon/himehabu_mag
+ name = "Himehabu Magazines"
+ desc = "Compact 10 round .22lr magazines for use in the Himehabu pistol."
+ item = /obj/item/ammo_box/magazine/m22lr
+
+ price_min = 100
+ price_max = 200
+ stock_min = 3
+ stock_max = 6
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/e10
+ name = "E-10 Laser Pistol"
+ desc = "Sharplite letting you down? Try these classic Eoehoma Firearms E-10 Laser Pistols."
+ item = /obj/item/gun/energy/laser/e10
+
+ price_min = 500
+ price_max = 1250
+ stock_max = 5
+ availability_prob = 20
+
+/datum/blackmarket_item/weapon/e11
+ name = "E-11 Energy Gun"
+ desc = "Look. I'll be straight with you. These guns are awful. But, they are cheap if you're that desperate."
+ item = /obj/item/gun/energy/e_gun/e11
+
+ price_min = 250
+ price_max = 750
+ stock = 5
+ availability_prob = 60
+
+/datum/blackmarket_item/weapon/e40
+ name = "E-40 Hybrid Assault Rifle"
+ desc = "A dual mode hybrid assault rifle made by the now defunct Eoehoma Firearms. Capable of firing both bullets AND lasers, for the discerning dealer in death. Chambered in Eoehoma .299 Caseless."
+ item = /obj/item/gun/ballistic/automatic/assault/e40
+ pair_item = /datum/blackmarket_item/weapon/e40_mag
+
+ price_min = 7000
+ price_max = 15000
+ stock_max = 2
+ availability_prob = 20
+
+/datum/blackmarket_item/weapon/e40_mag
+ name = "Eoehoma .299 Caseless Magazine"
+ desc = "A 30 round magazine for the E-40 Hybrid Rifle."
+ item = /obj/item/ammo_box/magazine/e40
+
+ price_min = 750
+ price_max = 1250
+ stock_min = 2
+ stock_max = 6
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/e50
+ name = "E-50 Energy Emitter"
+ desc = "An Eoehoma Firearms E-50 Emitter cannon. For when you want a send a message. A really big message."
+ item = /obj/item/gun/energy/laser/e50
+
+ price_min = 4000
+ price_max = 7000
+ stock_max = 2
+ availability_prob = 20
+
+/datum/blackmarket_item/weapon/saber_smg
+ name = "Saber 9mm SMG"
+ desc = "A prototype 9mm submachine gun. Most of these never got past the RND phase and into distribution. But we happen know a guy."
+ item = /obj/item/gun/ballistic/automatic/smg/skm_carbine/inteq/proto
+ pair_item = /datum/blackmarket_item/weapon/saber_mag
+
+ price_min = 2500
+ price_max = 4200
+ stock_max = 2
+ availability_prob = 25
+
+/datum/blackmarket_item/weapon/saber_mag
+ name = "Saber 9mm SMG Magazines"
+ desc = "Magazines for use in the Saber 9mm SMG. No, they don't work as swords."
+ item = /obj/item/ammo_box/magazine/smgm9mm
+
+ price_min = 500
+ price_max = 1000
+ stock = 2
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/bg_16
+ name = "BG-16 Beam Gun"
+ desc = "Not satisfied by Etherbor's civilian offerings? Try this military grade one we found!"
+ item = /obj/item/gun/energy/kalix/pgf
+
+ price_min = 2500
+ price_max = 5000
+ stock = 2
+ availability_prob = 20
+
+/datum/blackmarket_item/weapon/sawn_illestren
+ name = "Sawn off Illestren Rifle"
+ desc = "We had to saw down the barrels on these to fit them in the smuggling compartment. They don't aim too good, but it still packs a good punch."
+ item = /obj/item/gun/ballistic/rifle/illestren/sawn
+
+ price_min = 600
+ price_max = 1250
+ stock_min = 2
+ stock_max = 5
+ availability_prob = 60
+
+/datum/blackmarket_item/weapon/combat_shotgun
+ name = "Combat Shotgun"
+ desc = "Are your arms tired from pumping Hunter's Pride shotguns? This semi-automatic combat shotgun will make killing a breeze."
+ item = /obj/item/gun/ballistic/shotgun/automatic/combat
+
+ price_min = 2000
+ price_max = 4000
+ stock_max = 3
+ availability_prob = 40
+
+/datum/blackmarket_item/weapon/mecha_weapon_bay
+ name = "Concealed Weapons Bay"
+ desc = "Ripley with a laser cannon? Odysseus with a missile rack? Sky's the limit with this omni-compatible weapons bay! (Missiles and lasers not included)"
+ item = /obj/item/mecha_parts/concealed_weapon_bay
+
+ price_min = 1000
+ price_max = 2000
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/weapon/mecha_syringe_gun
+ name = "Mounted Syringe Gun"
+ desc = "We ripped this off an old Nanotrasen exosuit. It's a real advanced piece of equipment. Exosuit not included."
+ item = /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun
+
+ price_min = 5000
+ price_max = 7000
+ stock = 1
+ availability_prob = 15
+
+/datum/blackmarket_item/weapon/mecha_hades
+ name = "Mounted FNX-99 Carbine"
+ desc = "This so called \"Hades\" carbine is sure to burn brightly above the competition! Not to be confused with the \"Hades\" energy rifle. Exosuit not included."
+ item = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine
+ pair_item = /datum/blackmarket_item/weapon/mecha_hades_ammo
+
+ price_min = 2000
+ price_max = 3000
+ stock_max = 2
+ availability_prob = 25
+
+/datum/blackmarket_item/weapon/mecha_hades_ammo
+ name = "FNX-99 Incediary Ammo"
+ desc = "A box of 24 incendiary shells for the FNX-99 mounted carbine."
+ item = /obj/item/mecha_ammo/incendiary
+
+ price_min = 250
+ price_max = 350
+ stock_min = 3
+ stock_max = 5
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/model_h
+ name = "Model H"
+ desc = "A Model H slug pistol. The H stands for Hurt. Chambered in ferromagnetic slugs."
+ item = /obj/item/gun/ballistic/automatic/powered/gauss/modelh
+ pair_item = /datum/blackmarket_item/weapon/model_h_mag
+
+ price_min = 2000
+ price_max = 3500
+ stock = 2
+ availability_prob = 35
+
+/datum/blackmarket_item/weapon/model_h/spawn_item(loc)
+ var/model_h = pick(list(/obj/item/gun/ballistic/automatic/powered/gauss/modelh/suns,
+ /obj/item/gun/ballistic/automatic/powered/gauss/modelh))
+ return new model_h(loc)
+
+/datum/blackmarket_item/weapon/model_h_mag
+ name = "Model H Magazine"
+ desc = "A 10 round magazine for Model H slug pistol."
+ item = /obj/item/ammo_box/magazine/modelh
+
+ price_min = 500
+ price_max = 1000
+ stock_max = 4
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/sgg
+ name = "SSG-669C Rotary Sniper Rifle"
+ desc = "I could tell you it's full name, but we'd be here all day. It's a sniper rifle. It shoots people from far away. Chambered in 8x58mm."
+ item = /obj/item/gun/ballistic/rifle/solgov
+ pair_item = /datum/blackmarket_item/weapon/sgg_stripper
+
+ price_min = 3000
+ price_max = 6000
+ stock = 1
+ availability_prob = 20
+
+/datum/blackmarket_item/weapon/sgg_stripper
+ name = "8x58mm Stripper Clip"
+ desc = "A five round 8x58mm stripper clip for use with the SGG-669C."
+ item = /obj/item/ammo_box/a858
+
+ price_min = 500
+ price_max = 1000
+ stock_min = 4
+ stock_max = 6
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/pistole_c
+ name = "Pistole C"
+ desc = "Pistole Compact? Pistole Caseless? Pistole Cheese? Fuck if I know. All I know is these little numbers pack a nasty sting. Chambered in 5.56 caseless."
+ item = /obj/item/gun/ballistic/automatic/pistol/solgov/old
+ pair_item = /datum/blackmarket_item/weapon/pistole_c_mag
+
+ price_min = 900
+ price_max = 1250
+ stock_max = 3
+ availability_prob = 30
+
+/datum/blackmarket_item/weapon/pistole_c_mag
+ name = "5.56 Caseless Magazine"
+ desc = "A 12 round magazine for the Pistole Cheese."
+ item = /obj/item/ammo_box/magazine/pistol556mm
+
+ price_min = 250
+ price_max = 750
+ stock_max = 2
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/proto_gauss
+ name = "Prototype Gauss Rifle"
+ desc = "A prototype gauss rifle made by Nanotrasen. Perfect for making swiss cheese out of people. Chambered in ferromagnetic pellets."
+ item = /obj/item/gun/ballistic/automatic/powered/gauss
+ pair_item = /datum/blackmarket_item/weapon/proto_gauss_mag
+
+ price_min = 3500
+ price_max = 6000
+ stock = 2
+ availability_prob = 25
+
+/datum/blackmarket_item/weapon/proto_gauss_mag
+ name = "Prototype Gauss Rifle Magazine"
+ desc = "A 25 round ferromagnetic pellet magazine for the prototype gauss rifle."
+ item = /obj/item/ammo_box/magazine/gauss
+
+ price_min = 600
+ price_max = 1100
+ stock_min = 2
+ stock_max = 4
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/tec
+ name = "TEC-9 Machine Pistol"
+ desc = "Hallelujah! It's raining lead! This 9mm machine pistol is capable of spitting out bullets at rapid pace."
+ item = /obj/item/gun/ballistic/automatic/pistol/tec9
+ pair_item = /datum/blackmarket_item/weapon/tec_mag
+
+ price_min = 1500
+ price_max = 2750
+ stock_max = 2
+ availability_prob = 35
+
+/datum/blackmarket_item/weapon/tec_mag
+ name = "TEC-9 AP Magazine"
+ desc = "A 20 round magazine of AP ammo for the TEC-9 machine pistol."
+ item = /obj/item/ammo_box/magazine/tec9
+
+ price_min = 600
+ price_max = 1000
+ stock_max = 2
+ availability_prob = 0
+
+/datum/blackmarket_item/weapon/scout
+ name = "HP Scout"
+ desc = "A scoped rifle chambered in .300 Magnum. As the name would imply, perfect for scouts. Try not to tunnel vision with the scope like the last guy."
+ item = /obj/item/gun/ballistic/rifle/scout
+ pair_item = /datum/blackmarket_item/weapon/scout_stripper
+
+ price_min = 4000
+ price_max = 6500
+ stock = 1
+ availability_prob = 20
+
+/datum/blackmarket_item/weapon/scout_stripper
+ name = ".300 Magnum Stripper Clip"
+ desc = "A 5 round .300 Magnum stripper clips for use with the HP Scout."
+ item = /obj/item/ammo_box/a300
+
+ price_min = 500
+ price_max = 1000
+ stock_min = 4
+ stock_max = 6
+ availability_prob = 0
+
+
diff --git a/code/modules/cargo/blackmarket/blackmarket_market.dm b/code/modules/cargo/blackmarket/blackmarket_market.dm
index 6979d62e1021..3e055048a85b 100644
--- a/code/modules/cargo/blackmarket/blackmarket_market.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_market.dm
@@ -13,8 +13,8 @@
var/list/categories = list()
/// Adds item to the available items and add it's category if it is not in categories yet.
-/datum/blackmarket_market/proc/add_item(datum/blackmarket_item/item)
- if(!prob(initial(item.availability_prob)))
+/datum/blackmarket_market/proc/add_item(datum/blackmarket_item/item, paired)
+ if(!prob(initial(item.availability_prob)) && !paired)
return FALSE
if(ispath(item))
@@ -25,6 +25,10 @@
available_items[item.category] = list()
available_items[item.category] += item
+
+ if(item.pair_item)
+ add_item(item.pair_item, TRUE)
+
return TRUE
/// Handles buying the item, this is mainly for future use and moving the code away from the uplink.
@@ -49,5 +53,4 @@
/datum/blackmarket_market/blackmarket
name = "Black Market"
shipping = list(SHIPPING_METHOD_LTSRBT =50,
- SHIPPING_METHOD_LAUNCH =10,
- SHIPPING_METHOD_TELEPORT=75)
+ SHIPPING_METHOD_LAUNCH =10)
diff --git a/code/modules/cargo/blackmarket/blackmarket_telepad.dm b/code/modules/cargo/blackmarket/blackmarket_telepad.dm
index 0a77d9822bf3..14211cad6878 100644
--- a/code/modules/cargo/blackmarket/blackmarket_telepad.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_telepad.dm
@@ -16,7 +16,7 @@
circuit = /obj/item/circuitboard/machine/ltsrbt
density = TRUE
- idle_power_usage = 200
+ idle_power_usage = IDLE_DRAW_LOW
/// Divider for power_usage_per_teleport.
var/power_efficiency = 1
@@ -27,7 +27,7 @@
/// Current recharge progress.
var/recharge_cooldown = 0
/// Base recharge time which is used to get recharge_time.
- var/base_recharge_time = 100
+ var/base_recharge_time = 10
/// Current /datum/blackmarket_purchase being recieved.
var/recieving
/// Current /datum/blackmarket_purchase being sent to the target uplink.
@@ -37,10 +37,8 @@
/obj/machinery/ltsrbt/Initialize()
. = ..()
- SSblackmarket.telepads += src
/obj/machinery/ltsrbt/Destroy()
- SSblackmarket.telepads -= src
// Bye bye orders.
if(SSblackmarket.telepads.len)
for(var/datum/blackmarket_purchase/P in queue)
@@ -49,9 +47,9 @@
/obj/machinery/ltsrbt/RefreshParts()
recharge_time = base_recharge_time
- // On tier 4 recharge_time should be 20 and by default it is 80 as scanning modules should be tier 1.
+ // On tier 4 recharge_time should be 2 and by default it is 8 as scanning modules should be tier 1.
for(var/obj/item/stock_parts/scanning_module/scan in component_parts)
- recharge_time -= scan.rating * 10
+ recharge_time -= scan.rating
recharge_cooldown = recharge_time
power_efficiency = 0
@@ -61,6 +59,16 @@
if(!power_efficiency)
power_efficiency = 1
+/// Stores the LTSRBT Data in the uplink for linking
+/obj/machinery/ltsrbt/attackby(obj/item/O, mob/user, params)
+ if(istype(O, /obj/item/blackmarket_uplink))
+ var/obj/item/blackmarket_uplink/uplink = O
+ uplink.target = src
+ to_chat(user, "[src] linked to [O].")
+ return TRUE
+
+ return ..()
+
/// Adds /datum/blackmarket_purchase to queue unless the machine is free, then it sets the purchase to be instantly recieved
/obj/machinery/ltsrbt/proc/add_to_queue(datum/blackmarket_purchase/purchase)
if(!recharge_cooldown && !recieving && !transmitting)
diff --git a/code/modules/cargo/blackmarket/blackmarket_uplink.dm b/code/modules/cargo/blackmarket/blackmarket_uplink.dm
index e8abd0424b2d..26363bf71b82 100644
--- a/code/modules/cargo/blackmarket/blackmarket_uplink.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_uplink.dm
@@ -2,6 +2,7 @@
name = "Black Market Uplink"
icon = 'icons/obj/blackmarket.dmi'
icon_state = "uplink"
+ desc = "A jury rigged uplink capable of accessing illicit or grey market vendors. There's a port on side for linking it to a LTSRBT for more practical shipping."
// UI variables.
var/viewing_category
@@ -13,6 +14,8 @@
var/money = 0
/// List of typepaths for "/datum/blackmarket_market"s that this uplink can access.
var/list/accessible_markets = list(/datum/blackmarket_market/blackmarket)
+ // Linked LTSRBT for uplink to send to.
+ var/obj/machinery/ltsrbt/target
/obj/item/blackmarket_uplink/Initialize()
. = ..()
@@ -53,6 +56,10 @@
user.put_in_hands(holochip)
to_chat(user, "You withdraw [amount_to_remove] credits into a holochip.")
+/obj/item/blackmarket_uplink/examine(mob/user)
+ . = ..()
+ . += "It's LTSRBT link [target ? "contains a [target]." : "is empty."]"
+
/obj/item/blackmarket_uplink/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
@@ -87,7 +94,7 @@
/obj/item/blackmarket_uplink/ui_static_data(mob/user)
var/list/data = list()
data["delivery_method_description"] = SSblackmarket.shipping_method_descriptions
- data["ltsrbt_built"] = SSblackmarket.telepads.len
+ data["ltsrbt_built"] = target
data["markets"] = list()
for(var/M in accessible_markets)
var/datum/blackmarket_market/BM = SSblackmarket.markets[M]
@@ -155,7 +162,7 @@
time = 30
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER, TOOL_MULTITOOL)
reqs = list(
- /obj/item/stock_parts/subspace/amplifier = 1,
+ /obj/item/stock_parts/scanning_module = 1,
/obj/item/stack/cable_coil = 15,
/obj/item/radio = 1,
/obj/item/analyzer = 1
diff --git a/code/modules/cargo/bounties/mining.dm b/code/modules/cargo/bounties/mining.dm
index b2df34d8f964..4eb48b09c7cb 100644
--- a/code/modules/cargo/bounties/mining.dm
+++ b/code/modules/cargo/bounties/mining.dm
@@ -41,7 +41,7 @@
description = "Station 14's Research Director claims that pagan bone talismans protect their wearer. Ship them a few so they can start testing."
reward = 7500
required_count = 3
- wanted_types = list(/obj/item/clothing/accessory/talisman)
+ wanted_types = list(/obj/item/clothing/accessory/bonearmlet)
/datum/bounty/item/mining/bone_dagger
name = "Bone Daggers"
diff --git a/code/modules/cargo/bounties/reagent.dm b/code/modules/cargo/bounties/reagent.dm
index a3ece1cce8c6..0fcbbf4f1794 100644
--- a/code/modules/cargo/bounties/reagent.dm
+++ b/code/modules/cargo/bounties/reagent.dm
@@ -71,7 +71,7 @@
/datum/reagent/consumable/ethanol/syndicatebomb,\
/datum/reagent/consumable/ethanol/tequila_sunrise,\
/datum/reagent/consumable/ethanol/manly_dorf,\
- /datum/reagent/consumable/ethanol/thirteenloko,\
+ /datum/reagent/consumable/ethanol/vimukti,\
/datum/reagent/consumable/triple_citrus,\
/datum/reagent/consumable/ethanol/vodkamartini,\
/datum/reagent/consumable/ethanol/whiskeysoda,\
@@ -100,10 +100,7 @@
/datum/reagent/consumable/ethanol/booger,\
/datum/reagent/consumable/ethanol/hippies_delight,\
/datum/reagent/consumable/ethanol/drunkenblumpkin,\
- /datum/reagent/consumable/ethanol/fetching_fizz,\
/datum/reagent/consumable/ethanol/goldschlager,\
- /datum/reagent/consumable/ethanol/manhattan_proj,\
- /datum/reagent/consumable/ethanol/narsour,\
/datum/reagent/consumable/ethanol/neurotoxin,\
/datum/reagent/consumable/ethanol/patron,\
/datum/reagent/consumable/ethanol/quadruple_sec,\
diff --git a/code/modules/cargo/bounties/special.dm b/code/modules/cargo/bounties/special.dm
index af61a6698e44..fa581504ca89 100644
--- a/code/modules/cargo/bounties/special.dm
+++ b/code/modules/cargo/bounties/special.dm
@@ -19,12 +19,12 @@
return (Copy.copy_type && ispath(Copy.copy_type, /obj/item/documents/syndicate))
return TRUE
-/datum/bounty/item/adamantine
- name = "Adamantine"
- description = "Nanotrasen's anomalous materials division is in desparate need for Adamantine. Send them a large shipment and we'll make it worth your while."
+/datum/bounty/item/hellstone
+ name = "Hellstone"
+ description = "Nanotrasen's anomalous materials division is in desparate need for Hellstone. Send them a large shipment and we'll make it worth your while."
reward = 35000
required_count = 10
- wanted_types = list(/obj/item/stack/sheet/mineral/adamantine)
+ wanted_types = list(/obj/item/stack/sheet/mineral/hidden/hellstone)
/datum/bounty/item/trash
name = "Trash"
diff --git a/code/modules/cargo/bounty.dm b/code/modules/cargo/bounty.dm
index 01efd57be70b..3807e9bd6984 100644
--- a/code/modules/cargo/bounty.dm
+++ b/code/modules/cargo/bounty.dm
@@ -166,7 +166,7 @@ GLOBAL_LIST_EMPTY(bounties_list)
/********************************Low Priority Gens********************************/
var/list/low_priority_strict_type_list = list( /datum/bounty/item/alien_organs,
/datum/bounty/item/syndicate_documents,
- /datum/bounty/item/adamantine,
+ /datum/bounty/item/hellstone,
/datum/bounty/item/trash,
/datum/bounty/more_bounties)
diff --git a/code/modules/cargo/centcom_podlauncher.dm b/code/modules/cargo/centcom_podlauncher.dm
index 61e416e9d4f1..dfec659e1644 100644
--- a/code/modules/cargo/centcom_podlauncher.dm
+++ b/code/modules/cargo/centcom_podlauncher.dm
@@ -19,7 +19,7 @@
/client/proc/centcom_podlauncher() //Creates a verb for admins to open up the ui
set name = "Config/Launch Supplypod"
set desc = "Configure and launch a CentCom supplypod full of whatever your heart desires!"
- set category = "Admin.Events"
+ set category = "Event"
new /datum/centcom_podlauncher(usr)//create the datum
//Variables declared to change how items in the launch bay are picked and launched. (Almost) all of these are changed in the ui_act proc
diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm
index 143480b2bc71..82fd2c11d01a 100644
--- a/code/modules/cargo/console.dm
+++ b/code/modules/cargo/console.dm
@@ -1,42 +1,57 @@
+#define BEACON_COST 500
+#define SP_LINKED 1
+#define SP_READY 2
+#define SP_LAUNCH 3
+#define SP_UNLINK 4
+#define SP_UNREADY 5
+
/obj/machinery/computer/cargo
- name = "supply console"
- desc = "Used to order supplies, approve requests, and control the shuttle."
- icon_screen = "supply"
+ name = "outpost communications console"
+ desc = "This console allows the user to communicate with a nearby outpost to \
+ purchase supplies and manage missions. Purchases are delivered near-instantly."
+ icon_screen = "supply_express"
circuit = /obj/item/circuitboard/computer/cargo
light_color = COLOR_BRIGHT_ORANGE
- var/requestonly = FALSE
var/contraband = FALSE
var/self_paid = FALSE
var/safety_warning = "For safety reasons, the automated supply shuttle \
cannot transport live organisms, human remains, classified nuclear weaponry, \
homing beacons or machinery housing any form of artificial intelligence."
- var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible."
- /// radio used by the console to send messages on supply channel
- var/obj/item/radio/headset/radio
/// var that tracks message cooldown
var/message_cooldown
-
-/obj/machinery/computer/cargo/request
- name = "supply request console"
- desc = "Used to request supplies from cargo."
- icon_screen = "request"
- circuit = /obj/item/circuitboard/computer/cargo/request
- requestonly = TRUE
+ var/blockade_warning = "Bluespace instability detected. Delivery impossible."
+ var/message
+ /// Number of beacons printed. Used to determine beacon names.
+ var/printed_beacons = 0
+ var/list/supply_pack_data
+ /// The currently linked supplypod beacon
+ var/obj/item/supplypod_beacon/beacon
+ /// Area instance that cargo pods are sent to
+ var/area/landingzone
+ /// The pod type used to deliver orders
+ var/podType = /obj/structure/closet/supplypod/centcompod
+ /// Cooldown to prevent printing supplypod beacon spam
+ var/cooldown = 0
+ /// Is the console in beacon mode? exists to let beacon know when a pod may come in
+ var/use_beacon = FALSE
+ /// The account to charge purchases to, defaults to the cargo budget
+ var/datum/bank_account/charge_account
/obj/machinery/computer/cargo/Initialize()
. = ..()
- radio = new /obj/item/radio/headset/headset_cargo(src)
var/obj/item/circuitboard/computer/cargo/board = circuit
contraband = board.contraband
if (board.obj_flags & EMAGGED)
obj_flags |= EMAGGED
else
obj_flags &= ~EMAGGED
+ generate_pack_data()
/obj/machinery/computer/cargo/Destroy()
- QDEL_NULL(radio)
+ if(beacon)
+ beacon.unlink_console()
return ..()
/obj/machinery/computer/cargo/proc/get_export_categories()
@@ -65,49 +80,68 @@
/obj/machinery/computer/cargo/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
- ui = new(user, src, "Cargo", name)
+ ui = new(user, src, "OutpostCommunications", name)
ui.open()
+ if(!charge_account)
+ reconnect()
-/obj/machinery/computer/cargo/ui_data()
+/obj/machinery/computer/cargo/ui_data(mob/user)
+ var/canBeacon = beacon && (isturf(beacon.loc) || ismob(beacon.loc))//is the beacon in a valid location?
var/list/data = list()
- data["location"] = SSshuttle.supply.getStatusText()
- var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
+
+ // not a big fan of get_containing_shuttle
+ var/obj/docking_port/mobile/D = SSshuttle.get_containing_shuttle(src)
+ var/datum/overmap/ship/controlled/ship
+ var/outpost_docked = FALSE
if(D)
- data["points"] = D.account_balance
- data["away"] = SSshuttle.supply.get_docked() == SSshuttle.supply_away_port
- data["self_paid"] = self_paid
- data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE
- var/message = "Remember to stamp and send back the supply manifests."
- if(SSshuttle.centcom_message)
- message = SSshuttle.centcom_message
+ ship = D.current_ship
+ outpost_docked = istype(ship.docked_to, /datum/overmap/outpost)
+
+ data["onShip"] = !isnull(ship)
+ data["numMissions"] = ship ? LAZYLEN(ship.missions) : 0
+ data["maxMissions"] = ship ? ship.max_missions : 0
+ data["outpostDocked"] = outpost_docked
+ data["points"] = charge_account ? charge_account.account_balance : 0
+ data["siliconUser"] = user.has_unlimited_silicon_privilege && check_ship_ai_access(user)
+ data["beaconZone"] = beacon ? get_area(beacon) : ""//where is the beacon located? outputs in the tgui
+ data["usingBeacon"] = use_beacon //is the mode set to deliver to the beacon or the cargobay?
+ data["canBeacon"] = !use_beacon || canBeacon //is the mode set to beacon delivery, and is the beacon in a valid location?
+ data["canBuyBeacon"] = charge_account ? (cooldown <= 0 && charge_account.account_balance >= BEACON_COST) : FALSE
+ data["beaconError"] = use_beacon && !canBeacon ? "(BEACON ERROR)" : ""//changes button text to include an error alert if necessary
+ data["hasBeacon"] = beacon != null//is there a linked beacon?
+ data["beaconName"] = beacon ? beacon.name : "No Beacon Found"
+ data["printMsg"] = cooldown > 0 ? "Print Beacon for [BEACON_COST] credits ([cooldown])" : "Print Beacon for [BEACON_COST] credits"//buttontext for printing beacons
+ data["supplies"] = list()
+ message = "Sales are near-instantaneous - please choose carefully."
if(SSshuttle.supplyBlocked)
message = blockade_warning
+ if(use_beacon && !beacon)
+ message = "BEACON ERROR: BEACON MISSING"//beacon was destroyed
+ else if (use_beacon && !canBeacon)
+ message = "BEACON ERROR: MUST BE EXPOSED"//beacon's loc/user's loc must be a turf
data["message"] = message
- data["cart"] = list()
- for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
- data["cart"] += list(list(
- "object" = SO.pack.name,
- "cost" = SO.pack.cost,
- "id" = SO.id,
- "orderer" = SO.orderer,
- "paid" = !isnull(SO.paying_account) //paid by requester
- ))
+ if(!supply_pack_data)
+ generate_pack_data()
+ stack_trace("You didn't give the cargo tech good advice, and he ripped the manifest. As a result, there was no pack data for [src]")
+ data["supplies"] = supply_pack_data
+ if (cooldown > 0)//cooldown used for printing beacons
+ cooldown--
- data["requests"] = list()
- for(var/datum/supply_order/SO in SSshuttle.requestlist)
- data["requests"] += list(list(
- "object" = SO.pack.name,
- "cost" = SO.pack.cost,
- "orderer" = SO.orderer,
- "reason" = SO.reason,
- "id" = SO.id
- ))
+ data["shipMissions"] = list()
+ data["outpostMissions"] = list()
+
+ if(ship)
+ for(var/datum/mission/M as anything in ship.missions)
+ data["shipMissions"] += list(M.get_tgui_info())
+ if(outpost_docked)
+ var/datum/overmap/outpost/out = ship.docked_to
+ for(var/datum/mission/M as anything in out.missions)
+ data["outpostMissions"] += list(M.get_tgui_info())
return data
/obj/machinery/computer/cargo/ui_static_data(mob/user)
var/list/data = list()
- data["requestonly"] = requestonly
data["supplies"] = list()
for(var/pack in SSshuttle.supply_packs)
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
@@ -116,7 +150,7 @@
"name" = P.group,
"packs" = list()
)
- if((P.hidden && !(obj_flags & EMAGGED)) || (P.contraband && !contraband) || (P.special && !P.special_enabled) || P.DropPodOnly)
+ if(P.hidden && !(obj_flags & EMAGGED))
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
@@ -124,7 +158,6 @@
"id" = pack,
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
"small_item" = P.small_item,
- "access" = P.access
))
return data
@@ -133,115 +166,154 @@
if(.)
return
switch(action)
- if("send")
- if(!SSshuttle.supply.canMove())
- say(safety_warning)
+ if("withdrawCash")
+ var/val = text2num(params["value"])
+ // no giving yourself money
+ if(!charge_account || !val || val <= 0)
return
- if(SSshuttle.supplyBlocked)
- say(blockade_warning)
- return
- if(SSshuttle.supply.get_docked() == SSshuttle.supply_home_port)
- SSshuttle.supply.export_categories = get_export_categories()
- SSshuttle.moveShuttle(SSshuttle.supply, SSshuttle.supply_away_port, TRUE)
- say("The supply shuttle is departing.")
- investigate_log("[key_name(usr)] sent the supply shuttle away.", INVESTIGATE_CARGO)
- else
- investigate_log("[key_name(usr)] called the supply shuttle.", INVESTIGATE_CARGO)
- say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(600)] minutes.")
- SSshuttle.moveShuttle(SSshuttle.supply, SSshuttle.supply_home_port, TRUE)
- . = TRUE
+ if(charge_account.adjust_money(-val))
+ var/obj/item/holochip/cash_chip = new /obj/item/holochip(drop_location(), val)
+ if(ishuman(usr))
+ var/mob/living/carbon/human/user = usr
+ user.put_in_hands(cash_chip)
+ playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE)
+ src.visible_message("[src] dispenses a holochip.")
+ return TRUE
+
+ if("LZCargo")
+ use_beacon = FALSE
+ if (beacon)
+ beacon.update_status(SP_UNREADY) //ready light on beacon will turn off
+ if("LZBeacon")
+ use_beacon = TRUE
+ if (beacon)
+ beacon.update_status(SP_READY) //turns on the beacon's ready light
+ if("printBeacon")
+ if(charge_account?.adjust_money(-BEACON_COST))
+ cooldown = 10//a ~ten second cooldown for printing beacons to prevent spam
+ var/obj/item/supplypod_beacon/C = new /obj/item/supplypod_beacon(drop_location())
+ C.link_console(src, usr)//rather than in beacon's Initialize(), we can assign the computer to the beacon by reusing this proc)
+ printed_beacons++//printed_beacons starts at 0, so the first one out will be called beacon # 1
+ beacon.name = "Supply Pod Beacon #[printed_beacons]"
if("add")
- if(istype(src, /obj/machinery/computer/cargo/express))
- return
- var/id = text2path(params["id"])
- var/datum/supply_pack/pack = SSshuttle.supply_packs[id]
- if(!istype(pack))
- return
- if((pack.hidden && !(obj_flags & EMAGGED)) || (pack.contraband && !contraband) || pack.DropPodOnly)
+ var/area/ship/current_area = get_area(src)
+ var/datum/supply_pack/pack = SSshuttle.supply_packs[text2path(params["id"])]
+ if( \
+ !pack || !charge_account?.has_money(pack.cost) || !istype(current_area) || \
+ !istype(current_area.mobile_port.current_ship.docked_to, /datum/overmap/outpost) \
+ )
return
- var/name = "*None Provided*"
- var/rank = "*None Provided*"
- var/ckey = usr.ckey
- if(ishuman(usr))
- var/mob/living/carbon/human/H = usr
- name = H.get_authentification_name()
- rank = H.get_assignment(hand_first = TRUE)
- else if(issilicon(usr))
- name = usr.real_name
- rank = "Silicon"
-
- var/datum/bank_account/account
- if(self_paid && ishuman(usr))
- var/mob/living/carbon/human/H = usr
- var/obj/item/card/id/id_card = H.get_idcard(TRUE)
- if(!istype(id_card))
- say("No ID card detected.")
- return
- account = id_card.registered_account
- if(!istype(account))
- say("Invalid bank account.")
- return
+ var/turf/landing_turf
+ if(!isnull(beacon) && use_beacon) // prioritize beacons over landing in cargobay
+ landing_turf = get_turf(beacon)
+ beacon.update_status(SP_LAUNCH)
+ else if(!use_beacon)// find a suitable supplypod landing zone in cargobay
+ var/list/empty_turfs = list()
+ if(!landingzone)
+ reconnect()
+ if(!landingzone)
+ WARNING("[src] couldnt find a Ship/Cargo (aka cargobay) area on a ship, and as such it has set the supplypod landingzone to the area it resides in.")
+ landingzone = get_area(src)
+ for(var/turf/open/floor/T in landingzone.contents)//uses default landing zone
+ if(T.is_blocked_turf())
+ continue
+ empty_turfs += T
+ CHECK_TICK
+ landing_turf = pick(empty_turfs)
+
+ // note that, because of CHECK_TICK above, we aren't sure if we can
+ // afford the pack, even though we checked earlier. luckily adjust_money
+ // returns false if the account can't afford the price
+ if(landing_turf && charge_account.adjust_money(-pack.cost))
+ var/name = "*None Provided*"
+ var/rank = "*None Provided*"
+ if(ishuman(usr))
+ var/mob/living/carbon/human/H = usr
+ name = H.get_authentification_name()
+ rank = H.get_assignment(hand_first = TRUE)
+ else if(issilicon(usr))
+ name = usr.real_name
+ rank = "Silicon"
+ var/datum/supply_order/SO = new(pack, name, rank, usr.ckey, "")
+ new /obj/effect/pod_landingzone(landing_turf, podType, SO)
+ update_appearance() // ??????????????????
+ return TRUE
- var/reason = ""
- if(requestonly && !self_paid)
- reason = stripped_input("Reason:", name, "")
- if(isnull(reason) || ..())
+ if("mission-act")
+ var/datum/mission/mission = locate(params["ref"])
+ var/obj/docking_port/mobile/D = SSshuttle.get_containing_shuttle(src)
+ var/datum/overmap/ship/controlled/ship = D.current_ship
+ var/datum/overmap/outpost/outpost = ship.docked_to
+ if(!istype(outpost) || mission.source_outpost != outpost) // important to check these to prevent href fuckery
+ return
+ if(!mission.accepted)
+ if(LAZYLEN(ship.missions) >= ship.max_missions)
return
+ mission.accept(ship, loc)
+ return TRUE
+ else if(mission.servant == ship)
+ if(mission.can_complete())
+ mission.turn_in()
+ else
+ mission.give_up()
+ return TRUE
- var/turf/T = get_turf(src)
- var/datum/supply_order/SO = new(pack, name, rank, ckey, reason, account)
- SO.generateRequisition(T)
- if(requestonly && !self_paid)
- SSshuttle.requestlist += SO
- else
- SSshuttle.shoppinglist += SO
- if(self_paid)
- say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.")
- if(requestonly && message_cooldown < world.time)
- radio.talk_into(src, "A new order has been requested.", RADIO_CHANNEL_COMMAND)
- message_cooldown = world.time + 30 SECONDS
- . = TRUE
- if("remove")
- var/id = text2num(params["id"])
- for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
- if(SO.id == id)
- SSshuttle.shoppinglist -= SO
- . = TRUE
- break
- if("clear")
- SSshuttle.shoppinglist.Cut()
- . = TRUE
- if("approve")
- var/id = text2num(params["id"])
- for(var/datum/supply_order/SO in SSshuttle.requestlist)
- if(SO.id == id)
- SSshuttle.requestlist -= SO
- SSshuttle.shoppinglist += SO
- . = TRUE
- break
- if("deny")
- var/id = text2num(params["id"])
- for(var/datum/supply_order/SO in SSshuttle.requestlist)
- if(SO.id == id)
- SSshuttle.requestlist -= SO
- . = TRUE
- break
- if("denyall")
- SSshuttle.requestlist.Cut()
- . = TRUE
- if("toggleprivate")
- self_paid = !self_paid
- . = TRUE
- if(.)
- post_signal("supply")
+/obj/machinery/computer/cargo/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
+ . = ..()
+ reconnect(port)
-/obj/machinery/computer/cargo/proc/post_signal(command)
+/obj/machinery/computer/cargo/proc/reconnect(obj/docking_port/mobile/port)
+ if(!port)
+ var/area/ship/current_area = get_area(src)
+ if(!istype(current_area))
+ return
+ port = current_area.mobile_port
+ if(!port)
+ return
+ charge_account = port.current_ship.ship_account
+ landingzone = locate(/area/ship/cargo) in port.shuttle_areas
- var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS)
+/obj/machinery/computer/cargo/attackby(obj/item/W, mob/living/user, params)
+ var/value = W.get_item_credit_value()
+ if(value && charge_account)
+ charge_account.adjust_money(value)
+ to_chat(user, "You deposit [W]. The Vessel Budget is now [charge_account.account_balance] cr.")
+ qdel(W)
+ return TRUE
+ else if(istype(W, /obj/item/supplypod_beacon))
+ var/obj/item/supplypod_beacon/sb = W
+ if (sb.cargo_console != src)
+ sb.link_console(src, user)
+ return TRUE
+ else
+ to_chat(user, "[src] is already linked to [sb].")
+ ..()
- if(!frequency)
- return
+/obj/machinery/computer/cargo/proc/generate_pack_data()
+ supply_pack_data = list()
+ for(var/pack in SSshuttle.supply_packs)
+ var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
+ if(!supply_pack_data[P.group])
+ supply_pack_data[P.group] = list(
+ "name" = P.group,
+ "packs" = list()
+ )
+ if((P.hidden))
+ continue
+ supply_pack_data[P.group]["packs"] += list(list(
+ "name" = P.name,
+ "cost" = P.cost,
+ "id" = pack,
+ "desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name.
+ ))
+
+/obj/machinery/computer/cargo/retro
+ icon = 'icons/obj/machines/retro_computer.dmi'
+ icon_state = "computer-retro"
+ deconpath = /obj/structure/frame/computer/retro
- var/datum/signal/status_signal = new(list("command" = command))
- frequency.post_signal(src, status_signal)
+/obj/machinery/computer/cargo/solgov
+ icon = 'icons/obj/machines/retro_computer.dmi'
+ icon_state = "computer-solgov"
+ deconpath = /obj/structure/frame/computer/solgov
diff --git a/code/modules/cargo/exports/lavaland.dm b/code/modules/cargo/exports/lavaland.dm
index cd1946265374..4779886622a4 100644
--- a/code/modules/cargo/exports/lavaland.dm
+++ b/code/modules/cargo/exports/lavaland.dm
@@ -7,7 +7,6 @@
unit_name = "minor lava planet artifact"
export_types = list(/obj/item/immortality_talisman,
/obj/item/book_of_babel,
- /obj/item/gun/magic/hook,
/obj/item/wisp_lantern,
/obj/item/reagent_containers/glass/bottle/potion/flight,
/obj/item/katana/cursed,
@@ -23,9 +22,7 @@
/obj/item/lava_staff,
/obj/item/ship_in_a_bottle,
/obj/item/clothing/shoes/clown_shoes/banana_shoes,
- /obj/item/gun/magic/staff/honk,
/obj/item/kitchen/knife/envy,
- /obj/item/gun/ballistic/revolver/russian/soul,
/obj/item/veilrender/vealrender,
/obj/item/nullrod/scythe/talking/necro,
/obj/item/clothing/suit/armor/ascetic)
@@ -55,43 +52,42 @@
/obj/machinery/anomalous_crystal,
/obj/item/mayhem,
/obj/item/blood_contract,
- /obj/item/guardiancreator/miner/choose,//this is basically the most valulable mining loot so good luck getting a miner to part ways
- /obj/item/gun/magic/staff/spellblade,
+ /obj/item/guardiancreator/miner/choose//this is basically the most valulable mining loot so good luck getting a miner to part ways
)
-
+/*
/datum/export/lavaland/trophycommon
cost = 1500
unit_name = "common hunting trophy"
- export_types = list(/obj/item/crusher_trophy/legion_skull,
- /obj/item/crusher_trophy/wolf_ear,
- /obj/item/crusher_trophy/bear_paw,
- /obj/item/crusher_trophy/goliath_tentacle,
- /obj/item/crusher_trophy/watcher_wing)
+ export_types = list(/obj/item/mob_trophy/legion_skull,
+ /obj/item/mob_trophy/wolf_ear,
+ /obj/item/mob_trophy/bear_paw,
+ /obj/item/mob_trophy/goliath_tentacle,
+ /obj/item/mob_trophy/watcher_wing)
/datum/export/lavaland/trophyrare
cost = 5000
unit_name = "rare hunting trophy"
- export_types = list(/obj/item/crusher_trophy/dwarf_skull,
- /obj/item/crusher_trophy/fang,
- /obj/item/crusher_trophy/war_paw,
- /obj/item/crusher_trophy/elder_tentacle,
- /obj/item/crusher_trophy/ice_crystal,
- /obj/item/crusher_trophy/magma_wing,
- /obj/item/crusher_trophy/tail_spike,
- /obj/item/crusher_trophy/ice_wing)
+ export_types = list(/obj/item/mob_trophy/dwarf_skull,
+ /obj/item/mob_trophy/fang,
+ /obj/item/mob_trophy/war_paw,
+ /obj/item/mob_trophy/elder_tentacle,
+ /obj/item/mob_trophy/ice_crystal,
+ /obj/item/mob_trophy/magma_wing,
+ /obj/item/mob_trophy/tail_spike,
+ /obj/item/mob_trophy/ice_wing)
/datum/export/lavaland/trophymega
cost = 10000
unit_name = "big game hunting trophy"
- export_types = list(/obj/item/crusher_trophy/legionnaire_spine,
- /obj/item/crusher_trophy/ash_spike,
- /obj/item/crusher_trophy/demon_claws,
- /obj/item/crusher_trophy/broodmother_tongue,
- /obj/item/crusher_trophy/ice_block_talisman,
- /obj/item/crusher_trophy/king_goat,
- /obj/item/crusher_trophy/miner_eye,
- /obj/item/crusher_trophy/vortex_talisman,
- /obj/item/crusher_trophy/blaster_tubes)
+ export_types = list(/obj/item/mob_trophy/legionnaire_spine,
+ /obj/item/mob_trophy/ash_spike,
+ /obj/item/mob_trophy/demon_claws,
+ /obj/item/mob_trophy/broodmother_tongue,
+ /obj/item/mob_trophy/ice_block_talisman,
+ /obj/item/mob_trophy/miner_eye,
+ /obj/item/mob_trophy/vortex_talisman,
+ /obj/item/mob_trophy/blaster_tubes)
+*/
/datum/export/lavaland/megafauna/total_printout(datum/export_report/ex, notes = TRUE) //in the unlikely case a miner feels like selling megafauna loot
. = ..()
diff --git a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm
index 1bf35a94c440..f81654978ac2 100644
--- a/code/modules/cargo/exports/materials.dm
+++ b/code/modules/cargo/exports/materials.dm
@@ -26,11 +26,6 @@
// Materials. Prices have been heavily nerfed from the original values; mining is boring, so it shouldn't be a good way to make money.
-/datum/export/material/bananium
- cost = 250
- material_id = /datum/material/bananium
- message = "cm3 of bananium"
-
/datum/export/material/diamond
cost = 125
material_id = /datum/material/diamond
@@ -62,15 +57,10 @@
material_id = /datum/material/titanium
message = "cm3 of titanium"
-/datum/export/material/adamantine
+/datum/export/material/hellstone
cost = 125
- material_id = /datum/material/adamantine
- message = "cm3 of adamantine"
-
-/datum/export/material/mythril
- cost = 375
- material_id = /datum/material/mythril
- message = "cm3 of mythril"
+ material_id = /datum/material/hellstone
+ message = "cm3 of hellstone"
/datum/export/material/bscrystal
cost = 75
@@ -82,11 +72,6 @@
message = "cm3 of plastic"
material_id = /datum/material/plastic
-/datum/export/material/runite
- cost = 150
- message = "cm3 of runite"
- material_id = /datum/material/runite
-
/datum/export/material/metal
cost = 2
message = "cm3 of metal"
diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm
deleted file mode 100644
index 81409d63d031..000000000000
--- a/code/modules/cargo/expressconsole.dm
+++ /dev/null
@@ -1,262 +0,0 @@
-#define BEACON_COST 500
-#define SP_LINKED 1
-#define SP_READY 2
-#define SP_LAUNCH 3
-#define SP_UNLINK 4
-#define SP_UNREADY 5
-
-/obj/machinery/computer/cargo/express
- name = "outpost communications console"
- desc = "This console allows the user to communicate with a nearby outpost to \
- purchase supplies and manage missions. Purchases are delivered near-instantly."
- icon_screen = "supply_express"
- circuit = /obj/item/circuitboard/computer/cargo/express
- var/blockade_warning = "Bluespace instability detected. Delivery impossible."
-
- var/message
- /// Number of beacons printed. Used to determine beacon names.
- var/printed_beacons = 0
- var/list/meme_pack_data
- /// The currently linked supplypod beacon
- var/obj/item/supplypod_beacon/beacon
- /// Area instance that cargo pods are sent to
- var/area/landingzone
- /// The pod type used to deliver orders
- var/podType = /obj/structure/closet/supplypod/centcompod
- /// Cooldown to prevent printing supplypod beacon spam
- var/cooldown = 0
- /// Is the console in beacon mode? exists to let beacon know when a pod may come in
- var/use_beacon = FALSE
- /// The account to charge purchases to, defaults to the cargo budget
- var/datum/bank_account/charge_account
-
-/obj/machinery/computer/cargo/express/retro
- icon = 'icons/obj/machines/retro_computer.dmi'
- icon_state = "computer-retro"
- deconpath = /obj/structure/frame/computer/retro
-
-/obj/machinery/computer/cargo/express/solgov
- icon = 'icons/obj/machines/retro_computer.dmi'
- icon_state = "computer-solgov"
- deconpath = /obj/structure/frame/computer/solgov
-
-/obj/machinery/computer/cargo/express/Initialize()
- . = ..()
- packin_up()
-
-/obj/machinery/computer/cargo/express/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
- . = ..()
- reconnect(port)
-
-/obj/machinery/computer/cargo/express/proc/reconnect(obj/docking_port/mobile/port)
- if(!port)
- var/area/ship/current_area = get_area(src)
- if(!istype(current_area))
- return
- port = current_area.mobile_port
- if(!port)
- return
- charge_account = port.current_ship.ship_account
- landingzone = locate(/area/ship/cargo) in port.shuttle_areas
-
-/obj/machinery/computer/cargo/express/Destroy()
- if(beacon)
- beacon.unlink_console()
- return ..()
-
-/obj/machinery/computer/cargo/express/attackby(obj/item/W, mob/living/user, params)
- var/value = W.get_item_credit_value()
- if(value && charge_account)
- charge_account.adjust_money(value)
- to_chat(user, "You deposit [W]. The Vessel Budget is now [charge_account.account_balance] cr.")
- qdel(W)
- return TRUE
- else if(istype(W, /obj/item/supplypod_beacon))
- var/obj/item/supplypod_beacon/sb = W
- if (sb.express_console != src)
- sb.link_console(src, user)
- return TRUE
- else
- to_chat(user, "[src] is already linked to [sb].")
- ..()
-
-/obj/machinery/computer/cargo/express/proc/packin_up() // oh shit, I'm sorry
- meme_pack_data = list() // sorry for what?
- for(var/pack in SSshuttle.supply_packs) // our quartermaster taught us not to be ashamed of our supply packs
- var/datum/supply_pack/P = SSshuttle.supply_packs[pack] // specially since they're such a good price and all
- if(!meme_pack_data[P.group]) // yeah, I see that, your quartermaster gave you good advice
- meme_pack_data[P.group] = list( // it gets cheaper when I return it
- "name" = P.group, // mmhm
- "packs" = list() // sometimes, I return it so much, I rip the manifest
- ) // see, my quartermaster taught me a few things too
- if((P.hidden)) // like, how not to rip the manifest
- continue// by using someone else's crate
- meme_pack_data[P.group]["packs"] += list(list(
- "name" = P.name,
- "cost" = P.cost,
- "id" = pack,
- "desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name.
- ))
-
-/obj/machinery/computer/cargo/express/ui_interact(mob/living/user, datum/tgui/ui)
- ui = SStgui.try_update_ui(user, src, ui)
- if(!ui)
- ui = new(user, src, "OutpostCommunications", name)
- ui.open()
- if(!charge_account)
- reconnect()
-
-/obj/machinery/computer/cargo/express/ui_data(mob/user)
- var/canBeacon = beacon && (isturf(beacon.loc) || ismob(beacon.loc))//is the beacon in a valid location?
- var/list/data = list()
-
- // not a big fan of get_containing_shuttle
- var/obj/docking_port/mobile/D = SSshuttle.get_containing_shuttle(src)
- var/datum/overmap/ship/controlled/ship
- var/outpost_docked = FALSE
- if(D)
- ship = D.current_ship
- outpost_docked = istype(ship.docked_to, /datum/overmap/outpost)
-
- data["onShip"] = !isnull(ship)
- data["numMissions"] = ship ? LAZYLEN(ship.missions) : 0
- data["maxMissions"] = ship ? ship.max_missions : 0
- data["outpostDocked"] = outpost_docked
- data["points"] = charge_account ? charge_account.account_balance : 0
- data["siliconUser"] = user.has_unlimited_silicon_privilege && check_ship_ai_access(user)
- data["beaconZone"] = beacon ? get_area(beacon) : ""//where is the beacon located? outputs in the tgui
- data["usingBeacon"] = use_beacon //is the mode set to deliver to the beacon or the cargobay?
- data["canBeacon"] = !use_beacon || canBeacon //is the mode set to beacon delivery, and is the beacon in a valid location?
- data["canBuyBeacon"] = charge_account ? (cooldown <= 0 && charge_account.account_balance >= BEACON_COST) : FALSE
- data["beaconError"] = use_beacon && !canBeacon ? "(BEACON ERROR)" : ""//changes button text to include an error alert if necessary
- data["hasBeacon"] = beacon != null//is there a linked beacon?
- data["beaconName"] = beacon ? beacon.name : "No Beacon Found"
- data["printMsg"] = cooldown > 0 ? "Print Beacon for [BEACON_COST] credits ([cooldown])" : "Print Beacon for [BEACON_COST] credits"//buttontext for printing beacons
- data["supplies"] = list()
- message = "Sales are near-instantaneous - please choose carefully."
- if(SSshuttle.supplyBlocked)
- message = blockade_warning
- if(use_beacon && !beacon)
- message = "BEACON ERROR: BEACON MISSING"//beacon was destroyed
- else if (use_beacon && !canBeacon)
- message = "BEACON ERROR: MUST BE EXPOSED"//beacon's loc/user's loc must be a turf
- data["message"] = message
- if(!meme_pack_data)
- packin_up()
- stack_trace("You didn't give the cargo tech good advice, and he ripped the manifest. As a result, there was no pack data for [src]")
- data["supplies"] = meme_pack_data
- if (cooldown > 0)//cooldown used for printing beacons
- cooldown--
-
- data["shipMissions"] = list()
- data["outpostMissions"] = list()
-
- if(ship)
- for(var/datum/mission/M as anything in ship.missions)
- data["shipMissions"] += list(M.get_tgui_info())
- if(outpost_docked)
- var/datum/overmap/outpost/out = ship.docked_to
- for(var/datum/mission/M as anything in out.missions)
- data["outpostMissions"] += list(M.get_tgui_info())
-
- return data
-
-/obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui)
- . = ..()
- if(.)
- return
-
- switch(action)
- if("withdrawCash")
- var/val = text2num(params["value"])
- // no giving yourself money
- if(!charge_account || !val || val <= 0)
- return
- if(charge_account.adjust_money(-val))
- var/obj/item/holochip/cash_chip = new /obj/item/holochip(drop_location(), val)
- if(ishuman(usr))
- var/mob/living/carbon/human/user = usr
- user.put_in_hands(cash_chip)
- playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE)
- src.visible_message("[src] dispenses a holochip.")
- return TRUE
-
- if("LZCargo")
- use_beacon = FALSE
- if (beacon)
- beacon.update_status(SP_UNREADY) //ready light on beacon will turn off
- if("LZBeacon")
- use_beacon = TRUE
- if (beacon)
- beacon.update_status(SP_READY) //turns on the beacon's ready light
- if("printBeacon")
- if(charge_account?.adjust_money(-BEACON_COST))
- cooldown = 10//a ~ten second cooldown for printing beacons to prevent spam
- var/obj/item/supplypod_beacon/C = new /obj/item/supplypod_beacon(drop_location())
- C.link_console(src, usr)//rather than in beacon's Initialize(), we can assign the computer to the beacon by reusing this proc)
- printed_beacons++//printed_beacons starts at 0, so the first one out will be called beacon # 1
- beacon.name = "Supply Pod Beacon #[printed_beacons]"
-
- if("add")
- var/area/ship/current_area = get_area(src)
- var/datum/supply_pack/pack = SSshuttle.supply_packs[text2path(params["id"])]
- if( \
- !pack || !charge_account?.has_money(pack.cost) || !istype(current_area) || \
- !istype(current_area.mobile_port.current_ship.docked_to, /datum/overmap/outpost) \
- )
- return
-
- var/turf/landing_turf
- if(!isnull(beacon) && use_beacon) // prioritize beacons over landing in cargobay
- landing_turf = get_turf(beacon)
- beacon.update_status(SP_LAUNCH)
- else if(!use_beacon)// find a suitable supplypod landing zone in cargobay
- var/list/empty_turfs = list()
- if(!landingzone)
- reconnect()
- if(!landingzone)
- WARNING("[src] couldnt find a Ship/Cargo (aka cargobay) area on a ship, and as such it has set the supplypod landingzone to the area it resides in.")
- landingzone = get_area(src)
- for(var/turf/open/floor/T in landingzone.contents)//uses default landing zone
- if(T.is_blocked_turf())
- continue
- empty_turfs += T
- CHECK_TICK
- landing_turf = pick(empty_turfs)
-
- // note that, because of CHECK_TICK above, we aren't sure if we can
- // afford the pack, even though we checked earlier. luckily adjust_money
- // returns false if the account can't afford the price
- if(landing_turf && charge_account.adjust_money(-pack.cost))
- var/name = "*None Provided*"
- var/rank = "*None Provided*"
- if(ishuman(usr))
- var/mob/living/carbon/human/H = usr
- name = H.get_authentification_name()
- rank = H.get_assignment(hand_first = TRUE)
- else if(issilicon(usr))
- name = usr.real_name
- rank = "Silicon"
- var/datum/supply_order/SO = new(pack, name, rank, usr.ckey, "")
- new /obj/effect/pod_landingzone(landing_turf, podType, SO)
- update_appearance() // ??????????????????
- return TRUE
-
- if("mission-act")
- var/datum/mission/mission = locate(params["ref"])
- var/obj/docking_port/mobile/D = SSshuttle.get_containing_shuttle(src)
- var/datum/overmap/ship/controlled/ship = D.current_ship
- var/datum/overmap/outpost/outpost = ship.docked_to
- if(!istype(outpost) || mission.source_outpost != outpost) // important to check these to prevent href fuckery
- return
- if(!mission.accepted)
- if(LAZYLEN(ship.missions) >= ship.max_missions)
- return
- mission.accept(ship, loc)
- return TRUE
- else if(mission.servant == ship)
- if(mission.can_complete())
- mission.turn_in()
- else
- mission.give_up()
- return TRUE
diff --git a/code/modules/cargo/packs/ammo.dm b/code/modules/cargo/packs/ammo.dm
index 28d5ad1ec248..a04d62059792 100644
--- a/code/modules/cargo/packs/ammo.dm
+++ b/code/modules/cargo/packs/ammo.dm
@@ -9,7 +9,7 @@
/datum/supply_pack/ammo/co9mm_mag
name = "9mm Commander Magazine Crate"
desc = "Contains a 9mm magazine for the standard-issue Commander pistol, containing ten rounds."
- contains = list(/obj/item/ammo_box/magazine/co9mm,)
+ contains = list(/obj/item/ammo_box/magazine/co9mm)
cost = 500
/datum/supply_pack/ammo/m45_mag
@@ -18,17 +18,17 @@
contains = list(/obj/item/ammo_box/magazine/m45)
cost = 500
-/datum/supply_pack/ammo/m45_speedloader
- name = ".45 ACP Speedloader Crate"
- desc = "Contains a .45 ACP speedloader for the HP Montagne, containing six rounds."
- contains = list(/obj/item/ammo_box/c45_speedloader)
+/datum/supply_pack/ammo/a44roum_speedloader
+ name = ".44 Roumain Speedloader Crate"
+ desc = "Contains a .44 Roumain speedloader for the HP Montagne, containing six rounds."
+ contains = list(/obj/item/ammo_box/a44roum_speedloader)
cost = 400
/datum/supply_pack/ammo/c38_mag
name = ".38 Speedloader Crate"
desc = "Contains a .38 speedloader for revolvers, containing six rounds."
contains = list(/obj/item/ammo_box/c38)
- cost = 350
+ cost = 250
/datum/supply_pack/ammo/m10mm_mag
name = "10mm Stechkin Magazine Crate"
@@ -70,14 +70,20 @@
cost = 500
contains = list(/obj/item/ammo_box/a12g/slug)
+/datum/supply_pack/ammo/techshells
+ name = "Unloaded Shotgun Technological Shells Crate"
+ desc = "Contains a box of 7 versatile tech shells, capable of producing a variety of deadly effects for any situation. Some assembly required."
+ cost = 210
+ contains = list(/obj/item/storage/box/techshot)
+
/*
.38 ammo
*/
/datum/supply_pack/ammo/winchester_ammo
name = "Flaming Arrow and Detective Special .38 Ammo Boxes"
- desc = "Contains a 30 round ammo boxes for refilling .38 weapons."
- cost = 500
+ desc = "Contains two 50 round ammo boxes for refilling .38 weapons."
+ cost = 250
contains = list(/obj/item/ammo_box/c38_box,
/obj/item/ammo_box/c38_box)
crate_name = "ammo crate"
@@ -143,6 +149,12 @@
contains = list(/obj/item/ammo_box/amagpellet_claris)
cost = 1000
+/datum/supply_pack/ammo/a300
+ name = ".300 Magnum Stripper Clip Crate"
+ desc = "Contains a five round .300 Magnum stripper clip for sniper rifles such as the HP Scout."
+ contains = list(/obj/item/ammo_box/a300)
+ cost = 750
+
/datum/supply_pack/ammo/ebr_ammo
name = "M514 EBR .308 Magazine Crate"
desc = "Contains a .308 magazine for the M514 EBR rifle, containing ten rounds."
@@ -173,6 +185,12 @@
contains = list(/obj/item/ammo_box/a762_40)
cost = 500
+/datum/supply_pack/ammo/a357_ammo_box
+ name = ".357 Ammo Box Crate"
+ desc = "Contains a fifty-round .357 box for revolvers such as the Scarborough Revolver and the HP Firebrand."
+ contains = list(/obj/item/ammo_box/a357_box)
+ cost = 250
+
/datum/supply_pack/ammo/c556mmHITP_ammo_box
name = "5.56 Caseless Ammo Box Crate"
desc = "Contains a fifty-round 5.56mm caseless box for SolGov sidearms like the Pistole C."
@@ -195,7 +213,7 @@
name = "9mm Ammo Box Crate"
desc = "Contains a fifty-round 9mm box for pistols and SMGs such as the Commander or Saber."
contains = list(/obj/item/ammo_box/c9mm)
- cost = 250
+ cost = 200
/datum/supply_pack/ammo/a308_ammo_box
name = "308 Ammo Box Crate"
@@ -207,6 +225,12 @@
name = "9mm AP Ammo Box Crate"
desc = "Contains a fifty-round 9mm box loaded with armor piercing ammo."
contains = list(/obj/item/ammo_box/c9mm/ap)
+ cost = 400
+
+/datum/supply_pack/ammo/a357match_ammo_box
+ name = ".357 Match Ammo Box Crate"
+ desc = "Contains a fifty-round .357 match box for better performance against armor."
+ contains = list(/obj/item/ammo_box/a357_box/match)
cost = 500
/datum/supply_pack/ammo/c556mmHITPap_ammo_box
@@ -231,6 +255,12 @@
name = "9mm HP Ammo Box Crate"
desc = "Contains a fifty-round 9mm box loaded with hollow point ammo, great against unarmored targets."
contains = list(/obj/item/ammo_box/c9mm/hp)
+ cost = 400
+
+/datum/supply_pack/ammo/a357hp_ammo_box
+ name = ".357 HP Ammo Box Crate"
+ desc = "Contains a fifty-round .357 box loaded with hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/ammo_box/a357_box/hp)
cost = 500
/datum/supply_pack/ammo/c10mmhp_ammo_box
@@ -254,7 +284,7 @@
name = "9mm Rubber Ammo Box Crate"
desc = "Contains a fifty-round 9mm box loaded with less-than-lethal rubber rounds."
contains = list(/obj/item/ammo_box/c9mm/rubbershot)
- cost = 250
+ cost = 200
/datum/supply_pack/ammo/c10mmrubber_ammo_box
name = "10mm Rubber Ammo Box Crate"
@@ -281,6 +311,12 @@
contains = list(/obj/item/stock_parts/cell/gun)
cost = 500
+/datum/supply_pack/ammo/guncell/kalix
+ name = "Etherbor Cell Crate"
+ desc = "Contains an Etherbor weapon cell, compatible with Etherbor armaments with a slightly higher capacity."
+ contains = list(/obj/item/stock_parts/cell/gun/kalix)
+ cost = 600
+
/datum/supply_pack/ammo/c46x30mm_boxcrate
name = "4.6x30mm Ammo Box Crate"
desc = "Contains a fifty-round 4.6x30mm box for PDWs such as the WT-550."
@@ -299,6 +335,24 @@
contains = list(/obj/item/ammo_box/c8x50mmhp_box)
cost = 500
+/datum/supply_pack/ammo/a300_box
+ name = ".300 Ammo Box Crate"
+ desc = "Contains a twenty-round .300 Magnum ammo box for sniper rifles such as the HP Scout."
+ contains = list(/obj/item/ammo_box/a300_box)
+ cost = 500
+
+/datum/supply_pack/ammo/a4570_box
+ name = ".45-70 Ammo Box Crate"
+ desc = "Contains a twelve-round box containing devastatingly powerful .45-70 caliber ammunition."
+ contains = list(/obj/item/ammo_box/a4570)
+ cost = 500
+
+/datum/supply_pack/ammo/a4570_box/match
+ name = ".45-70 Match Crate"
+ desc = "Contains a twelve-round box containing devastatingly powerful .45-70 caliber ammunition, that travels faster, pierces armour better, and ricochets off targets."
+ contains = list(/obj/item/ammo_box/a4570/match)
+ cost = 750
+
/datum/supply_pack/ammo/ferropelletboxcrate
name = "Ferromagnetic Pellet Box Crate"
desc = "Contains a fifty-round ferromagnetic pellet ammo box for gauss guns such as the Claris."
@@ -316,3 +370,21 @@
desc = "Contains a fifty-round box for high-powered gauss guns such as the GAR assault rifle."
contains = list(/obj/item/ammo_box/ferrolancebox)
cost = 250
+
+/datum/supply_pack/ammo/a44roum
+ name = ".44 Roumain Ammo Box Crate"
+ desc = "Contains a fifty-round box of .44 roumain ammo for revolvers such as the Shadow and Montagne."
+ contains = list(/obj/item/ammo_box/a44roum)
+ cost = 250
+
+/datum/supply_pack/ammo/a44roum_rubber
+ name = ".44 Roumain Rubber Ammo Box Crate"
+ desc = "Contains a fifty-round box of .44 roumain ammo loaded with less-than-lethal rubber rounds."
+ contains = list(/obj/item/ammo_box/a44roum/rubber)
+ cost = 250
+
+/datum/supply_pack/ammo/a44roum_hp
+ name = ".44 Roumain Hollow Point Ammo Box Crate"
+ desc = "Contains a fifty-round box of .44 roumain hollow point ammo, great against unarmored targets."
+ contains = list(/obj/item/ammo_box/a44roum/hp)
+ cost = 500
diff --git a/code/modules/cargo/packs/costumes_toys.dm b/code/modules/cargo/packs/costumes_toys.dm
index 5bce9871719a..fa63529b7955 100644
--- a/code/modules/cargo/packs/costumes_toys.dm
+++ b/code/modules/cargo/packs/costumes_toys.dm
@@ -115,7 +115,7 @@
if(prob(30)) //Not all mafioso have mustaches, some people also find this item annoying.
new /obj/item/clothing/mask/fakemoustache/italian(C)
if(prob(10)) //A little extra sugar every now and then to shake things up.
- new /obj/item/switchblade(C)
+ new /obj/item/kitchen/knife/switchblade(C)
/datum/supply_pack/costumes_toys/mech_suits
name = "Mech Pilot's Suit Crate"
diff --git a/code/modules/cargo/packs/food.dm b/code/modules/cargo/packs/food.dm
index f383e4e706f1..c7d8b77f46a5 100644
--- a/code/modules/cargo/packs/food.dm
+++ b/code/modules/cargo/packs/food.dm
@@ -25,7 +25,7 @@
/datum/supply_pack/food/pizza
name = "Pizza Crate"
desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99.5% anomaly-free!"
- cost = 6000 // Best prices this side of the galaxy.
+ cost = 3000// Best prices this side of the galaxy.
contains = list(/obj/item/pizzabox/margherita,
/obj/item/pizzabox/mushroom,
/obj/item/pizzabox/meat,
@@ -184,7 +184,7 @@
cost = 5000
contains = list(/obj/item/stack/sheet/mineral/coal/five,
/obj/machinery/grill/unwrenched,
- /obj/item/reagent_containers/food/drinks/soda_cans/monkey_energy)
+ /obj/item/reagent_containers/food/drinks/soda_cans/xeno_energy)
crate_name = "grilling starter kit crate"
crate_type = /obj/structure/closet/crate/large
@@ -317,40 +317,3 @@
crate_name = "ration crate"
crate_type = /obj/structure/closet/crate
-/datum/supply_pack/food/syrup
- name = "Coffee Syrups Box"
- desc = "A packaged box of various syrups, perfect for making your delicious coffee even more diabetic."
- cost = 200
- contains = list(
- /obj/item/reagent_containers/food/drinks/bottle/syrup_bottle/caramel,
- /obj/item/reagent_containers/food/drinks/bottle/syrup_bottle/liqueur,
- )
- crate_name = "coffee syrups box"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/food/coffeekit
- name = "Coffee Equipment Crate"
- desc = "A complete kit to setup your own cozy coffee shop, the coffeemaker is for some reason not included."
- cost = 1000
- contains = list(
- /obj/item/storage/box/coffeepack/robusta,
- /obj/item/storage/box/coffeepack,
- /obj/item/reagent_containers/food/drinks/bottle/coffeepot,
- /obj/item/storage/box/coffee_condi_display,
- /obj/item/reagent_containers/food/condiment/milk,
- /obj/item/reagent_containers/food/condiment/soymilk,
- /obj/item/reagent_containers/food/condiment/sugar,
- /obj/item/reagent_containers/food/drinks/bottle/syrup_bottle/caramel, //one extra syrup as a treat
- )
- crate_name = "coffee equipment crate"
-
-/datum/supply_pack/food/coffeemaker
- name = "Impressa Coffeemaker Crate"
- desc = "An assembled Impressa model coffeemaker."
- cost = 500
- contains = list(
- /obj/machinery/coffeemaker/impressa,
- /obj/item/reagent_containers/food/drinks/bottle/coffeepot,
- )
- crate_name = "coffeemaker crate"
- crate_type = /obj/structure/closet/crate
diff --git a/code/modules/cargo/packs/gun.dm b/code/modules/cargo/packs/gun.dm
index 8ed63f7cfb47..4aaf2f60bef8 100644
--- a/code/modules/cargo/packs/gun.dm
+++ b/code/modules/cargo/packs/gun.dm
@@ -7,46 +7,54 @@
*/
/datum/supply_pack/gun/disposable
- name = "Disposable Guns Crate"
- desc = "In some sectors, these disposable pistols are the only firearms that can be legally sold for less than 400cr. That price is still far too high; this pack contains five."
- cost = 750
- contains = list(/obj/item/gun/ballistic/automatic/pistol/disposable,
- /obj/item/gun/ballistic/automatic/pistol/disposable,
- /obj/item/gun/ballistic/automatic/pistol/disposable,
- /obj/item/gun/ballistic/automatic/pistol/disposable,
- /obj/item/gun/ballistic/automatic/pistol/disposable)
+ name = "Disposable Gun Crate"
+ desc = "In some sectors, these disposable pistols are the only firearms that can be legally sold for less than 200cr. That price is still far too high."
+ cost = 300
+ contains = list(/obj/item/storage/pistolcase/disposable)
crate_name = "disposable gun crate"
+/datum/supply_pack/gun/derringer
+ name = ".38 Derringer Crate"
+ desc = "A cheap, concealable pistol manufactured by the reputable Hunter's Pride. At least it's better than a disposable pistol. Chambered in .38 rounds."
+ cost = 350
+ contains = list(/obj/item/storage/pistolcase/derringer)
+ crate_name = "derringer crate"
+
/datum/supply_pack/gun/commanders
- name = "Commander pistol crate"
+ name = "Commander Pistol Crate"
desc = "Contains a modified Candor 'Commander' pistol, produced by Nanotrasen and chambered in 9mm."
- cost = 750
- contains = list(/obj/item/gun/ballistic/automatic/pistol/commander)
+ cost = 1000
+ contains = list(/obj/item/storage/pistolcase/commander)
/datum/supply_pack/gun/makarovs
- name = "Stechkin pistol crate"
+ name = "Stechkin Pistol Crate"
desc = "Contains a concealable stechkin pistol, produced by Scarborough Arms and chambered in 10mm."
- cost = 1000
- contains = list(/obj/item/gun/ballistic/automatic/pistol,
- /obj/item/gun/ballistic/automatic/pistol)
+ cost = 1250
+ contains = list(/obj/item/storage/pistolcase/stechkin)
+
+/datum/supply_pack/gun/candors
+ name = "Candor Pistol Crate"
+ desc = "Contains a Candor pistol, the trusty sidearm of any spacer, produced by Hunter's Pride and chambered in .45 ACP."
+ cost = 1250
+ contains = list(/obj/item/storage/pistolcase/candor)
-/datum/supply_pack/gun/revolver
- name = "Scarbourgh Revolver crate"
- desc = "Contains a concealable Scarbourgh revolver, chambered in .357."
+/datum/supply_pack/gun/pepperbox
+ name = "HP Firebrand Pepperbox Revolver Crate"
+ desc = "Contains a concealable pepperbox revolver manufactured by the Saint Roumain Militia, chambered in .357."
cost = 1250
- contains = list(/obj/item/gun/ballistic/revolver)
+ contains = list(/obj/item/storage/pistolcase/firebrand)
/datum/supply_pack/gun/detrevolver
- name = "Hunter's Pride Detective Revolver crate"
- desc = "Contains a concealable Solarian revolver, chambered in .38."
- cost = 1000
- contains = list(/obj/item/gun/ballistic/revolver/detective)
+ name = "Hunter's Pride Detective Revolver Crate"
+ desc = "Contains a concealable revolver favored by police departments around the sector, chambered in .38."
+ cost = 600
+ contains = list(/obj/item/storage/pistolcase/detective)
/datum/supply_pack/gun/shadowrevolver
- name = "Shadow Revolver crate"
- desc = "Contains a concealable Shadow revolver, chambered in .45 ACP."
+ name = "Shadow Revolver Crate"
+ desc = "Contains a concealable Shadow revolver, chambered in .44 Roumain."
cost = 1000
- contains = list(/obj/item/gun/ballistic/revolver/shadow)
+ contains = list(/obj/item/storage/pistolcase/shadow)
/*
@@ -57,21 +65,21 @@
name = "Laser Gun Crate"
desc = "Contains a lethal, high-energy laser gun."
cost = 1000
- contains = list(/obj/item/gun/energy/laser)
+ contains = list(/obj/item/storage/pistolcase/laser)
crate_name = "laser crate"
-/datum/supply_pack/gun/laser
+/datum/supply_pack/gun/mini_energy
name = "Mini Energy Gun Crate"
desc = "Contains a small, versatile energy gun, capable of firing both nonlethal and lethal blasts, but with a limited power cell."
cost = 500
- contains = list(/obj/item/gun/energy/e_gun/mini)
+ contains = list(/obj/item/storage/pistolcase/miniegun)
crate_name = "laser crate"
/datum/supply_pack/gun/energy
name = "Energy Gun Crate"
desc = "Contains a versatile energy gun, capable of firing both nonlethal and lethal blasts of light."
cost = 1250
- contains = list(/obj/item/gun/energy/e_gun)
+ contains = list(/obj/item/storage/pistolcase/egun)
crate_name = "energy gun crate"
crate_type = /obj/structure/closet/crate/secure/plasma
@@ -79,27 +87,48 @@
name = "Ion Rifle Crate"
desc = "Contains a single Mk.I Ion Projector, a special anti-tank rifle designed to disable electronic threats at range."
cost = 10000
- contains = list(/obj/item/gun/energy/ionrifle)
+ contains = list(/obj/item/storage/pistolcase/iongun)
crate_name = "ion rifle crate"
crate_type = /obj/structure/closet/crate/secure/plasma
+/datum/supply_pack/gun/laser/kalix/pistol
+ name = "Etherbor SG-8 Beam Pistol Crate"
+ desc = "Contains a single SG-8 Beam Pistol, a civilian-grade sidearm developed in the PGF, manufactured by Etherbor Industries."
+ cost = 1000
+ contains = list(/obj/item/storage/pistolcase/kalixpistol)
+ crate_name = "beam pistol crate"
+
+/datum/supply_pack/gun/laser/kalix
+ name = "Etherbor BG-12 Beam Rifle Crate"
+ desc = "Contains a single BG-12 Beam Rifle, a civilian-grade semi-automatic developed in the PGF, manufactured by Etherbor Industries."
+ cost = 3000
+ contains = list(/obj/item/storage/guncase/kalixrifle)
+ crate_name = "beam rifle crate"
+
/*
Shotguns
*/
+/datum/supply_pack/gun/doublebarrel_shotgun
+ name = "Double Barrel Shotgun Crate"
+ desc = "For when you need to deal with 2 drunkards the old-fashioned way. Contains a double-barreled shotgun, favored by Bartenders. Warranty voided if sawed off."
+ cost = 1000
+ contains = list(/obj/item/storage/guncase/doublebarrel)
+ crate_name = "shotguns crate"
+
/datum/supply_pack/gun/hellfire_shotgun
name = "Hellfire Shotgun Crate"
- desc = "For when you need to deal with 7 hooligans. Contains a pump shotgun, with a 8-round capacity."
+ desc = "For when you need to deal with 8 hooligans. Contains a pump shotgun, with a 8-round capacity."
cost = 2000
- contains = list(/obj/item/gun/ballistic/shotgun/hellfire)
- crate_name = "shotguns crate"
+ contains = list(/obj/item/storage/guncase/hellfire)
+ crate_name = "shotgun crate"
/datum/supply_pack/gun/brimstone_shotgun
name = "Brimstone Shotgun Crate"
desc = "For when you need to deal with 5 hooligans, and QUICKLY. Contains a slamfire shotgun, with a 5-round capacity. Warranty voided if sawed off."
cost = 2000
- contains = list(/obj/item/gun/ballistic/shotgun/brimstone)
- crate_name = "shotguns crate"
+ contains = list(/obj/item/storage/guncase/brimstone)
+ crate_name = "shotgun crate"
/*
Rifles
@@ -107,61 +136,84 @@
/datum/supply_pack/gun/winchester
name = "Flaming Arrow Lever Action Rifle Crate"
- desc = "Contains a antiquated lever action rifle intended for hunting wildlife. Chambered in .38 rounds."
+ desc = "Contains an antiquated lever action rifle intended for hunting wildlife. Chambered in .38 rounds."
cost = 750
- contains = list(/obj/item/gun/ballistic/shotgun/flamingarrow)
+ contains = list(/obj/item/storage/guncase/winchester)
crate_name = "rifle crate"
-/datum/supply_pack/gun/cobra20
- name = "Cobra-20 SMG Crate"
- desc = "Contains a .45 submachine gun, manufactured by Scaraborough Arms and chambered in .45"
- cost = 3000
- contains = list(/obj/item/gun/ballistic/automatic/smg/c20r/cobra)
- crate_name = "SMG crate"
-
/datum/supply_pack/gun/illestren
name = "Illestren Rifle Crate"
- desc = "Contains a expertly made bolt action rifle intended for hunting wildlife. Chambered in 8x50mmR rounds."
+ desc = "Contains an expertly made bolt action rifle intended for hunting wildlife. Chambered in 8x50mmR rounds."
cost = 1250
- contains = list(/obj/item/gun/ballistic/rifle/illestren)
+ contains = list(/obj/item/storage/guncase/illestren)
+ crate_name = "rifle crate"
+
+/datum/supply_pack/gun/beacon
+ name = "Contender Break Action Rifle Crate"
+ desc = "Contains a single shot break action rifle to hunt wildlife that annoys you in particular. Chambered in devastating .45-70 rounds. Warranty voided if sawed off."
+ cost = 2250
+ contains = list(/obj/item/storage/guncase/beacon)
+ crate_name = "rifle crate"
+
+/datum/supply_pack/gun/scout
+ name = "Scout Sniper Rifle Crate"
+ desc = "Contains a traditional scoped rifle to hunt wildlife and big game from a respectful distance. Chambered in powerful .300 Magnum."
+ cost = 5500
+ contains = list(/obj/item/storage/guncase/scout)
crate_name = "rifle crate"
+/datum/supply_pack/gun/cobra20
+ name = "Cobra-20 SMG Crate"
+ desc = "Contains a .45 submachine gun, manufactured by Scaraborough Arms and chambered in .45"
+ cost = 6000
+ contains = list(/obj/item/storage/guncase/cobra)
+ crate_name = "SMG crate"
+
/datum/supply_pack/gun/wt550
name = "WT-550 Auto Rifle Crate"
desc = "Contains a high-powered, automatic personal defense weapon chambered in 4.6x30mm."
- cost = 4000
- contains = list(/obj/item/gun/ballistic/automatic/smg/wt550)
+ cost = 6000
+ contains = list(/obj/item/storage/guncase/wt550)
crate_name = "auto rifle crate"
/datum/supply_pack/gun/p16
name = "P16 Assault Rifle Crate"
desc = "Contains a high-powered, automatic rifle chambered in 5.56mm."
- cost = 5000
- contains = list(/obj/item/gun/ballistic/automatic/assault/p16)
+ cost = 9000
+ contains = list(/obj/item/storage/guncase/p16)
crate_name = "auto rifle crate"
/datum/supply_pack/gun/skm
name = "SKM-24 Rifle Crate"
desc = "Contains a high-powered, automatic rifle chambered in 7.62x40mm CLIP."
- cost = 5000
- contains = list(/obj/item/gun/ballistic/automatic/assault/skm)
+ cost = 9000
+ contains = list(/obj/item/storage/guncase/skm)
crate_name = "auto rifle crate"
-/*
- Firing pins
-*/
-
-/datum/supply_pack/gun/firingpins
- name = "Standard Firing Pins Crate"
- desc = "Upgrade your arsenal with 10 standard firing pins."
- cost = 2000
- contains = list(/obj/item/storage/box/firingpins,
- /obj/item/storage/box/firingpins)
- crate_name = "firing pins crate"
-
-/datum/supply_pack/gun/lasertag_pins
- name = "Laser Tag Firing Pins Crate"
- desc = "Three laser tag firing pins used in laser-tag units to ensure users are wearing their vests."
- cost = 1500
- contains = list(/obj/item/storage/box/lasertagpins)
- crate_name = "laser tag pin crate"
+/datum/supply_pack/gun/attachment/rail_light
+ name = "Tactical Rail Light Crate"
+ desc = "Contains a single rail light to be mounted on a firearm."
+ cost = 250
+ contains = list(/obj/item/attachment/rail_light)
+ crate_name = "rail light crate"
+
+/datum/supply_pack/gun/attachment/laser_sight
+ name = "Laser Sight Crate"
+ desc = "Contains a single rail light to be mounted on a firearm."
+ cost = 250
+ contains = list(/obj/item/attachment/laser_sight)
+ crate_name = "laser sight crate"
+
+/datum/supply_pack/gun/attachment/bayonet
+ name = "Bayonet Crate"
+ desc = "Contains a single bayonet to be mounted on a firearm."
+ cost = 250
+ contains = list(/obj/item/attachment/bayonet)
+ crate_name = "bayonet crate"
+
+/datum/supply_pack/gun/attachment/silencer
+ name = "Suppressor Crate"
+ desc = "Contains a single suppressor to be mounted on a firearm."
+ cost = 250
+ contains = list(/obj/item/attachment/silencer)
+ crate_name = "silencer crate"
diff --git a/code/modules/cargo/packs/machinery.dm b/code/modules/cargo/packs/machinery.dm
index 215b146fad43..f25e4818329e 100644
--- a/code/modules/cargo/packs/machinery.dm
+++ b/code/modules/cargo/packs/machinery.dm
@@ -66,25 +66,22 @@
/datum/supply_pack/machinery/thermomachine
name = "Thermomachine Crate"
desc = "Freeze or heat your air."
- cost = 2000
- contains = list(/obj/item/circuitboard/machine/thermomachine,
- /obj/item/circuitboard/machine/thermomachine)
+ cost = 1000
+ contains = list(/obj/item/circuitboard/machine/thermomachine)
crate_name = "thermomachine crate"
/datum/supply_pack/machinery/portapump
name = "Portable Air Pump Crate"
- desc = "Want to drain a room of air without losing a drop? We've got you covered. Contains two portable air pumps."
- cost = 3000
- contains = list(/obj/machinery/portable_atmospherics/pump,
- /obj/machinery/portable_atmospherics/pump)
+ desc = "Want to drain a room of air without losing a drop? We've got you covered. Contains a portable air pump."
+ cost = 1500
+ contains = list(/obj/machinery/portable_atmospherics/pump)
crate_name = "portable air pump crate"
/datum/supply_pack/machinery/portascrubber
name = "Portable Scrubber Crate"
- desc = "Clean up that pesky plasma leak with your very own set of two portable scrubbers."
- cost = 3000
- contains = list(/obj/machinery/portable_atmospherics/scrubber,
- /obj/machinery/portable_atmospherics/scrubber)
+ desc = "Clean up that pesky plasma leak with your very own portable scrubber."
+ cost = 1500
+ contains = list(/obj/machinery/portable_atmospherics/scrubber)
crate_name = "portable scrubber crate"
/datum/supply_pack/machinery/hugescrubber
@@ -136,6 +133,14 @@
Miscellaneous machines
*/
+/datum/supply_pack/machinery/gravgen
+ name = "Ship-Portable Gravity Generator Crate"
+ desc = "For those tired of their tools floating away from them. Contains a single gravity generator."
+ cost = 2000
+ contains = list(/obj/machinery/power/ship_gravity/unanchored)
+ crate_name = "gravity generator crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
/datum/supply_pack/machinery/breach_shield_gen
name = "Anti-breach Shield Projector Crate"
desc = "Hull breaches again? Say no more with the Nanotrasen Anti-Breach Shield Projector! Uses forcefield technology to keep the air in, and the space out. Contains two shield projectors."
@@ -147,11 +152,9 @@
/datum/supply_pack/machinery/wall_shield_gen
name = "Shield Generator Crate"
- desc = "These four shield wall generators are guaranteed to keep any unwanted lifeforms on the outside, where they belong! Not rated for containing singularities or tesla balls."
- cost = 2000
+ desc = "These two shield wall generators are guaranteed to keep any unwanted lifeforms on the outside, where they belong! Not rated for containing singularities or tesla balls."
+ cost = 1000
contains = list(/obj/machinery/power/shieldwallgen,
- /obj/machinery/power/shieldwallgen,
- /obj/machinery/power/shieldwallgen,
/obj/machinery/power/shieldwallgen)
crate_name = "shield generators crate"
crate_type = /obj/structure/closet/crate/secure/plasma
@@ -168,7 +171,7 @@
/datum/supply_pack/machinery/blackmarket_telepad
name = "Black Market LTSRBT"
desc = "Need a faster and better way of transporting your illegal goods from and to the sector? Fear not, the Long-To-Short-Range-Bluespace-Transceiver (LTSRBT for short) is here to help. Contains a LTSRBT circuit, two bluespace crystals, and one ansible."
- cost = 5000
+ cost = 1000
contains = list(
/obj/item/circuitboard/machine/ltsrbt,
/obj/item/stack/ore/bluespace_crystal/artificial,
@@ -207,6 +210,15 @@
crate_name = "plasma thruster crate"
crate_type = /obj/structure/closet/crate/engineering
+/datum/supply_pack/machinery/combustion_thruster
+ name = "Combustion Thruster Crate"
+ desc = "A crate containing a combustion thruster and its heater's electronics. For when you need complicated thrust."
+ cost = 2000
+ contains = list(/obj/item/circuitboard/machine/shuttle/fire_heater,
+ /obj/item/circuitboard/machine/shuttle/engine/fire)
+ crate_name = "combustion thruster crate"
+ crate_type = /obj/structure/closet/crate/engineering
+
/datum/supply_pack/machinery/drill_crate
name = "Heavy duty laser mining drill"
desc = "An experimental laser-based mining drill that Nanotrasen is kindly allowing YOU, the customer, to opt into testing of."
diff --git a/code/modules/cargo/packs/mechs.dm b/code/modules/cargo/packs/mechs.dm
index e184a8372627..937126a86361 100644
--- a/code/modules/cargo/packs/mechs.dm
+++ b/code/modules/cargo/packs/mechs.dm
@@ -103,21 +103,25 @@ Mech Equipment
/datum/supply_pack/mech/equipment/drill
name = "Mech drill kit"
- desc = "A trio of mechanized drills"
- cost = 1500
+ desc = "Contains one mechanized drill for heavy duty digging."
+ cost = 500
contains = list(
- /obj/item/mecha_parts/mecha_equipment/drill,
- /obj/item/mecha_parts/mecha_equipment/drill,
/obj/item/mecha_parts/mecha_equipment/drill
)
-/datum/supply_pack/mech/equipment/scanners
+/datum/supply_pack/mech/equipment/diamond_drill
+ name = "Mech diamond drill kit"
+ desc = "Contains mechanized diamond drill, for the enterprising prospector!"
+ cost = 750
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill
+ )
+
+/datum/supply_pack/mech/equipment/scanner
name = "Mech scanner kit"
- desc = "A trio of electronic mining scanners, graded to interface with a mech"
- cost = 1000
+ desc = "An electronic mining scanner, graded to interface with a mech."
+ cost = 350
contains = list(
- /obj/item/mecha_parts/mecha_equipment/mining_scanner,
- /obj/item/mecha_parts/mecha_equipment/mining_scanner,
/obj/item/mecha_parts/mecha_equipment/mining_scanner
)
@@ -129,15 +133,61 @@ Mech Equipment
/obj/item/mecha_parts/mecha_equipment/generator
)
+/datum/supply_pack/mech/equipment/nuclear_gen
+ name = "Mech nuclear generator kit"
+ desc = "Contains a uranium-fueled generator for a mech, ideal for polluting the environment."
+ cost = 1250
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/generator/nuclear
+ )
+
+/datum/supply_pack/mech/equipment/tesla_energy_relay
+ name = "Mech tesla relay kit"
+ desc = "Contains an advanced exosuit module which draws power from nearby APCs."
+ cost = 1750
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
+ )
+
/datum/supply_pack/mech/equipment/clamp
name = "Mech clamp kit"
- desc = "Two clamps designed for mechanized freight hauling."
- cost = 700
+ desc = "Contains a clamp designed for mechanized freight hauling."
+ cost = 350
contains = list(
- /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp,
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp
)
+/datum/supply_pack/mech/equipment/extinguisher
+ name = "Mech extinguisher kit"
+ desc = "Contains a heavy duty fire extinguisher, for heavy duty firefighting."
+ cost = 250
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/extinguisher
+ )
+
+/datum/supply_pack/mech/equipment/cable_layer
+ name = "Mech RCL Kit"
+ desc = "Contains a \"rapid cable layer\" for laying down long lengths of wire."
+ cost = 250
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/cable_layer
+ )
+
+/datum/supply_pack/mech/equipment/mech_sleeper
+ name = "Mech Mounted Sleeper Kit"
+ desc = "Contains a mounted sleeper device, used for retrieving and stabilizing patients."
+ cost = 1000
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/medical/sleeper
+ )
+
+/datum/supply_pack/mech/equipment/beam_gun
+ name = "Mech Beam Gun Kit"
+ desc = "Contains an advanced mounted medical beamgun, capable of alleviating wounds to targets."
+ cost = 7000
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam
+ )
/datum/supply_pack/mech/equipment/rcs
name = "Mech RCS kit"
desc = "A gas fueled RCS pack, ideal for mechanized space operation."
@@ -148,25 +198,46 @@ Mech Equipment
/datum/supply_pack/mech/equipment/ripley_upgrade
name = "APLU upgrade kit"
- desc = "The components needed to upgrade an APLU MK-I to be spaceworthy"
+ desc = "Contains an APLU MK II upgrade kit. The upgrade will replace the cockpit with a spaceworthy canopy, but the added weight makes it slower."
cost = 1500
contains = list(
/obj/item/mecha_parts/mecha_equipment/conversion_kit/ripley
)
+/datum/supply_pack/mech/equipment/melee_armor_booster
+ name = "Mech CCW armor kit"
+ desc = "A \"close combat weaponry\" module designed to deflect melee attacks."
+ cost = 750
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster
+ )
+
+/datum/supply_pack/mech/equipment/projectile_armor_booster
+ name = "Mech projectile armor kit"
+ desc = "A protective exosuit module designed to deflect ranged attacks."
+ cost = 1000
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
+ )
+
/*
weapons
*/
-/datum/supply_pack/mech/equipment/pka
- name = "Proto-Kinetic Accelerator kit"
+/datum/supply_pack/mech/weapon
+ name = "Mech weapons crate"
+ crate_type = /obj/structure/closet/crate/secure/weapon
+ crate_name = "mech weapon crate"
+
+/datum/supply_pack/mech/weapon/pka
+ name = "Mech Mounted Proto-Kinetic Accelerator kit"
desc = "A ranged mining attachment for any mech."
- cost = 1500
+ cost = 750
contains = list(
/obj/item/mecha_parts/mecha_equipment/weapon/energy/mecha_kineticgun
)
-/datum/supply_pack/mech/equipment/laser
+/datum/supply_pack/mech/weapon/laser
name = "Immolator kit"
desc = "A light laser cannon designed for combat usage."
cost = 1000
@@ -174,10 +245,75 @@ weapons
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
)
-/datum/supply_pack/mech/equipment/laser
+/datum/supply_pack/mech/weapon/biglaser
name = "Solaris kit"
desc = "A heavy laser cannon designed for combat usage."
cost = 2000
contains = list(
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
)
+
+/datum/supply_pack/mech/weapon/ion_cannon
+ name = "MK4 ion cannon kit"
+ desc = "Contains a heavy ion cannon for disabling technology in large blasts."
+ cost = 3000
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion
+ )
+
+/datum/supply_pack/mech/weapon/scattershot
+ name = "LBX AC 10 kit"
+ desc = "Contains a \"Scattershot\" gun to mount on combat exosuits."
+ cost = 1750
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
+ )
+
+/datum/supply_pack/mech/weapon/lmg
+ name = "Ultra AC 2 kit"
+ desc = "Contains a mounted gun which fires in three round bursts."
+ cost = 2250
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
+ )
+
+/datum/supply_pack/mech/weapon/missile_rack
+ name = "BRM-6 kit"
+ desc = "Contains a low-explosive missile launcher, excellent for breaching through obstacles."
+ cost = 3000
+ contains = list(
+ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/breaching
+ )
+
+/*
+ammo
+*/
+
+/datum/supply_pack/mech/ammo
+ name = "Mech ammo crate"
+ crate_type = /obj/structure/closet/crate/secure/gear
+ crate_name = "mech ammo crate"
+
+/datum/supply_pack/mech/ammo/scattershot_ammo
+ name = "LBX AC 10 ammo box"
+ desc = "Contains a fourty-round box of upscaled buckshot, to be loaded directly in a mounted LBX AC 10."
+ cost = 500
+ contains = list(
+ /obj/item/mecha_ammo/scattershot
+ )
+
+/datum/supply_pack/mech/ammo/lmg_ammo
+ name = "Ultra AC 2 ammo box"
+ desc = "Contains a three hundred-round box of heavy ammunition for the Ultra AC 2."
+ cost = 750
+ contains = list(
+ /obj/item/mecha_ammo/lmg
+ )
+
+/datum/supply_pack/mech/ammo/missile_rack_ammo
+ name = "BRM-6 missile box"
+ desc = "Contains a box of six breaching missiles designed to explode upon striking hard surfaces."
+ cost = 1000
+ contains = list(
+ /obj/item/mecha_ammo/missiles_br
+ )
diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm
index 090041f06382..08b576937138 100644
--- a/code/modules/cargo/packs/medical.dm
+++ b/code/modules/cargo/packs/medical.dm
@@ -61,10 +61,9 @@
/datum/supply_pack/medical/defibs
name = "Defibrillator Crate"
- desc = "Contains two defibrillators for bringing the recently deceased back to life."
- cost = 1500
- contains = list(/obj/item/defibrillator/loaded,
- /obj/item/defibrillator/loaded)
+ desc = "Contains a defibrillator for bringing the recently deceased back to life."
+ cost = 750
+ contains = list(/obj/item/defibrillator/loaded)
crate_name = "defibrillator crate"
/datum/supply_pack/medical/surgery
@@ -92,7 +91,9 @@
/obj/item/reagent_containers/blood/BMinus,
/obj/item/reagent_containers/blood/OPlus,
/obj/item/reagent_containers/blood/OMinus,
- /obj/item/reagent_containers/blood/lizard)
+ /obj/item/reagent_containers/blood/lizard,
+ /obj/item/reagent_containers/blood/elzuose,
+ /obj/item/reagent_containers/blood/synthetic)
crate_name = "blood freezer"
crate_type = /obj/structure/closet/crate/freezer
diff --git a/code/modules/cargo/packs/sec_supply.dm b/code/modules/cargo/packs/sec_supply.dm
index 023ab5ee853f..8ff09a5dc38a 100644
--- a/code/modules/cargo/packs/sec_supply.dm
+++ b/code/modules/cargo/packs/sec_supply.dm
@@ -56,11 +56,9 @@
/datum/supply_pack/sec_supply/riotshields
name = "Riot Shields Crate"
- desc = "For when the greytide gets really uppity. Contains three riot shields."
- cost = 2000
- contains = list(/obj/item/shield/riot,
- /obj/item/shield/riot,
- /obj/item/shield/riot)
+ desc = "Contains a riot shield, effective at holding back hostile fauna, xenofauna, or large crowds."
+ cost = 600
+ contains = list(/obj/item/shield/riot)
crate_name = "riot shields crate"
/datum/supply_pack/sec_supply/survknives
diff --git a/code/modules/cargo/packs/spacesuit_armor.dm b/code/modules/cargo/packs/spacesuit_armor.dm
index c873a7e2dac4..8346ea00b06e 100644
--- a/code/modules/cargo/packs/spacesuit_armor.dm
+++ b/code/modules/cargo/packs/spacesuit_armor.dm
@@ -8,48 +8,40 @@
/datum/supply_pack/spacesuit_armor/spacesuit
name = "Space Suit Crate"
- desc = "Contains three basic space suits. Although the technology is centuries old, they should protect you from the vacuum of space."
- cost = 1500
+ desc = "Contains one basic space suit. Although the technology is centuries old, it should protect you from the vacuum of space."
+ cost = 500
contains = list(/obj/item/clothing/suit/space,
- /obj/item/clothing/suit/space,
- /obj/item/clothing/suit/space,
- /obj/item/clothing/head/helmet/space,
- /obj/item/clothing/head/helmet/space,
/obj/item/clothing/head/helmet/space)
crate_name = "space suit crate"
/datum/supply_pack/spacesuit_armor/pilot_spacesuit
name = "Pilot Space Suit Crate"
- desc = "Two pilot space suits, for improved mobility in mechs and pods."
- cost = 3500
+ desc = "One pilot space suit, for improved mobility in mechs."
+ cost = 750
contains = list(/obj/item/clothing/suit/space/pilot,
- /obj/item/clothing/suit/space/pilot,
- /obj/item/clothing/head/helmet/space/pilot/random,
/obj/item/clothing/head/helmet/space/pilot/random)
crate_name = "pilot space suit crate"
/datum/supply_pack/spacesuit_armor/mining_hardsuits_indie
name = "Mining Hardsuit Crate"
- desc = "Two independent branded mining hardsuits for when explorer suits just dont cut it."
- cost = 4000
- contains = list(/obj/item/clothing/suit/space/hardsuit/mining/independent,
- /obj/item/clothing/suit/space/hardsuit/mining/independent)
+ desc = "One independent branded mining hardsuit for when explorer suits just dont cut it."
+ cost = 1500
+ contains = list(/obj/item/clothing/suit/space/hardsuit/mining/independent)
crate_name = "mining hardsuit crate"
crate_type = /obj/structure/closet/crate/secure/plasma
/datum/supply_pack/spacesuit_armor/med_hardsuit
name = "Medical Hardsuit Crate"
- desc = "Two medical hardsuits, resistant to diseases and useful for retrieving patients in space."
- cost = 5000
- contains = list(/obj/item/clothing/suit/space/hardsuit/medical,
- /obj/item/clothing/suit/space/hardsuit/medical)
+ desc = "One medical hardsuit, resistant to diseases and useful for retrieving patients in space."
+ cost = 1500
+ contains = list(/obj/item/clothing/suit/space/hardsuit/medical)
crate_name = "medical hardsuit crate"
crate_type = /obj/structure/closet/crate/medical
/datum/supply_pack/spacesuit_armor/mining_hardsuit_heavy
name = "Heavy Mining Hardsuit Crate"
desc = "One deluxe heavy mining hardsuit for dangerous frontier operations. Comes with a pair of EXOCOM jet boots."
- cost = 6000
+ cost = 3500
contains = list(/obj/item/clothing/suit/space/hardsuit/mining/heavy,
/obj/item/clothing/shoes/bhop)
crate_name = "heavy mining hardsuit crate"
@@ -57,53 +49,43 @@
/datum/supply_pack/spacesuit_armor/sec_hardsuit_bundle
name = "Security Hardsuit Crate"
- desc = "Contains two security hardsuits for light combat duty."
- cost = 7500
- contains = list(/obj/item/clothing/suit/space/hardsuit/security/independent,
- /obj/item/clothing/suit/space/hardsuit/security/independent)
+ desc = "Contains one security hardsuit for light combat duty."
+ cost = 2500
+ contains = list(/obj/item/clothing/suit/space/hardsuit/security/independent)
crate_name = "security hardsuit crate"
crate_type = /obj/structure/closet/crate/secure/gear
/datum/supply_pack/spacesuit_armor/sci_hardsuit
name = "Science Hardsuit Crate"
- desc = "Contains two science hardsuits, designed to provide safety under advanced experimental conditions."
- cost = 8500
- contains = list(/obj/item/clothing/suit/space/hardsuit/rd,
- /obj/item/clothing/suit/space/hardsuit/rd)
+ desc = "Contains one science hardsuit, designed to provide safety under advanced experimental conditions."
+ cost = 2000
+ contains = list(/obj/item/clothing/suit/space/hardsuit/rd)
crate_name = "science hardsuit crate"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/spacesuit_armor/engi_spacesuit_bundle
name = "Engineering Space Suit Crate"
- desc = "Need to turn your ship into a safety hazard? Not a problem! These three engineering space suits will help get the job done."
- cost = 9000
+ desc = "Need to turn your ship into a safety hazard? Not a problem! This engineering space suit will help get the job done."
+ cost = 1500
contains = list(/obj/item/clothing/suit/space/engineer,
- /obj/item/clothing/suit/space/engineer,
- /obj/item/clothing/suit/space/engineer,
- /obj/item/clothing/head/helmet/space/light/engineer,
- /obj/item/clothing/head/helmet/space/light/engineer,
/obj/item/clothing/head/helmet/space/light/engineer)
crate_name = "engineering space suit crate"
crate_type = /obj/structure/closet/crate/secure/engineering
/datum/supply_pack/spacesuit_armor/atmos_hardsuit
name = "Atmospherics Hardsuit Crate"
- desc = "The iconic hardsuit of Nanotrasen's Atmosphere Corps, these two hardsuits are known across space as a symbol of defiance in the face of sudden decompression. Smells faintly of plasma."
- cost = 12000
- contains = list(/obj/item/clothing/suit/space/hardsuit/engine/atmos,
- /obj/item/clothing/suit/space/hardsuit/engine/atmos)
+ desc = "The iconic hardsuit of Nanotrasen's Atmosphere Corps, this hardsuit is known across space as a symbol of defiance in the face of sudden decompression. Smells faintly of plasma."
+ cost = 2500
+ contains = list(/obj/item/clothing/suit/space/hardsuit/engine/atmos)
crate_name = "atmospherics hardsuit crate"
crate_type = /obj/structure/closet/crate/secure/engineering
/datum/supply_pack/spacesuit_armor/swat
name = "SWAT Crate"
- desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, and combat belt."
- cost = 12000
+ desc = "Contains one fullbody set of tough, fireproof, pressurized suit designed in a joint effort by IS-ERI and Nanotrasen. The set contains a suit, helmet, and combat belt."
+ cost = 3500
contains = list(/obj/item/clothing/head/helmet/swat/nanotrasen,
- /obj/item/clothing/head/helmet/swat/nanotrasen,
- /obj/item/clothing/suit/space/swat,
/obj/item/clothing/suit/space/swat,
- /obj/item/storage/belt/military/assault,
/obj/item/storage/belt/military/assault)
crate_name = "swat crate"
crate_type = /obj/structure/closet/crate/secure/gear
@@ -114,42 +96,35 @@
/datum/supply_pack/spacesuit_armor/basic_armor
name = "Armor Crate"
- desc = "Two sets of well-rounded body armor. Each set includes a helmet and vest."
- cost = 1500
+ desc = "One set of well-rounded body armor. The set includes a helmet and vest."
+ cost = 750
contains = list(/obj/item/clothing/suit/armor/vest,
- /obj/item/clothing/suit/armor/vest,
- /obj/item/clothing/head/helmet/sec,
/obj/item/clothing/head/helmet/sec)
crate_name = "armor crate"
crate_type = /obj/structure/closet/crate/secure/plasma
/datum/supply_pack/spacesuit_armor/riot_armor
name = "Riot Armor Crate"
- desc = "Contains two full sets of riot armor. Although heavily padded to deal with close-quarters threats, they perform poorly against most firearms."
- cost = 3000
+ desc = "Contains one full set of riot armor. Although heavily padded to deal with close-quarters threats, they perform poorly against most firearms."
+ cost = 1500
contains = list(/obj/item/clothing/suit/armor/riot,
- /obj/item/clothing/suit/armor/riot,
- /obj/item/clothing/head/helmet/riot,
/obj/item/clothing/head/helmet/riot)
crate_name = "riot armor crate"
crate_type = /obj/structure/closet/crate/secure/plasma
/datum/supply_pack/spacesuit_armor/bullet_armor
name = "Bulletproof Armor Crate"
- desc = "Contains two full sets of bulletproof armor, guaranteed to reduce a bullet's stopping power by half but with limited protection against melee weaponry."
- cost = 3500
+ desc = "Contains one full set of bulletproof armor, guaranteed to reduce a bullet's stopping power by half but with limited protection against melee weaponry."
+ cost = 1750
contains = list(/obj/item/clothing/suit/armor/vest/bulletproof,
- /obj/item/clothing/suit/armor/vest/bulletproof,
- /obj/item/clothing/head/helmet/bulletproof,
/obj/item/clothing/head/helmet/bulletproof)
crate_name = "bulletproof armor crate"
crate_type = /obj/structure/closet/crate/secure/plasma
/datum/supply_pack/spacesuit_armor/laser_armor
name = "Reflector Vest Crate"
- desc = "Contains two vests of highly reflective material. Each armor piece diffuses a laser's energy by over half, as well as offering a good chance to reflect the laser entirely."
- cost = 3000
- contains = list(/obj/item/clothing/suit/armor/laserproof,
- /obj/item/clothing/suit/armor/laserproof)
+ desc = "Contains one vest made of highly reflective material. The armor piece diffuses a laser's energy by over half, as well as offering a good chance to reflect the laser entirely."
+ cost = 1500
+ contains = list(/obj/item/clothing/suit/armor/laserproof)
crate_name = "reflector vest crate"
crate_type = /obj/structure/closet/crate/secure/plasma
diff --git a/code/modules/cargo/packs/tools.dm b/code/modules/cargo/packs/tools.dm
index 92726a3ab6a6..6b43448a5d81 100644
--- a/code/modules/cargo/packs/tools.dm
+++ b/code/modules/cargo/packs/tools.dm
@@ -67,14 +67,11 @@
)
crate_name = "basic mining crate"
-/datum/supply_pack/tools/jackhammers
+/datum/supply_pack/tools/jackhammer
name = "Jackhammer Crate"
- desc = "Contains two jackhammers, ideal for breaking rocks and breaking hull."
- cost = 3500
- contains = list(
- /obj/item/pickaxe/drill/jackhammer,
- /obj/item/pickaxe/drill/jackhammer,
- )
+ desc = "Contains a jackhammer, ideal for breaking rocks and breaking hull."
+ cost = 1750
+ contains = list(/obj/item/pickaxe/drill/jackhammer)
crate_name = "jackhammer crate"
@@ -87,10 +84,9 @@
/datum/supply_pack/tools/insulated_gloves
name = "Insulated Gloves Crate"
- desc = "The backbone of modern society. Barely ever ordered for actual engineering. Contains two insulated gloves."
- cost = 1500
- contains = list(/obj/item/clothing/gloves/color/yellow,
- /obj/item/clothing/gloves/color/yellow)
+ desc = "The backbone of modern society. Barely ever ordered for actual engineering. Contains a pair of insulated gloves."
+ cost = 750
+ contains = list(/obj/item/clothing/gloves/color/yellow)
crate_name = "insulated gloves crate"
/datum/supply_pack/tools/jetpack
@@ -101,13 +97,12 @@
crate_name = "jetpack crate"
crate_type = /obj/structure/closet/crate/secure/plasma
-/datum/supply_pack/tools/transfer_valves
+/datum/supply_pack/tools/transfer_valve
name = "Tank Transfer Valves Crate"
- desc = "The key ingredient for making a lot of people very angry very fast. Contains two tank transfer valves."
- cost = 6000
- contains = list(/obj/item/transfer_valve,
- /obj/item/transfer_valve)
- crate_name = "tank transfer valves crate"
+ desc = "The key ingredient for making a lot of people very angry very fast. Contains a tank transfer valve."
+ cost = 3000
+ contains = list(/obj/item/transfer_valve)
+ crate_name = "tank transfer valve crate"
crate_type = /obj/structure/closet/crate/secure/science
/*
diff --git a/code/modules/cargo/supplypod_beacon.dm b/code/modules/cargo/supplypod_beacon.dm
index 11fd10229e5e..b9c41a29e11f 100644
--- a/code/modules/cargo/supplypod_beacon.dm
+++ b/code/modules/cargo/supplypod_beacon.dm
@@ -7,7 +7,7 @@
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
- var/obj/machinery/computer/cargo/express/express_console
+ var/obj/machinery/computer/cargo/cargo_console
var/linked = FALSE
var/ready = FALSE
var/launched = FALSE
@@ -49,39 +49,39 @@
/obj/item/supplypod_beacon/examine(user)
. = ..()
- if(!express_console)
+ if(!cargo_console)
. += "[src] is not currently linked to an Express Supply console."
else
. += "Alt-click to unlink it from the Express Supply console."
/obj/item/supplypod_beacon/Destroy()
- if(express_console)
- express_console.beacon = null
+ if(cargo_console)
+ cargo_console.beacon = null
return ..()
/obj/item/supplypod_beacon/proc/unlink_console()
- if(express_console)
- express_console.beacon = null
- express_console = null
+ if(cargo_console)
+ cargo_console.beacon = null
+ cargo_console = null
update_status(SP_UNLINK)
update_status(SP_UNREADY)
-/obj/item/supplypod_beacon/proc/link_console(obj/machinery/computer/cargo/express/C, mob/living/user)
+/obj/item/supplypod_beacon/proc/link_console(obj/machinery/computer/cargo/C, mob/living/user)
if (C.beacon)//if new console has a beacon, then...
C.beacon.unlink_console()//unlink the old beacon from new console
- if (express_console)//if this beacon has an express console
- express_console.beacon = null//remove the connection the expressconsole has from beacons
- express_console = C//set the linked console var to the console
- express_console.beacon = src//out with the old in with the news
+ if (cargo_console)//if this beacon has an express console
+ cargo_console.beacon = null//remove the connection the expressconsole has from beacons
+ cargo_console = C//set the linked console var to the console
+ cargo_console.beacon = src//out with the old in with the news
update_status(SP_LINKED)
- if (express_console.use_beacon)
+ if (cargo_console.use_beacon)
update_status(SP_READY)
to_chat(user, "[src] linked to [C].")
/obj/item/supplypod_beacon/AltClick(mob/user)
if (!user.canUseTopic(src, !issilicon(user)))
return
- if (express_console)
+ if (cargo_console)
unlink_console()
else
to_chat(user, "There is no linked console.")
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 4153a2f409e5..87a33b0c989b 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -107,6 +107,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
cmd_admin_pm(href_list["priv_msg"],null)
return
+ if(href_list["commandbar_typing"])
+ handle_commandbar_typing(href_list)
+
switch(href_list["_src_"])
if("holder")
hsrc = holder
@@ -226,6 +229,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
// Instantiate tgui panel
tgui_panel = new(src, "browseroutput")
+ initialize_commandbar_spy()
+
GLOB.ahelp_tickets.client_login(src)
GLOB.interviews.client_login(src)
GLOB.requests.client_login(src)
@@ -1087,7 +1092,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
return
var/list/verblist = list()
var/list/verbstoprocess = verbs.Copy()
- if(mob?.client?.prefs.broadcast_login_logout)
+ if(mob)
verbstoprocess += mob.verbs
for(var/atom/movable/thing as anything in mob.contents)
verbstoprocess += thing.verbs
diff --git a/code/modules/client/loadout/loadout_accessories.dm b/code/modules/client/loadout/loadout_accessories.dm
index 40702e5fc2be..c1e4d7a088a8 100644
--- a/code/modules/client/loadout/loadout_accessories.dm
+++ b/code/modules/client/loadout/loadout_accessories.dm
@@ -50,6 +50,16 @@
display_name = "tie, recolorable"
path = /obj/item/clothing/neck/tie
+//Bone
+/datum/gear/accessory/fangnecklace
+ display_name = "wolf fang necklace"
+ path = /obj/item/clothing/neck/fangnecklace
+
+/datum/gear/accessory/bonearmlet
+ display_name = "bone armlet"
+ path = /obj/item/clothing/accessory/bonearmlet
+ slot = null
+
//Misc
/datum/gear/accessory/waistcoat
@@ -62,11 +72,6 @@
path = /obj/item/clothing/neck/stethoscope
allowed_roles = list("Medical Doctor", "Chief Medical Officer")
-/datum/gear/accessory/collar
- display_name = "pet collar"
- description = "Only the truly insane would wear this around their neck."
- path = /obj/item/clothing/neck/petcollar
-
/datum/gear/accessory/gloves/black
display_name = "black gloves"
description = "Standard hand coverings for everyday use."
@@ -77,19 +82,13 @@
description = "Standard hand coverings for everyday use."
path = /obj/item/clothing/gloves/color/white
+/datum/gear/accessory/gloves/fingerless
+ display_name = "fingerless gloves"
+ description = "Radical hand coverings for everyday use."
+ path = /obj/item/clothing/gloves/fingerless
+
/datum/gear/accessory/gloves/evening
display_name = "evening gloves"
description = "Excessively fancy elbow-length gloves."
path = /obj/item/clothing/gloves/color/evening
slot = ITEM_SLOT_GLOVES
-
-/datum/gear/accessory/tiki
- display_name = "tiki mask"
- description = "A wooden mask, simple, really."
- path = /obj/item/clothing/mask/gas/tiki_mask
- slot = ITEM_SLOT_MASK
-
-/datum/gear/accessory/joymask
- display_name = "face with tears of joy mask"
- path = /obj/item/clothing/mask/joy
- slot = ITEM_SLOT_MASK
diff --git a/code/modules/client/loadout/loadout_general.dm b/code/modules/client/loadout/loadout_general.dm
index 042315cc981f..8bb3ff3cb69d 100644
--- a/code/modules/client/loadout/loadout_general.dm
+++ b/code/modules/client/loadout/loadout_general.dm
@@ -30,17 +30,13 @@
display_name = "bandana, red"
path = /obj/item/clothing/mask/bandana/red
-/datum/gear/bible
- display_name = "bible"
- path = /obj/item/storage/book/bible
-
/datum/gear/flask
display_name = "flask"
path = /obj/item/reagent_containers/food/drinks/flask
/datum/gear/mug
display_name = "coffee mug"
- path = /obj/item/reagent_containers/food/drinks/britcup
+ path = /obj/item/reagent_containers/food/drinks/mug
/datum/gear/rilena_mug
display_name = "coffee mug, rilena"
@@ -66,10 +62,6 @@
display_name = "toy, magic eight ball"
path = /obj/item/toy/eightball
-/datum/gear/wallet
- display_name = "wallet"
- path = /obj/item/storage/wallet
-
/datum/gear/pai
display_name = "personal AI device"
path = /obj/item/paicard
@@ -102,10 +94,6 @@
display_name = "cane"
path = /obj/item/cane
-/datum/gear/radio
- display_name = "hand radio"
- path = /obj/item/radio
-
/datum/gear/lizard
display_name = "toy, lizard plushie"
path = /obj/item/toy/plush/lizardplushie
@@ -154,6 +142,10 @@
display_name = "hair dye"
path = /obj/item/dyespray
+/datum/gear/colorsalve
+ display_name = "Elzuose color salve"
+ path = /obj/item/colorsalve
+
/datum/gear/tablebell
display_name = "table bell, brass"
path = /obj/item/table_bell/brass
@@ -168,14 +160,6 @@
display_name = "tool, emergency crowbar"
path = /obj/item/crowbar/red
-/datum/gear/balloon
- display_name = "toy, balloon"
- path = /obj/item/toy/balloon
-
-/datum/gear/balloon/ian
- display_name = "toy, ian balloon"
- path = /obj/item/toy/balloon/corgi
-
/datum/gear/surgical_mask
display_name = "surgical mask"
path = /obj/item/clothing/mask/surgical
diff --git a/code/modules/client/loadout/loadout_hat.dm b/code/modules/client/loadout/loadout_hat.dm
index d4ab1c858f26..23e34d7d19c3 100644
--- a/code/modules/client/loadout/loadout_hat.dm
+++ b/code/modules/client/loadout/loadout_hat.dm
@@ -92,10 +92,6 @@
display_name = "beanie"
path = /obj/item/clothing/head/beanie
-/datum/gear/hat/tinfoil
- display_name = "tinfoil hat"
- path = /obj/item/clothing/head/foilhat
-
/datum/gear/hat/wig
display_name = "wig"
path = /obj/item/clothing/head/wig
@@ -104,20 +100,10 @@
display_name = "cowboy hat"
path = /obj/item/clothing/head/cowboy
-/datum/gear/hat/catears
- display_name = "cat ears"
- path = /obj/item/clothing/head/kitty
-
-/datum/gear/hat/horse
- display_name = "horse mask"
- path = /obj/item/clothing/mask/horsehead
- slot = ITEM_SLOT_MASK
-
-/datum/gear/hat/piratehat
- display_name = "pirate hat"
- description = "Yarr. Comes with one free pirate speak manual."
- path = /obj/item/clothing/head/pirate
-
/datum/gear/hat/trapper
display_name = "trapper hat"
path = /obj/item/clothing/head/trapper
+
+/datum/gear/hat/flowers
+ display_name = "plastic flower, pickable"
+ path = /obj/item/clothing/head/plastic_flower
diff --git a/code/modules/client/loadout/loadout_suit.dm b/code/modules/client/loadout/loadout_suit.dm
index ec9fc916723e..f8757bfa5b38 100644
--- a/code/modules/client/loadout/loadout_suit.dm
+++ b/code/modules/client/loadout/loadout_suit.dm
@@ -81,6 +81,10 @@
display_name = "hoodie, T4L1"
path = /obj/item/clothing/suit/hooded/hoodie/rilena
+/datum/gear/suit/jacket/hoodie_baw
+ display_name = "hoodie, black w grey hood"
+ path = /obj/item/clothing/suit/hooded/hoodie/blackwa
+
/datum/gear/suit/jacket/highvis
display_name = "industrial jacket"
path = /obj/item/clothing/suit/toggle/industrial
@@ -103,7 +107,7 @@
path = /obj/item/clothing/suit/toggle/labcoat
/datum/gear/suit/raincoat
- display_name = "Cybersun labcoat"
+ display_name = "translucent labcoat"
description = "Designer lab safety equipment. You're pretty sure this is just a raincoat."
path = /obj/item/clothing/suit/toggle/labcoat/raincoat
@@ -111,3 +115,7 @@
display_name = "worn shirt"
path = /obj/item/clothing/suit/ianshirt
+/datum/gear/suit/hawaiian
+ display_name = "floral shirt"
+ description = "From grills to guns, this shirt's seen it all."
+ path = /obj/item/clothing/suit/hawaiian
diff --git a/code/modules/client/loadout/loadout_uniform.dm b/code/modules/client/loadout/loadout_uniform.dm
index 616c4308b437..96b4088b65bd 100644
--- a/code/modules/client/loadout/loadout_uniform.dm
+++ b/code/modules/client/loadout/loadout_uniform.dm
@@ -160,10 +160,6 @@
display_name = "suit, charcoal"
path = /obj/item/clothing/under/suit/charcoal
-/datum/gear/uniform/suit/galaxy
- display_name = "suit, galaxy"
- path = /obj/item/clothing/under/rank/civilian/lawyer/galaxy
-
/datum/gear/uniform/suit/white_skirt
display_name = "suitskirt, white shirt"
path = /obj/item/clothing/under/suit/black/skirt
@@ -236,8 +232,3 @@
/datum/gear/uniform/dress/rilena
display_name = "red dress, Ri cosplay"
path = /obj/item/clothing/under/dress/rilena
-
-//Premium
-/datum/gear/uniform/tacticool
- display_name = "tacticool turtleneck"
- path = /obj/item/clothing/under/syndicate/tacticool
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index ebf32c163d89..006074e74bcd 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -114,9 +114,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"ipc_tail" = "None",
"ipc_chassis" = "Morpheus Cyberkinetics (Custom)",
"ipc_brain" = "Posibrain",
- "kepori_feathers" = "Plain",
- "kepori_body_feathers" = "Plain",
- "kepori_tail_feathers" = "Fan",
+ "kepori_feathers" = "None",
+ "kepori_body_feathers" = "None",
+ "kepori_head_feathers" = "None",
+ "kepori_tail_feathers" = "None",
"vox_head_quills" = "Plain",
"vox_neck_quills" = "Plain",
"elzu_horns" = "None",
@@ -154,11 +155,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
)
var/fbp = FALSE
var/phobia = "spiders"
+ var/preferred_smoke_brand = PREF_CIG_SPACE
var/list/alt_titles_preferences = list()
var/list/custom_names = list()
var/preferred_ai_core_display = "Blue"
var/prefered_security_department = SEC_DEPT_RANDOM
-
+ var/generic_adjective = "Unremarkable"
//Quirk list
var/list/all_quirks = list()
@@ -243,7 +245,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
return
#define APPEARANCE_CATEGORY_COLUMN "
"
-#define MAX_MUTANT_ROWS 4
+#define MAX_MUTANT_ROWS 5
/datum/preferences/proc/ShowChoices(mob/user)
show_loadout = (current_tab != 1) ? show_loadout : FALSE
@@ -425,9 +427,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Change "
dat += "Change "
- if(istype(pref_species, /datum/species/ethereal)) //not the best thing to do tbf but I dont know whats better.
+ if(istype(pref_species, /datum/species/elzuose)) //not the best thing to do tbf but I dont know whats better.
- dat += "
Ethereal Color
"
+ dat += "
Elzuosa Color
"
dat += "Change "
@@ -727,6 +729,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "
"
mutant_category = 0
+ if("kepori_head_feathers" in pref_species.default_features)
+ if(!mutant_category)
+ dat += APPEARANCE_CATEGORY_COLUMN
+
+ dat += "
Head Feathers
"
+ dat += "[features["kepori_head_feathers"]] "
+ dat += "Change "
+
+ mutant_category++
+ if(mutant_category >= MAX_MUTANT_ROWS)
+ dat += ""
+ mutant_category = 0
+
if("kepori_body_feathers" in pref_species.default_features)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -835,10 +850,22 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//Adds a thing to select which phobia because I can't be assed to put that in the quirks window
if("Phobia" in all_quirks)
+ if(!mutant_category)
+ dat += APPEARANCE_CATEGORY_COLUMN
dat += "
Phobia
"
dat += "[phobia] "
+ mutant_category++
+ if(mutant_category >= MAX_MUTANT_ROWS)
+ dat += ""
+ mutant_category = 0
+
+ if("Smoker" in all_quirks)
+ dat += "
Smoker
"
+
+ dat += "[preferred_smoke_brand] "
+
if("body_size" in pref_species.default_features)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -852,6 +879,20 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += ""
mutant_category = 0
+ // begin generic adjective
+ if(!mutant_category)
+ dat += APPEARANCE_CATEGORY_COLUMN
+
+ dat += "
Character Adjective
"
+
+ dat += "[generic_adjective] "
+
+ mutant_category++
+ if(mutant_category >= MAX_MUTANT_ROWS)
+ dat += ""
+ mutant_category = 0
+ // end generic adjective
+
if("wings" in pref_species.default_features && GLOB.r_wings_list.len >1)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -1665,9 +1706,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
age = clamp(round(text2num(new_age)), pref_species.species_age_min, pref_species.species_age_max)
if("flavor_text")
- var/msg = sanitize(stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", features["flavor_text"], 4096, TRUE))
+ var/msg = stripped_multiline_input(usr, "A snippet of text shown when others examine you, describing what you may look like. This can also be used for OOC notes.", "Flavor Text", html_decode(features["flavor_text"]), MAX_FLAVOR_LEN, TRUE)
if(msg) //WS edit - "Cancel" does not clear flavor text
- features["flavor_text"] = html_decode(msg)
+ features["flavor_text"] = msg
if("hair")
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null
@@ -1816,7 +1857,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
to_chat(user, "Invalid color. Your color is not bright enough.")
if("color_ethereal")
- var/new_etherealcolor = input(user, "Choose your elzuosa color:", "Character Preference","#"+features["ethcolor"]) as color|null
+ var/new_etherealcolor = input(user, "Choose your elzuose color:", "Character Preference","#"+features["ethcolor"]) as color|null
if(new_etherealcolor)
var/temp_hsv = RGBtoHSV(new_etherealcolor)
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#505050")[3]) // elzu colors should be bright
@@ -1959,6 +2000,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if (new_kepori_feathers)
features["kepori_feathers"] = new_kepori_feathers
+ if("kepori_head_feathers")
+ var/new_kepori_feathers
+ new_kepori_feathers = input(user, "Choose your character's head feathers:", "Character Preference") as null|anything in GLOB.kepori_head_feathers_list
+ if (new_kepori_feathers)
+ features["kepori_head_feathers"] = new_kepori_feathers
+
if("kepori_body_feathers")
var/new_kepori_feathers
new_kepori_feathers = input(user, "Choose your character's body feathers:", "Character Preference") as null|anything in GLOB.kepori_body_feathers_list
@@ -2073,6 +2120,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/phobiaType = input(user, "What are you scared of?", "Character Preference", phobia) as null|anything in SStraumas.phobia_types
if(phobiaType)
phobia = phobiaType
+ if("preferred_smoke_brand")
+ var/smokeBrand = input(user, "What cigarettes are your favorite?", "Character Preference", preferred_smoke_brand) as null|anything in GLOB.valid_smoke_types
+ if(smokeBrand)
+ preferred_smoke_brand = smokeBrand
+
+ if("generic_adjective")
+ var/selectAdj
+ if(istype(pref_species, /datum/species/ipc))
+ selectAdj = input(user, "In one word, how would you describe your character's appereance?", "Character Preference", generic_adjective) as null|anything in GLOB.ipc_preference_adjectives
+ else
+ selectAdj = input(user, "In one word, how would you describe your character's appereance?", "Character Preference", generic_adjective) as null|anything in GLOB.preference_adjectives
+ if(selectAdj)
+ generic_adjective = selectAdj
if ("max_chat_length")
var/desiredlength = input(user, "Choose the max character length of shown Runechat messages. Valid range is 1 to [CHAT_MESSAGE_MAX_LENGTH] (default: [initial(max_chat_length)]))", "Character Preference", max_chat_length) as null|num
@@ -2473,6 +2533,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE)
//Because of how set_species replaces all bodyparts with new ones, hair needs to be set AFTER species.
character.dna.real_name = character.real_name
+ character.generic_adjective = generic_adjective
character.hair_color = hair_color
character.facial_hair_color = facial_hair_color
character.grad_color = features["grad_color"]
@@ -2492,20 +2553,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
/datum/preferences/proc/get_default_name(name_id)
switch(name_id)
- if("human")
- return random_unique_name()
if("ai")
return pick(GLOB.ai_names)
if("cyborg")
return DEFAULT_CYBORG_NAME
- if("clown")
- return pick(GLOB.clown_names)
- if("mime")
- return pick(GLOB.mime_names)
- if("religion")
- return DEFAULT_RELIGION
- if("deity")
- return DEFAULT_DEITY
return random_unique_name()
/datum/preferences/proc/ask_for_custom_name(mob/user,name_id)
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 0b95e291b794..71d968d16130 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -405,6 +405,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
READ_FILE(S["jumpsuit_style"], jumpsuit_style)
READ_FILE(S["uplink_loc"], uplink_spawn_loc)
READ_FILE(S["phobia"], phobia)
+ READ_FILE(S["preferred_smoke_brand"], preferred_smoke_brand)
+ READ_FILE(S["generic_adjective"], generic_adjective)
READ_FILE(S["randomise"], randomise)
READ_FILE(S["body_size"], features["body_size"])
READ_FILE(S["prosthetic_limbs"], prosthetic_limbs)
@@ -436,6 +438,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
READ_FILE(S["feature_ipc_brain"], features["ipc_brain"])
READ_FILE(S["feature_kepori_feathers"], features["kepori_feathers"])
READ_FILE(S["feature_kepori_body_feathers"], features["kepori_body_feathers"])
+ READ_FILE(S["feature_kepori_head_feathers"], features["kepori_head_feathers"])
READ_FILE(S["feature_kepori_tail_feathers"], features["kepori_tail_feathers"])
READ_FILE(S["feature_vox_head_quills"], features["vox_head_quills"])
READ_FILE(S["feature_vox_neck_quills"], features["vox_neck_quills"])
@@ -445,9 +448,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
READ_FILE(S["equipped_gear"], equipped_gear)
if(config) //This should *probably* always be there, but just in case.
if(length(equipped_gear) > CONFIG_GET(number/max_loadout_items))
- to_chat(parent, "Loadout maximum items exceeded in loaded slot, Your loadout has been cleared! You had [length(equipped_gear)]/[CONFIG_GET(number/max_loadout_items)] equipped items!")
+ to_chat(parent, span_userdanger("Loadout maximum items exceeded in loaded slot, Your loadout has been cleared! You had [length(equipped_gear)]/[CONFIG_GET(number/max_loadout_items)] equipped items!"))
equipped_gear = list()
- WRITE_FILE(S["equipped_gear"] , equipped_gear)
+ WRITE_FILE(S["equipped_gear"], equipped_gear)
+
+ for(var/gear in equipped_gear)
+ if(!(gear in GLOB.gear_datums))
+ to_chat(parent, span_warning("Removing nonvalid loadout item [gear] from loadout"))
+ equipped_gear -= gear //be GONE
+ WRITE_FILE(S["equipped_gear"], equipped_gear)
READ_FILE(S["feature_human_tail"], features["tail_human"])
READ_FILE(S["feature_human_ears"], features["ears"])
@@ -546,8 +555,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["ipc_chassis"] = sanitize_inlist(features["ipc_chassis"], GLOB.ipc_chassis_list)
features["ipc_brain"] = sanitize_inlist(features["ipc_brain"], GLOB.ipc_brain_list)
features["kepori_feathers"] = sanitize_inlist(features["kepori_feathers"], GLOB.kepori_feathers_list, "Plain")
- features["kepori_body_feathers"] = sanitize_inlist(features["kepori_body_feathers"], GLOB.kepori_body_feathers_list, "Plain")
- features["kepori_tail_feathers"] = sanitize_inlist(features["kepori_tail_feathers"], GLOB.kepori_tail_feathers_list, "Fan")
+ features["kepori_body_feathers"] = sanitize_inlist(features["kepori_body_feathers"], GLOB.kepori_body_feathers_list, "None")
+ features["kepori_head_feathers"] = sanitize_inlist(features["kepori_head_feathers"], GLOB.kepori_head_feathers_list, "None")
+ features["kepori_tail_feathers"] = sanitize_inlist(features["kepori_tail_feathers"], GLOB.kepori_tail_feathers_list, "None")
features["vox_head_quills"] = sanitize_inlist(features["vox_head_quills"], GLOB.vox_head_quills_list, "None")
features["vox_neck_quills"] = sanitize_inlist(features["vox_neck_quills"], GLOB.vox_neck_quills_list, "None")
features["elzu_horns"] = sanitize_inlist(features["elzu_horns"], GLOB.elzu_horns_list)
@@ -593,7 +603,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc)
WRITE_FILE(S["randomise"] , randomise)
WRITE_FILE(S["species"] , pref_species.id)
+ WRITE_FILE(S["preferred_smoke_brand"] , preferred_smoke_brand)
WRITE_FILE(S["phobia"] , phobia)
+ WRITE_FILE(S["generic_adjective"] , generic_adjective)
WRITE_FILE(S["body_size"] , features["body_size"])
WRITE_FILE(S["prosthetic_limbs"] , prosthetic_limbs)
WRITE_FILE(S["feature_mcolor"] , features["mcolor"])
@@ -625,6 +637,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["feature_ipc_brain"] , features["ipc_brain"])
WRITE_FILE(S["feature_kepori_feathers"] , features["kepori_feathers"])
WRITE_FILE(S["feature_kepori_body_feathers"], features["kepori_body_feathers"])
+ WRITE_FILE(S["feature_kepori_head_feathers"], features["feature_kepori_head_feathers"])
WRITE_FILE(S["feature_kepori_tail_feathers"], features["kepori_tail_feathers"])
WRITE_FILE(S["feature_vox_head_quills"] , features["vox_head_quills"])
WRITE_FILE(S["feature_vox_neck_quills"] , features["vox_neck_quills"])
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index b12e7cdf3d00..b40e1702652e 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -443,7 +443,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
//Admin Preferences
/client/proc/toggleadminhelpsound()
set name = "Hear/Silence Adminhelps"
- set category = "Prefs - Admin"
+ set category = "Preferences.Admin"
set desc = "Toggle hearing a notification when admin PMs are received"
if(!holder)
return
@@ -454,7 +454,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/toggleannouncelogin()
set name = "Do/Don't Announce Login"
- set category = "Prefs - Admin"
+ set category = "Preferences.Admin"
set desc = "Toggle if you want an announcement to admins when you login during a round"
if(!holder)
return
@@ -465,7 +465,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/toggle_hear_radio()
set name = "Show/Hide Radio Chatter"
- set category = "Prefs - Admin"
+ set category = "Preferences.Admin"
set desc = "Toggle seeing radiochatter from nearby radios and speakers"
if(!holder)
return
@@ -487,7 +487,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/deadchat()
set name = "Show/Hide Deadchat"
- set category = "Prefs - Admin"
+ set category = "Preferences.Admin"
set desc ="Toggles seeing deadchat"
if(!holder)
return
@@ -498,7 +498,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/toggleprayers()
set name = "Show/Hide Prayers"
- set category = "Prefs - Admin"
+ set category = "Preferences.Admin"
set desc = "Toggles seeing prayers"
if(!holder)
return
@@ -509,7 +509,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/toggle_prayer_sound()
set name = "Hear/Silence Prayer Sounds"
- set category = "Prefs - Admin"
+ set category = "Preferences.Admin"
set desc = "Hear Prayer Sounds"
if(!holder)
return
@@ -520,7 +520,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/colorasay()
set name = "Set Admin Say Color"
- set category = "Prefs - Admin"
+ set category = "Preferences.Admin"
set desc = "Set the color of your ASAY messages"
if(!holder)
return
@@ -537,7 +537,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
/client/proc/resetasaycolor()
set name = "Reset your Admin Say Color"
set desc = "Returns your ASAY Color to default"
- set category = "Prefs - Admin"
+ set category = "Preferences.Admin"
if(!holder)
return
if(!CONFIG_GET(flag/allow_admin_asaycolor))
diff --git a/code/modules/client/verbs/looc.dm b/code/modules/client/verbs/looc.dm
index 47d4e0e82aec..1c66a077a065 100644
--- a/code/modules/client/verbs/looc.dm
+++ b/code/modules/client/verbs/looc.dm
@@ -59,32 +59,33 @@ GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC")
mob.log_talk(raw_msg, LOG_LOOC, tag = "(LOOC)")
- var/list/heard = get_hearers_in_view(7, get_top_level_mob(src.mob))
- for(var/mob/M in heard)
- if(!M.client)
+ var/list/heard = get_hearers_in_view(7, get_top_level_mob(mob))
+ for(var/mob/hearer_mob in heard)
+ var/client/hearer = hearer_mob.client
+
+ if(!hearer)
continue
- var/client/C = M.client
- if(key in C.prefs.ignoring)
+ if(key in hearer.prefs.ignoring)
continue
- if(holder?.fakekey in C.prefs.ignoring)
+ if(holder?.fakekey in hearer.prefs.ignoring)
continue
- if(!(C.prefs.chat_toggles & CHAT_LOOC))
+ if(!(hearer.prefs.chat_toggles & CHAT_LOOC))
continue
//Handled before admins so that they see this if they're in range anyways
- if(C.prefs.chat_on_map && mob.invisibility <= M.see_invisible)
- M.create_chat_message(mob, null, "\[LOOC: [raw_msg]\]", null, LOOC_MESSAGE)
+ if(hearer.prefs.chat_on_map && mob.invisibility <= hearer_mob.see_invisible)
+ hearer_mob.create_chat_message(mob, null, "\[LOOC: [raw_msg]\]", null, LOOC_MESSAGE)
- if(C in GLOB.admins)
+ if(hearer in GLOB.admins)
continue //handled in the next loop
if(GLOB.LOOC_COLOR)
- to_chat(C, "LOOC:[src.mob.name]:[msg]", MESSAGE_TYPE_LOOC)
+ to_chat(hearer, "LOOC:[mob.get_screentip_name(hearer)]:[msg]", MESSAGE_TYPE_LOOC)
else
- to_chat(C, "LOOC:[src.mob.name]:[msg]", MESSAGE_TYPE_LOOC)
+ to_chat(hearer, "LOOC:[mob.get_screentip_name(hearer)]:[msg]", MESSAGE_TYPE_LOOC)
for(var/client/C in GLOB.admins)
if(key in C.prefs.ignoring)
@@ -100,9 +101,9 @@ GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC")
if (C.mob in heard)
prefix = "LOOC"
if(GLOB.LOOC_COLOR)
- to_chat(C, "[ADMIN_FLW(usr)] [prefix]:[src.key]/[src.mob.name]:[msg]", MESSAGE_TYPE_LOOC)
+ to_chat(C, "[ADMIN_FLW(usr)] [prefix]:[key]/[mob.real_name]:[msg]", MESSAGE_TYPE_LOOC)
else
- to_chat(C, "[ADMIN_FLW(usr)] [prefix]:[src.key]/[src.mob.name]:[msg]", MESSAGE_TYPE_LOOC)
+ to_chat(C, "[ADMIN_FLW(usr)] [prefix]:[key]/[mob.real_name]:[msg]", MESSAGE_TYPE_LOOC)
/proc/toggle_looc(toggle = null)
if(toggle == null)
diff --git a/code/modules/client/verbs/typing.dm b/code/modules/client/verbs/typing.dm
new file mode 100644
index 000000000000..28abf10ee7e8
--- /dev/null
+++ b/code/modules/client/verbs/typing.dm
@@ -0,0 +1,28 @@
+#define IC_VERBS list("say", "me", "whisper")
+
+/client/var/commandbar_thinking = FALSE
+/client/var/commandbar_typing = FALSE
+
+/client/proc/initialize_commandbar_spy()
+ src << output('html/typing_indicator.html', "commandbar_spy")
+
+/client/proc/handle_commandbar_typing(href_list)
+ if (length(href_list["verb"]) < 1 || !(lowertext(href_list["verb"]) in IC_VERBS) || text2num(href_list["argument_length"]) < 1)
+ if (commandbar_typing)
+ commandbar_typing = FALSE
+ stop_typing()
+ return
+
+ if (!commandbar_typing)
+ commandbar_typing = TRUE
+ start_typing()
+
+/client/proc/start_typing()
+ mob.set_typing_indicator(TRUE)
+
+/client/proc/stop_typing()
+ if(isnull(mob))
+ return FALSE
+ mob.set_typing_indicator(FALSE)
+
+#undef IC_VERBS
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index 203bcf416b13..f5c37b18997d 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -150,7 +150,7 @@
card.assignment = J.name
card.update_appearance()
card.assignment = old_assignment
- card.update_label()
+ card.name = "[(istype(src, /obj/item/card/id/syndicate)) ? "[initial(name)]" : "access card"][(!old_assignment) ? "" : " ([old_assignment])"]"
H.sec_hud_set_ID()
qdel(outfit)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index b1e1cc1f2105..166f437dc3af 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -286,7 +286,7 @@
if("[layer]" in mob_species.offset_clothing)
// This code taken from Baystation 12
- var/icon/final_I = icon('icons/blanks/32x32.dmi', "nothing")
+ var/icon/final_I = icon('icons/blanks/64x64.dmi', "nothing")
var/list/shifts = mob_species.offset_clothing["[layer]"]
// Apply all pixel shifts for each direction.
@@ -294,9 +294,10 @@
var/list/facing_list = shifts[shift_facing]
var/use_dir = text2num(shift_facing)
var/icon/equip = icon(file2use, icon_state = state2use, dir = use_dir)
- var/icon/canvas = icon('icons/blanks/32x32.dmi', "nothing")
+ var/icon/canvas = icon('icons/blanks/64x64.dmi', "nothing")
canvas.Blend(equip, ICON_OVERLAY, facing_list["x"]+1, facing_list["y"]+1)
final_I.Insert(canvas, dir = use_dir)
+
final_I = fcopy_rsc(final_I)
GLOB.species_clothing_icons[mob_species.id]["[file2use]-[state2use]"] = final_I
return TRUE
diff --git a/code/modules/clothing/factions/clip.dm b/code/modules/clothing/factions/clip.dm
index 82e1fdee68b0..ce87ea624d7a 100644
--- a/code/modules/clothing/factions/clip.dm
+++ b/code/modules/clothing/factions/clip.dm
@@ -6,6 +6,7 @@
icon = 'icons/obj/clothing/faction/clip/uniforms.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/uniforms.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
icon_state = "clip_deck"
item_state = "b_suit"
@@ -16,7 +17,7 @@
dying_key = DYE_REGISTRY_UNDER //??? // it's for washing machines don't worry about it
can_adjust = FALSE
- supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION | KEPORI_VARIATION // a new record!
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE | VOX_VARIATION // a new record! UPDATE 2 MONTHS LATER: :'(
/obj/item/clothing/under/clip/minutemen
name = "clip minutemen fatigues"
@@ -28,7 +29,7 @@
strip_delay = 50
can_adjust = FALSE
- supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE | VOX_VARIATION
/obj/item/clothing/under/clip/formal
name = "formal clip outfit"
@@ -37,7 +38,7 @@
icon_state = "clip_formal"
armor = null
- supports_variations = null
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE | VOX_VARIATION
/obj/item/clothing/under/clip/formal/alt
name = "formal clip outfit"
@@ -62,6 +63,8 @@
icon_state = "clip_medic"
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE | VOX_VARIATION
+
/obj/item/clothing/under/clip/officer
name = "clip minutemen officer uniform"
desc = "A uniform used by higher ranking officers of the CLIP Minutemen."
@@ -69,6 +72,8 @@
item_state = "g_suit"
can_adjust = FALSE
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE | VOX_VARIATION
+
/obj/item/clothing/under/clip/officer/alt
name = "clip minutemen officer uniform"
desc = "A uniform with a pencil skirt used by higher ranking officers of the CLIP Minutemen."
@@ -109,6 +114,8 @@
icon_state = "clip_general"
item_state = "clip_general"
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
+
/obj/item/clothing/suit/armor/vest/capcarapace/clip/admiral
name = "CLIP Minutemen admiral trenchcoat"
desc = "A very fancy trenchcoat used by admirals of the CLIP Minutemen."
@@ -137,7 +144,8 @@
armor = list("melee" = 25, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
cold_protection = CHEST|LEGS|ARMS
heat_protection = CHEST|LEGS|ARMS
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
+
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE
/obj/item/clothing/suit/armor/clip_capcoat
name = "\improper CLIP Minutemen captain's coat"
@@ -152,23 +160,38 @@
armor = list("melee" = 25, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
cold_protection = CHEST|LEGS|ARMS
heat_protection = CHEST|LEGS|ARMS
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
+
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE
+
+/obj/item/clothing/suit/armor/vest/clip_correspondent
+ name = "press armor vest"
+ desc = "A slim Type I armored vest that provides decent protection against most types of damage. The white letters on the front read \"PRESS\" in CLIP Kalixcian."
+
+ icon = 'icons/obj/clothing/faction/clip/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/clip/suits.dmi'
+
+ icon_state = "armor_correspondant"
+ item_state = "armor_correspondant"
//spacesuits
-/obj/item/clothing/suit/space/hardsuit/security/independent/clip //TODO: replace
- name = "\improper CMM Patroller hardsuit"
- desc = "A hardsuit used by the CLIP Minutemen. To reduce costs, its a modified version of a more popular model from a independent manufacturer, and given to patrol vessels. As should be obvious, it's not extremely armored, as it's made for reconnaissance and speed."
+/obj/item/clothing/suit/space/hardsuit/clip_patroller
+ name = "\improper CM-410 'Patroller' EVA Hardsuit"
+ desc = "A CLIP produced hardsuit adapted from an existing design. Intended for reconnaissance and speed, it's not extremely armored, that job goes to the Spotter hardsuit."
icon = 'icons/obj/clothing/faction/clip/suits.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/suits.dmi'
icon_state = "hardsuit-clip-patrol"
hardsuit_type = "hardsuit-clip-patrol"
- helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/independent/clip
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/clip_patroller
+
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE
+
+ armor = list("melee" = 35, "bullet" = 25, "laser" = 20,"energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
-/obj/item/clothing/head/helmet/space/hardsuit/security/independent/clip //TODO: replace
- name = "\improper CMM Patroller hardsuit helmet"
- desc = "A hardsuit used by the CLIP Minutemen. To reduce costs, its a modified version of a more popular model from a independent manufacturer, and given to patrol vessels. As should be obvious, it's not extremely armored, as it's made for reconnaissance and speed."
+/obj/item/clothing/head/helmet/space/hardsuit/clip_patroller
+ name = "\improper CM-410 'Patroller' EVA Hardsuit helmet"
+ desc = "A CLIP produced hardsuit adapted from an existing design. Intended for reconnaissance and speed, it's not extremely armored, that job goes to the Spotter hardsuit."
icon = 'icons/obj/clothing/faction/clip/head.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/head.dmi'
@@ -176,6 +199,10 @@
icon_state = "hardsuit0-clip-patrol"
hardsuit_type = "clip-patrol"
+ supports_variations = SNOUTED_VARIATION
+
+ armor = list("melee" = 35, "bullet" = 25, "laser" = 20,"energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
+
/obj/item/clothing/suit/space/hardsuit/clip_spotter
name = "CM-490 'Spotter' Combat Hardsuit"
desc = "CLIP's standard EVA combat hardsuit. Due to CLIP's doctrine on range, it doesn't have advanced components that allow swift movement, and thus slows down the user despite the heavy armor."
@@ -193,6 +220,8 @@
resistance_flags = null
slowdown = 1
+ supports_variations = DIGITIGRADE_VARIATION_SAME_ICON_FILE
+
/obj/item/clothing/head/helmet/space/hardsuit/clip_spotter
name = "CM-490 'Spotter' Combat Hardsuit Helmet"
desc = "CLIP's standard EVA combat hardsuit. Due to CLIP's doctrine on range, it doesn't have advanced components that allow swift movement, and thus slows down the user despite the heavy armor."
@@ -206,6 +235,7 @@
armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 40, "bomb" = 35, "bio" = 100, "rad" = 60, "fire" = 50, "acid" = 80)
resistance_flags = null
+ supports_variations = SNOUTED_VARIATION
//hats
/obj/item/clothing/head/clip
@@ -213,11 +243,13 @@
desc = "A standard issue soft cap dating back to the original Zohil colonial peroid. While usually given to recruits and volunteers, it's sometimes used by occasionally by some Minutemen."
icon = 'icons/obj/clothing/faction/clip/head.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/head.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
// lefthand_file = 'icons/mob/inhands/faction/clip/gezena_lefthand.dmi'
// righthand_file = 'icons/mob/inhands/faction/clip/gezena_righthand.dmi'
icon_state = "clip_cap"
item_state = "bluecloth"
- armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+
+ supports_variations = VOX_VARIATION
/obj/item/clothing/head/clip/corpsman
name = "\improper CLIP Minutemen corpsman cap"
@@ -225,28 +257,35 @@
icon_state = "clip_mediccap"
item_state = "whitecloth"
+ supports_variations = VOX_VARIATION
+
/obj/item/clothing/head/clip/slouch
name = "CLIP Minutemen slouch hat"
desc = "A commanding slouch hat used by the CLIP Minutemen."
icon_state = "clip_slouch_hat"
+ supports_variations = VOX_VARIATION
+
/obj/item/clothing/head/clip/slouch/officer
name = "CLIP Minutemen officer's slouch hat"
desc = "A commanding slouch hat adorned with a officer's badge, used by the CLIP Minutemen."
icon_state = "clip_officer_hat"
- armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
- strip_delay = 60
+
+ supports_variations = VOX_VARIATION
/obj/item/clothing/head/clip/boonie
name = "CLIP Minutemen boonie hat"
desc = "A wide brimmed cap to keep yourself cool during blistering hot weather."
icon_state = "clip_boonie"
+ supports_variations = VOX_VARIATION
+
/obj/item/clothing/head/clip/bicorne
name = "general's bicorne"
desc = "A fancy bicorne used by generals of the CLIP Minutemen."
icon_state = "clip_general_hat"
- armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+
+ supports_variations = VOX_VARIATION
/obj/item/clothing/head/helmet/bulletproof/x11/clip
name = "\improper Minutemen X11 Helmet"
@@ -254,26 +293,43 @@
icon = 'icons/obj/clothing/faction/clip/head.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/head.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
icon_state = "clip_x11"
allow_post_reskins = FALSE
unique_reskin = null
+ supports_variations = VOX_VARIATION
+
/obj/item/clothing/head/helmet/bulletproof/m10/clip_vc
name = "\improper Minutemen Vehicle Crewman M10 Helmet"
desc = "A light bulletproof helmet worn by Vehicle Crewmen of the CLIP Minutemen. The ear padding protects the ears from loud noises and the microphone automatically connects with a headset."
icon = 'icons/obj/clothing/faction/clip/head.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/head.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
icon_state = "clip_m10_vc"
allow_post_reskins = FALSE
unique_reskin = null
+ supports_variations = VOX_VARIATION
+
/obj/item/clothing/head/helmet/bulletproof/m10/clip_vc/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_HEAD))
+/obj/item/clothing/head/helmet/bulletproof/m10/clip_correspondent
+ name = "CLIP War Correspondant M10 Helmet"
+ desc = "A light bulletproof helmet worn by War Correspondants of the CLIP."
+
+ icon = 'icons/obj/clothing/faction/clip/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/clip/head.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
+
+ icon_state = "clip_m10_correspondant"
+ item_state = "clip_m10_correspondant"
+
/obj/item/clothing/head/helmet/riot/clip
name = "\improper Minutemen riot helmet"
desc = "Designed to protect against close range attacks. Mainly used by the CMM-BARD against hostile xenofauna, it also sees prolific use on some Minutemen member worlds."
@@ -282,6 +338,8 @@
mob_overlay_icon = 'icons/mob/clothing/faction/clip/head.dmi'
icon_state = "riot_clip"
+ supports_variations = SNOUTED_VARIATION
+
//GOLD
/obj/item/clothing/head/fedora/det_hat/clip
name = "GOLD fedora"
@@ -289,11 +347,12 @@
icon = 'icons/obj/clothing/faction/clip/head.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/head.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
icon_state = "clip_fedora"
item_state = "detective"
- armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) //dets hat is armored for some reaon
+ supports_variations = VOX_VARIATION
/obj/item/clothing/head/flatcap/clip
name = "GOLD flatcap"
@@ -301,9 +360,12 @@
icon = 'icons/obj/clothing/faction/clip/head.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/head.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
icon_state = "flatcap_clip"
item_state = "detective"
+
+ supports_variations = VOX_VARIATION
//mask
/obj/item/clothing/mask/gas/clip
@@ -316,6 +378,10 @@
icon_state = "clip-gasmask"
strip_delay = 60
+ flags_inv = HIDEEARS|HIDEFACE|HIDEFACIALHAIR
+
+ supports_variations = SNOUTED_VARIATION
+
//gloves
/obj/item/clothing/gloves/color/latex/nitrile/clip
@@ -324,10 +390,13 @@
icon = 'icons/obj/clothing/faction/clip/hands.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/hands.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
icon_state = "nitrile_clip"
item_state = "nitrile_clip"
+ supports_variations = VOX_VARIATION
+
//boots
//belt
@@ -337,12 +406,15 @@
icon = 'icons/obj/clothing/faction/clip/belt.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/belt.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
icon_state = "clipwebbing"
item_state = "clipwebbing"
unique_reskin = null
+ supports_variations = VOX_VARIATION
+
/obj/item/storage/belt/military/clip/p16/PopulateContents()
for(var/i in 1 to 4)
new /obj/item/ammo_box/magazine/p16(src)
@@ -389,9 +461,12 @@
icon = 'icons/obj/clothing/faction/clip/belt.dmi'
mob_overlay_icon = 'icons/mob/clothing/faction/clip/belt.dmi'
+ vox_override_icon = 'icons/mob/clothing/faction/clip/vox.dmi'
icon_state = "clip-medwebbing"
+ supports_variations = VOX_VARIATION
+
/obj/item/storage/belt/medical/webbing/clip/prefilled/PopulateContents()
new /obj/item/reagent_containers/medigel/styptic(src)
new /obj/item/reagent_containers/medigel/styptic(src)
@@ -408,6 +483,8 @@
icon_state = "clippack"
+ supports_variations = VOX_VARIATION
+
/obj/item/storage/backpack/satchel/sec/clip
name = "clip satchel"
desc = "A robust satchel for anti-piracy related needs."
diff --git a/code/modules/clothing/factions/frontiersmen.dm b/code/modules/clothing/factions/frontiersmen.dm
new file mode 100644
index 000000000000..9bac6c40a004
--- /dev/null
+++ b/code/modules/clothing/factions/frontiersmen.dm
@@ -0,0 +1,260 @@
+//////////////
+//Jumpsuits//
+/////////////
+
+/obj/item/clothing/under/frontiersmen
+ name = "\improper frontiersmen uniform"
+ desc = "Fatigues worn by members of the Frontiersmen pirate fleet. Its poor-quality linen is very uncomfortable to move around in."
+ icon_state = "frontier"
+ item_state = "frontier"
+ can_adjust = FALSE
+ icon = 'icons/obj/clothing/faction/frontiersmen/uniforms.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/uniforms.dmi'
+
+/obj/item/clothing/under/frontiersmen/deckhand
+ name = "\improper deckhand jumpsuit"
+ desc = "A cheap olive-green jumpsuit used by the Frontiersmen on their vessels. It has an old smell permeating it."
+ icon_state = "frontier_deckhand"
+ item_state = "frontier_deckhand"
+
+/obj/item/clothing/under/frontiersmen/fireproof
+ name = "\improper fireproof frontiersmen fatigues"
+ desc = "An all-black set of fatigues worn by the flamethrower units of the Frontiersmen. It feels oddly itchy when worn..."
+ icon_state = "frontier_fireproof"
+ item_state = "frontier_fireproof"
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
+ resistance_flags = FIRE_PROOF
+
+/obj/item/clothing/under/frontiersmen/officer
+ name = "\improper Frontiersmen officer's uniform"
+ desc = "Worn by officers of the Frontiersmen pirate fleet. It's less comfortable than it looks."
+ icon_state = "frontier_officer"
+
+/obj/item/clothing/under/frontiersmen/admiral
+ name = "\improper frontiersmen admiral uniform"
+ desc = "Worn by admirals of the Frontiersmen pirate fleet, adorned with a tasteful amount of gold and completed with a very-stylish all-white aesthetic. Quite snobby for a bunch of pirates."
+ icon_state = "frontier_admiral"
+ item_state = "frontier_admiral"
+
+////////////////////
+//Unarmored suits//
+///////////////////
+
+/obj/item/clothing/suit/frontiersmen
+ name = "frontiersmen smock"
+ desc = "A basic white surgical apron worn by the Frontiersmen. It seems it could stain very easily..."
+ icon_state = "frontier_surgery"
+ icon = 'icons/obj/clothing/faction/frontiersmen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/suits.dmi'
+
+//////////////////
+//Armored suits//
+/////////////////
+
+/obj/item/clothing/suit/armor/vest/bulletproof/frontier
+ name = "\improper Frontiersmen bulletproof armor"
+ desc = "A scrap piece of armor made of disused protective plates. This one was used to protect the squishy bits of a Frontiersman, once."
+ icon_state = "frontier_armor"
+ icon = 'icons/obj/clothing/faction/frontiersmen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/suits.dmi'
+ blood_overlay_type = "armor"
+
+/obj/item/clothing/suit/armor/vest/marine/frontier
+ name = "light tactical armor vest"
+ desc = "A bulky set of stamped plasteel armor plates, coated with the intimidating grey of the Frontiersmen. If you have the time to inspect this vest, either you are about to die, or you have killed the one who wore it originally."
+ icon_state = "marine_frontier"
+ item_state = "armor"
+ icon = 'icons/obj/clothing/faction/frontiersmen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/suits.dmi'
+
+/obj/item/clothing/suit/armor/frontier
+ name = "reinforced fur coat"
+ desc = "A stiff olive-green coat, meant for frigid conditions. Commonly worn by Frontiersmen command."
+ icon_state = "frontier_coat"
+ body_parts_covered = CHEST|GROIN|ARMS
+ cold_protection = CHEST|GROIN|ARMS
+ heat_protection = CHEST|GROIN|ARMS
+ icon_state = "frontier_coat"
+ item_state = "frontier_coat"
+ blood_overlay_type = "coat"
+ armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+ icon = 'icons/obj/clothing/faction/frontiersmen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/suits.dmi'
+
+/obj/item/clothing/suit/armor/frontier/fireproof
+ name = "frontiersmen fireproof coat"
+ desc = "A stiff olive-green coat, used particularly by Frontiersmen flame troopers. It seems to be lined with asbestos, to provide maximum heat and fire deterrence... At the cost of comfort. And mesothelioma."
+ icon_state = "frontier_fireproof_suit"
+ armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
+ w_class = WEIGHT_CLASS_BULKY
+ gas_transfer_coefficient = 0.9
+ permeability_coefficient = 0.5
+ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
+ slowdown = 0.5
+ clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL
+ heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
+ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
+ cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
+ min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
+ allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/tank/internals/plasmaman, /obj/item/extinguisher, /obj/item/crowbar)
+
+///////////////
+//Spacesuits//
+//////////////
+
+/obj/item/clothing/head/helmet/space/hardsuit/security/independent/frontier
+ name = "\improper Frontiersmen hardsuit helmet"
+ desc = "An old hardsuit helmet based on a even older hardsuit helmet. Used prolifically by the Frontiersmen pirate fleet."
+ icon_state = "hardsuit0-frontier"
+ icon = 'icons/obj/clothing/faction/frontiersmen/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/head.dmi'
+ hardsuit_type = "frontier"
+
+/obj/item/clothing/suit/space/hardsuit/security/independent/frontier
+ name = "\improper Frontiersmen hardsuit"
+ desc = "An old hardsuit based on a even older hardsuit. Used prolifically by the Frontiersmen pirate fleet."
+ icon_state = "hardsuit_frontier"
+ hardsuit_type = "hardsuit_frontier"
+ icon = 'icons/obj/clothing/faction/frontiersmen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/suits.dmi'
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/independent/frontier
+
+/////////
+//Hats//
+////////
+
+/obj/item/clothing/head/soft/frontiersmen
+ name = "frontiersman cap"
+ desc = "An olive-green and grey baseball hat, worn by cargo technicians working under the Frontiersmen. Even they have the rights for a cool cap!"
+ icon_state = "frontiersoft"
+ soft_type = "frontiersmen"
+ icon = 'icons/obj/clothing/faction/frontiersmen/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/head.dmi'
+
+/obj/item/clothing/head/beret/sec/frontier
+ name = "\improper Frontiersmen beret"
+ desc = "A scratchy olive green beret, worn by Frontiersmen who want to look good while intimidating freighter crew."
+ icon_state = "frontier_beret"
+ icon = 'icons/obj/clothing/faction/frontiersmen/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/head.dmi'
+
+/obj/item/clothing/head/beret/sec/frontier/officer
+ name = "\improper Frontiersmen officer beret"
+ desc = "A scratchy olive green beret emblazoned with the Frontiersmen insignia, worn by Frontiersmen who want to look good while intimidating freighter captains."
+ icon_state = "frontier_officer_beret"
+ armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+
+/obj/item/clothing/head/frontier
+ name = "frontier surgical cap"
+ desc = "A white surgical cap used by the quite uncommon doctors part of the Frontiersmen."
+ icon_state = "frontier_surgery"
+ icon = 'icons/obj/clothing/faction/frontiersmen/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/head.dmi'
+
+/obj/item/clothing/head/hardhat/frontier
+ name = "faded white hard hat"
+ desc = "A grimy white hardhat used by the mechanics and engineers of the Frontiersmen fleet. Smells old."
+ icon_state = "frontier_hardhat"
+ icon = 'icons/obj/clothing/faction/frontiersmen/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/head.dmi'
+
+/obj/item/clothing/head/frontier/peaked
+ name = "\improper frontiersmen commander's cap"
+ desc = "An imposing peaked cap, meant for a commander of the Frontiersmen."
+ icon_state = "frontier_cap"
+
+/obj/item/clothing/head/frontier/admiral
+ name = "\improper frontiersmen admiral's cap"
+ desc = "An imposing peaked cap meant for only the highest of officers of the Frontiersmen pirate fleet."
+ icon_state = "frontier_admiral_cap"
+
+/obj/item/clothing/head/helmet/bulletproof/x11/frontier
+ name = "\improper frontiersmen X-11 helmet"
+ desc = "A heavily modified X-11 pattern helmet used by the Frontiersmen pirate fleet."
+ icon_state = "x11helm_frontier"
+ unique_reskin = null
+
+/obj/item/clothing/head/helmet/bulletproof/x11/frontier/fireproof
+ name = "\improper fireproof frontiersmen X-11 helmet"
+ desc = "A subtly but helpful modifcation of the Frontiersmen X11 to make it fireproof."
+ heat_protection = HEAD
+ max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
+ cold_protection = HEAD
+ min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
+ resistance_flags = FIRE_PROOF
+ armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
+
+/obj/item/clothing/head/helmet/marine/frontier
+ name = "frontiersmen reinforced helmet"
+ desc = "A reinforced Frontiersmen X-11. The front plate has a small window to let the user see."
+ icon_state = "marine_frontier"
+ icon = 'icons/obj/clothing/faction/frontiersmen/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/head.dmi'
+
+////////////
+//Glasses//
+///////////
+
+//////////
+//Masks//
+/////////
+
+/obj/item/clothing/mask/gas/frontiersmen
+ name = "sack gas mask"
+ desc = "A gas mask that can be connected to an air supply. It's made out of sack, but still works just as good for protecting you."
+ icon_state = "gasmask_frontier"
+ icon = 'icons/obj/clothing/faction/frontiersmen/mask.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/mask.dmi'
+ resistance_flags = FIRE_PROOF
+
+//////////
+//Neck//
+/////////
+
+//////////
+//Belts//
+/////////
+
+/obj/item/storage/belt/security/military/frontiersmen
+ name = "leather bandolier"
+ desc = "A rudimentary leather bandolier, utilized by both independents and frontiersmen alike. Usually slung diagonally, from the shoulder to the waist."
+ icon_state = "frontierwebbing"
+ item_state = "frontierwebbing"
+ icon = 'icons/obj/clothing/faction/frontiersmen/belt.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/belt.dmi'
+
+ unique_reskin = null
+
+/obj/item/storage/belt/medical/webbing/frontiersmen
+ name = "leather medical bandolier"
+ desc = "A rudimentary leather bandolier, utilized by both independents and frontiersmen alike. This one is painted white, usually to be worn by a medic."
+ icon_state = "frontiermedicalwebbing"
+ item_state = "frontiermedicalwebbing"
+ icon = 'icons/obj/clothing/faction/frontiersmen/belt.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/frontiersmen/belt.dmi'
+
+/obj/item/storage/belt/medical/webbing/frontiersmen/surgery/PopulateContents()
+ new /obj/item/scalpel(src)
+ new /obj/item/circular_saw(src)
+ new /obj/item/surgicaldrill(src)
+ new /obj/item/retractor(src)
+ new /obj/item/cautery(src)
+ new /obj/item/hemostat(src)
+ new /obj/item/hypospray/mkii(src)
+ update_appearance()
+
+
+/obj/item/storage/belt/security/military/frontiersmen/skm_ammo/PopulateContents()
+ for(var/i in 1 to 4)
+ new /obj/item/ammo_box/magazine/skm_762_40(src)
+ new /obj/item/grenade/frag(src)
+
+/obj/item/storage/belt/security/military/frontiersmen/aps_mp_ammo/PopulateContents() //replace with spitter. remind me.
+ for(var/i in 1 to 4)
+ new /obj/item/ammo_box/magazine/pistolm9mm(src)
+ new /obj/item/grenade/frag(src)
+
+/obj/item/storage/belt/security/military/frontiersmen/flamer/PopulateContents()
+ for(var/i in 1 to 4)
+ new /obj/item/reagent_containers/glass/beaker/large/napalm(src)
+ new /obj/item/grenade/frag(src)
diff --git a/code/modules/clothing/factions/gezena.dm b/code/modules/clothing/factions/gezena.dm
index b6b0839509fa..96c6eee3c734 100644
--- a/code/modules/clothing/factions/gezena.dm
+++ b/code/modules/clothing/factions/gezena.dm
@@ -1,5 +1,4 @@
//Jumpsuits
-//thgvr TODO: Make more stuff (backpacks, headsets, doodads, part 2?)
/obj/item/clothing/under/gezena
name = "gezenan navywear"
desc = "Made of a slick synthetic material that is both breathable, and resistant to scale and thorn alike."
@@ -37,7 +36,7 @@
item_state = "bluecloth"
blood_overlay_type = "coat"
togglename = "zipper"
- body_parts_covered = CHEST|ARMS
+ body_parts_covered = CHEST
pocket_storage_component_path = /datum/component/storage/concrete/pockets/exo
supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
armor = list("melee" = 20, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
@@ -54,20 +53,11 @@
icon_state = "coat"
item_state = "bluecloth"
blood_overlay_type = "coat"
- body_parts_covered = CHEST|ARMS|GROIN|LEGS
+ body_parts_covered = CHEST|GROIN
pocket_storage_component_path = /datum/component/storage/concrete/pockets/exo
supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
armor = list("melee" = 35, "bullet" = 35, "laser" = 20, "energy" = 40, "bomb" = 20, "bio" = 20, "rad" = 0, "fire" = 50, "acid" = 50)
- allowed = list(
- /obj/item/flashlight,
- /obj/item/tank/internals/emergency_oxygen,
- /obj/item/tank/internals/plasmaman,
- /obj/item/toy,
- /obj/item/storage/fancy/cigarettes,
- /obj/item/lighter,
- /obj/item/radio,
- /obj/item/gun/energy/kalix,
- )
+ allowed = null
/obj/item/clothing/suit/armor/gezena/engi
name = "engineer navywear coat"
diff --git a/code/modules/clothing/factions/hardliners.dm b/code/modules/clothing/factions/hardliners.dm
new file mode 100644
index 000000000000..5c3423f745c0
--- /dev/null
+++ b/code/modules/clothing/factions/hardliners.dm
@@ -0,0 +1,181 @@
+//////////////
+//Jumpsuits//
+/////////////
+
+/obj/item/clothing/under/syndicate/hardliners
+ name = "hardliners uniform"
+ desc = "A crimson combat uniform, reminiscent of the Gorlex Marauders at the height of the Inter-Corporate Wars. It's oddly comfortable, and warm."
+ icon_state = "hardliners"
+ item_state = "hardliners"
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
+ can_adjust = FALSE
+ icon = 'icons/obj/clothing/faction/hardliners/uniforms.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/uniforms.dmi'
+
+/obj/item/clothing/under/syndicate/hardliners/jumpsuit
+ name = "hardliners jumpsuit"
+ desc = "A black jumpsuit with white overalls, a scant reminder of the old miners of Gorlex VII."
+ icon_state = "hl_jumpsuit"
+ item_state = "hl_jumpsuit"
+
+/obj/item/clothing/under/syndicate/hardliners/officer
+ name = "hardliners officer uniform"
+ desc = "A button-up uniform with cargo pants, certainly more tactical than most officer uniforms."
+ icon_state = "hl_officer"
+ item_state = "hl_officer"
+
+////////////////////
+//Unarmored suits//
+///////////////////
+
+/obj/item/clothing/suit/hardliners
+ name = "white smock"
+ desc = "A plain-white surgical smock typically worn by both Hardliners and Cybersun staff. Even mercenaries need medical attention!"
+ icon = 'icons/obj/clothing/faction/hardliners/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/suits.dmi'
+ icon_state = "hl_apron"
+ item_state = "whitecloth"
+
+/obj/item/clothing/suit/hazardvest/hardliners
+ name = "blood-red hazard vest"
+ desc = "A white high-visibility vest, worn by mechanics associated with Hardliners. Safety first!"
+ icon = 'icons/obj/clothing/faction/hardliners/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/suits.dmi'
+ icon_state = "hl_hazard"
+ item_state = "whitecloth"
+
+//////////////////
+//Armored suits//
+/////////////////
+
+/obj/item/clothing/suit/armor/hardliners
+ name = "hardliners armor vest"
+ desc = "A slim Type I armored vest, painted in a classic white associated with the Hardliners. It would probably make bloodstains very obvious..."
+ icon_state = "hl_vest"
+ item_state = "armor"
+ icon = 'icons/obj/clothing/faction/hardliners/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/suits.dmi'
+ blood_overlay_type = "armor"
+
+/obj/item/clothing/suit/armor/hardliners/jacket
+ name = "hardliners armored kutte"
+ desc = "A leather Kutte with a slim Type I armored vest, painted in a classic white associated with the Hardliners. The patch of the Hardliner movement can be seen behind the leather kutte, a nostalgic callback to the leather outfits used by the civilians of Gorlex VII."
+ icon_state = "hl_jacket"
+ item_state = "armor"
+ icon = 'icons/obj/clothing/faction/hardliners/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/suits.dmi'
+ blood_overlay_type = "armor"
+
+/obj/item/clothing/suit/armor/hardliners/sergeant
+ name = "hardliners sergeant jacket"
+ desc = "An armored jacket typically worn by sergeant of the Hardliners. They're reminiscent of the garb worn by old Gorlex navymen, prior to its destruction."
+ body_parts_covered = CHEST|GROIN|ARMS
+ icon_state = "hl_sergeant"
+ item_state = "hl_sergeant"
+ blood_overlay_type = "coat"
+ armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+
+/obj/item/clothing/suit/toggle/armor/vest/hardliners
+ name = "hardliners captain coat"
+ desc = "An imposing armored coat worn by captains of Hardliner fleets, hand-designed by Cybersun tailors to provide maximum protection to its wearer."
+ body_parts_covered = CHEST|GROIN|ARMS
+ icon_state = "hl_captain"
+ item_state = "hl_captain"
+ icon = 'icons/obj/clothing/faction/hardliners/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/suits.dmi'
+ blood_overlay_type = "coat"
+ armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+ togglename = "buttons"
+
+///////////////
+//Spacesuits//
+//////////////
+
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/hl
+ name = "white-red hardsuit helmet"
+ desc = "An advanced dual-mode helmet derived from ICW-era advanced special operations helmets, its red partly replaced by white. It is in EVA mode. Manufactured by Cybersun Biodynamics."
+ alt_desc = "An advanced dual-mode helmet derived from ICW-era advanced special operations helmets, its red partly replaced by white. It is in combat mode. Manufactured by Cybersun Biodynamics."
+ icon_state = "hardsuit1-hl"
+ item_state = "hardsuit1-hl"
+ icon = 'icons/obj/clothing/faction/hardliners/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/head.dmi'
+ hardsuit_type = "hl"
+
+/obj/item/clothing/suit/space/hardsuit/syndi/hl
+ name = "white-red hardsuit"
+ desc = "An advanced dual-mode hardsuit derived from ICW-era advanced special operations hardsuits, its red partly replaced by white. It is in EVA mode. Manufactured by Cybersun Biodynamics."
+ alt_desc = "An advanced dual-mode hardsuit derived from ICW-era advanced special operations hardsuits, its red partly replaced by white. It is in combat mode. Manufactured by Cybersun Biodynamics."
+ icon_state = "hardsuit1-hl"
+ item_state = "hardsuit1-hl"
+ hardsuit_type = "hl"
+ icon = 'icons/obj/clothing/faction/hardliners/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/suits.dmi'
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/hl
+ lightweight = 1
+ jetpack = null
+
+/////////
+//Hats//
+////////
+
+/obj/item/clothing/head/hardliners
+ name = "white surgical cap"
+ desc = "A surgical cap used by doctors of Hardliner fleets, matching their white smocks."
+ icon_state = "hl_surgery"
+ icon = 'icons/obj/clothing/faction/hardliners/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/head.dmi'
+
+
+/obj/item/clothing/head/hardhat/hardliners
+ name = "white-red hard hat"
+ desc = "A white-red hardhat typically used by both miners and mechanics under the Hardliner fleets."
+ icon_state = "hl_hardhat"
+ icon = 'icons/obj/clothing/faction/hardliners/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/head.dmi'
+
+/obj/item/clothing/head/hardliners/peaked
+ name = "Hardliner peaked cap"
+ desc = "A stylish peaked cap utilized by high-ranking officers of the Hardliner movement. Most who wear it are likely to have been a veteran of the ICW, still vying for revenge against Nanotrasen..."
+ icon_state = "hl_officer"
+ item_state = "hl_officer"
+
+/obj/item/clothing/head/helmet/hardliners
+ name = "hardliners X-11 helmet"
+ desc = "A well-armored helmet utilized by the Hardliners, though painted in their iconic white. Either it makes them stick out like a sore thumb, or it provides excellent camouflage in snow-covered planets."
+ icon = 'icons/obj/clothing/faction/hardliners/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/head.dmi'
+ armor = list("melee" = 40, "bullet" = 60, "laser" = 35, "energy" = 35, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) // The guys who specialize in ballistics would probably have better bullet armor. Maybe.
+ icon_state = "hl_x11"
+ item_state = "hl_x11"
+
+/obj/item/clothing/head/helmet/hardliners/swat
+ name = "hardliners pilot helmet"
+ desc = "A modified X-11 helmet utilized by regular pilots, as well as the feared mech pilots of the Hardliner movement. The attached visor helps protect against sudden flashes from explosions."
+ flash_protect = FLASH_PROTECTION_WELDER
+ icon_state = "hl_pilot"
+ item_state = "hl_pilot"
+
+////////////
+//Glasses//
+///////////
+
+/obj/item/clothing/glasses/hud/security/sunglasses/hardliners
+ name = "hardliners security goggles"
+ desc = "Tinted-red flash-proof goggles used by Hardliners, with an integrated security HUD, courtesy of their partners, Cybersun."
+ icon_state = "hl_goggles"
+ item_state = "hl_goggles"
+ icon = 'icons/obj/clothing/faction/hardliners/eyes.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/eyes.dmi'
+ glass_colour_type = /datum/client_colour/glass_colour/red
+
+//////////
+//Belts//
+/////////
+
+/obj/item/storage/belt/security/webbing/hardliners
+ name = "hardliners webbing"
+ desc = "A set of tactical webbing for operators of the Hardliner movement, can hold security gear."
+ icon_state = "hl_webbing"
+ item_state = "hl_webbing"
+ icon = 'icons/obj/clothing/faction/hardliners/belt.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/hardliners/belt.dmi'
diff --git a/code/modules/clothing/factions/nanotrasen.dm b/code/modules/clothing/factions/nanotrasen.dm
new file mode 100644
index 000000000000..664c534d236e
--- /dev/null
+++ b/code/modules/clothing/factions/nanotrasen.dm
@@ -0,0 +1,391 @@
+// Uniforms //
+
+/obj/item/clothing/under/nanotrasen
+ name = "deckhand's uniform"
+ desc = "A plain grey work uniform with a Nanotrasen, Inc. logo embroidered on the front. Typical of entry-level employees."
+ icon = 'icons/obj/clothing/faction/nanotrasen/uniforms.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/nanotrasen/uniforms.dmi'
+ lefthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi'
+ icon_state = "deckhand"
+ item_state = "graycloth"
+ supports_variations = DIGITIGRADE_VARIATION
+
+// Engineering uniforms
+/obj/item/clothing/under/nanotrasen/engineering
+ name = "engineering jumpsuit"
+ desc = "A dirty grey jumpsuit with reflective blue flashes on the limbs and a wrench icon on the back. A Nanotrasen, Inc. logo is stitched into the collar."
+ icon_state = "engi"
+ item_state = "greycloth"
+
+/obj/item/clothing/under/nanotrasen/engineering/atmos
+ name = "atmospherics jumpsuit"
+ desc = "A thick grey jumpsuit with black stripes and an 'O2' icon on the back. A Nanotrasen, Inc. logo is stitched into the collar."
+ icon_state = "atmos_tech"
+ item_state = "greycloth"
+
+/obj/item/clothing/under/nanotrasen/engineering/director
+ name = "engineering director's overalls"
+ desc = "Thick black overalls over a blue office shirt. Unlike most managerial staff, Nanotrasen engineering directors still need to get hands-on with their work."
+ icon_state = "engi_director"
+ item_state = "blackcloth"
+
+//Supply uniforms
+/obj/item/clothing/under/nanotrasen/supply
+ name = "cargo handler shorts"
+ desc = "A cheap work shirt and black shorts, typical of cargo handlers and clerks at N+S Logistics."
+ icon_state = "supply"
+ item_state = "browncloth"
+
+/obj/item/clothing/under/nanotrasen/supply/qm
+ name = "supply director slacks"
+ desc = "Crisp slacks and a pressed brown shirt that any supply director could be proud of. N+S Logistics' compass rose logo is embossed on every button."
+ icon_state = "supply_director"
+ item_state = "browncloth"
+
+/obj/item/clothing/under/nanotrasen/supply/miner
+ name = "mining overalls"
+ desc = "Cheap brown overalls over a grey jumpsuit, already slightly frayed and saturated with rock dust. N+S Logistics logos are prominently sewn on in several places."
+ icon_state = "miner"
+ item_state = "browncloth"
+
+//Science uniforms
+/obj/item/clothing/under/nanotrasen/science
+ name = "science slacks"
+ desc = "A thick buttoned shirt and slacks for some protection against low-level lab hazards. The basic uniform of Nanotrasen, Inc.'s research division."
+ icon_state = "sci"
+ item_state = "whitecloth"
+
+/obj/item/clothing/under/nanotrasen/science/robotics
+ name = "robotics jumpsuit"
+ desc = "A cheap black jumpsuit with blue arm flashes. Expendable armor against oil and sparks, issued en masse to Nanotrasen robotics technicians."
+ icon_state = "robotics"
+ item_state = "blackcloth"
+
+/obj/item/clothing/under/nanotrasen/science/director
+ name = "science director's slacks"
+ desc = "A well-made black shirt with blue slacks, practically begging to be paired with a garish tie of some description. Nanotrasen logos are neatly stitched into the collar and cuffs."
+ icon_state = "sci_director"
+ item_state = "blackcloth"
+
+//Medical uniforms
+/obj/item/clothing/under/nanotrasen/medical
+ name = "medical slacks"
+ desc = "A crisp white shirt with blue stripes on the arms, identifying the owner as trained Nanotrasen medical staff. The faint smell of antiseptic won't wash out."
+ icon_state = "doctor"
+ item_state = "whitecloth"
+
+/obj/item/clothing/under/nanotrasen/medical/paramedic
+ name = "paramedic uniform"
+ desc = "Tough synthetic pants and a white uniform shirt, designed to handle all manner of scrapes and splashes in the line of duty. The tag identifies this as property of Nanotrasen, Inc."
+ icon_state = "paramedic"
+ item_state = "whitecloth"
+
+/obj/item/clothing/under/nanotrasen/medical/director
+ name = "medical director's slacks"
+ desc = "A neat blue shirt with white arm bands and comfortable black slacks. Nanotrasen logos are finely stitched into the collar and cuffs. It smells like burnt coffee and antiseptic."
+ icon_state = "medical_director"
+ item_state = "bluecloth"
+
+//Security/civilian uniforms
+
+/obj/item/clothing/under/nanotrasen/janitor
+ name = "custodial jumpsuit"
+ desc = "A grey jumpsuit with purple sleeves and faint stains on the elbows and knees. It looks stiff and cheap, but is surprisingly comfortable."
+ icon_state = "janitor"
+ item_state = "graycloth"
+
+/obj/item/clothing/under/nanotrasen/affairs
+ name = "neatly pleated slacks"
+ desc = "Flawlessly pleated slacks and a linen shirt with the Nanotrasen logo stitched repeatedly into the cuffs and collar. It exudes an aura of quiet authority."
+ icon_state = "affairs"
+ item_state = "whitecloth"
+
+/obj/item/clothing/under/nanotrasen/security
+ name = "security slacks"
+ desc = "A starched grey uniform with red arm flashes, of a type seen throughout the core worlds. The Vigilitas Interstellar logo is proudly emblazoned on the front."
+ icon_state = "security"
+ item_state = "graycloth"
+
+/obj/item/clothing/under/nanotrasen/security/director
+ name = "security director's slacks"
+ desc = "A robust crimson uniform, heavily starched, with a Vigilitas logo neatly stitched onto either end of the collar. The last line of defense for Vigilitas's managerial staff."
+ icon_state = "security_director"
+ item_state = "redcloth"
+
+//Command uniforms
+/obj/item/clothing/under/nanotrasen/captain
+ name = "blue captain's slacks"
+ desc = "A quality uniform in Nanotrasen Blue, with gold trim. Gold Nanotrasen logo pins adorn the collar and cuffs. The fine fabrics and comfortable fit set this apart from the more utilitarian uniforms worn by lower-level employees."
+ icon_state = "nt_captain"
+ item_state = "bluecloth"
+
+/obj/item/clothing/under/nanotrasen/captain/skirt
+ name = "blue captain's skirt"
+ desc = "A quality uniform in Nanotrasen Blue, with gold trim. Gold Nanotrasen logo pins adorn the collar and cuffs. The fine fabrics and comfortable fit set this apart from the more utilitarian uniforms worn by lower-level employees."
+ icon_state = "nt_captain_skirt"
+ body_parts_covered = CHEST|GROIN|ARMS
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
+
+/*
+/obj/item/clothing/under/nanotrasen/captain/parade
+ name = ""
+ desc = ""
+ icon_state = "captain_parade"
+ can_adjust = FALSE
+*/
+
+/obj/item/clothing/under/nanotrasen/officer
+ name = "officer's slacks"
+ desc = "An unadorned uniform in Nanotrasen Blue. While it isn't as nice as a captain's uniform, the color and quality still mark its owner as part of Nanotrasen's managerial class."
+ icon_state = "officer"
+ item_state = "bluecloth"
+
+/obj/item/clothing/under/nanotrasen/officer/skirt
+ name = "officer's skirt"
+ desc = "An unadorned uniform in Nanotrasen Blue. While it isn't as nice as a captain's uniform, the color and quality still mark its owner as part of Nanotrasen's managerial class."
+ icon_state = "officer_skirt"
+ body_parts_covered = CHEST|GROIN|ARMS
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
+
+// Suits //
+
+/obj/item/clothing/suit/nanotrasen //Base type, do not use
+ name = "Suit"
+ desc = "You shouldn't be here."
+ icon = 'icons/obj/clothing/faction/nanotrasen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/nanotrasen/suits.dmi'
+ lefthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi'
+
+/obj/item/clothing/suit/nanotrasen/medical_smock
+ name = "surgical smock"
+ desc = "A thick fluid-repelling smock rendered in what is unmistakeably Nanotrasen Blue. The tag on the inside declares it property of Nanotrasen, Inc."
+ icon_state = "med_smock"
+ item_state = "bluecloth"
+
+/obj/item/clothing/suit/nanotrasen/suitjacket
+ name = "fancy black suit jacket"
+ desc = "A fine black linen suit jacket with blue markings and a Nanotrasen lapel pin. It has a strangely menacing aura."
+ icon_state = "suit_jacket"
+ item_state = "blackcloth"
+
+/obj/item/clothing/suit/nanotrasen/vest
+ name = "black hazard vest"
+ desc = "A thin black vest with reflective markings, worn to guarantee visibility when operating around industrial equipment or in dark or dusty conditions. Property of Nanotrasen, Inc."
+ icon_state = "engi_vest"
+ item_state = "blackcloth"
+
+/obj/item/clothing/suit/nanotrasen/vest/blue
+ name = "blue hazard vest"
+ desc = "A thin vest with reflective stripes, worn to guarantee visibility in dangerous conditions. The vest itself is an offensively bright shade of Nanotrasen Blue. Property of Nanotrasen, Inc."
+ icon_state = "atmos_vest"
+ item_state = "bluecloth"
+
+/obj/item/clothing/suit/toggle/nanotrasen
+ name = "officer's coat"
+ desc = "A smart blue uniform jacket with red silk accents and a large buckle with an engraved Nanotrasen logo. Standard wear for command officers aboard Nanotrasen, Inc. ships."
+ icon = 'icons/obj/clothing/faction/nanotrasen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/nanotrasen/suits.dmi'
+ lefthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi'
+ icon_state = "officer_formal"
+ item_state = "bluecloth"
+
+/obj/item/clothing/suit/toggle/labcoat/nanotrasen
+ name = "corporate labcoat"
+ desc = "A standardized white labcoat used by Nanotrasen, Inc.'s medical and research divisions. A simplified Nanotrasen logo is stitched on the front."
+ icon = 'icons/obj/clothing/faction/nanotrasen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/nanotrasen/suits.dmi'
+ lefthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi'
+ icon_state = "labcoat"
+ item_state = "whitecloth"
+
+/obj/item/clothing/suit/toggle/labcoat/nanotrasen/blue
+ name = "medical director's labcoat"
+ desc = "A well-made, fitted labcoat, crafted from high-quality materials and sporting blue markings around the arms and hem. A Nanotrasen logo is neatly embroidered on the front. Stylish, practical, and exceptionally professional."
+ icon_state = "med_labcoat"
+ item_state = "whitecloth"
+
+/obj/item/clothing/suit/toggle/labcoat/nanotrasen/black
+ name = "science director's labcoat"
+ desc = "An overdesigned and rather intimidating black labcoat with a very high collar, as impervious to lab hazards as one can get without a full-body suit. Nanotrasen, Inc.'s logo is proudly emblazoned on the chest."
+ icon_state = "black_labcoat"
+ item_state = "blackcloth"
+
+/obj/item/clothing/suit/toggle/labcoat/nanotrasen/paramedic
+ name = "bright blue paramedic jacket"
+ desc = "A thick, protective blue jacket with reflective visibility stripes and a Nanotrasen logo stitched into the chest. Safe against all manner of scrapes and splashes."
+ icon_state = "med_jacket"
+ item_state = "bluecloth"
+
+/obj/item/clothing/suit/armor/nanotrasen
+ name = "armor vest"
+ desc = "A sturdy vest designed to protect Vigilitas Interstellar officers from a variety of basic threats. Sports a stylish red stripe down the front."
+ icon = 'icons/obj/clothing/faction/nanotrasen/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/nanotrasen/suits.dmi'
+ lefthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi'
+ icon_state = "armor"
+ item_state = "blackcloth"
+ body_parts_covered = CHEST|GROIN
+ armor = list("melee" = 30, "bullet" = 40, "laser" = 30, "energy" = 50, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90)
+ resistance_flags = FIRE_PROOF
+
+/obj/item/clothing/suit/armor/nanotrasen/slim
+ name = "slim armor vest"
+ icon_state = "armor_slim"
+
+/obj/item/clothing/suit/armor/nanotrasen/sec_director
+ name = "security director's overcoat"
+ desc = "A tailored black overcoat, made from cutting-edge ballistic fabrics and composites. Vigilitas's 'VI' logo is embossed on every button. Intimidating and profoundly stylish."
+ icon_state = "command_coat"
+ body_parts_covered = CHEST|GROIN|ARMS
+ armor = list("melee" = 30, "bullet" = 0, "laser" = 30, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90)
+
+/obj/item/clothing/suit/armor/nanotrasen/captain
+ name = "captain's jacket"
+ desc = "A sturdy jacket in Nanotrasen Blue, accentuated with gold thread and lined with a layer of ballistic fabric. Its large, shiny belt buckle is embossed with Nanotrasen's corporate logo."
+ icon_state = "armor_captain"
+ item_state = "bluecloth"
+ body_parts_covered = CHEST|GROIN
+ armor = list("melee" = 50, "bullet" = 60, "laser" = 60, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90)
+ resistance_flags = FIRE_PROOF
+
+/obj/item/clothing/suit/armor/nanotrasen/captain/parade
+ name = "ostentatious captain's coat"
+ desc = "An exquisitely-decorated fine blue jacket, suitable for especially formal situations, or for a commanding officer who wants to flaunt their status even more than usual. Richly decorated with gold thread and embroidered Nanotrasen logos."
+ icon_state = "captain_formal"
+ item_state = "bluecloth"
+ body_parts_covered = CHEST|GROIN|ARMS
+ armor = list("melee" = 30, "bullet" = 0, "laser" = 30, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90)
+
+// Hats //
+
+/obj/item/clothing/head/nanotrasen
+ name = "blue flatcap"
+ desc = "A simple blue flat cap with a Nanotrasen logo on the side. Not standard uniform, but occasionally worn by Nanotrasen office workers."
+ icon = 'icons/obj/clothing/faction/nanotrasen/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/nanotrasen/head.dmi'
+ lefthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi'
+ icon_state = "com_flatcap"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/nanotrasen/beret
+ name = "fancy blue beret"
+ desc = "A well-made beret in Nanotrasen Blue with a corporate logo on the side, often seen topping the heads of Nanotrasen, Inc. managerial staff."
+ icon_state = "beret_blue"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/nanotrasen/beret/security
+ name = "fancy red beret"
+ desc = "A cherry-red beret issued to Vigilitas security officers for formal occasions. Vigilitas Interstellar's 'VI' logo is stitched into the side."
+ icon_state = "beret_red"
+ item_state = "redcloth"
+
+/obj/item/clothing/head/nanotrasen/beret/security/command
+ name = "fancy black beret"
+ desc = "A deep black beret with a Vigilitas Interstellar 'VI' badge on the front. An unmistakeable hallmark of Vigilitas managerial staff."
+ icon_state = "beret_black"
+ item_state = "blackcloth"
+
+/obj/item/clothing/head/nanotrasen/surgical
+ name = "white surgical cap"
+ desc = "A white surgical cap with a Nanotrasen Blue stripe down the middle."
+ icon_state = "surgical_white"
+ item_state = "whitecloth"
+
+/obj/item/clothing/head/nanotrasen/surgical/blue
+ name = "blue surgical cap"
+ desc = "A Nanotrasen Blue surgical cap with a white stripe down the middle, issued to NT medical directors as the last line of recognizability, should their uniforms, coats, and unflappable nature ever fail."
+ icon_state = "surgical_blue"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/nanotrasen/cap // Base type, do not use
+ name = "generic cap"
+ desc = "You don't belong here."
+
+/obj/item/clothing/head/nanotrasen/cap/security
+ name = "red softcap"
+ desc = "A cherry red cap with a white 'VI' logo embroidered on the front. Issued to Vigilitas security guards as casual wear and low-threat workwear. Surprisingly durable, and very popular among current and retired employees."
+ icon_state = "cap_red"
+ item_state = "redcloth"
+
+/obj/item/clothing/head/nanotrasen/cap/supply
+ name = "brown softcap"
+ desc = "A brown cap with N+S Logistics' compass rose logo on the front. Issued to almost every N+S employee, although its wear is optional."
+ icon_state = "cap_brown"
+ item_state = "browncloth"
+
+/obj/item/clothing/head/nanotrasen/cap/janitor
+ name = "purple softcap"
+ desc = "A rich purple soft cap with a Nanotrasen logo on the front. For some reason, this peculiar shade of purple is only used by custodial personnel instead of the Nanotrasen Blue used by every other division. It's already slightly stained."
+ icon_state = "cap_purple"
+ //item_state = "purplecloth" //todo: purple
+
+/obj/item/clothing/head/nanotrasen/cap/medical
+ name = "blue medical softcap"
+ desc = "A soft cap in Nanotrasen Blue, with a large white cross on the front marking the wearer as a trained medical worker. Wearing this without medical training is a violation of Nanotrasen, Inc. employee guidelines."
+ icon_state = "cap_blue"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/nanotrasen/officer
+ name = "officer's hat"
+ desc = "A blue peaked hat with red silk decoration and an embroidered Nanotrasen logo, worn exclusively by management."
+ icon_state = "officer_peaked"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/nanotrasen/officer
+ name = "officer's fedora"
+ desc = "A fedora in a violent shade of Nanotrasen Blue, with a red silk band."
+ icon_state = "officer_fedora"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/nanotrasen/captain
+ name = "captain's broad hat"
+ desc = "A curious rounded hat, decorated with gold thread and a Nanotrasen logo badge. Particular to Nanotrasen, Inc. captains, though nobody is quite certain where this distinctive design originated."
+ icon_state = "com_hat"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/nanotrasen/captain/peaked
+ name = "captain's peaked cap"
+ desc = "A decorated blue peaked cap, rife with laurels and gold thread, with a large badge on the front displaying the Nanotrasen, Inc. logo. This hat practically oozes authority."
+ icon_state = "com_peaked"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/hardhat/nanotrasen //TODO: inhands for hardhats
+ name = "black heavy-duty hat"
+ desc = "A tough plastic helmet with a suspension rig, designed to protect against blunt impacts. This one is a sober shade of black, with a Nanotrasen logo on the front."
+ icon = 'icons/obj/clothing/faction/nanotrasen/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/nanotrasen/head.dmi'
+ lefthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi'
+ icon_state = "hardhat_black"
+ item_state = "blackcloth"
+
+/obj/item/clothing/head/hardhat/nanotrasen/blue
+ name = "blue heavy-duty hat"
+ desc = "A tough plastic helmet with suspension rig, designed to protect against blunt impacts. This one is brightly colored in Nanotrasen Blue, with the company logo on the front."
+ icon_state = "hardhat_blue"
+ item_state = "bluecloth"
+
+/obj/item/clothing/head/hardhat/nanotrasen/white
+ name = "white heavy-duty hat"
+ desc = "An extremely tough plastic helmet with suspension rig, designed to protect against blunt impacts. This one is colored bright white, typical of managerial staff, and has a Nanotrasen logo on the front."
+ icon_state = "hardhat_white"
+ item_state = "graycloth"
+
+
+// Neck //
+
+/obj/item/clothing/neck/cloak/nanotrasen
+ name = "command sash"
+ desc = "A fine red silk sash that would pair nicely with a formal uniform. A small tag inside declares this property of Nanotrasen, Inc."
+ icon = 'icons/obj/clothing/faction/nanotrasen/neck.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/nanotrasen/neck.dmi'
+ lefthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi'
+ icon_state = "sash"
+ item_state = "redcloth"
diff --git a/code/modules/clothing/factions/ngr.dm b/code/modules/clothing/factions/ngr.dm
new file mode 100644
index 000000000000..7892a098b50d
--- /dev/null
+++ b/code/modules/clothing/factions/ngr.dm
@@ -0,0 +1,244 @@
+//////////////
+//Jumpsuits//
+/////////////
+
+/obj/item/clothing/under/syndicate/ngr
+ name = "\improper NGR uniform"
+ desc = "A button-up in a tasteful beige with black pants, used as the basic uniform of the New Gorlex Republic."
+ icon_state = "ngr"
+ item_state = "ngr"
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
+ can_adjust = FALSE
+ icon = 'icons/obj/clothing/faction/ngr/uniforms.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/uniforms.dmi'
+
+/obj/item/clothing/under/syndicate/ngr/fatigues
+ name = "\improper NGR fatigues"
+ desc = "Beige fatigues used primarily by the ship and mech pilots of the New Gorlex Republic."
+ icon_state = "ngr_fatigues"
+ item_state = "ngr_fatigues"
+
+/obj/item/clothing/under/syndicate/ngr/jumpsuit
+ name = "\improper NGR jumpsuit"
+ desc = "A beige jumpsuit with black overalls used by wreckers of the New Gorlex Republic. A reminder of Gorlex VII's history as a mining colony, prior to its destruction."
+ icon_state = "ngr_jumpsuit"
+ item_state = "ngr_jumpsuit"
+
+/obj/item/clothing/under/syndicate/ngr/officer
+ name = "\improper NGR officer uniform"
+ desc = "A button-up in a tasteful black with beige pants, used by officers of the New Gorlex Republic."
+ icon_state = "ngr_officer"
+ item_state = "ngr_officer"
+
+/obj/item/clothing/under/plasmaman/ngr
+ name = "\improper NGR phorid envirosuit"
+ desc = "A button-up envirosuit with use intended for phorids of the New Gorlex Republic. Ensures they don't die of combustion."
+ icon_state = "ngr_envirosuit"
+ item_state = "ngr_envirosuit"
+ icon = 'icons/obj/clothing/faction/ngr/uniforms.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/uniforms.dmi'
+
+
+////////////////////
+//Unarmored suits//
+///////////////////
+
+/obj/item/clothing/suit/ngr
+ name = "foreman's jacket"
+ desc = "A beige high-visibility jacket worn by the Foreman of the New Gorlex Republic."
+ icon = 'icons/obj/clothing/faction/ngr/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/suits.dmi'
+ icon_state = "ngr_foreman"
+ item_state = "blackcloth"
+
+/obj/item/clothing/suit/ngr/smock
+ name = "blood red smock"
+ desc = "A blood-red surgical smock typically worn by field medics of the New Gorlex Republic. It hides red blood really well!"
+ icon_state = "ngr_apron"
+ item_state = "redcloth"
+
+/obj/item/clothing/suit/hazardvest/ngr
+ name = "blood-red hazard vest"
+ desc = "A blood-red high-visibility vest typically used in work zones by the New Gorlex Republic."
+ icon = 'icons/obj/clothing/faction/ngr/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/suits.dmi'
+ icon_state = "ngr_hazard"
+ item_state = "redcloth"
+
+//////////////////
+//Armored suits//
+/////////////////
+
+/obj/item/clothing/suit/armor/ngr
+ name = "NGR armor vest"
+ desc = "A slim Type I armored vest, utilized by the 2nd Battlegroup of the New Gorlex Republic that provides decent protection against most types of damage."
+ icon_state = "ngr_vest"
+ item_state = "armor"
+ icon = 'icons/obj/clothing/faction/ngr/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/suits.dmi'
+ blood_overlay_type = "armor"
+
+/obj/item/clothing/suit/armor/ngr/lieutenant
+ name = "\improper 2nd Battlegroup overcoat"
+ desc = "An armored overcoat worn by the lieutenants of the New Gorlex Republic's 2nd Battlegroup."
+ body_parts_covered = CHEST|GROIN|ARMS
+ icon_state = "ngr_lieutenant"
+ item_state = "ngr_lieutenant"
+ blood_overlay_type = "coat"
+ armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+
+/obj/item/clothing/suit/armor/ngr/captain
+ name = "\improper 2nd Battlegroup coat"
+ desc = "An armored coat worn by captains the New Gorlex Republic's 2nd Battlegroup."
+ body_parts_covered = CHEST|GROIN|ARMS
+ icon_state = "ngr_captain"
+ item_state = "ngr_captain"
+ blood_overlay_type = "coat"
+ armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+
+///////////////
+//Spacesuits//
+//////////////
+
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/ngr
+ name = "beige-red hardsuit helmet"
+ desc = "A standardized dual-mode helmet derived from ICW-era advanced special operations helmets, its red partly replaced by beige. It is in EVA mode. Manufactured by Second Battlegroup."
+ alt_desc = "A standardized dual-mode helmet derived from ICW-era advanced special operations helmets, its red partly replaced by beige. It is in combat mode. Manufactured by Second Battlegroup."
+ icon_state = "hardsuit1-ngr"
+ item_state = "hardsuit1-ngr"
+ icon = 'icons/obj/clothing/faction/ngr/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/head.dmi'
+ hardsuit_type = "ngr"
+
+/obj/item/clothing/suit/space/hardsuit/syndi/ngr
+ name = "beige-red hardsuit"
+ desc = "A standardized dual-mode hardsuit derived from ICW-era advanced special operations hardsuits, its red partly replaced by beige. It is in EVA mode. Manufactured by Second Battlegroup."
+ alt_desc = "A standardized dual-mode hardsuit derived from ICW-era advanced special operations hardsuits, its red partly replaced by beige. It is in combat mode. Manufactured by the Second Battlegroup."
+ icon_state = "hardsuit1-ngr"
+ item_state = "hardsuit1-ngr"
+ hardsuit_type = "ngr"
+ icon = 'icons/obj/clothing/faction/ngr/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/suits.dmi'
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/ngr
+ lightweight = 1
+ jetpack = null
+
+/obj/item/clothing/head/helmet/space/plasmaman/ngr
+ name = "NGR phorid envirosuit helmet"
+ desc = "An envirohelmet designed for phorids of the New Gorlex Republic, with intimidating blood-red stripes."
+ icon_state = "ngr_envirohelm"
+ item_state = "ngr_envirohelm"
+ icon = 'icons/obj/clothing/faction/ngr/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/head.dmi'
+
+/////////
+//Hats//
+////////
+
+/obj/item/clothing/head/ngr
+ name = "beige garrison cap"
+ desc = "A garrison cap used by low-ranking members of the New Gorlex Republic's 2nd Battlegroup when off-duty."
+ icon_state = "ngr_garrison"
+ icon = 'icons/obj/clothing/faction/ngr/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/head.dmi'
+ armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+
+/obj/item/clothing/head/ngr/flap
+ name = "beige flap cap"
+ desc = "A flap cap used by soldiers of the New Gorlex Republic's 2nd Battlegroup in desert environments."
+ icon_state = "ngr_flap"
+
+/obj/item/clothing/head/ngr/surgical
+ name = "blood-red surgical cap"
+ desc = "A surgical cap used by field medics of the New Gorlex Republic's 2nd Battlegroup."
+ icon_state = "ngr_surgery"
+
+/obj/item/clothing/head/hardhat/ngr
+ name = "blood-red hard hat"
+ desc = "A blood-red hardhat typically used by Wreckers and Ship Engineers of the New Gorlex Republic."
+ icon_state = "ngr_hardhat"
+ icon = 'icons/obj/clothing/faction/ngr/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/head.dmi'
+
+/obj/item/clothing/head/hardhat/ngr/foreman
+ name = "beige hard hat"
+ desc = "A beige hardhat used exclusively by the Foreman of the New Gorlex Republic."
+ icon_state = "ngr_foreman"
+
+/obj/item/clothing/head/ngr/peaked
+ name = "2nd Battlegroup peaked cap"
+ desc = "A cap worn by officers of the New Gorlex Republic's 2nd Battlegroup."
+ icon_state = "ngr_officer"
+ item_state = "ngr_officer"
+
+/obj/item/clothing/head/helmet/ngr
+ name = "\improper NGR X-11 helmet"
+ desc = "A well-armored helmet utilized by the New Gorlex Republic's 2nd Battlegroup, far better at protecting one's head than the softer caps."
+ icon = 'icons/obj/clothing/faction/ngr/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/head.dmi'
+ armor = list("melee" = 40, "bullet" = 60, "laser" = 35, "energy" = 35, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) // The guys who specialize in ballistics would probably have better bullet armor. Maybe.
+ icon_state = "ngr_x11"
+ item_state = "ngr_x11"
+
+/obj/item/clothing/head/helmet/ngr/swat
+ name = "\improper NGR pilot helmet"
+ desc = "A modified X-11 helmet utilized by the pilots of the New Gorlex Republic's 2nd Battlegroup. The attached visor helps protect against sudden flashes from explosions."
+ flash_protect = FLASH_PROTECTION_WELDER
+ icon_state = "ngr_pilot"
+ item_state = "ngr_pilot"
+
+////////////
+//Glasses//
+///////////
+
+/obj/item/clothing/glasses/hud/security/sunglasses/ngr
+ name = "NGR modified mesons"
+ desc = "A modified version of widely-used optical meson scanners, with a flash-proof tint and integrated security HUD. Unfortunately, the opaque visor disables the meson functionality."
+ icon_state = "ngr_goggles"
+ item_state = "ngr_goggles"
+ icon = 'icons/obj/clothing/faction/ngr/eyes.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/eyes.dmi'
+ glass_colour_type = /datum/client_colour/glass_colour/green
+
+//////////
+//Masks//
+/////////
+
+/obj/item/clothing/mask/gas/sechailer/balaclava/ngr
+ name = "NGR combat balaclava"
+ desc = "A surprisingly advanced balaclava. while it doesn't muffle your voice it has a miniature rebreather for internals. Comfy to boot! This version is commonly used by the soldiers of the New Gorlex Republic to protect against sandstorms."
+ icon_state = "ngr_balaclava"
+ item_state = "ngr_balaclava"
+ icon = 'icons/obj/clothing/faction/ngr/mask.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/mask.dmi'
+
+/obj/item/clothing/mask/gas/syndicate/ngr
+ name = "NGR face mask"
+ desc = "A face mask that covers the nose, mouth and neck of those who wear it. Favored by field medics over the balaclava due to lessened heat while wearing."
+ icon_state = "ngr_facemask"
+ item_state = "ngr_facemask"
+ icon = 'icons/obj/clothing/faction/ngr/mask.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/mask.dmi'
+
+//////////
+//Neck//
+/////////
+
+/obj/item/clothing/neck/shemagh/ngr
+ name = "shemagh"
+ desc = "An oversized shemagh, in a tacticool blood-red for use in the 2nd Battlegroup."
+ icon_state = "ngr_shemagh"
+ icon = 'icons/obj/clothing/faction/ngr/neck.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/neck.dmi'
+
+//////////
+//Belts//
+/////////
+
+/obj/item/storage/belt/security/webbing/ngr
+ name = "NGR webbing"
+ desc = "A set of tactical webbing for operators of the New Gorlex Republic, can hold security gear."
+ icon_state = "ngr_webbing"
+ item_state = "ngr_webbing"
+ icon = 'icons/obj/clothing/faction/ngr/belt.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/ngr/belt.dmi'
diff --git a/code/modules/clothing/factions/srm.dm b/code/modules/clothing/factions/srm.dm
new file mode 100644
index 000000000000..cd901306b7a7
--- /dev/null
+++ b/code/modules/clothing/factions/srm.dm
@@ -0,0 +1,154 @@
+//////////////
+//Jumpsuits//
+/////////////
+
+/obj/item/clothing/under/suit/roumain
+ name = "saint-roumain's worksuit"
+ desc = "A simple, hard-wearing suit designed for the hardworking hunters of the Saint-Roumain Militia."
+ icon_state = "rouma_work"
+ item_state = "rouma_work"
+ can_adjust = FALSE
+ icon = 'icons/obj/clothing/faction/srm/uniforms.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/srm/uniforms.dmi'
+
+//////////////////
+//Armored suits//
+/////////////////
+
+/obj/item/clothing/suit/armor/roumain
+ name = "saint-roumain duster"
+ desc = "A coat made from hard leather. Meant to withstand long hunts in harsh wilderness."
+ icon_state = "armor_rouma"
+ item_state = "rouma_coat"
+ body_parts_covered = CHEST|GROIN|ARMS
+ cold_protection = CHEST|GROIN|ARMS
+ heat_protection = CHEST|GROIN|ARMS
+ icon = 'icons/obj/clothing/faction/srm/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/srm/suits.dmi'
+
+/obj/item/clothing/suit/armor/roumain/shadow
+ name = "saint-roumain shadow duster"
+ desc = "A coat made from hard leather. Its rough, barely-treated finish is typical of one of the Saint-Roumain Militia's trainees."
+ icon_state = "armor_rouma_shadow"
+ item_state = "rouma_shadow_coat"
+
+/obj/item/clothing/suit/toggle/labcoat/roumain_med
+ name = "saint-roumain medical duster"
+ desc = "A coat made from hard leather and further treated with exotic sterilizing oils and wax. The treatment and its more closed design offers much better protection against biological hazards."
+ icon = 'icons/obj/clothing/faction/srm/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/srm/suits.dmi'
+ icon_state = "rouma_med_coat"
+ armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 50, "rad" = 0, "fire" = 50, "acid" = 50)
+
+/obj/item/clothing/suit/hazardvest/roumain
+ name = "saint-roumain machinist leather vest"
+ desc = "A modified Roumain leather duster with its large flaps and sleeves cut off to provide extra mobility when maintaining weapons and vessels belonging to the Church of Saint Roumain. Its specialty treatment grants it better protection against acid and fire."
+ icon = 'icons/obj/clothing/faction/srm/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/srm/suits.dmi'
+ icon_state = "armor_rouma_machinist"
+ item_state = "rouma_coat"
+ armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 40, "bomb" = 35, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60)
+
+/obj/item/clothing/suit/armor/roumain/flamebearer
+ name = "saint-roumain flamebearer robes"
+ desc = "A set of ashy-grey robes made from hard leather, adorned with gold trims. Its rough finish after a near-char and application of aromatics is heavily favored for the ecclesiastical sect of the Church of Saint Roumain, a living reminder of the Ashen Huntsman himself."
+ icon_state = "armor_rouma_flamebearer"
+
+/obj/item/clothing/suit/armor/roumain/colligne
+ name = "saint-roumain colligne coat"
+ desc = "A well-maintained hard leather coat typically worn to denote the rank of Colligne, a trainee Hunter Montagne. It is treated with bullet-resistant materials, and lined with the dark fur of Illestrian dire wolves."
+ icon_state = "armor_rouma_colligne"
+ item_state = "rouma_coat"
+ body_parts_covered = CHEST|GROIN|ARMS|LEGS
+ cold_protection = CHEST|GROIN|LEGS|ARMS
+ heat_protection = CHEST|GROIN|LEGS|ARMS
+
+/obj/item/clothing/suit/armor/roumain/montagne
+ name = "saint-roumain montagne coat"
+ desc = "A stylish red coat to indicate that you are, in fact, a Hunter Montagne. Made of extra hard exotic leather, treated with bullet-resistant materials, and lined with the fur of some unidentifiable creature."
+ icon_state = "armor_rouma_montagne"
+ item_state = "rouma_montagne_coat"
+ body_parts_covered = CHEST|GROIN|ARMS|LEGS
+ armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90)
+ cold_protection = CHEST|GROIN|LEGS|ARMS
+ heat_protection = CHEST|GROIN|LEGS|ARMS
+
+///////////////
+//Spacesuits//
+//////////////
+
+/obj/item/clothing/head/helmet/space/hardsuit/solgov/roumain
+ name = "\improper roumain hardsuit helmet"
+ desc = "An armored helmet with an unusual design that recalls both pre-industrial Solarian armor and iconography depicting the Ashen Huntsman. Though hand-made, it is surprisingly quite spaceworthy."
+ icon = 'icons/obj/clothing/faction/srm/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/srm/head.dmi'
+ icon_state = "hardsuit0-roumain"
+ item_state = "hardsuit0-roumain"
+ hardsuit_type = "roumain"
+ worn_y_offset = 4
+
+/obj/item/clothing/suit/space/hardsuit/solgov/roumain
+ name = "\improper roumain hardsuit"
+ desc = "A hand-crafted suit of armor either modified from a set of normal plate armor or designed to resemble one. A powered exoskeleton has been cleverly integrated into the design and, surprisingly, it is completely vacuum-proof. Suits like this are a testament to what the master craftsmen of Hunter's Pride are capable of."
+ icon = 'icons/obj/clothing/faction/srm/suits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/srm/suits.dmi'
+ icon_state = "hardsuit-roumain"
+ item_state = "hardsuit-roumain"
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/solgov/roumain
+ slowdown = 0.5
+
+/////////
+//Hats//
+////////
+
+/obj/item/clothing/head/cowboy/sec/roumain
+ name = "hunter's hat"
+ desc = "A fancy hat with a nice feather. The way it covers your eyes makes you feel like a badass."
+ icon_state = "rouma_hat"
+ icon = 'icons/obj/clothing/faction/srm/head.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/faction/srm/head.dmi'
+
+/obj/item/clothing/head/cowboy/sec/roumain/shadow
+ name = "shadow's hat"
+ desc = "A rough, simple hat. The way it covers your eyes makes you feel badass, but you just look like a wannabe hunter."
+ icon_state = "rouma_shadow_hat"
+
+/obj/item/clothing/head/cowboy/sec/roumain/machinist
+ name = "machinist's hat"
+ desc = "A small, humble leather top hat. It gives you the gnawing urge to create classical gizmos and goobers, or alternatively repair any breaches within your vessel."
+ icon_state = "rouma_machinist_hat"
+
+/obj/item/clothing/head/cowboy/sec/roumain/med
+ name = "medical hunter's hat"
+ desc = "A very wide-brimmed, round hat treated with oil and wax. Somehow manages to look stylish and creepy at the same time."
+ icon_state = "rouma_med_hat"
+
+/obj/item/clothing/head/cowboy/sec/roumain/flamebearer
+ name = "flamebearer's hat"
+ desc = "A wide-brimmed, pointed hat with charred leather, granting it an ash-grey appearance. The design honors the one the Ashen Huntsman himself wore, according to legend."
+ icon_state = "rouma_flamebearer_hat"
+
+/obj/item/clothing/head/cowboy/sec/roumain/colligne
+ name = "colligne's hat"
+ desc = "A fancy, pointy leather hat with a large feather plume to signal that you are, in fact... A Hunter Colligne. You still have some ways to go before you gain the title of Montagne."
+ icon_state = "rouma_colligne_hat"
+
+/obj/item/clothing/head/cowboy/sec/roumain/montagne
+ name = "montagne's hat"
+ desc = "A very fancy hat with a large feather plume to signal that you are, in fact, a Hunter Montagne. The exotic fur lining is impeccably soft."
+ icon_state = "rouma_montagne_hat"
+
+///////////////
+//Accessories//
+///////////////
+
+//These are stored in clothing/accessories.dmi instead of a factional variant due to accessory code being dogwater
+//Please transfer them over to a factional file if accessory code is ever fixed
+
+/obj/item/clothing/accessory/waistcoat/roumain
+ name = "roumain waistcoat"
+ desc = "A warm, red wool waistcoat, worn by any member of the Church of Saint Roumain, though heavily favored by Machinists for the added warmth given to their rather breezy outfit."
+ icon_state = "rouma_waistcoat"
+ icon = 'icons/obj/clothing/accessories.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/accessories.dmi'
+ minimize_when_attached = TRUE
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 385baa647432..559816007b13 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -248,7 +248,6 @@
tint = 1
glass_colour_type = /datum/client_colour/glass_colour/gray
-
/obj/item/clothing/glasses/hud/spacecop/hidden // for the undercover cop
name = "sunglasses"
desc = "These sunglasses are special, and let you view potential criminals."
@@ -260,7 +259,7 @@
desc = "A snazzy looking pair of ballistic goggles with an integrated security hud. The opaque visor provides flash protection."
icon_state = "inteq_goggles"
item_state = "inteq_goggles"
- supports_variations = KEPORI_VARIATION
+ supports_variations = KEPORI_VARIATION | VOX_VARIATION
glass_colour_type = /datum/client_colour/glass_colour/orange
/obj/item/clothing/glasses/hud/health/prescription
@@ -274,4 +273,3 @@
desc = "A heads-up display that scans the humanoids in view and provides accurate data about their ID status and security records. This pair also corrects nearsightedness."
icon_state = "prescriptionsecurityhud"
vision_correction = 1
-
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index 06bd05a45795..cbac3e0e8901 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -220,7 +220,7 @@
icon_state = "nitrile"
transfer_prints = FALSE
carrytrait = TRAIT_QUICKER_CARRY
- supports_variations = KEPORI_VARIATION
+ //supports_variations = KEPORI_VARIATION
/obj/item/clothing/gloves/color/latex/nitrile/evil
name = "red nitrile gloves"
@@ -240,10 +240,8 @@
desc = "Overdesigned engineering gloves that have automated construction subrutines dialed in, allowing for faster construction while worn."
icon = 'icons/obj/clothing/clockwork_garb.dmi'
icon_state = "clockwork_gauntlets"
- siemens_coefficient = 0 //WS Station eddit "Tinkers Gloves Insuls"
- permeability_coefficient = 0.05 //WS Station eddit "Tinkers Gloves Insuls"
- //siemens_coefficient = 0.8 WS Station eddit "Tinkers Gloves Insuls"
- //permeability_coefficient = 0.3 WS Station eddit "Tinkers Gloves Insuls"
+ siemens_coefficient = 0
+ permeability_coefficient = 0.05
carrytrait = TRAIT_QUICK_BUILD
custom_materials = list(/datum/material/iron=2000, /datum/material/silver=1500, /datum/material/gold = 1000)
@@ -276,7 +274,8 @@
/obj/item/clothing/gloves/color/light_brown = 1,
/obj/item/clothing/gloves/color/brown = 1,
/obj/item/clothing/gloves/color/white = 1,
- /obj/item/clothing/gloves/color/rainbow = 1)
+ /obj/item/clothing/gloves/color/rainbow = 1,
+ )
/obj/item/clothing/gloves/maid
name = "maid arm covers"
diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm
index 314af8aaf44a..9d8db3c035d8 100644
--- a/code/modules/clothing/gloves/miscellaneous.dm
+++ b/code/modules/clothing/gloves/miscellaneous.dm
@@ -38,7 +38,7 @@
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
resistance_flags = NONE
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50)
- supports_variations = KEPORI_VARIATION
+ //supports_variations = KEPORI_VARIATION
/obj/item/clothing/gloves/combat/maid
name = "combat maid sleeves"
diff --git a/code/modules/clothing/head/berets.dm b/code/modules/clothing/head/berets.dm
index f8b542f40b9f..9d3ca21ed4f0 100644
--- a/code/modules/clothing/head/berets.dm
+++ b/code/modules/clothing/head/berets.dm
@@ -32,9 +32,9 @@
/obj/item/clothing/head/beret/durathread
name = "durathread beret"
- desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer."
+ desc = "A beret made from durathread, its resilient fibres provide a modicum of fire protection to the wearer."
icon_state = "beretdurathread"
- armor = list("melee" = 15, "bullet" = 5, "laser" = 15, "energy" = 25, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 5)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 15, "acid" = 5)
//Civilian
/obj/item/clothing/head/beret/grey
@@ -56,7 +56,6 @@
name = "quartermaster beret"
desc = "A cargo beret with a faded medal haphazardly stitched into it. Worn by a true cargonian, it commands respect from everyone."
icon_state = "beret_qm"
- armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5)
/obj/item/clothing/head/beret/cargo
name = "cargo beret"
@@ -65,30 +64,25 @@
/obj/item/clothing/head/beret/mining
name = "mining beret"
- desc = "A grey beret with a pickaxe insignia sewn into it. Seems to be padded and fireproofed to offer the wearer some protection."
+ desc = "A grey beret with a pickaxe insignia sewn into it."
icon_state = "beret_mining"
- armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 15, "bomb" = 30, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
//Sec
/obj/item/clothing/head/beret/sec
name = "security beret"
- desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection."
+ desc = "A robust beret with the security insignia emblazoned on it."
icon_state = "beret_sec"
- armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
- strip_delay = 60
dog_fashion = null
/obj/item/clothing/head/beret/sec/hos
name = "head of security's black beret"
desc = "A black beret with the Head of Security's insignia emblazoned on it. A symbol of excellence, a badge of courage, a mark of distinction."
icon_state = "beret_hos"
- armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60)
/obj/item/clothing/head/beret/sec/warden
name = "warden's beret"
desc = "A beret made with black reinforced fabric with the Warden's insignia emblazoned on it. For wardens with class."
icon_state = "beret_warden"
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
/obj/item/clothing/head/beret/sec/officer
desc = "A beret made out of black reinforced fabric with the security insignia emblazoned on it. For officers with class."
@@ -103,7 +97,7 @@
name = "engineering beret"
desc = "A beret with the engineering insignia emblazoned on it. For engineers that are more inclined towards style than safety."
icon_state = "beret_engineering"
- armor = list("rad" = 10, "fire" = 10)
+ armor = list("rad" = 5, "fire" = 10)
/obj/item/clothing/head/beret/eng/hazard
name = "engineering hazardberet"
@@ -114,13 +108,13 @@
name = "atmospherics beret"
desc = "A beret for those who have shown immaculate proficienty in piping. Or plumbing. Mostly piping."
icon_state = "beret_atmospherics"
- armor = list("rad" = 10, "fire" = 10)
+ armor = list("rad" = 5, "fire" = 10)
/obj/item/clothing/head/beret/ce
name = "chief engineer beret"
desc = "A white beret with the engineering insignia emblazoned on it. Its owner knows what they're doing. Probably."
icon_state = "beret_ce"
- armor = list("rad" = 20, "fire" = 30)
+ armor = list("rad" = 10, "fire" = 30)
//Science
/obj/item/clothing/head/beret/sci
@@ -170,22 +164,16 @@
name = "captain beret"
desc = "A lovely blue Captain beret with a gold and white insignia. Truly fit for only the finest officers."
icon_state = "beret_captain"
- armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
- strip_delay = 90
/obj/item/clothing/head/beret/hop
name = "head of personnel beret"
desc = "A lovely blue Head of Personnel's beret with a silver and white insignia. It smells faintly of paper and dogs."
icon_state = "beret_hop"
- armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
- strip_delay = 90
/obj/item/clothing/head/beret/command
name = "command beret"
desc = "A modest blue command beret with a silver rank insignia. Smells of power and the sweat of assistants."
icon_state = "beret_com"
- armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 15, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 25, "acid" = 25)
- strip_delay = 90
// SolGov
@@ -193,7 +181,6 @@
name = "\improper SolGov beret"
desc = "A beret with SolGov's emblem emblazoned on it. Colored in SolGov blue."
icon_state = "beret_solgov"
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
/obj/item/clothing/head/beret/solgov/plain
name = "\improper SolGov beret"
@@ -226,26 +213,14 @@
name = "honorable vanguard beret"
desc = "A snow white beret with an air of distinction around it, emblazoned with the golden shield of the IRMG as the badge."
icon_state = "inteq_honorable_beret"
- armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90)
-
-// Frontier
-
-/obj/item/clothing/head/beret/sec/frontier
- name = "\improper Frontiersmen beret"
- desc = "A scratchy olive green beret, worn by Frontiersmen who want to look good while intimidating freighter crew."
- icon_state = "frontier_beret"
-
-/obj/item/clothing/head/beret/sec/frontier/officer
- name = "\improper Frontiersmen officer beret"
- desc = "A scratchy olive green beret emblazoned with the Frontiersmen insignia, worn by Frontiersmen who want to look good while intimidating freighter captains."
- icon_state = "frontier_officer_beret"
-
// CentCom
/obj/item/clothing/head/beret/centcom_formal
name = "\improper CentCom Formal Beret"
desc = "Sometimes, a compromise between fashion and defense needs to be made. Thanks to Nanotrasen's most recent nano-fabric durability enhancements, this time, it's not the case."
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
icon_state = "beret_badge"
greyscale_colors = "#46b946#f2c42e"
armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "fire" = 100, "acid" = 90)
diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm
index f44e133360e6..036d6ffbd417 100644
--- a/code/modules/clothing/head/collectable.dm
+++ b/code/modules/clothing/head/collectable.dm
@@ -46,6 +46,8 @@
/obj/item/clothing/head/collectable/police
name = "collectable police officer's hat"
desc = "A collectable police officer's Hat. This hat emphasizes that you are THE LAW."
+ icon = 'icons/obj/clothing/head/armor.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/armor.dmi'
icon_state = "policehelm"
dog_fashion = /datum/dog_fashion/head/warden
@@ -77,6 +79,8 @@
/obj/item/clothing/head/collectable/pirate
name = "collectable pirate hat"
desc = "You'd make a great Dread Syndie Roberts!"
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
icon_state = "pirate"
dog_fashion = /datum/dog_fashion/head/pirate
@@ -121,6 +125,8 @@
/obj/item/clothing/head/collectable/thunderdome
name = "collectable Thunderdome helmet"
desc = "Go Red! I mean Green! I mean Red! No Green!"
+ icon = 'icons/obj/clothing/head/armor.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/armor.dmi'
icon_state = "thunderdome"
clothing_flags = SNUG_FIT
flags_inv = HIDEHAIR
@@ -128,6 +134,8 @@
/obj/item/clothing/head/collectable/swat
name = "collectable SWAT helmet"
desc = "That's not real blood. That's red paint." //Reference to the actual description
+ icon = 'icons/obj/clothing/head/armor.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/armor.dmi'
icon_state = "swat"
item_state = "swat"
clothing_flags = SNUG_FIT
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index f96d23fa9ba2..a6de8769642a 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -1,6 +1,8 @@
/obj/item/clothing/head/helmet
name = "helmet"
desc = "Standard Security gear. Protects the head from impacts."
+ icon = 'icons/obj/clothing/head/armor.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/armor.dmi'
icon_state = "helmet"
item_state = "helmet"
var/flashlight_state = "helmet_flight_overlay"
@@ -16,10 +18,15 @@
dog_fashion = /datum/dog_fashion/head/helmet
- var/can_flashlight = FALSE //if a flashlight can be mounted. if it has a flashlight and this is false, it is permanently attached.
+ //if a flashlight can be mounted. if it has a flashlight and this is false, it is permanently attached.
+ var/can_flashlight = FALSE
var/obj/item/flashlight/seclite/attached_light
var/datum/action/item_action/toggle_helmet_flashlight/action_light
+ pocket_storage_component_path = /datum/component/storage/concrete/pockets/helmet
+ // should we overlay the items inside our helmet
+ var/content_overlays = FALSE
+
/obj/item/clothing/head/helmet/Initialize()
. = ..()
if(attached_light)
@@ -171,16 +178,21 @@
var/mutable_appearance/flashlightlight_overlay
if(isinhands)
return
- if(!attached_light)
- return
- if(attached_light.on)
- flashlightlight_overlay = mutable_appearance('icons/mob/clothing/head.dmi', "[flashlight_state]_on")
+ if(attached_light)
+ if(attached_light.on)
+ flashlightlight_overlay = mutable_appearance('icons/mob/clothing/head.dmi', "[flashlight_state]_on")
+ else
+ flashlightlight_overlay = mutable_appearance('icons/mob/clothing/head.dmi', flashlight_state)
+ . += flashlightlight_overlay
+ if(content_overlays)
+ for(var/obj/item/I in contents)
+ . += I.get_helmet_overlay()
else
- flashlightlight_overlay = mutable_appearance('icons/mob/clothing/head.dmi', flashlight_state)
- . += flashlightlight_overlay
+ return
/obj/item/clothing/head/helmet/sec
can_flashlight = TRUE
+ content_overlays = TRUE
/obj/item/clothing/head/helmet/sec/attackby(obj/item/I, mob/user, params)
if(issignaler(I))
@@ -214,13 +226,15 @@
"Snow" = "helmetalt_snow",
"Urban" = "helmetalt_urban",
)
+ content_overlays = TRUE
/obj/item/clothing/head/helmet/marine
name = "tactical combat helmet"
- desc = "A tactical black helmet, sealed from outside hazards with a plate of reinforced glass."
+ desc = "A tactical black helmet, sealed from outside hazards with a reinforced visor."
icon_state = "marine_command"
item_state = "helmetalt"
- armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 25, "bomb" = 50, "bio" = 100, "fire" = 40, "acid" = 50)
+ armor = list("melee" = 50, "bullet" = 75, "laser" = 55, "energy" = 25, "bomb" = 60, "bio" = 100, "fire" = 70, "acid" = 50)
+ slowdown = 0.3
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
clothing_flags = STOPSPRESSUREDAMAGE
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -469,16 +483,6 @@
armor = list("melee" = 20, "bullet" = 10, "laser" = 30, "energy" = 40, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 50)
strip_delay = 60
-/obj/item/clothing/head/helmet/r_trapper
- name = "reinforced trapper hat"
- desc = "An occasional sight on the heads of Frontiersmen stationed on cold worlds. 200% bear."
- icon_state = "rus_ushanka"
- item_state = "rus_ushanka"
- body_parts_covered = HEAD
- cold_protection = HEAD
- min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
- armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 30, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50)
-
/obj/item/clothing/head/helmet/infiltrator
name = "infiltrator helmet"
desc = "The galaxy isn't big enough for the two of us."
@@ -497,6 +501,8 @@
icon_state = "inteq_swat"
item_state = "inteq_swat"
flags_inv = HIDEHAIR
+ supports_variations = KEPORI_VARIATION | VOX_VARIATION
+ content_overlays = TRUE
/obj/item/clothing/head/helmet/inteq
name = "inteq helmet"
@@ -504,11 +510,12 @@
icon_state = "inteq_helmet"
icon_state = "inteq_helmet"
can_flashlight = TRUE
+ supports_variations = KEPORI_VARIATION | VOX_VARIATION
+ content_overlays = TRUE
/obj/item/clothing/head/solgov
name = "\improper SolGov officer's cap"
desc = "A blue cap worn by high-ranking officers of SolGov."
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
icon_state = "cap_solgov"
item_state = "cap_solgov"
strip_delay = 80
@@ -516,7 +523,6 @@
/obj/item/clothing/head/solgov/terragov
name = "\improper TerraGov officer's cap"
desc = "A cap worn by high-ranking officers of SolGov. This one is still in original TerraGov green."
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
icon_state = "cap_terragov"
item_state = "cap_terragov"
@@ -527,7 +533,6 @@
item_state = "sonnensoldner_hat"
worn_y_offset = 4
dog_fashion = null
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
/obj/item/clothing/head/solgov/captain
name = "\improper SolGov bicorne hat"
@@ -536,7 +541,6 @@
item_state = "solgov_bicorne"
worn_y_offset = 2
dog_fashion = null
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
/obj/item/clothing/head/helmet/space/plasmaman/solgov
name = "\improper SolGov envirosuit helmet"
@@ -549,6 +553,7 @@
desc = "A robust combat helmet commonly employed by Syndicate forces, regardless of alignment."
icon_state = "operator"
item_state = "operator"
+ content_overlays = TRUE
/obj/item/clothing/head/helmet/medical
name = "\improper trauma team helmet"
@@ -584,9 +589,3 @@
"Snow" = "x11helm_snow",
"Urban" = "x11helm_urban",
)
-
-/obj/item/clothing/head/helmet/bulletproof/x11/frontier
- name = "\improper Frontiersmen X11 Helmet"
- desc = "A heavily modified X11 used by the Frontiersmen pirate fleet."
- icon_state = "x11helm_frontier"
- unique_reskin = null
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 663af5e6f758..3e04245e1a14 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -21,18 +21,13 @@
icon_state = "captain"
item_state = "that"
flags_inv = 0
- armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
- strip_delay = 60
dog_fashion = /datum/dog_fashion/head/captain
-//Captain: This is no longer space-worthy
/obj/item/clothing/head/caphat/parade
name = "captain's parade cap"
desc = "Worn only by Captains with an abundance of class."
icon_state = "capcap"
- dog_fashion = null
-
/obj/item/clothing/head/caphat/cowboy
name = "general's hat"
desc = "A commanding white stetson adorned with a general's badge. Why this belongs to a captain is anybody's guess."
@@ -42,12 +37,12 @@
name = "captain's hat"
icon_state = "captain_nt"
-/obj/item/clothing/head/caphat/frontier
+/obj/item/clothing/head/frontier/peaked
name = "\improper Frontiersmen commander's cap"
desc = "An imposing peaked cap, meant for a commander of the Frontiersmen."
icon_state = "frontier_cap"
-/obj/item/clothing/head/caphat/frontier/admiral
+/obj/item/clothing/head/frontier/peaked/admiral
name = "\improper Frontiersmen admiral's cap"
desc = "An imposing peaked cap meant for only the highest of officers of the Frontiersmen pirate fleet."
icon_state = "frontier_admiral_cap"
@@ -57,7 +52,6 @@
name = "head of personnel's cap"
icon_state = "hopcap"
desc = "The symbol of true bureaucratic micromanagement."
- armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
dog_fashion = /datum/dog_fashion/head/head_of_personnel
/obj/item/clothing/head/hopcap/nt
@@ -92,7 +86,6 @@
/obj/item/clothing/head/fedora/det_hat
name = "detective's fedora"
desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat."
- armor = list("melee" = 25, "bullet" = 5, "laser" = 25, "energy" = 35, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 50)
icon_state = "detective"
var/candy_cooldown = 0
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/fedora/detective
@@ -132,8 +125,6 @@
name = "head of security cap"
desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge."
icon_state = "hoscap"
- armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60)
- strip_delay = 80
/obj/item/clothing/head/HoS/cowboy
name = "sheriff's hat"
@@ -144,30 +135,8 @@
/obj/item/clothing/head/cowboy/sec
name = "deputy hat"
- desc = "A robust stetson adorned with a deputy's badge. It has a reinforced lining under the imitation leather."
+ desc = "A robust stetson adorned with a deputy's badge. Its imitation leather is thick and worn."
icon_state = "cowboysec"
- armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
- strip_delay = 60
-
-/obj/item/clothing/head/cowboy/sec/roumain
- name = "hunter's hat"
- desc = "A fancy hat with a nice feather. The way it covers your eyes makes you feel like a badass."
- icon_state = "rouma_hat"
-
-/obj/item/clothing/head/cowboy/sec/roumain/shadow
- name = "shadow's hat"
- desc = "A rough, simple hat. The way it covers your eyes makes you feel badass, but you just look like a wannabe hunter."
- icon_state = "rouma_shadow_hat"
-
-/obj/item/clothing/head/cowboy/sec/roumain/med
- name = "medical hunter's hat"
- desc = "A very wide-brimmed, round hat treated with oil and wax. Somehow manages to look stylish and creepy at the same time."
- icon_state = "rouma_med_hat"
-
-/obj/item/clothing/head/HoS/cowboy/montagne
- name = "montagne's hat"
- desc = "A very fancy hat with a large feather plume to signal that you are, in fact, a Hunter Montagne. The exotic fur lining is impeccably soft and bafflingly bulletproof."
- icon_state = "rouma_montagne_hat"
/obj/item/clothing/head/HoS/syndicate
name = "syndicate cap"
@@ -181,41 +150,39 @@
/obj/item/clothing/head/HoS/beret/syndicate
name = "syndicate beret"
- desc = "A black beret with thick armor padding inside. Stylish and robust."
+ desc = "A nondescript black beret. Stylish and robust."
icon_state = "beret_officer"
item_state = "beret_officer"
/obj/item/clothing/head/warden
name = "warden's police hat"
- desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts."
+ desc = "It's a special hat issued to the Warden of a security force. A classic symbol of middling authority."
+ icon = 'icons/obj/clothing/head/armor.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/armor.dmi'
icon_state = "policehelm"
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
- strip_delay = 60
dog_fashion = /datum/dog_fashion/head/warden
/obj/item/clothing/head/warden/red
name = "warden's red hat"
desc = "A warden's red hat. Looking at it gives you the feeling of wanting to keep people in cells for as long as possible."
icon_state = "wardenhat"
- armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60)
- strip_delay = 60
dog_fashion = /datum/dog_fashion/head/warden_red
/obj/item/clothing/head/warden/cowboy
name = "jailor's hat"
- desc = "A menacing black stetson adorned with a jailor's badge. It has a heavily reinforced lining under the imitation leather."
+ desc = "A menacing black stetson adorned with a jailor's badge. Made of thick imitation leather."
icon_state = "cowboywarden"
dog_fashion = /datum/dog_fashion/head/cowboy
/obj/item/clothing/head/warden/inteq
name = "master at arms' campaign hat"
- desc = "A special armored campaign hat with the IRMG insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection."
+ desc = "A special brown campaign hat with the IRMG insignia emblazoned on it. For yelling at clueless recruits in style."
icon_state = "maahat"
/obj/item/clothing/head/warden/drill
name = "warden's campaign hat"
- desc = "A special armored campaign hat with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection."
+ desc = "A special campaign hat with the security insignia emblazoned on it."
icon_state = "wardendrill"
item_state = "wardendrill"
dog_fashion = null
@@ -285,3 +252,12 @@
#undef DRILL_SHOUTING
#undef DRILL_YELLING
#undef DRILL_CANADIAN
+
+/obj/item/clothing/head/witchunter
+ name = "witchunter hat"
+ desc = "This hat saw much use back in the day."
+ icon_state = "witchhunterhat"
+ item_state = "witchhunterhat"
+ flags_cover = HEADCOVERSEYES
+ flags_inv = HIDEEYES|HIDEHAIR
+ armor = list("melee" = 30, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 5bc28ff5dc18..61f032b5ef61 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -70,6 +70,8 @@
/obj/item/clothing/head/syndicatefake
name = "black space-helmet replica"
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
icon_state = "syndicate-helm-black-red"
item_state = "syndicate-helm-black-red"
desc = "A plastic replica of a Syndicate agent's space helmet. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!"
@@ -129,6 +131,8 @@
/obj/item/clothing/head/pirate
name = "pirate hat"
desc = "Yarr."
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
icon_state = "pirate"
item_state = "pirate"
dog_fashion = /datum/dog_fashion/head/pirate
@@ -161,6 +165,8 @@
/obj/item/clothing/head/bandana
name = "pirate bandana"
desc = "Yarr."
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
icon_state = "bandana"
item_state = "bandana"
@@ -266,7 +272,6 @@
/obj/item/clothing/head/hunter
name = "bounty hunting hat"
desc = "Ain't nobody gonna cheat the hangman in my town."
- armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/clothing/head/cone
@@ -321,7 +326,6 @@
name = "crown"
desc = "A crown fit for a king, a petty king maybe."
icon_state = "crown"
- armor = list("melee" = 15, "bullet" = 0, "laser" = 0,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
resistance_flags = FIRE_PROOF
/obj/item/clothing/head/crown/fancy
@@ -448,15 +452,6 @@
icon_state = "JackFrostHat"
item_state = "JackFrostHat"
-/obj/item/clothing/head/ngrcap
- name = "2nd Battlegroup peaked cap"
- desc = "A cap worn by officers of the New Gorlex Republic's 2nd Battlegroup."
- icon_state = "ngrcap"
- item_state = "ngrcap"
- flags_inv = 0
- armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
- strip_delay = 60
-
/obj/item/clothing/head/maidheadband/syndicate
name = "tactical maid headband"
desc = "Tacticute."
@@ -475,8 +470,6 @@
icon_state = "inteq_peaked"
item_state = "inteq_peaked"
flags_inv = 0
- armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60)
- strip_delay = 60
/obj/item/clothing/head/maidheadband
name = "maid headband"
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index b9e828ab3974..24e2f95f03bd 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -315,13 +315,6 @@
var/datum/brain_trauma/mild/phobia/conspiracies/paranoia
var/warped = FALSE
-/obj/item/clothing/head/foilhat/Initialize(mapload)
- . = ..()
- if(!warped)
- AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD, 6, TRUE, null, CALLBACK(src, PROC_REF(warp_up)))
- else
- warp_up()
-
/obj/item/clothing/head/foilhat/equipped(mob/living/carbon/human/user, slot)
. = ..()
if(slot != ITEM_SLOT_HEAD || warped)
@@ -374,3 +367,20 @@
if(!warped)
warp_up()
+/obj/item/clothing/head/plastic_flower
+ name = "plastic flower"
+ desc = "A realistic imitation of a flower. Not edible though."
+ icon = 'icons/obj/hydroponics/harvest.dmi'
+ icon_state = "poppy"
+ body_parts_covered = null
+ unique_reskin = list(
+ "Poppy" = "poppy",
+ "Sunflower" = "sunflower",
+ "Moonflower" = "moonflower",
+ "Novaflower" = "novaflower",
+ "Harebell" = "harebell",
+ "Geranium" = "geranium",
+ "Lily" = "lily"
+ )
+ custom_materials = (list(/datum/material/plastic = 1000))
+
diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm
index 9bccedb4f49b..3e5052cacc92 100644
--- a/code/modules/clothing/head/soft_caps.dm
+++ b/code/modules/clothing/head/soft_caps.dm
@@ -121,8 +121,6 @@
desc = "It's a robust baseball hat in tasteful red colour."
icon_state = "secsoft"
soft_type = "sec"
- armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 50)
- strip_delay = 60
dog_fashion = null
/obj/item/clothing/head/soft/sec/brig_phys
@@ -155,7 +153,6 @@
desc = "A rich brown utility cover with the golden shield of the IRMG on it."
icon_state = "inteqsoft"
soft_type = "inteq"
- armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 35, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 50)
dog_fashion = null
/obj/item/clothing/head/soft/inteq/corpsman
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 725764a10b04..d2b573711051 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -154,13 +154,6 @@
clothing_flags = VOICEBOX_TOGGLABLE
modifies_speech = TRUE
-/obj/item/clothing/mask/frog/handle_speech(datum/source, list/speech_args) //whenever you speak
- if(!(clothing_flags & VOICEBOX_DISABLED))
- if(prob(5)) //sometimes, the angry spirit finds others words to speak.
- speech_args[SPEECH_MESSAGE] = pick("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!")
- else
- speech_args[SPEECH_MESSAGE] = pick("Ree!!", "Reee!!","REEE!!","REEEEE!!") //but its usually just angry gibberish,
-
/obj/item/clothing/mask/frog/cursed
clothing_flags = NONE
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index 8d5251e9e8c8..3f431df81ccb 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -433,3 +433,9 @@
playsound(src,"shatter", 70)
new /obj/effect/decal/cleanable/glass/strange(get_turf(src))
return ..()
+
+/obj/item/clothing/neck/fangnecklace
+ name = "wolf fang necklace"
+ desc = "A necklace made out of a wolf's fang and some sinew. According to a common Frontier superstition, it brings good luck to its wearer."
+ icon_state = "fang_necklace"
+ cuttable = FALSE
diff --git a/code/modules/clothing/outfits/ert/frontiersmen_ert.dm b/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
index f0fd3bb81eb2..b3a2b20f687c 100644
--- a/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
+++ b/code/modules/clothing/outfits/ert/frontiersmen_ert.dm
@@ -1,11 +1,10 @@
-/datum/outfit/job/frontiersmen/ert
+/datum/outfit/job/frontiersmen/ert //most basic of grunts
name = "ERT - Frontiersman Basic"
- head = /obj/item/clothing/head/beret/sec/frontier
- mask = /obj/item/clothing/mask/gas/sechailer/balaclava
+ head = /obj/item/clothing/head/helmet/bulletproof/x11/frontier
suit = /obj/item/clothing/suit/armor/vest/bulletproof/frontier
suit_store = /obj/item/gun/ballistic/rifle/illestren
- uniform = /obj/item/clothing/under/rank/security/officer/frontier
+ uniform = /obj/item/clothing/under/frontiersmen
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/color/black
ears = /obj/item/radio/headset/pirate/alt
@@ -13,9 +12,10 @@
l_pocket = /obj/item/flashlight/seclite
r_pocket = /obj/item/tank/internals/emergency_oxygen/double
+ box = /obj/item/storage/box/survival/frontier
id = null // lol
- backpack_contents = list(/obj/item/ammo_box/magazine/illestren_a850r=5, /obj/item/grenade/frag=1)
+ backpack_contents = list(/obj/item/clothing/mask/gas/frontiersmen, /obj/item/ammo_box/magazine/illestren_a850r=5, /obj/item/grenade/frag=1)
/datum/outfit/job/frontiersmen/ert/random
name = "ERT - Frontiersman Randomized"
@@ -48,7 +48,7 @@
if(prob(30))
mask = pickweight(list(
- /obj/item/clothing/mask/gas = 5,
+ /obj/item/clothing/mask/gas/frontiersmen = 5,
/obj/item/clothing/mask/gas/sechailer/balaclava = 5,
/obj/item/clothing/mask/breath = 5,
/obj/item/clothing/mask/whistle = 3))
@@ -61,6 +61,7 @@
/obj/item/melee/baton/cattleprod/loaded = 5,
/obj/item/reagent_containers/food/snacks/baguette = 2, // yes you can put this on your back
/obj/item/deployable_turret_folded = 1,
+ /obj/item/gun/ballistic/automatic/hmg/skm_lmg/extended = 1,
))
if(prob(90))
@@ -74,6 +75,8 @@
if("Doctor")
backpack_contents += list(/obj/item/storage/firstaid/regular = 1)
gloves = /obj/item/clothing/gloves/color/latex
+ suit = /obj/item/clothing/suit/frontiersmen
+ head = /obj/item/clothing/head/frontier
if(prob(50))
belt = /obj/item/storage/belt/medical/surgery
if(prob(30))
@@ -83,7 +86,16 @@
if(prob(10))
belt = /obj/item/storage/belt/grenade/full
if("Ammo Carrier")
- backpack_contents += list(/obj/item/ammo_box/a762_40 = 1)
+ var/loops = rand(1,3)
+ for(var/i in 1 to loops)
+ var/ammotype = pick(list(
+ /obj/item/ammo_box/c8x50mm_box,
+ /obj/item/ammo_box/c45,
+ /obj/item/ammo_box/a357_box,
+ /obj/item/ammo_box/c45,
+ /obj/item/ammo_box/a4570,
+ /obj/item/stock_parts/cell/gun/mini))
+ backpack_contents += ammotype
var/weapon = pick(list("Bolt-Action", "Pistol", "Melee"))
switch(weapon)
@@ -96,50 +108,78 @@
if("Pistol")
r_hand = pick(list(
/obj/item/gun/ballistic/automatic/pistol/disposable,
- /obj/item/gun/ballistic/automatic/pistol,
+ /obj/item/gun/ballistic/automatic/pistol/candor,
/obj/item/gun/ballistic/revolver/firebrand,
+ /obj/item/gun/ballistic/revolver/shadow,
+ /obj/item/gun/ballistic/shotgun/doublebarrel/beacon/presawn,
/obj/item/gun/energy/e_gun/mini))
if(prob(30))
l_hand = pick(list(
/obj/item/gun/ballistic/automatic/pistol/disposable,
- /obj/item/gun/ballistic/automatic/pistol,
+ /obj/item/gun/ballistic/automatic/pistol/candor,
/obj/item/gun/ballistic/revolver/firebrand,
+ /obj/item/gun/ballistic/revolver/shadow,
+ /obj/item/gun/ballistic/shotgun/doublebarrel/beacon/presawn,
/obj/item/gun/energy/e_gun/mini))
if("Melee")
r_hand = pickweight(list(
- /obj/item/kitchen/knife = 15,
+ /obj/item/kitchen/knife/combat/survival = 15,
/obj/item/melee/baseball_bat = 10,
- /obj/item/melee/cleric_mace = 7,
/obj/item/melee/roastingstick = 2,
/obj/item/kitchen/fork = 1,
/obj/item/melee/flyswatter = 1,
))
+/datum/outfit/job/frontiersmen/ert/grunt //better armed, use for quick creating pirate ships
+ name = "ERT - Frontiersman Grunt (Unarmed)"
+
+ suit_store = null
+ belt = /obj/item/storage/belt/security/military/frontiersmen
+
+ backpack_contents = list(/obj/item/clothing/mask/gas/frontiersmen)
+
+/datum/outfit/job/frontiersmen/ert/grunt/skm
+ name = "ERT - Frontiersman Grunt (SKM-24)"
+
+ suit_store = /obj/item/gun/ballistic/automatic/assault/skm
+ belt = /obj/item/storage/belt/security/military/frontiersmen/skm_ammo
+
+/datum/outfit/job/frontiersmen/ert/grunt/aps_mp //remember. Remind me to replace this with the spitter.
+ name = "ERT - Frontiersman Grunt (Stechkin APS)"
+
+ suit_store = /obj/item/gun/ballistic/automatic/pistol/APS
+ belt = /obj/item/storage/belt/security/military/frontiersmen/aps_mp_ammo
/datum/outfit/job/frontiersmen/ert/leader
name = "ERT - Frontiersman Officer"
- uniform = /obj/item/clothing/under/rank/security/officer/frontier/officer
+ uniform = /obj/item/clothing/under/frontiersmen/officer
head = /obj/item/clothing/head/beret/sec/frontier/officer
ears = /obj/item/radio/headset/pirate/alt/captain
back = /obj/item/storage/backpack/satchel/leather
suit = /obj/item/clothing/suit/armor/frontier
- suit_store = /obj/item/gun/ballistic/revolver
- belt = /obj/item/storage/belt/military/assault
+ suit_store = /obj/item/gun/ballistic/automatic/pistol/deagle
+
+ backpack_contents = list(/obj/item/clothing/mask/gas/frontiersmen, /obj/item/ammo_box/magazine/m50=2, /obj/item/binoculars=1, /obj/item/kitchen/knife/combat/survival)
+
+/datum/outfit/job/frontiersmen/ert/leader/unnarmed
+ name = "ERT - Frontiersman Officer (Unnarmed)"
+
+ suit_store = null
- backpack_contents = list(/obj/item/ammo_box/a357=3, /obj/item/binoculars=1, /obj/item/kitchen/knife/combat/survival)
+ backpack_contents = list(/obj/item/clothing/mask/gas/frontiersmen, /obj/item/binoculars=1, /obj/item/kitchen/knife/combat/survival)
/datum/outfit/job/frontiersmen/ert/medic
name = "ERT - Frontiersman Medic"
+ head = /obj/item/clothing/head/frontier
back = /obj/item/storage/backpack/medic
mask = /obj/item/clothing/mask/surgical
gloves = /obj/item/clothing/gloves/color/latex/nitrile
- belt = /obj/item/storage/belt/medical/surgery
- suit = null
- suit_store = null
+ belt = /obj/item/storage/belt/medical/webbing/frontiersmen/surgery
+ suit_store = /obj/item/gun/ballistic/automatic/pistol/APS
- backpack_contents = list(/obj/item/storage/firstaid/medical=1, /obj/item/reagent_containers/hypospray/medipen/stimpack=3)
+ backpack_contents = list(/obj/item/clothing/mask/gas/frontiersmen, /obj/item/storage/firstaid/medical=1, /obj/item/reagent_containers/hypospray/medipen/stimpack=3, /obj/item/ammo_box/magazine/pistolm9mm=2)
/datum/outfit/job/frontiersmen/ert/engineer
@@ -147,8 +187,38 @@
back = /obj/item/storage/backpack/industrial
belt = /obj/item/storage/belt/utility/full
- head = /obj/item/clothing/head/hardhat/weldhat
+ head = /obj/item/clothing/head/hardhat/frontier
+ glasses = /obj/item/clothing/glasses/welding
suit_store = null
- backpack_contents = list(/obj/item/grenade/c4=3, /obj/item/crowbar/large=1)
+ backpack_contents = list(/obj/item/clothing/mask/gas/frontiersmen, /obj/item/grenade/c4=3, /obj/item/crowbar/large=1)
+
+/datum/outfit/job/frontiersmen/ert/flamer
+ name = "ERT - Frontiersman Flame Trooper"
+
+ head = /obj/item/clothing/head/helmet/bulletproof/x11/frontier/fireproof
+ mask = /obj/item/clothing/mask/gas/frontiersmen
+ suit = /obj/item/clothing/suit/armor/frontier/fireproof
+ suit_store = /obj/item/tank/internals/oxygen/red
+ uniform = /obj/item/clothing/under/frontiersmen/fireproof
+ gloves = /obj/item/clothing/gloves/combat
+ back = /obj/item/storage/backpack
+ belt = /obj/item/storage/belt/security/military/frontiersmen/flamer
+
+ l_hand = /obj/item/flamethrower/full/tank
+
+ backpack_contents = list(/obj/item/gun/ballistic/shotgun/doublebarrel/presawn=1,/obj/item/ammo_box/a12g=1,/obj/item/extinguisher=2,/obj/item/radio=1)
+
+
+/datum/outfit/job/frontiersmen/ert/sentry_lmg
+ name = "ERT - Frontiersman Sentry (SKM-24v)"
+
+ head = /obj/item/clothing/head/helmet/marine/frontier
+ mask = /obj/item/clothing/mask/gas/sechailer/balaclava
+ suit = /obj/item/clothing/suit/armor/vest/marine/frontier
+ suit_store = /obj/item/gun/ballistic/automatic/hmg/skm_lmg/drum_mag
+ gloves = /obj/item/clothing/gloves/combat
+
+ belt = /obj/item/gun/ballistic/revolver/mateba
+ backpack_contents = list(/obj/item/ammo_box/magazine/skm_762_40/drum=2,/obj/item/ammo_box/a357=2,/obj/item/grenade/frag=1,/obj/item/radio=1)
diff --git a/code/modules/clothing/outfits/ert/nanotrasen_ert.dm b/code/modules/clothing/outfits/ert/nanotrasen_ert.dm
index 7e39f0b2f32a..4cec7ad56f8a 100644
--- a/code/modules/clothing/outfits/ert/nanotrasen_ert.dm
+++ b/code/modules/clothing/outfits/ert/nanotrasen_ert.dm
@@ -29,7 +29,7 @@
belt = /obj/item/storage/belt/security/full
backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\
/obj/item/melee/baton/loaded=1)
- l_pocket = /obj/item/switchblade
+ l_pocket = /obj/item/kitchen/knife/switchblade
/datum/outfit/centcom/ert/commander/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
@@ -47,7 +47,7 @@
glasses = /obj/item/clothing/glasses/thermal/eyepatch
backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\
/obj/item/melee/baton/loaded=1,\
- /obj/item/gun/energy/pulse/pistol/loyalpin=1)
+ /obj/item/gun/energy/pulse/pistol=1)
l_pocket = /obj/item/melee/transforming/energy/sword/saber
/datum/outfit/centcom/ert/security
@@ -77,7 +77,7 @@
/datum/outfit/centcom/ert/security/alert
name = "ERT Security - High Alert"
- suit_store = /obj/item/gun/energy/pulse/carbine/loyalpin
+ suit_store = /obj/item/gun/energy/pulse/carbine
mask = /obj/item/clothing/mask/gas/sechailer/swat
backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\
/obj/item/storage/box/handcuffs=1,\
@@ -114,7 +114,7 @@
mask = /obj/item/clothing/mask/gas/sechailer/swat
backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\
/obj/item/melee/baton/loaded=1,\
- /obj/item/gun/energy/pulse/pistol/loyalpin=1,\
+ /obj/item/gun/energy/pulse/pistol=1,\
/obj/item/reagent_containers/hypospray/combat/nanites=1,\
/obj/item/gun/medbeam=1)
@@ -150,7 +150,7 @@
mask = /obj/item/clothing/mask/gas/sechailer/swat
backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\
/obj/item/melee/baton/loaded=1,\
- /obj/item/gun/energy/pulse/pistol/loyalpin=1,\
+ /obj/item/gun/energy/pulse/pistol=1,\
/obj/item/construction/rcd/combat=1)
// official
@@ -282,7 +282,7 @@
suit = /obj/item/clothing/suit/armor/vest/marine
back = /obj/item/storage/backpack/ert
backpack_contents = list(
- /obj/item/storage/box/survival/engineer/radio = 1,
+ /obj/item/storage/box/survival/engineer = 1,
/obj/item/gun_voucher/nanotrasen = 1
)
belt = /obj/item/storage/belt/military/assault
@@ -332,7 +332,7 @@
l_pocket = /obj/item/healthanalyzer
head = /obj/item/clothing/head/helmet/marine/medic
backpack_contents = list(
- /obj/item/storage/box/survival/engineer/radio = 1,
+ /obj/item/storage/box/survival/engineer = 1,
/obj/item/gun_voucher/nanotrasen = 1,
/obj/item/reagent_containers/hypospray/combat = 1,
/obj/item/storage/firstaid/regular = 1,
@@ -359,7 +359,7 @@
head = /obj/item/clothing/head/helmet/marine/engineer
back = /obj/item/storage/backpack/ert/engineer
backpack_contents = list(
- /obj/item/storage/box/survival/engineer/radio = 1,
+ /obj/item/storage/box/survival/engineer = 1,
/obj/item/gun_voucher/nanotrasen = 1,
/obj/item/rcd_ammo/large = 2,
)
@@ -460,6 +460,5 @@
glasses = /obj/item/clothing/glasses/hud/security/sunglasses
back = /obj/item/storage/backpack/ert
- box = /obj/item/storage/box/survival/radio
l_pocket = /obj/item/megaphone/command
r_pocket = /obj/item/binoculars
diff --git a/code/modules/clothing/outfits/ert/syndicate_ert.dm b/code/modules/clothing/outfits/ert/syndicate_ert.dm
index 472983e890db..29da95448ee4 100644
--- a/code/modules/clothing/outfits/ert/syndicate_ert.dm
+++ b/code/modules/clothing/outfits/ert/syndicate_ert.dm
@@ -27,7 +27,7 @@
head = /obj/item/clothing/head/HoS/beret/syndicate
ears = /obj/item/radio/headset/syndicate/captain
- backpack_contents = list(/obj/item/gun/ballistic/automatic/pistol=1, /obj/item/ammo_box/magazine/m10mm=2, /obj/item/radio=1)
+ backpack_contents = list(/obj/item/gun/ballistic/automatic/pistol/syndicate=1, /obj/item/ammo_box/magazine/m10mm=2, /obj/item/radio=1)
// gorlex loyalist/2nd battlegroup
@@ -58,7 +58,7 @@
belt = /obj/item/storage/belt/medical/webbing/paramedic
glasses = /obj/item/clothing/glasses/hud/health/sunglasses
gloves = /obj/item/clothing/gloves/color/latex/nitrile/evil
- suit_store = /obj/item/gun/ballistic/automatic/pistol
+ suit_store = /obj/item/gun/ballistic/automatic/pistol/syndicate
l_pocket = /obj/item/radio
@@ -73,7 +73,7 @@
gloves = /obj/item/clothing/gloves/fingerless
suit = /obj/item/clothing/suit/armor/vest
belt = /obj/item/storage/belt/security
- suit_store = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate
+ suit_store = /obj/item/gun/ballistic/automatic/marksman/sniper_rifle
r_pocket = /obj/item/kitchen/knife/combat/survival
l_pocket = /obj/item/binoculars
diff --git a/code/modules/clothing/outfits/factions/frontiersmen.dm b/code/modules/clothing/outfits/factions/frontiersmen.dm
index c30de3d40432..7045f5182188 100644
--- a/code/modules/clothing/outfits/factions/frontiersmen.dm
+++ b/code/modules/clothing/outfits/factions/frontiersmen.dm
@@ -3,7 +3,7 @@
// faction_icon = "bg_frontiersmen"
- uniform = /obj/item/clothing/under/rank/security/officer/frontier
+ uniform = /obj/item/clothing/under/frontiersmen
r_pocket = /obj/item/radio
shoes = /obj/item/clothing/shoes/jackboots
ears = /obj/item/radio/headset/pirate
@@ -24,12 +24,14 @@
// Assistant
/datum/outfit/job/frontiersmen/assistant
- name = "Frontiersmen - Rookie"
- id_assignment = "Rookie"
+ name = "Frontiersmen - Deckhand"
+ id_assignment = "Deckhand"
job_icon = "assistant"
jobtype = /datum/job/assistant
+ uniform = /obj/item/clothing/under/frontiersmen/deckhand
head = /obj/item/clothing/head/beret/sec/frontier
+ shoes = /obj/item/clothing/shoes/workboots
// Atmospheric Technician
@@ -39,7 +41,7 @@
jobtype = /datum/job/atmos
accessory = /obj/item/clothing/accessory/armband/engine
- head = /obj/item/clothing/head/hardhat
+ head = /obj/item/clothing/head/hardhat/frontier
// Cargo Technician
@@ -49,9 +51,8 @@
jobtype = /datum/job/cargo_tech
accessory = /obj/item/clothing/accessory/armband/cargo
- suit = /obj/item/clothing/suit/hazardvest
shoes = /obj/item/clothing/shoes/workboots
- head = /obj/item/clothing/head/soft
+ head = /obj/item/clothing/head/soft/frontiersmen
backpack_contents = list(/obj/item/modular_computer/tablet/preset/cargo)
// Captain
@@ -62,26 +63,22 @@
jobtype = /datum/job/captain
ears = /obj/item/radio/headset/pirate/alt/captain
- uniform = /obj/item/clothing/under/rank/security/officer/frontier/officer
- head = /obj/item/clothing/head/caphat/frontier
- mask = /obj/item/clothing/mask/gas/sechailer
+ uniform = /obj/item/clothing/under/frontiersmen/officer
+ head = /obj/item/clothing/head/frontier/peaked
suit = /obj/item/clothing/suit/armor/frontier
- shoes = /obj/item/clothing/shoes/cowboy/black
+ shoes = /obj/item/clothing/shoes/jackboots
gloves = /obj/item/clothing/gloves/combat
- glasses = /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch
/datum/outfit/job/frontiersmen/captain/admiral
name = "Frontiersmen - Admiral"
id_assignment = "Admiral"
- uniform = /obj/item/clothing/under/rank/security/officer/frontier/admiral
- head = /obj/item/clothing/head/caphat/frontier/admiral
- shoes = /obj/item/clothing/shoes/cowboy/white
+ uniform = /obj/item/clothing/under/frontiersmen/admiral
+ head = /obj/item/clothing/head/frontier/peaked/admiral
+ shoes = /obj/item/clothing/shoes/jackboots
ears = /obj/item/radio/headset/pirate/captain
- gloves = /obj/item/clothing/gloves/color/evening
+ gloves = /obj/item/clothing/gloves/combat
suit = null
- mask = null
- glasses = null
// Chief Engineer
/datum/outfit/job/frontiersmen/ce
@@ -92,8 +89,8 @@
accessory = /obj/item/clothing/accessory/armband/engine
ears = /obj/item/radio/headset/pirate/captain
- uniform = /obj/item/clothing/under/rank/security/officer/frontier/officer
- head = /obj/item/clothing/head/hardhat/weldhat/white
+ uniform = /obj/item/clothing/under/frontiersmen/officer
+ head = /obj/item/clothing/head/hardhat/frontier
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
belt = /obj/item/storage/belt/utility/full
@@ -106,13 +103,9 @@
jobtype = /datum/job/engineer
accessory = /obj/item/clothing/accessory/armband/engine
- belt = /obj/item/storage/belt/utility/full/engi
- suit = /obj/item/clothing/suit/toggle/industrial
shoes = /obj/item/clothing/shoes/workboots
- glasses = /obj/item/clothing/glasses/welding
- head = /obj/item/clothing/head/beret/sec/frontier
+ head = /obj/item/clothing/head/hardhat/frontier
- l_pocket = /obj/item/radio
r_pocket = /obj/item/analyzer
// Cook
@@ -123,7 +116,7 @@
job_icon = "cook"
jobtype = /datum/job/cook
- uniform = /obj/item/clothing/under/rank/security/officer/frontier
+ uniform = /obj/item/clothing/under/frontiersmen
head = /obj/item/clothing/head/chefhat
suit = /obj/item/clothing/suit/apron/chef
@@ -136,8 +129,8 @@
jobtype = /datum/job/head_of_personnel
ears = /obj/item/radio/headset/pirate/alt
- uniform = /obj/item/clothing/under/rank/security/officer/frontier/officer
- shoes = /obj/item/clothing/shoes/cowboy/black
+ uniform = /obj/item/clothing/under/frontiersmen/officer
+ shoes = /obj/item/clothing/shoes/jackboots
head = /obj/item/clothing/head/beret/sec/frontier/officer
gloves = /obj/item/clothing/gloves/combat
r_pocket = /obj/item/kitchen/knife/combat/survival
@@ -150,12 +143,12 @@
jobtype = /datum/job/hos
accessory = /obj/item/clothing/accessory/armband
- uniform = /obj/item/clothing/under/rank/security/officer/frontier/officer
+ uniform = /obj/item/clothing/under/frontiersmen/officer
head = /obj/item/clothing/head/beret/sec/frontier/officer
suit = /obj/item/clothing/suit/armor/vest/bulletproof/frontier
- shoes = /obj/item/clothing/shoes/cowboy/black
+ shoes = /obj/item/clothing/shoes/jackboots
gloves = /obj/item/clothing/gloves/combat
- backpack_contents = list(/obj/item/melee/baton/loaded=1)
+ backpack_contents = list(/obj/item/clothing/mask/gas/frontiersmen, /obj/item/melee/baton/loaded=1)
suit_store = null
// Security Officer
@@ -167,17 +160,19 @@
jobtype = /datum/job/officer
accessory = /obj/item/clothing/accessory/armband
- head = /obj/item/clothing/head/beret/sec/frontier
- mask = /obj/item/clothing/mask/gas/sechailer/balaclava
suit = null
- uniform = /obj/item/clothing/under/rank/security/officer/frontier
+ uniform = /obj/item/clothing/under/frontiersmen
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/color/black
ears = /obj/item/radio/headset/pirate/alt
+ box = /obj/item/storage/box/survival/frontier
+
l_pocket = /obj/item/flashlight/seclite
r_pocket = /obj/item/tank/internals/emergency_oxygen/double
+ backpack_contents = list(/obj/item/clothing/mask/gas/frontiersmen)
+
// Medical Doctor
/datum/outfit/job/frontiersmen/doctor
@@ -187,7 +182,9 @@
jobtype = /datum/job/doctor
accessory = /obj/item/clothing/accessory/armband/med
- uniform = /obj/item/clothing/under/rank/security/officer/frontier
- glasses = /obj/item/clothing/glasses/hud/health/prescription
+ uniform = /obj/item/clothing/under/frontiersmen
+ glasses = /obj/item/clothing/glasses/hud/health
r_pocket = /obj/item/kitchen/knife/combat/survival
- backpack_contents = list(/obj/item/storage/firstaid/medical)
+ suit = /obj/item/clothing/suit/frontiersmen
+ head = /obj/item/clothing/head/frontier
+ belt = /obj/item/storage/belt/medical/webbing/frontiersmen
diff --git a/code/modules/clothing/outfits/factions/gezena.dm b/code/modules/clothing/outfits/factions/gezena.dm
index ed32d8b698e7..df7a5145e47f 100644
--- a/code/modules/clothing/outfits/factions/gezena.dm
+++ b/code/modules/clothing/outfits/factions/gezena.dm
@@ -7,6 +7,7 @@
if(visualsOnly)
return
H.faction |= list(FACTION_PLAYER_GEZENA)
+ H.grant_language(/datum/language/draconic)
//Playable Roles (put in ships):
/datum/outfit/job/gezena/assistant
diff --git a/code/modules/clothing/outfits/factions/independent.dm b/code/modules/clothing/outfits/factions/independent.dm
index eeb6a1d8c7f3..db227c2903c7 100644
--- a/code/modules/clothing/outfits/factions/independent.dm
+++ b/code/modules/clothing/outfits/factions/independent.dm
@@ -6,8 +6,6 @@
box = /obj/item/storage/box/survival
id = /obj/item/card/id
- r_pocket = /obj/item/storage/wallet
-
// Assistant
/datum/outfit/job/independent/assistant
@@ -19,8 +17,21 @@
/datum/outfit/job/independent/assistant/waiter
name = "Independent - Assistant (Waiter)"
+
uniform = /obj/item/clothing/under/suit/waiter
+ alt_uniform = /obj/item/clothing/under/suit/waiter/syndicate
+ gloves = /obj/item/clothing/gloves/color/evening
+ ears = /obj/item/radio/headset/headset_srv
shoes = /obj/item/clothing/shoes/laceup
+ l_pocket = /obj/item/lighter
+ r_pocket = /obj/item/reagent_containers/glass/rag
+
+/datum/outfit/job/independent/assistant/waiter/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ ..()
+ if(visualsOnly)
+ return
+ var/obj/item/card/id/W = H.wear_id
+ W.access += list(ACCESS_KITCHEN)
/datum/outfit/job/independent/assistant/fancy
name = "Independent - Assistant (Formal Uniform)"
@@ -138,6 +149,18 @@
implants = list(/obj/item/implant/radio)
accessory = null
+/datum/outfit/job/independent/captain/manager
+ name = "Independent - Captain (Manager)"
+
+ id = /obj/item/card/id
+ gloves = /obj/item/clothing/gloves/color/white
+ uniform = /obj/item/clothing/under/suit/black_really
+ alt_uniform = /obj/item/clothing/under/suit/blacktwopiece
+ dcoat = null
+ glasses = /obj/item/clothing/glasses/sunglasses
+ head = null
+ accessory = null
+
// Head of Personnel
/datum/outfit/job/independent/hop
@@ -289,7 +312,6 @@
jobtype = /datum/job/engineer
belt = /obj/item/storage/belt/utility/full/engi
- l_pocket = /obj/item/storage/wallet
gloves = /obj/item/clothing/gloves/color/yellow
ears = /obj/item/radio/headset/headset_eng
uniform = /obj/item/clothing/under/rank/engineering/engineer
@@ -368,7 +390,6 @@
id = /obj/item/card/id/silver
belt = /obj/item/storage/belt/utility/chief/full
- l_pocket = /obj/item/storage/wallet
ears = /obj/item/radio/headset/headset_com
uniform = /obj/item/clothing/under/rank/engineering/chief_engineer
dcoat = /obj/item/clothing/suit/hooded/wintercoat/engineering
@@ -586,7 +607,8 @@
job_icon = "cook"
ears = /obj/item/radio/headset/headset_srv
- uniform = /obj/item/clothing/under/rank/civilian/chef //WS Edit - Alt Uniforms
+ shoes = /obj/item/clothing/shoes/laceup
+ uniform = /obj/item/clothing/under/rank/civilian/chef
suit = /obj/item/clothing/suit/toggle/chef
alt_suit = /obj/item/clothing/suit/apron/chef
head = /obj/item/clothing/head/chefhat
@@ -601,8 +623,6 @@
var/chosen_box = pick(possible_boxes)
var/obj/item/storage/box/I = new chosen_box(src)
H.equip_to_slot_or_del(I,ITEM_SLOT_BACKPACK)
- var/datum/martial_art/cqc/under_siege/justacook = new
- justacook.teach(H)
// Bartender
@@ -617,6 +637,14 @@
suit = /obj/item/clothing/suit/armor/vest
backpack_contents = list(/obj/item/storage/box/beanbag=1)
shoes = /obj/item/clothing/shoes/laceup
+ accessory = /obj/item/clothing/accessory/waistcoat
+
+/datum/outfit/job/independent/bartender/disarmed //No armor, no shotgun ammo.
+ name = "Independent - Bartender (Disarmed)"
+
+ suit = null
+ alt_suit = null
+ backpack_contents = null
/datum/outfit/job/independent/bartender/pharma
name = "Independent - Bartender (Mixologist)"
@@ -628,6 +656,7 @@
belt = /obj/item/storage/belt
gloves = /obj/item/clothing/gloves/color/latex/nitrile
uniform = /obj/item/clothing/under/suit/black
+ accessory = null
// Lawyer
@@ -729,7 +758,6 @@
/datum/outfit/job/independent/chemist/pharma
name = "Independent - Chemist (Pharmacology Student)"
- uniform = /obj/item/clothing/under/rank/medical
shoes = /obj/item/clothing/shoes/sneakers/white
accessory = /obj/item/clothing/neck/scarf/orange
l_pocket = /obj/item/pda/medical
diff --git a/code/modules/clothing/outfits/factions/inteq.dm b/code/modules/clothing/outfits/factions/inteq.dm
index 75a36b1a3132..6ad58203e2e6 100644
--- a/code/modules/clothing/outfits/factions/inteq.dm
+++ b/code/modules/clothing/outfits/factions/inteq.dm
@@ -29,31 +29,40 @@
///captains
/datum/outfit/job/inteq/captain
- name = "IRMG - Vanguard (Naked)"
+ name = "IRMG - Vanguard"
id_assignment = "Vanguard"
jobtype = /datum/job/captain
job_icon = "captain"
+ id = /obj/item/card/id/gold
+ head = /obj/item/clothing/head/beret/sec/hos/inteq
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses/inteq
+ mask = /obj/item/clothing/mask/gas/sechailer/balaclava/inteq
+ suit = /obj/item/clothing/suit/armor/hos/inteq
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/security/inteq
+ belt = /obj/item/storage/belt/security/webbing/inteq
+ gloves = /obj/item/clothing/gloves/combat
ears = /obj/item/radio/headset/inteq/alt/captain
shoes = /obj/item/clothing/shoes/combat
+
r_pocket = /obj/item/assembly/flash/handheld
l_pocket = /obj/item/restraints/handcuffs
- jobtype = /datum/job/captain
- id = /obj/item/card/id/gold
backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1)
-/datum/outfit/job/inteq/captain/geared
- name = "IRMG - Vanguard"
+/datum/outfit/job/inteq/captain/empty
+ name = "IRMG - Vanguard (Naked)"
- head = /obj/item/clothing/head/beret/sec/hos/inteq
- glasses = /obj/item/clothing/glasses/hud/security/sunglasses/inteq
- mask = /obj/item/clothing/mask/gas/sechailer/balaclava/inteq
- belt = /obj/item/storage/belt/security/webbing/inteq
- suit = /obj/item/clothing/suit/armor/hos/inteq
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/security/inteq
- gloves = /obj/item/clothing/gloves/combat
- accessory = null
+ head = null
+ glasses = null
+ mask = null
+ belt = null
+ suit = null
+ dcoat = null
+ gloves = null
+
+ r_pocket = null
+ l_pocket = null
/datum/outfit/job/inteq/captain/honorable
name = "IRMG - Honorable Vanguard"
@@ -71,8 +80,8 @@
///Chief Engineer
/datum/outfit/job/inteq/ce
- name = "IRMG - Artificer Class II"
- id_assignment = "Artificer Class II"
+ name = "IRMG - Honorable Artificer"
+ id_assignment = "Honorable Artificer"
job_icon = "chiefengineer"
jobtype = /datum/job/chief_engineer
@@ -140,6 +149,14 @@
satchel = /obj/item/storage/backpack/messenger/inteq
courierbag = /obj/item/storage/backpack/messenger/inteq
+/datum/outfit/job/inteq/security/empty
+ name = "IRMG - Enforcer (Naked)"
+ head = null
+ suit = null
+ belt = null
+ mask = null
+ gloves = null
+
/datum/outfit/job/inteq/security/beluga
name = "IRMG - Enforcer (Beluga)"
@@ -156,14 +173,6 @@
satchel = /obj/item/storage/backpack/messenger/inteq
courierbag = /obj/item/storage/backpack/messenger/inteq
-/datum/outfit/job/inteq/security/empty
- name = "IRMG - Enforcer (Naked)"
- head = null
- suit = null
- belt = null
- mask = null
- gloves = null
-
///engineers
/datum/outfit/job/inteq/engineer
@@ -201,6 +210,17 @@
courierbag = /obj/item/storage/backpack/messenger/inteq
backpack_contents = list(/obj/item/melee/classic_baton=1)
+/datum/outfit/job/inteq/warden/pilot
+ name = "IRMG - Shuttle Pilot"
+ job_icon = "securityofficer"
+ id_assignment = "Shuttle Pilot"
+
+ head = /obj/item/clothing/head/soft/inteq
+ suit = /obj/item/clothing/suit/armor/vest/alt
+ belt = null
+ mask = /obj/item/clothing/mask/breath
+ gloves = /obj/item/clothing/gloves/fingerless
+
// cmo
/datum/outfit/job/inteq/cmo
diff --git a/code/modules/clothing/outfits/factions/minutemen.dm b/code/modules/clothing/outfits/factions/minutemen.dm
index 9de9c0d152c3..5c038b05f181 100644
--- a/code/modules/clothing/outfits/factions/minutemen.dm
+++ b/code/modules/clothing/outfits/factions/minutemen.dm
@@ -246,6 +246,21 @@
r_pocket = /obj/item/radio
+/datum/outfit/job/clip/correspondant
+ name = "CLIP - War Correspondent"
+ job_icon = "curator"
+ jobtype = /datum/job/curator
+
+ head = /obj/item/clothing/head/helmet/bulletproof/m10/clip_correspondent
+ uniform = /obj/item/clothing/under/clip/formal/with_shirt
+ suit = /obj/item/clothing/suit/armor/vest/clip_correspondent
+ shoes = /obj/item/clothing/shoes/laceup
+
+ backpack = /obj/item/storage/backpack/satchel/leather
+ satchel = /obj/item/storage/backpack/satchel/leather
+
+ r_pocket = /obj/item/radio
+
// Colonial League Minutemen
/datum/outfit/job/clip/minutemen
@@ -308,7 +323,7 @@
suit = /obj/item/clothing/suit/armor/vest/capcarapace/clip
shoes = /obj/item/clothing/shoes/combat
- box = /obj/item/storage/box/survival/engineer/radio
+ box = /obj/item/storage/box/survival/engineer
backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/gun/ballistic/revolver/mateba=1)
/datum/outfit/job/clip/minutemen/captain/general/admiral // for flavor, might remove outright
@@ -545,7 +560,7 @@
/datum/outfit/job/clip/minutemen/grunt/dressed/armed/f4 //f4 is rename of GAL, don't wanna repath upon adding the clip guns though, if i forget to remove this during then, fucking yell at me
name = "CLIP Minutemen - Minuteman (Armed - CM-GAL)"
- suit_store = /obj/item/gun/ballistic/automatic/gal
+ suit_store = /obj/item/gun/ballistic/automatic/marksman/gal
belt = /obj/item/storage/belt/military/clip/gal
/datum/outfit/job/clip/minutemen/grunt/dressed/armed/cm5
diff --git a/code/modules/clothing/outfits/factions/nanotrasen.dm b/code/modules/clothing/outfits/factions/nanotrasen.dm
index f0fdb0e4ac1d..f03c91d51a11 100644
--- a/code/modules/clothing/outfits/factions/nanotrasen.dm
+++ b/code/modules/clothing/outfits/factions/nanotrasen.dm
@@ -1,3 +1,9 @@
+/*
+ * OUTFIT DATUMS THAT NEED MAKING:
+ * Research Director
+ * Medical Director
+*/
+
/datum/outfit/job/nanotrasen
name = "Nanotrasen - Base Outfit"
faction_icon = "bg_nanotrasen"
@@ -5,26 +11,15 @@
box = /obj/item/storage/box/survival
id = /obj/item/card/id
-
/datum/outfit/job/nanotrasen/post_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
if(visualsOnly)
return
H.faction |= list(FACTION_PLAYER_NANOTRASEN)
-// Assistant
-
-/datum/outfit/job/nanotrasen/assistant
- name = "Nanotrasen - Assistant"
- jobtype = /datum/job/assistant
- job_icon = "assistant"
-
- uniform = /obj/item/clothing/under/color/grey
- shoes = /obj/item/clothing/shoes/sneakers/black
- belt = /obj/item/pda
+// Command //
// Captain
-
/datum/outfit/job/nanotrasen/captain
name = "Nanotrasen - Captain"
job_icon = "captain"
@@ -34,11 +29,14 @@
belt = /obj/item/pda/captain
gloves = /obj/item/clothing/gloves/color/captain/nt
ears = /obj/item/radio/headset/nanotrasen/captain
- uniform = /obj/item/clothing/under/rank/command/captain/nt
- alt_uniform = /obj/item/clothing/under/rank/command/captain/parade
+ uniform = /obj/item/clothing/under/nanotrasen/captain
+ alt_uniform = /obj/item/clothing/under/nanotrasen/captain/skirt
+ suit = /obj/item/clothing/suit/armor/nanotrasen/captain
+ alt_suit = /obj/item/clothing/suit/armor/nanotrasen/captain/parade
dcoat = /obj/item/clothing/suit/hooded/wintercoat/captain
shoes = /obj/item/clothing/shoes/laceup
- head = /obj/item/clothing/head/caphat/nt
+ neck = /obj/item/clothing/neck/cloak/nanotrasen
+ head = /obj/item/clothing/head/nanotrasen/captain/peaked
backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1)
backpack = /obj/item/storage/backpack/captain
@@ -50,24 +48,21 @@
chameleon_extras = list(/obj/item/gun/energy/e_gun, /obj/item/stamp/captain)
-/datum/outfit/job/nanotrasen/captain/lp
- name = "Nanotrasen - Loss Prevention Lieutenant"
- id_assignment = "Lieutenant"
+/datum/outfit/job/nanotrasen/captain/ns
+ name = "Nanotrasen - Captain (N+S Logistics)"
- implants = list(/obj/item/implant/mindshield)
- ears = /obj/item/radio/headset/nanotrasen/alt/captain
- id = /obj/item/card/id/lplieu
- belt = /obj/item/pda/captain
- gloves = /obj/item/clothing/gloves/color/black
- uniform = /obj/item/clothing/under/rank/security/head_of_security/alt/lp
- alt_uniform = /obj/item/clothing/under/rank/security/head_of_security/alt/skirt/lp
- dcoat = /obj/item/clothing/suit/jacket
- shoes = /obj/item/clothing/shoes/jackboots
- head = /obj/item/clothing/head/beret/command
+ head = /obj/item/clothing/head/nanotrasen/cap/supply
+ uniform = /obj/item/clothing/under/nanotrasen/supply/qm
+ suit = null
+ alt_suit = null
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/cargo
+ shoes = /obj/item/clothing/shoes/sneakers/brown
+ glasses = /obj/item/clothing/glasses/sunglasses
+ gloves = null
+ neck = null
+ l_hand = /obj/item/clipboard
- satchel = /obj/item/storage/backpack/satchel/cap
- duffelbag = /obj/item/storage/backpack/duffelbag/captain
- courierbag = /obj/item/storage/backpack/messenger/com
+ chameleon_extras = /obj/item/stamp/qm
/datum/outfit/job/nanotrasen/captain/centcom
name = "Nanotrasen - Captain (Central Command)"
@@ -77,7 +72,6 @@
head = /obj/item/clothing/head/centhat
// Head of Personnel
-
/datum/outfit/job/nanotrasen/hop
name = "Nanotrasen - Head of Personnel"
job_icon = "headofpersonnel"
@@ -86,23 +80,30 @@
belt = /obj/item/pda/heads/head_of_personnel
id = /obj/item/card/id/silver
ears = /obj/item/radio/headset/headset_com
- uniform = /obj/item/clothing/under/rank/command/head_of_personnel/nt
- alt_suit = /obj/item/clothing/suit/ianshirt
+ uniform = /obj/item/clothing/under/nanotrasen/officer
+ alt_uniform = /obj/item/clothing/under/nanotrasen/officer/skirt
+ suit = /obj/item/clothing/suit/toggle/nanotrasen
dcoat = /obj/item/clothing/suit/hooded/wintercoat/captain
shoes = /obj/item/clothing/shoes/laceup
- head = /obj/item/clothing/head/hopcap/nt
- backpack_contents = list(/obj/item/storage/box/ids=1,\
- /obj/item/melee/classic_baton/telescopic=1, /obj/item/modular_computer/tablet/preset/advanced = 1)
+ head = /obj/item/clothing/head/nanotrasen/officer
+
+ backpack_contents = list(
+ /obj/item/storage/box/ids=1,
+ /obj/item/melee/classic_baton/telescopic=1,
+ /obj/item/modular_computer/tablet/preset/advanced = 1,
+ )
backpack = /obj/item/storage/backpack/captain
satchel = /obj/item/storage/backpack/satchel/cap
duffelbag = /obj/item/storage/backpack/duffelbag/captain
courierbag = /obj/item/storage/backpack/messenger/com
- chameleon_extras = list(/obj/item/gun/energy/e_gun, /obj/item/stamp/head_of_personnel)
+ chameleon_extras = list(
+ /obj/item/gun/energy/e_gun,
+ /obj/item/stamp/head_of_personnel,
+ )
// Head of Security
-
/datum/outfit/job/nanotrasen/hos
name = "Nanotrasen - Head of Security"
job_icon = "headofsecurity"
@@ -111,14 +112,14 @@
id = /obj/item/card/id/silver
belt = /obj/item/pda/heads/hos
ears = /obj/item/radio/headset/nanotrasen/alt
- uniform = /obj/item/clothing/under/rank/security/head_of_security/nt
+ uniform = /obj/item/clothing/under/nanotrasen/security/director
alt_uniform = null
shoes = /obj/item/clothing/shoes/jackboots
- suit = /obj/item/clothing/suit/armor/hos/trenchcoat
- alt_suit = /obj/item/clothing/suit/armor/vest/security/hos
+ suit = /obj/item/clothing/suit/armor/nanotrasen/slim
+ alt_suit = /obj/item/clothing/suit/armor/nanotrasen/sec_director
dcoat = /obj/item/clothing/suit/hooded/wintercoat/security
gloves = /obj/item/clothing/gloves/color/black
- head = /obj/item/clothing/head/beret/sec/hos
+ head = /obj/item/clothing/head/nanotrasen/beret/security/command
glasses = /obj/item/clothing/glasses/hud/security/sunglasses
suit_store = null
r_pocket = /obj/item/assembly/flash/handheld
@@ -135,74 +136,18 @@
chameleon_extras = list(/obj/item/gun/energy/e_gun/hos, /obj/item/stamp/hos)
-// Roboticist
-
-/datum/outfit/job/nanotrasen/roboticist
- name = "Nanotrasen - Mech Technician"
- id_assignment = "Mech Technician"
- job_icon = "roboticist"
- jobtype = /datum/job/roboticist
-
- uniform = /obj/item/clothing/under/rank/rnd/roboticist
- suit = /obj/item/clothing/suit/longcoat/robowhite
- ears = /obj/item/radio/headset/nanotrasen
- glasses = /obj/item/clothing/glasses/welding
-
- backpack_contents = list(/obj/item/weldingtool/hugetank)
-
-// Pilot. idk
-
-/datum/outfit/job/nanotrasen/pilot
- name = "Nanotrasen - Pilot"
- id_assignment = "Pilot"
-
- uniform = /obj/item/clothing/under/rank/security/officer/military
- suit = /obj/item/clothing/suit/jacket/leather/duster
- glasses = /obj/item/clothing/glasses/hud/spacecop
- accessory = /obj/item/clothing/accessory/holster
- head = /obj/item/clothing/head/beret/command
-
-// Lawyer
-
-/datum/outfit/job/nanotrasen/lawyer
- name = "Nanotrasen - Lawyer"
- job_icon = "lawyer"
- jobtype = /datum/job/lawyer
-
- ears = /obj/item/radio/headset/headset_srvsec
- uniform = /obj/item/clothing/under/suit/navy
- suit = /obj/item/clothing/suit/toggle/lawyer/navy
- shoes = /obj/item/clothing/shoes/laceup
- l_hand = /obj/item/storage/briefcase/lawyer
- l_pocket = /obj/item/laser_pointer
- r_pocket = /obj/item/clothing/accessory/lawyers_badge
-
- chameleon_extras = /obj/item/stamp/law
-
-/datum/outfit/job/nanotrasen/lawyer/corporaterepresentative
- name = "Nanotrasen - Corporate Representative"
- id_assignment = "Corporate Representative"
- job_icon = "nanotrasen"
-
- uniform = /obj/item/clothing/under/rank/command/head_of_personnel/suit
- suit = null
- ears = /obj/item/radio/headset/headset_cent
- l_hand = /obj/item/clipboard
- r_pocket = /obj/item/pen/fountain
-
// Security Officer
-
/datum/outfit/job/nanotrasen/security
name = "Nanotrasen - Security Officer"
jobtype = /datum/job/officer
job_icon = "securityofficer"
ears = /obj/item/radio/headset/alt
- uniform = /obj/item/clothing/under/rank/security/officer/nt
+ uniform = /obj/item/clothing/under/nanotrasen/security
gloves = /obj/item/clothing/gloves/color/black
- head = /obj/item/clothing/head/helmet/sec
- suit = /obj/item/clothing/suit/armor/vest
- alt_suit = /obj/item/clothing/suit/armor/vest/security/officer
+ head = /obj/item/clothing/head/nanotrasen/cap/security
+ suit = /obj/item/clothing/suit/armor/nanotrasen
+ alt_suit = /obj/item/clothing/suit/armor/nanotrasen/slim
dcoat = /obj/item/clothing/suit/hooded/wintercoat/security
shoes = /obj/item/clothing/shoes/jackboots
l_pocket = /obj/item/restraints/handcuffs
@@ -218,73 +163,36 @@
chameleon_extras = list(/obj/item/gun/energy/disabler, /obj/item/clothing/glasses/hud/security/sunglasses, /obj/item/clothing/head/helmet)
//The helmet is necessary because /obj/item/clothing/head/helmet/sec is overwritten in the chameleon list by the standard helmet, which has the same name and icon state
-/datum/outfit/job/nanotrasen/security/ert
- name = "Nanotrasen - ERT Officer"
-
- uniform = /obj/item/clothing/under/rank/security/officer/camo
- head = null
- backpack = /obj/item/storage/backpack/ert/security
- belt = /obj/item/storage/belt/military
- id = /obj/item/card/id/ert/security
- r_pocket = /obj/item/kitchen/knife/combat/survival
- backpack_contents = list(/obj/item/radio, /obj/item/flashlight/seclite)
-
-/datum/outfit/job/nanotrasen/security/ert/engi
- name = "Nanotrasen - ERT Engineering Officer"
-
- uniform = /obj/item/clothing/under/rank/security/officer/camo
- head = null
- backpack = /obj/item/storage/backpack/ert/engineer
- belt = /obj/item/storage/belt/utility/full/ert
- id = /obj/item/card/id/ert/security
- r_pocket = /obj/item/kitchen/knife/combat/survival
- backpack_contents = list(/obj/item/radio, /obj/item/flashlight/seclite)
- accessory = /obj/item/clothing/accessory/armband/engine
- glasses = /obj/item/clothing/glasses/hud/diagnostic/sunglasses
-
-/datum/outfit/job/nanotrasen/security/ert/med
- name = "Nanotrasen - ERT Medical Officer"
-
- uniform = /obj/item/clothing/under/rank/security/officer/camo
- head = /obj/item/clothing/head/beret/med
- backpack = /obj/item/storage/backpack/ert/medical
- belt = /obj/item/storage/belt/medical/webbing/paramedic
- id = /obj/item/card/id/ert/security
- r_pocket = /obj/item/kitchen/knife/combat/survival
- backpack_contents = list(/obj/item/radio, /obj/item/flashlight/seclite)
- accessory = /obj/item/clothing/accessory/armband/med
- glasses = /obj/item/clothing/glasses/hud/health/night
-
-/datum/outfit/job/nanotrasen/security/mech_pilot
- name = "Nanotrasen - Mech Pilot"
- id_assignment = "Mech Pilot"
-
- uniform = /obj/item/clothing/under/rank/security/officer/military/eng
- head = /obj/item/clothing/head/beret/sec/officer
- suit = /obj/item/clothing/suit/armor/vest/bulletproof
- backpack_contents = list(/obj/item/radio, /obj/item/flashlight/seclite)
-
-/datum/outfit/job/nanotrasen/security/lp
- name = "Nanotrasen - LP Security Specialist"
- id_assignment = "Security Specialist"
+// Warden
+/datum/outfit/job/nanotrasen/warden
+ name = "Nanotrasen - Warden"
+ job_icon = "warden"
+ jobtype = /datum/job/warden
- implants = list(/obj/item/implant/mindshield)
- ears = /obj/item/radio/headset/nanotrasen/alt/captain
- id = /obj/item/card/id/lpsec
- belt = /obj/item/pda/security
- gloves = /obj/item/clothing/gloves/color/black
- uniform = /obj/item/clothing/under/rank/security/head_of_security/nt/lp
- alt_uniform = /obj/item/clothing/under/rank/security/head_of_security/nt/skirt/lp
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/security
+ ears = /obj/item/radio/headset/headset_sec/alt
+ uniform = /obj/item/clothing/under/rank/security/warden/nt
shoes = /obj/item/clothing/shoes/jackboots
- head = /obj/item/clothing/head/beret/sec
+ suit = /obj/item/clothing/suit/armor/vest/security/warden/alt/nt
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/security
+ gloves = /obj/item/clothing/gloves/color/black
+ head = /obj/item/clothing/head/warden/red
+ glasses = /obj/item/clothing/glasses/hud/security/sunglasses
+ r_pocket = /obj/item/assembly/flash/handheld
+ l_pocket = /obj/item/restraints/handcuffs
+ suit_store = null
+ backpack_contents = list(/obj/item/melee/classic_baton)
+ backpack = /obj/item/storage/backpack/security
satchel = /obj/item/storage/backpack/satchel/sec
duffelbag = /obj/item/storage/backpack/duffelbag/sec
courierbag = /obj/item/storage/backpack/messenger/sec
+ box = /obj/item/storage/box/survival/security
-// Engineer
+ chameleon_extras = /obj/item/gun/ballistic/shotgun/automatic/combat/compact
+// Engineering //
+
+// Engineer
/datum/outfit/job/nanotrasen/engineer
name = "Nanotrasen - Engineer"
job_icon = "stationengineer"
@@ -293,10 +201,11 @@
belt = /obj/item/storage/belt/utility/full/engi
l_pocket = /obj/item/pda/engineering
ears = /obj/item/radio/headset/headset_eng
- uniform = /obj/item/clothing/under/rank/engineering/engineer/nt
+ uniform = /obj/item/clothing/under/nanotrasen/engineering
+ head = /obj/item/clothing/head/hardhat/nanotrasen
+ suit = /obj/item/clothing/suit/nanotrasen/vest
dcoat = /obj/item/clothing/suit/hooded/wintercoat/engineering
shoes = /obj/item/clothing/shoes/workboots
- head = /obj/item/clothing/head/hardhat
r_pocket = /obj/item/t_scanner
backpack = /obj/item/storage/backpack/industrial
@@ -307,53 +216,7 @@
box = /obj/item/storage/box/survival/engineer
backpack_contents = list(/obj/item/modular_computer/tablet/preset/advanced=1)
-/datum/outfit/job/nanotrasen/engineer/lp
- name = "Nanotrasen - LP Engineering Specialist"
-
- implants = list(/obj/item/implant/mindshield)
- ears = /obj/item/radio/headset/nanotrasen/alt/captain
- id = /obj/item/card/id/lpengie
- gloves = /obj/item/clothing/gloves/color/yellow
- uniform = /obj/item/clothing/under/rank/engineering/engineer/nt/lp
- alt_uniform = /obj/item/clothing/under/rank/engineering/engineer/nt/skirt/lp
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/engineering
- shoes = /obj/item/clothing/shoes/jackboots
- head = /obj/item/clothing/head/beret/eng
-
- satchel = /obj/item/storage/backpack/satchel/eng
- duffelbag = /obj/item/storage/backpack/duffelbag/engineering
- courierbag = /obj/item/storage/backpack/messenger/engi
-
-// Warden
-
-/datum/outfit/job/nanotrasen/warden
- name = "Nanotrasen - Warden"
- job_icon = "warden"
- jobtype = /datum/job/warden
-
- ears = /obj/item/radio/headset/headset_sec/alt
- uniform = /obj/item/clothing/under/rank/security/warden/nt
- shoes = /obj/item/clothing/shoes/jackboots
- suit = /obj/item/clothing/suit/armor/vest/security/warden/alt/nt
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/security
- gloves = /obj/item/clothing/gloves/color/black
- head = /obj/item/clothing/head/warden/red
- glasses = /obj/item/clothing/glasses/hud/security/sunglasses
- r_pocket = /obj/item/assembly/flash/handheld
- l_pocket = /obj/item/restraints/handcuffs
- suit_store = null
- backpack_contents = list(/obj/item/melee/classic_baton)
-
- backpack = /obj/item/storage/backpack/security
- satchel = /obj/item/storage/backpack/satchel/sec
- duffelbag = /obj/item/storage/backpack/duffelbag/sec
- courierbag = /obj/item/storage/backpack/messenger/sec
- box = /obj/item/storage/box/survival/security
-
- chameleon_extras = /obj/item/gun/ballistic/shotgun/automatic/combat/compact
-
// Chief Engineer
-
/datum/outfit/job/nanotrasen/ce
name = "Nanotrasen - Chief Engineer"
jobtype = /datum/job/chief_engineer
@@ -361,14 +224,17 @@
id = /obj/item/card/id/silver
belt = /obj/item/storage/belt/utility/chief/full
- l_pocket = /obj/item/storage/wallet
ears = /obj/item/radio/headset/headset_com
- uniform = /obj/item/clothing/under/rank/engineering/chief_engineer
+ uniform = /obj/item/clothing/under/nanotrasen/engineering/director
dcoat = /obj/item/clothing/suit/hooded/wintercoat/engineering
shoes = /obj/item/clothing/shoes/sneakers/brown
- head = /obj/item/clothing/head/hardhat/white
+ head = /obj/item/clothing/head/hardhat/nanotrasen/white
gloves = /obj/item/clothing/gloves/color/black
- backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/modular_computer/tablet/preset/advanced=1)
+
+ backpack_contents = list(
+ /obj/item/melee/classic_baton/telescopic=1,
+ /obj/item/modular_computer/tablet/preset/advanced=1,
+ )
backpack = /obj/item/storage/backpack/industrial
satchel = /obj/item/storage/backpack/satchel/eng
@@ -378,49 +244,91 @@
box = /obj/item/storage/box/survival/engineer
chameleon_extras = /obj/item/stamp/ce
-// Medical Doctor
+// Atmos Tech
+/datum/outfit/job/nanotrasen/atmos
+ name = "Nanotrasen - Atmos Tech"
+ jobtype = /datum/job/atmos
+ job_icon = "atmospherictechnician"
-/datum/outfit/job/nanotrasen/doctor
- name = "Nanotrasen - Medical Doctor"
- job_icon = "medicaldoctor"
- jobtype = /datum/job/doctor
+ belt = /obj/item/storage/belt/utility/atmostech
+ ears = /obj/item/radio/headset/headset_eng
+ uniform = /obj/item/clothing/under/nanotrasen/engineering/atmos
+ head = /obj/item/clothing/head/hardhat/nanotrasen/blue
+ suit = /obj/item/clothing/suit/nanotrasen/vest/blue
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/engineering
- belt = /obj/item/pda/medical
- ears = /obj/item/radio/headset/headset_med
- uniform = /obj/item/clothing/under/rank/medical/doctor
- shoes = /obj/item/clothing/shoes/sneakers/white
- suit = /obj/item/clothing/suit/toggle/labcoat
- alt_suit = /obj/item/clothing/suit/apron/surgical
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/medical
+ backpack = /obj/item/storage/backpack/industrial
+ satchel = /obj/item/storage/backpack/satchel/eng
+ duffelbag = /obj/item/storage/backpack/duffelbag/engineering
+ courierbag = /obj/item/storage/backpack/messenger/engi
+ box = /obj/item/storage/box/survival/engineer
+ backpack_contents = list(/obj/item/modular_computer/tablet/preset/advanced=1)
- backpack = /obj/item/storage/backpack/medic
- satchel = /obj/item/storage/backpack/satchel/med
- duffelbag = /obj/item/storage/backpack/duffelbag/med
- courierbag = /obj/item/storage/backpack/messenger/med
- box = /obj/item/storage/box/survival/medical
+// Brig Physician
-/datum/outfit/job/nanotrasen/doctor/lp
- name = "Nanotrasen - LP Medical Specialist"
- id_assignment = "Medical Specialist"
+/datum/outfit/job/nanotrasen/brig_phys
+ name = "Nanotrasen - Brig Physician"
+ jobtype = /datum/job/brig_phys
+ job_icon = "brigphysician"
- implants = list(/obj/item/implant/mindshield)
- ears = /obj/item/radio/headset/nanotrasen/alt/captain
- id = /obj/item/card/id/lpmed
- belt = /obj/item/pda/medical
- gloves = /obj/item/clothing/gloves/color/latex/nitrile
- uniform = /obj/item/clothing/under/rank/medical/paramedic/lp
- alt_uniform = /obj/item/clothing/under/rank/medical/paramedic/skirt/lp
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/medical
- shoes = /obj/item/clothing/shoes/sneakers/white
- head = /obj/item/clothing/head/beret/med
+ ears = /obj/item/radio/headset/headset_medsec/alt
+ uniform = /obj/item/clothing/under/rank/security/brig_phys/nt
+ shoes = /obj/item/clothing/shoes/jackboots
+ glasses = /obj/item/clothing/glasses/hud/health/sunglasses
+ suit = /obj/item/clothing/suit/toggle/labcoat/brig_phys
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/security
+ head = /obj/item/clothing/head/soft/sec/brig_phys
+ implants = list(/obj/item/implant/mindshield)
- satchel = /obj/item/storage/backpack/satchel/med
- duffelbag = /obj/item/storage/backpack/duffelbag/med
- courierbag = /obj/item/storage/backpack/messenger/med
- box = /obj/item/storage/box/survival/medical
+// Supply //
-// Cargo Tech
+// Quartermaster
+/datum/outfit/job/nanotrasen/quartermaster
+ name = "Nanotrasen - Quartermaster"
+ jobtype = /datum/job/qm
+ job_icon = "quartermaster"
+
+ ears = /obj/item/radio/headset/headset_cargo
+ head = /obj/item/clothing/head/nanotrasen/cap/supply
+ uniform = /obj/item/clothing/under/nanotrasen/supply/qm
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/cargo
+ shoes = /obj/item/clothing/shoes/sneakers/brown
+ glasses = /obj/item/clothing/glasses/sunglasses
+ l_hand = /obj/item/clipboard
+ backpack_contents = list(/obj/item/modular_computer/tablet/preset/cargo=1)
+
+ chameleon_extras = /obj/item/stamp/qm
+
+//Miner
+/datum/outfit/job/nanotrasen/miner
+ name = "Nanotrasen - Miner"
+ jobtype = /datum/job/mining
+ job_icon = "shaftminer"
+ ears = /obj/item/radio/headset/headset_cargo/mining
+ shoes = /obj/item/clothing/shoes/workboots/mining
+ head = /obj/item/clothing/head/hardhat/nanotrasen
+ gloves = /obj/item/clothing/gloves/color/black
+ uniform = /obj/item/clothing/under/nanotrasen/supply/miner
+ suit = /obj/item/clothing/suit/nanotrasen/vest
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/miner
+ r_pocket = /obj/item/storage/bag/ore
+
+ backpack_contents = list(
+ /obj/item/flashlight/seclite=1,
+ /obj/item/kitchen/knife/combat/survival=1,
+ /obj/item/stack/marker_beacon/ten=1,
+ /obj/item/radio/weather_monitor=1,
+ )
+
+ backpack = /obj/item/storage/backpack/explorer
+ satchel = /obj/item/storage/backpack/satchel/explorer
+ duffelbag = /obj/item/storage/backpack/duffelbag
+ box = /obj/item/storage/box/survival/mining
+
+ chameleon_extras = /obj/item/gun/energy/kinetic_accelerator
+
+// Cargo Tech
/datum/outfit/job/nanotrasen/cargo_tech
name = "Nanotrasen - Cargo Tech"
jobtype = /datum/job/cargo_tech
@@ -428,126 +336,264 @@
belt = /obj/item/pda/cargo
ears = /obj/item/radio/headset/headset_cargo
- uniform = /obj/item/clothing/under/rank/cargo/tech
+ head = /obj/item/clothing/head/nanotrasen/cap/supply
+ uniform = /obj/item/clothing/under/nanotrasen/supply
dcoat = /obj/item/clothing/suit/hooded/wintercoat/cargo
backpack_contents = list(/obj/item/modular_computer/tablet/preset/cargo=1)
-// Atmos Tech
+// Medical //
-/datum/outfit/job/nanotrasen/atmos
- name = "Nanotrasen - Atmos Tech"
- jobtype = /datum/job/atmos
- job_icon = "atmospherictechnician"
+// Medical Doctor
+/datum/outfit/job/nanotrasen/doctor
+ name = "Nanotrasen - Medical Doctor"
+ job_icon = "medicaldoctor"
+ jobtype = /datum/job/doctor
- belt = /obj/item/storage/belt/utility/atmostech
- ears = /obj/item/radio/headset/headset_eng
- uniform = /obj/item/clothing/under/rank/engineering/atmospheric_technician
- alt_suit = /obj/item/clothing/suit/hazardvest
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/engineering
+ belt = /obj/item/pda/medical
+ ears = /obj/item/radio/headset/headset_med
+ head = /obj/item/clothing/head/nanotrasen/surgical
+ uniform = /obj/item/clothing/under/nanotrasen/medical
+ shoes = /obj/item/clothing/shoes/sneakers/white
+ suit = /obj/item/clothing/suit/nanotrasen/medical_smock
+ alt_suit = /obj/item/clothing/suit/toggle/labcoat/nanotrasen
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/medical
- backpack = /obj/item/storage/backpack/industrial
- satchel = /obj/item/storage/backpack/satchel/eng
- duffelbag = /obj/item/storage/backpack/duffelbag/engineering
- courierbag = /obj/item/storage/backpack/messenger/engi
- box = /obj/item/storage/box/survival/engineer
- backpack_contents = list(/obj/item/modular_computer/tablet/preset/advanced=1)
+ backpack = /obj/item/storage/backpack/medic
+ satchel = /obj/item/storage/backpack/satchel/med
+ duffelbag = /obj/item/storage/backpack/duffelbag/med
+ courierbag = /obj/item/storage/backpack/messenger/med
+ box = /obj/item/storage/box/survival/medical
-// Scientist
+// Paramedic
+/datum/outfit/job/nanotrasen/paramedic
+ name = "Nanotrasen - Paramedic"
+ jobtype = /datum/job/paramedic
+ job_icon = "paramedic"
+
+ ears = /obj/item/radio/headset/headset_med
+ uniform = /obj/item/clothing/under/nanotrasen/medical/paramedic
+ head = /obj/item/clothing/head/nanotrasen/cap/medical
+ shoes = /obj/item/clothing/shoes/sneakers/blue
+ suit = /obj/item/clothing/suit/toggle/labcoat/nanotrasen/paramedic
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/medical/paramedic
+ gloves = /obj/item/clothing/gloves/color/latex/nitrile
+ id = /obj/item/card/id
+
+ backpack_contents = list(/obj/item/roller=1)
+
+ backpack = /obj/item/storage/backpack/medic
+ satchel = /obj/item/storage/backpack/satchel/med
+ duffelbag = /obj/item/storage/backpack/duffelbag/med
+ courierbag = /obj/item/storage/backpack/messenger/para
+ box = /obj/item/storage/box/survival/medical
+
+ chameleon_extras = /obj/item/gun/syringe
+
+// Civilian //
+
+// Assistant
+/datum/outfit/job/nanotrasen/assistant
+ name = "Nanotrasen - Assistant"
+ jobtype = /datum/job/assistant
+ job_icon = "assistant"
+
+ uniform = /obj/item/clothing/under/nanotrasen
+ shoes = /obj/item/clothing/shoes/sneakers/black
+ belt = /obj/item/pda
+// Lawyer
+/datum/outfit/job/nanotrasen/lawyer
+ name = "Nanotrasen - Lawyer"
+ job_icon = "lawyer"
+ jobtype = /datum/job/lawyer
+
+ ears = /obj/item/radio/headset/headset_srvsec
+ uniform = /obj/item/clothing/under/nanotrasen/affairs
+ suit = /obj/item/clothing/suit/nanotrasen/suitjacket
+ shoes = /obj/item/clothing/shoes/laceup
+ l_hand = /obj/item/storage/briefcase/lawyer
+ l_pocket = /obj/item/laser_pointer
+ r_pocket = /obj/item/clothing/accessory/lawyers_badge
+
+ chameleon_extras = /obj/item/stamp/law
+
+// Corp. Rep
+/datum/outfit/job/nanotrasen/lawyer/corporaterepresentative
+ name = "Nanotrasen - Corporate Representative"
+ id_assignment = "Corporate Representative"
+ job_icon = "nanotrasen"
+
+ uniform = /obj/item/clothing/under/rank/command/head_of_personnel/suit
+ suit = null
+ ears = /obj/item/radio/headset/headset_cent
+ l_hand = /obj/item/clipboard
+ r_pocket = /obj/item/pen/fountain
+
+// Science //
+
+// Scientist
/datum/outfit/job/nanotrasen/scientist
name = "Nanotrasen - Scientist"
jobtype = /datum/job/scientist
job_icon = "scientist"
ears = /obj/item/radio/headset/headset_sci
- uniform = /obj/item/clothing/under/rank/rnd/scientist
+ uniform = /obj/item/clothing/under/nanotrasen/science
shoes = /obj/item/clothing/shoes/sneakers/white
- suit = /obj/item/clothing/suit/toggle/labcoat/science
+ suit = /obj/item/clothing/suit/toggle/labcoat/nanotrasen
dcoat = /obj/item/clothing/suit/hooded/wintercoat/science
backpack = /obj/item/storage/backpack/science
satchel = /obj/item/storage/backpack/satchel/tox
courierbag = /obj/item/storage/backpack/messenger/tox
-// Brig Physician
+// Roboticist
+/datum/outfit/job/nanotrasen/roboticist
+ name = "Nanotrasen - Roboticist"
+ id_assignment = "Roboticist"
+ job_icon = "roboticist"
+ jobtype = /datum/job/roboticist
-/datum/outfit/job/nanotrasen/brig_phys
- name = "Nanotrasen - Brig Physician"
- jobtype = /datum/job/brig_phys
- job_icon = "brigphysician"
+ uniform = /obj/item/clothing/under/nanotrasen/science/robotics
+ suit = /obj/item/clothing/suit/toggle/labcoat/nanotrasen
+ ears = /obj/item/radio/headset/nanotrasen
+ glasses = /obj/item/clothing/glasses/welding
- ears = /obj/item/radio/headset/headset_medsec/alt
- uniform = /obj/item/clothing/under/rank/security/brig_phys/nt
+ backpack_contents = list(/obj/item/weldingtool/hugetank)
+
+// Pilot. idk
+/datum/outfit/job/nanotrasen/pilot
+ name = "Nanotrasen - Pilot"
+ id_assignment = "Pilot"
+
+ uniform = /obj/item/clothing/under/rank/security/officer/military
+ suit = /obj/item/clothing/suit/jacket/leather/duster
+ glasses = /obj/item/clothing/glasses/hud/spacecop
+ accessory = /obj/item/clothing/accessory/holster
+ head = /obj/item/clothing/head/beret/command
+
+// Mech Pilot
+/datum/outfit/job/nanotrasen/security/mech_pilot
+ name = "Nanotrasen - Mech Pilot"
+ id_assignment = "Mech Pilot"
+
+ uniform = /obj/item/clothing/under/rank/security/officer/military/eng
+ head = /obj/item/clothing/head/beret/sec/officer
+ suit = /obj/item/clothing/suit/armor/vest/bulletproof
+ backpack_contents = list(/obj/item/radio, /obj/item/flashlight/seclite)
+
+// LP - for Ranger ship //
+
+/datum/outfit/job/nanotrasen/captain/lp
+ name = "Nanotrasen - Loss Prevention Lieutenant"
+ id_assignment = "Lieutenant"
+
+ implants = list(/obj/item/implant/mindshield)
+ ears = /obj/item/radio/headset/nanotrasen/alt/captain
+ id = /obj/item/card/id/lplieu
+ belt = /obj/item/pda/captain
+ gloves = /obj/item/clothing/gloves/color/black
+ uniform = /obj/item/clothing/under/rank/security/head_of_security/alt/lp
+ alt_uniform = /obj/item/clothing/under/rank/security/head_of_security/alt/skirt/lp
+ dcoat = /obj/item/clothing/suit/jacket
shoes = /obj/item/clothing/shoes/jackboots
- glasses = /obj/item/clothing/glasses/hud/health/sunglasses
- suit = /obj/item/clothing/suit/toggle/labcoat/brig_phys
+ head = /obj/item/clothing/head/beret/command
+
+ satchel = /obj/item/storage/backpack/satchel/cap
+ duffelbag = /obj/item/storage/backpack/duffelbag/captain
+ courierbag = /obj/item/storage/backpack/messenger/com
+
+/datum/outfit/job/nanotrasen/security/lp
+ name = "Nanotrasen - LP Security Specialist"
+ id_assignment = "Security Specialist"
+
+ implants = list(/obj/item/implant/mindshield)
+ ears = /obj/item/radio/headset/nanotrasen/alt/captain
+ id = /obj/item/card/id/lpsec
+ belt = /obj/item/pda/security
+ gloves = /obj/item/clothing/gloves/color/black
+ uniform = /obj/item/clothing/under/rank/security/head_of_security/nt/lp
+ alt_uniform = /obj/item/clothing/under/rank/security/head_of_security/nt/skirt/lp
dcoat = /obj/item/clothing/suit/hooded/wintercoat/security
- head = /obj/item/clothing/head/soft/sec/brig_phys
+ shoes = /obj/item/clothing/shoes/jackboots
+ head = /obj/item/clothing/head/beret/sec
+
+ satchel = /obj/item/storage/backpack/satchel/sec
+ duffelbag = /obj/item/storage/backpack/duffelbag/sec
+ courierbag = /obj/item/storage/backpack/messenger/sec
+
+/datum/outfit/job/nanotrasen/engineer/lp
+ name = "Nanotrasen - LP Engineering Specialist"
+
implants = list(/obj/item/implant/mindshield)
+ ears = /obj/item/radio/headset/nanotrasen/alt/captain
+ id = /obj/item/card/id/lpengie
+ gloves = /obj/item/clothing/gloves/color/yellow
+ uniform = /obj/item/clothing/under/rank/engineering/engineer/nt/lp
+ alt_uniform = /obj/item/clothing/under/rank/engineering/engineer/nt/skirt/lp
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/engineering
+ shoes = /obj/item/clothing/shoes/jackboots
+ head = /obj/item/clothing/head/beret/eng
-// Paramedic
+ satchel = /obj/item/storage/backpack/satchel/eng
+ duffelbag = /obj/item/storage/backpack/duffelbag/engineering
+ courierbag = /obj/item/storage/backpack/messenger/engi
-/datum/outfit/job/nanotrasen/paramedic
- name = "Nanotrasen - Paramedic"
- jobtype = /datum/job/paramedic
- job_icon = "paramedic"
+/datum/outfit/job/nanotrasen/doctor/lp
+ name = "Nanotrasen - LP Medical Specialist"
+ id_assignment = "Medical Specialist"
- ears = /obj/item/radio/headset/headset_med
- uniform = /obj/item/clothing/under/rank/medical/paramedic
- head = /obj/item/clothing/head/soft/paramedic
- shoes = /obj/item/clothing/shoes/sneakers/blue
- suit = /obj/item/clothing/suit/toggle/labcoat/paramedic
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/medical/paramedic
+ implants = list(/obj/item/implant/mindshield)
+ ears = /obj/item/radio/headset/nanotrasen/alt/captain
+ id = /obj/item/card/id/lpmed
+ belt = /obj/item/pda/medical
gloves = /obj/item/clothing/gloves/color/latex/nitrile
- id = /obj/item/card/id
- backpack_contents = list(/obj/item/roller=1)
+ uniform = /obj/item/clothing/under/rank/medical/paramedic/lp
+ alt_uniform = /obj/item/clothing/under/rank/medical/paramedic/skirt/lp
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/medical
+ shoes = /obj/item/clothing/shoes/sneakers/white
+ head = /obj/item/clothing/head/beret/med
- backpack = /obj/item/storage/backpack/medic
satchel = /obj/item/storage/backpack/satchel/med
duffelbag = /obj/item/storage/backpack/duffelbag/med
- courierbag = /obj/item/storage/backpack/messenger/para
+ courierbag = /obj/item/storage/backpack/messenger/med
box = /obj/item/storage/box/survival/medical
- chameleon_extras = /obj/item/gun/syringe
+// ERT //
-// Quartermaster
-
-/datum/outfit/job/nanotrasen/quartermaster
- name = "Nanotrasen - Quartermaster"
- jobtype = /datum/job/qm
- job_icon = "quartermaster"
-
- ears = /obj/item/radio/headset/headset_cargo
- uniform = /obj/item/clothing/under/rank/cargo/qm
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/cargo
- shoes = /obj/item/clothing/shoes/sneakers/brown
- glasses = /obj/item/clothing/glasses/sunglasses
- l_hand = /obj/item/clipboard
- backpack_contents = list(/obj/item/modular_computer/tablet/preset/cargo=1)
+/datum/outfit/job/nanotrasen/security/ert
+ name = "Nanotrasen - ERT Officer"
- chameleon_extras = /obj/item/stamp/qm
+ uniform = /obj/item/clothing/under/rank/security/officer/camo
+ head = null
+ backpack = /obj/item/storage/backpack/ert/security
+ belt = /obj/item/storage/belt/military
+ id = /obj/item/card/id/ert/security
+ r_pocket = /obj/item/kitchen/knife/combat/survival
+ backpack_contents = list(/obj/item/radio, /obj/item/flashlight/seclite)
-/datum/outfit/job/nanotrasen/miner
- name = "Nanotrasen - Miner"
- jobtype = /datum/job/mining
- job_icon = "shaftminer"
+/datum/outfit/job/nanotrasen/security/ert/engi
+ name = "Nanotrasen - ERT Engineering Officer"
- ears = /obj/item/radio/headset/headset_cargo/mining
- shoes = /obj/item/clothing/shoes/workboots/mining
- gloves = /obj/item/clothing/gloves/explorer
- uniform = /obj/item/clothing/under/rank/cargo/miner/lavaland
- suit = /obj/item/clothing/suit/hazardvest
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/miner
- r_pocket = /obj/item/storage/bag/ore
- backpack_contents = list(
- /obj/item/flashlight/seclite=1,\
- /obj/item/kitchen/knife/combat/survival=1,\
- /obj/item/stack/marker_beacon/ten=1,\
- /obj/item/radio/weather_monitor=1)
+ uniform = /obj/item/clothing/under/rank/security/officer/camo
+ head = null
+ backpack = /obj/item/storage/backpack/ert/engineer
+ belt = /obj/item/storage/belt/utility/full/ert
+ id = /obj/item/card/id/ert/security
+ r_pocket = /obj/item/kitchen/knife/combat/survival
+ backpack_contents = list(/obj/item/radio, /obj/item/flashlight/seclite)
+ accessory = /obj/item/clothing/accessory/armband/engine
+ glasses = /obj/item/clothing/glasses/hud/diagnostic/sunglasses
- backpack = /obj/item/storage/backpack/explorer
- satchel = /obj/item/storage/backpack/satchel/explorer
- duffelbag = /obj/item/storage/backpack/duffelbag
- box = /obj/item/storage/box/survival/mining
+/datum/outfit/job/nanotrasen/security/ert/med
+ name = "Nanotrasen - ERT Medical Officer"
- chameleon_extras = /obj/item/gun/energy/kinetic_accelerator
+ uniform = /obj/item/clothing/under/rank/security/officer/camo
+ head = /obj/item/clothing/head/beret/med
+ backpack = /obj/item/storage/backpack/ert/medical
+ belt = /obj/item/storage/belt/medical/webbing/paramedic
+ id = /obj/item/card/id/ert/security
+ r_pocket = /obj/item/kitchen/knife/combat/survival
+ backpack_contents = list(/obj/item/radio, /obj/item/flashlight/seclite)
+ accessory = /obj/item/clothing/accessory/armband/med
+ glasses = /obj/item/clothing/glasses/hud/health/night
diff --git a/code/modules/clothing/outfits/factions/roumain.dm b/code/modules/clothing/outfits/factions/roumain.dm
index 424827e69010..fe31fddd9041 100644
--- a/code/modules/clothing/outfits/factions/roumain.dm
+++ b/code/modules/clothing/outfits/factions/roumain.dm
@@ -19,7 +19,7 @@
name = "Saint-Roumain Militia - Shadow"
id_assignment = "Shadow"
jobtype = /datum/job/assistant
- job_icon = "assistant"
+ job_icon = "srm_shadow"
uniform = /obj/item/clothing/under/suit/roumain
alt_uniform = null
@@ -33,14 +33,40 @@
/datum/outfit/job/roumain/captain
name = "Saint-Roumain Militia - Hunter Montagne"
id_assignment = "Hunter Montagne"
- job_icon = "captain"
+ job_icon = "srm_montagne"
jobtype = /datum/job/captain
+ ears = /obj/item/radio/headset/headset_com/alt
+ uniform = /obj/item/clothing/under/suit/roumain
+ shoes = /obj/item/clothing/shoes/workboots/mining
+ suit = /obj/item/clothing/suit/armor/roumain/montagne
+ head = /obj/item/clothing/head/cowboy/sec/roumain/montagne
+ id = /obj/item/card/id/gold
+
+ duffelbag = /obj/item/storage/backpack/cultpack
+ courierbag = /obj/item/storage/backpack/cultpack
+ backpack = /obj/item/storage/backpack/cultpack
+ satchel = /obj/item/storage/backpack/cultpack
+
+ backpack_contents = list(/obj/item/book/manual/srmlore=1,
+ /obj/item/stamp/chap = 1,
+ /obj/item/melee/classic_baton/telescopic=1,
+ )
+ chameleon_extras = null
+
+// Second-In-Command
+
+/datum/outfit/job/roumain/hop
+ name = "Saint-Roumain Militia - Hunter Colligne"
+ id_assignment = "Hunter Colligne"
+ job_icon = "srm_colligne"
+ jobtype = /datum/job/head_of_personnel
+
ears = /obj/item/radio/headset/headset_com
uniform = /obj/item/clothing/under/suit/roumain
shoes = /obj/item/clothing/shoes/workboots/mining
- suit = /obj/item/clothing/suit/armor/hos/roumain/montagne
- head = /obj/item/clothing/head/HoS/cowboy/montagne
+ suit = /obj/item/clothing/suit/armor/roumain/colligne
+ head = /obj/item/clothing/head/cowboy/sec/roumain/colligne
id = /obj/item/card/id/silver
duffelbag = /obj/item/storage/backpack/cultpack
@@ -58,7 +84,7 @@
name = "Saint-Roumain Militia - Hunter"
id_assignment = "Hunter"
jobtype = /datum/job/officer
- job_icon = "securityofficer"
+ job_icon = "hsrm_hunter"
uniform = /obj/item/clothing/under/suit/roumain
alt_uniform = null
@@ -74,12 +100,34 @@
backpack_contents = null
+// engineer
+
+/datum/outfit/job/roumain/engineer
+ name = "Saint-Roumain Militia - Machinist"
+ id_assignment = "Machinist"
+ job_icon = "srm_machinist"
+ jobtype = /datum/job/engineer
+
+ uniform = /obj/item/clothing/under/suit/roumain
+ alt_uniform = null
+ shoes = /obj/item/clothing/shoes/workboots/mining
+ belt = /obj/item/storage/belt/utility/full/engi
+ suit = /obj/item/clothing/suit/hazardvest/roumain
+ head = /obj/item/clothing/head/cowboy/sec/roumain/machinist
+ accessory = /obj/item/clothing/accessory/waistcoat/roumain
+ gloves = null
+
+ backpack = /obj/item/storage/backpack
+ satchel = /obj/item/storage/backpack/satchel
+ duffelbag = /obj/item/storage/backpack/duffelbag
+ courierbag = /obj/item/storage/backpack/messenger
+
// Medical Doctor
/datum/outfit/job/roumain/doctor
name = "Saint-Roumain Militia - Hunter Doctor"
id_assignment = "Hunter Doctor"
- job_icon = "medicaldoctor"
+ job_icon = "srm_doctor"
jobtype = /datum/job/doctor
uniform = /obj/item/clothing/under/suit/roumain
@@ -94,3 +142,27 @@
satchel = /obj/item/storage/backpack/satchel
duffelbag = /obj/item/storage/backpack/duffelbag
courierbag = /obj/item/storage/backpack/messenger
+
+// Chaplain
+
+/datum/outfit/job/roumain/flamebearer
+ name = "Saint-Roumain Militia - Flamebearer"
+ id_assignment = "Flamebearer"
+ job_icon = "srm_flamebearer"
+ jobtype = /datum/job/chaplain
+
+ uniform = /obj/item/clothing/under/suit/roumain
+ alt_uniform = null
+ shoes = /obj/item/clothing/shoes/workboots/mining
+ suit = /obj/item/clothing/suit/armor/roumain/flamebearer
+ head = /obj/item/clothing/head/cowboy/sec/roumain/flamebearer
+ gloves = null
+
+ duffelbag = /obj/item/storage/backpack/cultpack
+ courierbag = /obj/item/storage/backpack/cultpack
+ backpack = /obj/item/storage/backpack/cultpack
+ satchel = /obj/item/storage/backpack/cultpack
+
+ backpack_contents = list(/obj/item/book/manual/srmlore=1,
+ /obj/item/stamp/chap = 1,
+ )
diff --git a/code/modules/clothing/outfits/factions/syndicate.dm b/code/modules/clothing/outfits/factions/syndicate.dm
index 44199ac361a3..4dbbe0826e21 100644
--- a/code/modules/clothing/outfits/factions/syndicate.dm
+++ b/code/modules/clothing/outfits/factions/syndicate.dm
@@ -22,10 +22,11 @@
//generates a codename and assigns syndicate access, used in the twinkleshine.
/datum/outfit/job/syndicate/proc/assign_codename(mob/living/carbon/human/H)
- var/obj/item/card/id/I = H.wear_id
- I.registered_name = pick(GLOB.twinkle_names) + "-" + num2text(rand(1, 12)) // squidquest real
- I.access |= list(ACCESS_SYNDICATE)
- I.update_label()
+ var/obj/item/card/id/I = H.get_idcard()
+ if(I)
+ I.registered_name = pick(GLOB.twinkle_names) + "-" + num2text(rand(1, 12)) // squidquest real
+ I.access |= list(ACCESS_SYNDICATE)
+ I.update_label()
//and now, for the Assistants
@@ -54,10 +55,20 @@
box = /obj/item/storage/box/survival/syndie
/datum/outfit/job/syndicate/assistant/gorlex
- name = "Syndicate - Junior Agent (Gorlex Marauders)"
+ name = "Syndicate - Junior Agent (Hardliner)"
- uniform = /obj/item/clothing/under/syndicate/gorlex
- alt_uniform = /obj/item/clothing/under/syndicate
+ uniform = /obj/item/clothing/under/syndicate/hardliners
+ alt_uniform = /obj/item/clothing/under/syndicate/hardliners/jumpsuit
+
+/datum/outfit/job/syndicate/assistant/ngr
+ name = "Syndicate - Initiate (New Gorlex Republic)"
+ id_assignment = "Initiate"
+
+ head = /obj/item/clothing/head/ngr
+ uniform = /obj/item/clothing/under/syndicate/ngr
+ shoes = /obj/item/clothing/shoes/combat
+
+ alt_uniform = null
/datum/outfit/job/syndicate/assistant/gec
name = "Syndicate - Deckhand (GEC)"
@@ -189,11 +200,33 @@
/datum/outfit/job/syndicate/bartender/post_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
- var/obj/item/card/id/W = H.wear_id
+ var/obj/item/card/id/W = H.get_idcard()
if(H.age < AGE_MINOR)
W.registered_age = AGE_MINOR
to_chat(H, "You're not technically old enough to access or serve alcohol, but your ID has been discreetly modified to display your age as [AGE_MINOR]. Try to keep that a secret!")
+/datum/outfit/job/syndicate/bartender/suns
+ name = "Syndicate - Student Mixologist (SUNS)"
+ id_assignment = "Student Mixologist"
+
+ uniform = /obj/item/clothing/under/syndicate/suns/uniform2
+ alt_uniform = /obj/item/clothing/under/syndicate/suns/alt
+ mask = /obj/item/clothing/mask/breath/suns
+ suit = null
+ belt = null
+ head = null
+ shoes = /obj/item/clothing/shoes/laceup/suns
+ gloves = null
+ ears = null
+ accessory = /obj/item/clothing/accessory/waistcoat/suns/poof
+
+ backpack = /obj/item/storage/backpack
+ satchel = /obj/item/storage/backpack/satchel
+ duffelbag = /obj/item/storage/backpack/duffelbag
+ courierbag = /obj/item/storage/backpack/messenger
+
+ backpack_contents = null
+
/datum/outfit/job/syndicate/bartender/twink
name = "Syndicate - Bartender (Twinkleshine, Donk)"
@@ -296,11 +329,20 @@
/datum/outfit/job/syndicate/captain/gorlex
- name = "Syndicate - Captain (Gorlex Marauders)"
- uniform = /obj/item/clothing/under/syndicate/ngr/officer
+ name = "Syndicate - Captain (Hardliner)"
+ uniform = /obj/item/clothing/under/syndicate/hardliners/officer
+
+ head = /obj/item/clothing/head/hardliners/peaked
+ suit = /obj/item/clothing/suit/toggle/armor/vest/hardliners
+ shoes = /obj/item/clothing/shoes/combat
+
+/datum/outfit/job/syndicate/captain/ngr
+ name = "Syndicate - Captain (New Gorlex Republic)"
- head = /obj/item/clothing/head/ngrcap
- suit = /obj/item/clothing/suit/armor/vest/capcarapace/ngr_captain
+ uniform = /obj/item/clothing/under/syndicate/ngr/officer
+ head = /obj/item/clothing/head/ngr/peaked
+ suit = /obj/item/clothing/suit/armor/ngr/captain
+ shoes = /obj/item/clothing/shoes/combat
/datum/outfit/job/syndicate/captain/cybersun
name = "Syndicate - Captain (Cybersun)"
@@ -410,17 +452,19 @@
id = /obj/item/card/id/syndicate_command/captain_id
gloves = /obj/item/clothing/gloves/combat
-/datum/outfit/job/syndicate/ce/gorlex
- name = "Syndicate - Foreman (Gorlex Marauders)"
+/datum/outfit/job/syndicate/ce/ngr
+ name = "Syndicate - Foreman (New Gorlex Republic)"
+ head = /obj/item/clothing/head/hardhat/ngr/foreman
ears = /obj/item/radio/headset/syndicate/alt
- uniform = /obj/item/clothing/under/syndicate/gorlex
+ uniform = /obj/item/clothing/under/syndicate/ngr/officer
alt_uniform = null
- suit = /obj/item/clothing/suit/toggle/hazard
+ suit = /obj/item/clothing/suit/ngr
alt_suit = null
- shoes = /obj/item/clothing/shoes/jackboots
+ shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
+
//Chief Medical Officer
/datum/outfit/job/syndicate/cmo
@@ -535,9 +579,28 @@
backpack_contents = list(/obj/item/melee/baton/loaded=1)
/datum/outfit/job/syndicate/hos/gorlex
- name = "Syndicate - Sergeant (Gorlex)"
+ name = "Syndicate - Sergeant (Hardliner)"
id_assignment = "Sergeant"
+ uniform = /obj/item/clothing/under/syndicate/hardliners/officer
+ head = /obj/item/clothing/head/hardliners/peaked
+ suit = /obj/item/clothing/suit/armor/hardliners/sergeant
+ id = /obj/item/card/id/syndicate_command/crew_id
+ shoes = /obj/item/clothing/shoes/combat
+ suit_store = /obj/item/gun/ballistic/automatic/pistol/syndicate
+
+/datum/outfit/job/syndicate/hos/ngr
+ name = "Syndicate - Lieutenant (New Gorlex Republic)"
+ id_assignment = "Lieutenant"
+
+ uniform = /obj/item/clothing/under/syndicate/ngr/officer
+ head = /obj/item/clothing/head/ngr/peaked
+ suit = /obj/item/clothing/suit/armor/ngr/lieutenant
+ id = /obj/item/card/id/syndicate_command/crew_id
+ shoes = /obj/item/clothing/shoes/combat
+ suit_store = /obj/item/gun/ballistic/automatic/pistol/syndicate
+
+
/datum/outfit/job/syndicate/hos/twink
name = "Syndicate - Lieutenant (Twinkleshine, NGR)"
id_assignment = "Lieutenant"
@@ -644,13 +707,27 @@
uniform = /obj/item/clothing/under/syndicate/medic
accessory = /obj/item/clothing/accessory/armband/medblue
- shoes = /obj/item/clothing/shoes/jackboots
+ shoes = /obj/item/clothing/shoes/combat
/datum/outfit/job/syndicate/doctor/gorlex
- name = "Syndicate - Medical Doctor (Gorlex)"
+ name = "Syndicate - Medical Doctor (Hardliner)"
- uniform = /obj/item/clothing/under/syndicate/gorlex
- glasses = /obj/item/clothing/glasses/hud/health/prescription
+ uniform = /obj/item/clothing/under/syndicate/hardliners
+ head = /obj/item/clothing/head/hardliners
+ suit = /obj/item/clothing/suit/hardliners
+ glasses = /obj/item/clothing/glasses/hud/health
+ r_pocket = /obj/item/kitchen/knife/combat/survival
+ back = /obj/item/storage/backpack/duffelbag/syndie/med
+ id = /obj/item/card/id/syndicate_command/crew_id
+ backpack_contents = list(/obj/item/storage/box/survival/syndie=1, /obj/item/storage/firstaid/medical,)
+
+/datum/outfit/job/syndicate/doctor/ngr
+ name = "Syndicate - Medical Doctor (New Gorlex Republic)"
+
+ uniform = /obj/item/clothing/under/syndicate/ngr
+ head = /obj/item/clothing/head/ngr/surgical
+ suit = /obj/item/clothing/suit/ngr/smock
+ glasses = /obj/item/clothing/glasses/hud/health
r_pocket = /obj/item/kitchen/knife/combat/survival
back = /obj/item/storage/backpack/duffelbag/syndie/med
id = /obj/item/card/id/syndicate_command/crew_id
@@ -845,7 +922,47 @@
/datum/outfit/job/syndicate/security/gorlex
- name = "Syndicate - Assault Operative (Gorlex)"
+ name = "Syndicate - Trooper (Hardliner)"
+ id_assignment = "Trooper"
+ job_icon = "securityofficer"
+
+ uniform = /obj/item/clothing/under/syndicate/hardliners
+ belt = /obj/item/storage/belt/security/webbing/hardliners
+ suit = /obj/item/clothing/suit/armor/hardliners
+ gloves = /obj/item/clothing/gloves/color/black
+ head = /obj/item/clothing/head/helmet/hardliners
+ shoes = /obj/item/clothing/shoes/combat
+ l_pocket = /obj/item/restraints/handcuffs
+ r_pocket = /obj/item/assembly/flash/handheld
+
+/datum/outfit/job/syndicate/security/gorlex
+ name = "Syndicate - Pilot (Hardliner)"
+ id_assignment = "Pilot"
+ job_icon = "securityofficer"
+
+ head = /obj/item/clothing/head/helmet/hardliners/swat
+
+/datum/outfit/job/syndicate/security/ngr
+ name = "Syndicate - Operative (New Gorlex Republic)"
+ id_assignment = "Operative"
+ job_icon = "securityofficer"
+
+ uniform = /obj/item/clothing/under/syndicate/ngr
+ belt = /obj/item/storage/belt/security/webbing/ngr
+ suit = /obj/item/clothing/suit/armor/ngr
+ gloves = /obj/item/clothing/gloves/color/black
+ head = /obj/item/clothing/head/helmet/ngr
+ shoes = /obj/item/clothing/shoes/combat
+ l_pocket = /obj/item/restraints/handcuffs
+ r_pocket = /obj/item/assembly/flash/handheld
+
+/datum/outfit/job/syndicate/security/ngr/pilot
+ name = "Syndicate - Pilot (New Gorlex Republic)"
+ id_assignment = "Pilot"
+ job_icon = "securityofficer"
+
+ uniform = /obj/item/clothing/under/syndicate/ngr/fatigues
+ head = /obj/item/clothing/head/helmet/ngr/swat
/datum/outfit/job/syndicate/security/twink
name = "Syndicate - Operative (Twinkleshine)"
@@ -914,10 +1031,24 @@
/obj/item/stack/marker_beacon/ten=1)
/datum/outfit/job/syndicate/miner/gorlex
- name = "Syndicate - Wrecker (Gorlex Marauders)"
+ name = "Syndicate - Wrecker (Hardliner)"
id_assignment = "Wrecker"
- uniform = /obj/item/clothing/under/syndicate/gorlex
+ head = /obj/item/clothing/head/hardhat/hardliners
+ suit = /obj/item/clothing/suit/hazardvest/hardliners
+ uniform = /obj/item/clothing/under/syndicate/hardliners/jumpsuit
+ accessory = /obj/item/clothing/accessory/armband/cargo
+ shoes = /obj/item/clothing/shoes/workboots
+ ears = /obj/item/radio/headset/alt
+
+/datum/outfit/job/syndicate/miner/ngr
+ name = "Syndicate - Wrecker (New Gorlex Republic)"
+ id_assignment = "Wrecker"
+
+ head = /obj/item/clothing/head/hardhat/ngr
+ suit = /obj/item/clothing/suit/hazardvest/ngr
+ uniform = /obj/item/clothing/under/syndicate/ngr/jumpsuit
+ accessory = /obj/item/clothing/accessory/armband/cargo
shoes = /obj/item/clothing/shoes/workboots
ears = /obj/item/radio/headset/alt
@@ -1005,10 +1136,22 @@
id = /obj/item/card/id/syndicate_command/crew_id
/datum/outfit/job/syndicate/engineer/gorlex
- name = "Syndicate - Mechanic (Gorlex Marauders)"
+ name = "Syndicate - Mechanic (Hardliner)"
id_assignment = "Mechanic"
- uniform = /obj/item/clothing/under/syndicate/gorlex
+ head = /obj/item/clothing/head/hardhat/hardliners
+ suit = /obj/item/clothing/suit/hazardvest/hardliners
+ uniform = /obj/item/clothing/under/syndicate/hardliners
+ shoes = /obj/item/clothing/shoes/workboots
+ glasses = null
+
+/datum/outfit/job/syndicate/engineer/ngr
+ name = "Syndicate - Mechanic (New Gorlex Republic)"
+ id_assignment = "Mechanic"
+
+ head = /obj/item/clothing/head/hardhat/ngr
+ suit = /obj/item/clothing/suit/hazardvest/ngr
+ uniform = /obj/item/clothing/under/syndicate/ngr
shoes = /obj/item/clothing/shoes/workboots
glasses = null
diff --git a/code/modules/clothing/outfits/plasmaman.dm b/code/modules/clothing/outfits/plasmaman.dm
index ba38a4a9240b..05b8c0e1a42c 100644
--- a/code/modules/clothing/outfits/plasmaman.dm
+++ b/code/modules/clothing/outfits/plasmaman.dm
@@ -217,3 +217,9 @@
head = /obj/item/clothing/head/helmet/space/plasmaman/solgov
uniform = /obj/item/clothing/under/plasmaman/solgov
gloves = /obj/item/clothing/gloves/color/plasmaman/white
+
+/datum/outfit/plasmaman/ngr
+ name = "Plasmangr"
+ head = /obj/item/clothing/head/helmet/space/plasmaman/ngr
+ uniform= /obj/item/clothing/under/plasmaman/ngr
+ gloves = /obj/item/clothing/gloves/color/plasmaman/black
diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm
index 7a848b9ca330..100cc7ff0f52 100644
--- a/code/modules/clothing/outfits/standard.dm
+++ b/code/modules/clothing/outfits/standard.dm
@@ -169,7 +169,7 @@
r_pocket = /obj/item/shield/energy
suit_store = /obj/item/tank/internals/emergency_oxygen/double
belt = /obj/item/gun/ballistic/revolver/mateba
- r_hand = /obj/item/gun/energy/pulse/loyalpin
+ r_hand = /obj/item/gun/energy/pulse
id = /obj/item/card/id/ert/deathsquad
ears = /obj/item/radio/headset/headset_cent/alt
@@ -226,8 +226,6 @@
backpack_contents = list(
/obj/item/melee/transforming/energy/axe=1,\
/obj/item/storage/part_replacer/bluespace/tier4=1,\
- /obj/item/gun/magic/wand/resurrection/debug=1,\
- /obj/item/gun/magic/wand/death/debug=1,\
/obj/item/debug/human_spawner=1,\
/obj/item/debug/omnitool=1
)
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index 7b2ded27e269..336ac43c7d4d 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -134,9 +134,12 @@
return
if(user == loc && tied != SHOES_TIED) // if they're our own shoes, go tie-wards
+ if(DOING_INTERACTION_WITH_TARGET(user, our_guy))
+ to_chat(user, span_warning("You're already interacting with [src]!"))
+ return
user.visible_message("[user] begins [tied ? "unknotting" : "tying"] the laces of [user.p_their()] [src.name].", "You begin [tied ? "unknotting" : "tying"] the laces of your [src.name]...")
- if(do_after(user, lace_time, needhand=TRUE, target=our_guy, extra_checks=CALLBACK(src, PROC_REF(still_shoed), our_guy)))
+ if(do_after(user, lace_time, target = our_guy, extra_checks = CALLBACK(src, PROC_REF(still_shoed), our_guy)))
to_chat(user, "You [tied ? "unknot" : "tie"] the laces of your [src.name].")
if(tied == SHOES_UNTIED)
adjust_laces(SHOES_TIED, user)
@@ -151,13 +154,16 @@
if(tied == SHOES_KNOTTED)
to_chat(user, "The laces on [loc]'s [src.name] are already a hopelessly tangled mess!")
return
+ if(DOING_INTERACTION_WITH_TARGET(user, our_guy))
+ to_chat(user, span_warning("You're already interacting with [src]!"))
+ return
var/mod_time = lace_time
to_chat(user, "You quietly set to work [tied ? "untying" : "knotting"] [loc]'s [src.name]...")
if(HAS_TRAIT(user, TRAIT_CLUMSY)) // based clowns trained their whole lives for this
mod_time *= 0.75
- if(do_after(user, mod_time, needhand=TRUE, target=our_guy, extra_checks=CALLBACK(src, PROC_REF(still_shoed), our_guy)))
+ if(do_after(user, mod_time, target = our_guy, extra_checks = CALLBACK(src, PROC_REF(still_shoed), our_guy)))
to_chat(user, "You [tied ? "untie" : "knot"] the laces on [loc]'s [src.name].")
if(tied == SHOES_UNTIED)
adjust_laces(SHOES_KNOTTED, user)
@@ -232,8 +238,12 @@
/obj/item/clothing/shoes/attack_self(mob/user)
. = ..()
+ if(DOING_INTERACTION_WITH_TARGET(user, src))
+ to_chat(user, "You're already interacting with [src]!")
+ return
+
to_chat(user, "You begin [tied ? "untying" : "tying"] the laces on [src]...")
- if(do_after(user, lace_time, needhand=TRUE, target=src,extra_checks=CALLBACK(src, PROC_REF(still_shoed), user)))
+ if(do_after(user, lace_time, target = src,extra_checks = CALLBACK(src, PROC_REF(still_shoed), user)))
to_chat(user, "You [tied ? "untie" : "tie"] the laces on [src].")
adjust_laces(tied ? SHOES_TIED : SHOES_UNTIED, user)
diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm
index a09ea07a3250..4ed246a587be 100644
--- a/code/modules/clothing/shoes/bananashoes.dm
+++ b/code/modules/clothing/shoes/bananashoes.dm
@@ -16,7 +16,7 @@
/obj/item/clothing/shoes/clown_shoes/banana_shoes/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
- AddComponent(/datum/component/material_container, list(/datum/material/bananium), 200000, TRUE, /obj/item/stack)
+ AddComponent(/datum/component/material_container, list(/datum/material/hellstone), 200000, TRUE, /obj/item/stack)
AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 75, falloff_exponent = 20)
/obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action()
@@ -24,7 +24,7 @@
var/mob/wearer = loc
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
if(on && istype(wearer))
- if(bananium.get_material_amount(/datum/material/bananium) < 100)
+ if(bananium.get_material_amount(/datum/material/hellstone) < 100)
on = !on
if(!always_noslip)
clothing_flags &= ~NOSLIP
@@ -32,7 +32,7 @@
to_chat(loc, "You ran out of bananium!")
else
new /obj/item/grown/bananapeel/specialpeel(get_step(src,turn(wearer.dir, 180))) //honk
- bananium.use_amount_mat(100, /datum/material/bananium)
+ bananium.use_amount_mat(100, /datum/material/hellstone)
/obj/item/clothing/shoes/clown_shoes/banana_shoes/attack_self(mob/user)
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
@@ -48,7 +48,7 @@
/obj/item/clothing/shoes/clown_shoes/banana_shoes/ui_action_click(mob/user)
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
- if(bananium.get_material_amount(/datum/material/bananium))
+ if(bananium.get_material_amount(/datum/material/hellstone))
on = !on
update_appearance()
to_chat(user, "You [on ? "activate" : "deactivate"] the prototype shoes.")
diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm
index 4b19735b5f62..cb98f607089c 100644
--- a/code/modules/clothing/spacesuits/_spacesuits.dm
+++ b/code/modules/clothing/spacesuits/_spacesuits.dm
@@ -2,6 +2,8 @@
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
/obj/item/clothing/head/helmet/space
name = "space helmet"
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
icon_state = "spaceold"
desc = "A special helmet with solar UV shielding to protect your eyes from harmful rays."
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS //WS Port - Cit Internals
@@ -19,6 +21,8 @@
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
resistance_flags = NONE
dog_fashion = null
+ content_overlays = FALSE
+ pocket_storage_component_path = null
/obj/item/clothing/suit/space
name = "space suit"
@@ -36,7 +40,7 @@
slowdown = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
- cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS
+ cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 1ea5af9f1ea4..02fbb162892b 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -166,7 +166,7 @@
if(L.status)
to_chat(user, "This bulb is too damaged to use as a replacement!")
return
- if(do_after(user, 50, 1, src))
+ if(do_after(user, 50, src))
qdel(I)
helmet = new helmettype(src)
to_chat(user, "You have successfully repaired [src]'s helmet.")
@@ -444,47 +444,6 @@
combat_slowdown = 0.5
jetpack = null
-//2nd Battlegroup Syndie suit
-/obj/item/clothing/head/helmet/space/hardsuit/syndi/sbg
- name = "beige-red hardsuit helmet"
- desc = "A standardized dual-mode helmet derived from ICW-era advanced special operations helmets, its red partly replaced by beige. It is in EVA mode. Manufactured by Second Battlegroup."
- alt_desc = "A standardized dual-mode helmet derived from ICW-era advanced special operations helmets, its red partly replaced by beige. It is in combat mode. Manufactured by Second Battlegroup."
- icon_state = "hardsuit1-sbg"
- item_state = "hardsuit1-sbg"
- hardsuit_type = "sbg"
-
-/obj/item/clothing/suit/space/hardsuit/syndi/sbg
- name = "beige-red hardsuit"
- desc = "A standardized dual-mode hardsuit derived from ICW-era advanced special operations hardsuits, its red partly replaced by beige. It is in EVA mode. Manufactured by Second Battlegroup."
- alt_desc = "A standardized dual-mode hardsuit derived from ICW-era advanced special operations hardsuits, its red partly replaced by beige. It is in combat mode. Manufactured by the Second Battlegroup."
- icon_state = "hardsuit1-sbg"
- item_state = "hardsuit1-sbg"
- hardsuit_type = "sbg"
- helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/sbg
- lightweight = 1
- jetpack = null
-
-//Hardliner Syndie suit
-/obj/item/clothing/head/helmet/space/hardsuit/syndi/hl
- name = "white-red hardsuit helmet"
- desc = "An advanced dual-mode helmet derived from ICW-era advanced special operations helmets, its red partly replaced by white. It is in EVA mode. Manufactured by Second Battlegroup."
- alt_desc = "An advanced dual-mode helmet derived from ICW-era advanced special operations helmets, its red partly replaced by white. It is in combat mode. Manufactured by Second Battlegroup."
- icon_state = "hardsuit1-hl"
- item_state = "hardsuit1-hl"
- hardsuit_type = "hl"
-
-/obj/item/clothing/suit/space/hardsuit/syndi/hl
- name = "white-red hardsuit"
- desc = "An advanced dual-mode hardsuit derived from ICW-era advanced special operations hardsuits, its red partly replaced by white. It is in EVA mode. Manufactured by Second Battlegroup."
- alt_desc = "An advanced dual-mode hardsuit derived from ICW-era advanced special operations hardsuits, its red partly replaced by white. It is in combat mode. Manufactured by the Second Battlegroup."
- icon_state = "hardsuit1-hl"
- item_state = "hardsuit1-hl"
- hardsuit_type = "hl"
- helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/hl
- lightweight = 1
- jetpack = null
-
-
//Elite Syndie suit
/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite
name = "elite syndicate hardsuit helmet"
@@ -605,11 +564,6 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/wizard
-/obj/item/clothing/suit/space/hardsuit/wizard/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, TRUE, FALSE, FALSE, ITEM_SLOT_OCLOTHING, INFINITY, FALSE)
-
-
//Medical hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/medical
name = "medical hardsuit helmet"
@@ -1093,12 +1047,6 @@
armor = list("melee" = 35, "bullet" = 25, "laser" = 20,"energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
supports_variations = VOX_VARIATION
-/obj/item/clothing/head/helmet/space/hardsuit/security/independent/frontier
- name = "\improper Frontiersmen hardsuit helmet"
- desc = "An old hardsuit helmet based on a even older hardsuit helmet. Used prolifically by the Frontiersmen pirate fleet."
- icon_state = "hardsuit0-frontier"
- hardsuit_type = "frontier"
-
/obj/item/clothing/suit/space/hardsuit/security/independent
icon_state = "hardsuit-independent-sec"
name = "security hardsuit"
@@ -1110,13 +1058,6 @@
armor = list("melee" = 35, "bullet" = 25, "laser" = 20, "energy" = 40, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
supports_variations = VOX_VARIATION
-/obj/item/clothing/suit/space/hardsuit/security/independent/frontier
- name = "\improper Frontiersmen hardsuit"
- desc = "An old hardsuit based on a even older hardsuit. Used prolifically by the Frontiersmen pirate fleet."
- icon_state = "hardsuit_frontier"
- hardsuit_type = "hardsuit_frontier"
- helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/independent/frontier
-
//Mining
/obj/item/clothing/head/helmet/space/hardsuit/mining/independent
name = "mining hardsuit helmet"
@@ -1276,6 +1217,7 @@
item_state = "hardsuit_solgov"
armor = list("melee" = 50, "bullet" = 45, "laser" = 40, "energy" = 30, "bomb" = 60, "bio" = 100, "rad" = 60, "fire" = 90, "acid" = 75) //intentionally the fucking strong, this is master chief-tier armor //is this really what you call the strong?? is this the best solgov has to offer??????
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/solgov
+ allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
slowdown = 0
supports_variations = DIGITIGRADE_VARIATION
diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm
index e999caf7624b..67dc7ce529b3 100644
--- a/code/modules/clothing/spacesuits/miscellaneous.dm
+++ b/code/modules/clothing/spacesuits/miscellaneous.dm
@@ -281,28 +281,6 @@ Contains:
flash_protect = FLASH_PROTECTION_NONE
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65)
-/obj/item/clothing/head/helmet/space/freedom
- name = "eagle helmet"
- desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle."
- icon_state = "griffinhat"
- item_state = "griffinhat"
- armor = list("melee" = 20, "bullet" = 40, "laser" = 30, "energy" = 40, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
- strip_delay = 130
- max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
- resistance_flags = ACID_PROOF | FIRE_PROOF
-
-/obj/item/clothing/suit/space/freedom
- name = "eagle suit"
- desc = "An advanced, light suit, fabricated from a mixture of synthetic feathers and space-resistant material. A gun holster appears to be integrated into the suit and the wings appear to be stuck in 'freedom' mode."
- icon_state = "freedom"
- item_state = "freedom"
- allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
- armor = list("melee" = 20, "bullet" = 40, "laser" = 30,"energy" = 40, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80)
- strip_delay = 130
- max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
- resistance_flags = ACID_PROOF | FIRE_PROOF
- slowdown = 0
-
//Carpsuit, bestsuit, lovesuit
/obj/item/clothing/head/helmet/space/hardsuit/carp
name = "carp helmet"
@@ -354,10 +332,6 @@ Contains:
actions_types = list()
resistance_flags = FIRE_PROOF
-/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_OCLOTHING)
-
/obj/item/clothing/suit/space/hardsuit/ert/paranormal
name = "paranormal response team hardsuit"
desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats."
@@ -367,10 +341,6 @@ Contains:
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF
-/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE, TRUE, ITEM_SLOT_OCLOTHING)
-
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor
name = "inquisitor's hardsuit"
icon_state = "hardsuit-inq"
@@ -395,11 +365,6 @@ Contains:
resistance_flags = FIRE_PROOF
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/pickaxe, /obj/item/spear, /obj/item/organ/regenerative_core/legion, /obj/item/kitchen/knife, /obj/item/kinetic_crusher, /obj/item/resonator, /obj/item/melee/transforming/cleaving_saw)
-
-/obj/item/clothing/suit/space/hardsuit/berserker/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE, TRUE, ITEM_SLOT_OCLOTHING)
-
/obj/item/clothing/suit/space/hardsuit/berserker/RemoveHelmet()
var/obj/item/clothing/head/helmet/space/hardsuit/berserker/helm = helmet
if(helm?.berserk_active)
@@ -581,14 +546,3 @@ Contains:
icon_state = "space-inteq"
armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 15, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
w_class = WEIGHT_CLASS_NORMAL
-
-/obj/item/clothing/suit/space/scar
- name = "Scar Suit"
- desc = "A heavily modified eva suit, custom made for the captain of the ember."
- icon_state = "hostile_env"
- item_state = "hostile_env"
- max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
- resistance_flags = FIRE_PROOF
- slowdown = 0.5
- armor = list("melee" = 40, "bullet" = 35, "laser" = 30, "energy" = 25, "bomb" = 70, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
- allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy, /obj/item/tank/internals)
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 953899ca40ce..9dfd23210d9c 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -15,6 +15,8 @@
greyscale_colors = list(list(18, 19), list(13, 18), list(20, 15))
greyscale_icon_state = "armor"
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
+
/obj/item/clothing/suit/armor/Initialize()
. = ..()
if(!allowed)
@@ -32,21 +34,27 @@
desc = "A Type I armored vest that provides decent protection against most types of damage."
icon_state = "armor_alt"
item_state = "armoralt"
- supports_variations = KEPORI_VARIATION
+ //supports_variations = KEPORI_VARIATION
+
+/obj/item/clothing/suit/armor/vest/trauma
+ name = "cybersun trauma team armor vest"
+ icon_state = "traumavest"
+ desc = "A set of stamped plasteel armor plates decorated with a medical cross and colors associated with the medical division of Cybersun."
/obj/item/clothing/suit/armor/vest/marine
- name = "light tactical armor vest"
- desc = "A set of the finest mass-produced stamped plasteel armor plates money can buy."
+ name = "tactical armor vest"
+ desc = "A heavy set of the finest mass-produced stamped plasteel armor plates money can buy."
icon_state = "marine_light"
item_state = "armor"
clothing_flags = THICKMATERIAL
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
- armor = list("melee" = 50, "bullet" = 50, "laser" = 30, "energy" = 25, "bomb" = 50, "bio" = 100, "fire" = 40, "acid" = 50)
+ armor = list("melee" = 50, "bullet" = 75, "laser" = 55, "energy" = 25, "bomb" = 60, "bio" = 100, "fire" = 70, "acid" = 50)
cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
resistance_flags = FIRE_PROOF | ACID_PROOF
supports_variations = VOX_VARIATION | DIGITIGRADE_VARIATION_NO_NEW_ICON
+ slowdown = 0.5
/obj/item/clothing/suit/armor/vest/marine/medium
name = "medium tactical armor vest"
@@ -56,11 +64,6 @@
name = "large tactical armor vest"
icon_state = "marine_heavy"
-/obj/item/clothing/suit/armor/vest/marine/trauma
- name = "cybersun trauma team armor vest"
- icon_state = "traumavest"
- desc = "A set of stamped plasteel armor plates decorated with a medical cross and colors associated with the medical division of Cybersun."
-
/obj/item/clothing/suit/armor/vest/old
name = "degrading armor vest"
desc = "Older generation Type 1 armored vest. Due to degradation over time the vest is far less maneuverable to move in."
@@ -157,21 +160,6 @@
desc = "An extraordinarily fashionable haori, utilized by Cybersun captains. Weaved with armored fabric to protect the user from gunshots."
icon_state = "carapace_cybersun"
-/obj/item/clothing/suit/armor/vest/capcarapace/ngr_captain
- name = "\improper 2nd Battlegroup jacket"
- desc = "An armored jacket worn by the New Gorlex Republic's 2nd Battlegroup."
- body_parts_covered = CHEST|GROIN|ARMS|HANDS
- icon_state = "carapace_ngr"
- item_state = "carapace_ngr"
- blood_overlay_type = "coat"
- armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
-
-/obj/item/clothing/suit/armor/vest/capcarapace/alt
- name = "captain's parade jacket"
- desc = "For when an armoured vest isn't fashionable enough."
- icon_state = "carapace_ntformal"
- item_state = "capspacesuit"
-
/obj/item/clothing/suit/armor/vest/capcarapace/captunic
name = "captain's parade coat"
desc = "Worn by a captain to show their class."
@@ -215,11 +203,6 @@
strip_delay = 70
equip_delay_other = 50
-/obj/item/clothing/suit/armor/vest/bulletproof/frontier
- name = "\improper Frontiersmen bulletproof armor"
- desc = "A scrap piece of armor made of disused protective plates. This one was used to protect the squishy bits of a Frontiersman, once."
- icon_state = "frontier_armor"
-
/obj/item/clothing/suit/armor/laserproof
name = "reflector vest"
desc = "A vest that excels in protecting the wearer against energy projectiles, as well as occasionally reflecting them."
@@ -339,7 +322,7 @@
desc = "A luxurious brown coat made from a crossweave of kevlar and ballistic fibre, the collar and wrist trims are made from genuine wolf fur. as protective as it is stylish."
icon_state = "armor_inteq_battlecoat"
item_state = "inteq_battlecoat"
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
/obj/item/clothing/suit/armor/hos/inteq/honorable //Basically CC higherup clothing for inteq
name = "honorable vanguard battlecoat"
@@ -347,7 +330,7 @@
icon_state = "armor_inteq_honorable_battlecoat"
item_state = "inteq_honorable_battlecoat"
armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90)
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
/obj/item/clothing/suit/armor/inteq/corpsman
name = "inteq corpsman vest"
@@ -377,27 +360,6 @@
/obj/item/melee/baton,
)
-/obj/item/clothing/suit/armor/roumain
- name = "saint-roumain duster"
- desc = "A coat made from hard leather. Meant to withstand long hunts in harsh wilderness."
- icon_state = "armor_rouma"
- item_state = "rouma_coat"
- body_parts_covered = CHEST|GROIN|ARMS
- cold_protection = CHEST|GROIN|ARMS
- heat_protection = CHEST|GROIN|ARMS
-
-/obj/item/clothing/suit/armor/roumain/shadow
- name = "saint-roumain shadow duster"
- desc = "A coat made from hard leather. Its rough, barely-treated finish is typical of one of the Saint-Roumain Militia's trainees."
- icon_state = "armor_rouma_shadow"
- item_state = "rouma_shadow_coat"
-
-/obj/item/clothing/suit/armor/hos/roumain/montagne
- name = "saint-roumain montagne coat"
- desc = "A stylish red coat to indicate that you are, in fact, a Hunter Montagne. Made of extra hard exotic leather, treated with bullet-resistant materials, and lined with the fur of some unidentifiable creature."
- icon_state = "armor_rouma_montagne"
- item_state = "rouma_montagne_coat"
-
/obj/item/clothing/suit/armor/vest/bulletproof/solgov
name = "\improper Sonnensoldner gambison"
desc = "A standard armor vest fielded for SolGov's Sonnensoldners."
@@ -499,14 +461,6 @@
icon_state = "armor_brigphysjacket"
body_parts_covered = CHEST|ARMS
-/obj/item/clothing/suit/armor/frontier
- name = "reinforced fur coat"
- desc = "A stiff coat, meant for frigid conditions."
- icon_state = "frontier_coat"
- body_parts_covered = CHEST|GROIN|ARMS
- cold_protection = CHEST|GROIN|ARMS
- heat_protection = CHEST|GROIN|ARMS
-
/obj/item/clothing/suit/toggle/armor/vest/centcom_formal
name = "\improper CentCom formal coat"
desc = "A stylish coat given to CentCom Commanders. Perfect for sending ERTs to suicide missions with style!"
diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm
index bce5d5bd2445..4e3f6d5e3a9c 100644
--- a/code/modules/clothing/suits/cloaks.dm
+++ b/code/modules/clothing/suits/cloaks.dm
@@ -67,6 +67,11 @@
desc = "Worn by high ranking vampires of the transylvanian society of vampires."
icon_state = "trans"
+/obj/item/clothing/neck/cloak/bi
+ name = "solarian marine biologist cloak"
+ desc = "Commonly worn by members of the Solarian Marine Biologist Society, dedicated to the study and preservation of marine wildlife."
+ icon_state = "bi"
+
/obj/item/clothing/suit/hooded/cloak/goliath
name = "goliath cloak"
icon_state = "goliath_cloak"
diff --git a/code/modules/clothing/suits/hoodies.dm b/code/modules/clothing/suits/hoodies.dm
index b9e7ebb218c0..b69061cffbd1 100644
--- a/code/modules/clothing/suits/hoodies.dm
+++ b/code/modules/clothing/suits/hoodies.dm
@@ -11,6 +11,7 @@
/obj/item/storage/fancy/cigarettes,
/obj/item/lighter,
/obj/item/radio,
+ /obj/item/storage/pill_bottle
)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) //it's just a hoodie.
supports_variations = KEPORI_VARIATION
@@ -85,11 +86,13 @@
/obj/item/clothing/head/hooded/hood/fbp
name = "\improper FBP kepori hood"
desc = "A hood for your FBP hoodie."
+ icon_state = "hoodie_fbp"
item_state = "hoodie_fbp"
/obj/item/clothing/suit/hooded/hoodie/rilena
name = "K4L1 hoodie"
desc = "A hoodie themed to look like K4L1 from the popular webseries RILENA. It has a comfy pocket for keeping your hands warm."
+ icon_state = "hoodie_rilena"
item_state = "hoodie_rilena"
hoodtype = /obj/item/clothing/head/hooded/hood/rilena
@@ -110,5 +113,12 @@
/obj/item/clothing/head/hooded/hood/rilena
name = "RILENA: LMR K4L1 hood"
desc = "A hood for your RILENA themed hoodie."
+ icon_state = "hoodie_rilena"
item_state = "hoodie_rilena"
+/obj/item/clothing/suit/hooded/hoodie/blackwa
+ name = "black and white hoodie"
+ desc = "A hoodie that is black, with a white hood. It has a comfy pocket for keeping your hands warm."
+ icon_state = "hoodie_bwa"
+ item_state = "hoodie_bwa"
+ hoodtype = /obj/item/clothing/head/hooded/hood/gray
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index 43c349d6e095..56018c288b6a 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -129,6 +129,8 @@
body_parts_covered = CHEST|ARMS
togglename = "buttons"
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
+
/obj/item/clothing/suit/toggle/lawyer/purple
name = "purple suit jacket"
desc = "A foppish dress jacket."
@@ -284,3 +286,10 @@
body_parts_covered = HEAD
flags_inv = HIDEHAIR|HIDEEARS|HIDEFACE|HIDEFACIALHAIR
+/obj/item/clothing/suit/armor/witchhunter
+ name = "witchunter garb"
+ desc = "This worn outfit saw much use back in the day."
+ icon_state = "chaplain_witchhunter"
+ item_state = "witchhunter"
+ body_parts_covered = CHEST|GROIN|LEGS|ARMS
+ allowed = list(/obj/item/storage/book/bible, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm
index 24836f6f2404..798a34606bc1 100644
--- a/code/modules/clothing/suits/labcoat.dm
+++ b/code/modules/clothing/suits/labcoat.dm
@@ -4,7 +4,7 @@
icon_state = "labcoat"
item_state = "labcoat"
blood_overlay_type = "coat"
- body_parts_covered = CHEST|ARMS
+ body_parts_covered = CHEST|ARMS|GROIN
allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/soap, /obj/item/sensor_device, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 50, "acid" = 50)
togglename = "buttons"
@@ -59,21 +59,15 @@
armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0, fire = 50, acid = 50)
/obj/item/clothing/suit/toggle/labcoat/raincoat
- name = "\improper Cybersun labcoat"
- desc = {"A translucent, uniquely designed labcoat from Cybersun Solutions. It's made from a special material that actively repels fluids.
+ name = "translucent labcoat"
+ desc = {"A uniquely designed, translucent labcoat. It's made from a special material that actively repels fluids.
You're pretty sure this is just a raincoat.
-Wearing a raincoat inside is like wearing sunglasses at night. A good Cybersun exec does both.
+Wearing a raincoat inside is like wearing sunglasses at night. A good chemist does both.
"}
icon_state = "raincoat"
item_state = "raincoat"
-/obj/item/clothing/suit/toggle/labcoat/roumain_med
- name = "saint-roumain medical duster"
- desc = "A coat made from hard leather and further treated with exotic sterilizing oils and wax. The treatment and its more closed design offers much better protection against biological hazards."
- icon_state = "rouma_med_coat"
- armor = list("melee" = 35, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 50, "rad" = 0, "fire" = 50, "acid" = 50)
-
/obj/item/clothing/suit/longcoat
name = "longcoat"
desc = "A long, victorian styled labcoat."
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index ddd11a4e78e6..f8e8c3f69909 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -326,6 +326,8 @@
/obj/item/clothing/head/hooded/human_head
name = "bloated human head"
desc = "A horribly bloated and mismatched human head."
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
icon_state = "lingspacehelmet"
body_parts_covered = HEAD
flags_cover = HEADCOVERSEYES
@@ -512,8 +514,9 @@
/obj/item/clothing/suit/caution
name = "wet floor sign"
- desc = "Caution! Wet Floor!"
+ desc = "No running."
icon_state = "caution"
+ icon = 'icons/obj/janitor.dmi'
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
force = 1
@@ -660,8 +663,8 @@
flags_inv = HIDEHAIR|HIDEEARS|HIDEFACIALHAIR|HIDEFACE|HIDEMASK
/obj/item/clothing/suit/hawaiian
- name = "hawaiian overshirt"
- desc = "A cool shirt for chilling on the beach."
+ name = "floral shirt"
+ desc = "From grills to guns, this shirt's seen it all."
icon_state = "hawaiian_blue"
item_state = "hawaiian_blue"
diff --git a/code/modules/clothing/suits/wintercoats.dm b/code/modules/clothing/suits/wintercoats.dm
index 588a8f1600de..5c1bfb47be66 100644
--- a/code/modules/clothing/suits/wintercoats.dm
+++ b/code/modules/clothing/suits/wintercoats.dm
@@ -1,5 +1,7 @@
// WINTER COATS
+//Someone please make the allowed lists globals or something
+
/obj/item/clothing/suit/hooded/wintercoat
name = "winter coat"
desc = "A heavy jacket made from 'synthetic' animal furs."
@@ -10,13 +12,15 @@
body_parts_covered = CHEST|GROIN|ARMS
cold_protection = CHEST|GROIN|ARMS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ pocket_storage_component_path = /datum/component/storage/concrete/pockets/exo/large
allowed = list( /obj/item/flashlight,
/obj/item/tank/internals/emergency_oxygen,
/obj/item/tank/internals/plasmaman,
/obj/item/toy,
/obj/item/storage/fancy/cigarettes,
/obj/item/lighter,
+ /obj/item/radio,
+ /obj/item/storage/pill_bottle
)
/obj/item/clothing/head/hooded/winterhood
@@ -29,13 +33,11 @@
cold_protection = HEAD
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
flags_inv = HIDEHAIR|HIDEEARS
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/suit/hooded/wintercoat/captain
name = "captain's winter coat"
icon_state = "coatcaptain"
item_state = "coatcaptain"
- armor = list("melee" = 25, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
hoodtype = /obj/item/clothing/head/hooded/winterhood/captain
/obj/item/clothing/suit/hooded/wintercoat/captain/Initialize()
@@ -44,13 +46,11 @@
/obj/item/clothing/head/hooded/winterhood/captain
icon_state = "hood_captain"
- armor = list("melee" = 25, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
/obj/item/clothing/suit/hooded/wintercoat/security
name = "security winter coat"
icon_state = "coatsecurity"
item_state = "coatsecurity"
- armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45)
hoodtype = /obj/item/clothing/head/hooded/winterhood/security
/obj/item/clothing/suit/hooded/wintercoat/security/Initialize()
@@ -59,19 +59,37 @@
/obj/item/clothing/head/hooded/winterhood/security
icon_state = "hood_security"
- armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45)
/obj/item/clothing/suit/hooded/wintercoat/medical
name = "medical winter coat"
icon_state = "coatmedical"
item_state = "coatmedical"
- allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45)
hoodtype = /obj/item/clothing/head/hooded/winterhood/medical
+ allowed = list(
+ /obj/item/analyzer,
+ /obj/item/sensor_device,
+ /obj/item/stack/medical,
+ /obj/item/dnainjector,
+ /obj/item/reagent_containers/dropper,
+ /obj/item/reagent_containers/syringe,
+ /obj/item/reagent_containers/hypospray,
+ /obj/item/healthanalyzer,
+ /obj/item/flashlight/pen,
+ /obj/item/reagent_containers/glass/bottle,
+ /obj/item/reagent_containers/glass/beaker,
+ /obj/item/reagent_containers/pill,
+ /obj/item/storage/pill_bottle,
+ /obj/item/paper,
+ /obj/item/melee/classic_baton/telescopic,
+ /obj/item/toy,
+ /obj/item/storage/fancy/cigarettes,
+ /obj/item/lighter,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/plasmaman,
+ )
/obj/item/clothing/head/hooded/winterhood/medical
icon_state = "hood_medical"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45)
/obj/item/clothing/suit/hooded/wintercoat/medical/paramedic
name = "paramedic winter coat"
@@ -86,25 +104,52 @@
name = "science winter coat"
icon_state = "coatscience"
item_state = "coatscience"
- allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman)
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
hoodtype = /obj/item/clothing/head/hooded/winterhood/science
+ allowed = list(
+ /obj/item/analyzer,
+ /obj/item/stack/medical,
+ /obj/item/dnainjector,
+ /obj/item/reagent_containers/dropper,
+ /obj/item/reagent_containers/syringe,
+ /obj/item/reagent_containers/hypospray,
+ /obj/item/healthanalyzer,
+ /obj/item/flashlight/pen,
+ /obj/item/reagent_containers/glass/bottle,
+ /obj/item/reagent_containers/glass/beaker,
+ /obj/item/reagent_containers/pill,
+ /obj/item/storage/pill_bottle,
+ /obj/item/paper,
+ /obj/item/melee/classic_baton/telescopic,
+ /obj/item/toy,
+ /obj/item/storage/fancy/cigarettes,
+ /obj/item/lighter,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/plasmaman,
+ )
/obj/item/clothing/head/hooded/winterhood/science
icon_state = "hood_science"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/suit/hooded/wintercoat/engineering
name = "engineering winter coat"
icon_state = "coatengineer"
item_state = "coatengineer"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45)
- allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering
+ allowed = list(
+ /obj/item/flashlight,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/plasmaman,
+ /obj/item/t_scanner,
+ /obj/item/construction/rcd,
+ /obj/item/pipe_dispenser,
+ /obj/item/toy,
+ /obj/item/storage/fancy/cigarettes,
+ /obj/item/lighter,
+ )
+
/obj/item/clothing/head/hooded/winterhood/engineering
icon_state = "hood_engineer"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45)
/obj/item/clothing/suit/hooded/wintercoat/engineering/atmos
name = "atmospherics winter coat"
@@ -119,8 +164,22 @@
name = "hydroponics winter coat"
icon_state = "coathydro"
item_state = "coathydro"
- allowed = list(/obj/item/reagent_containers/spray/plantbgone, /obj/item/plant_analyzer, /obj/item/seeds, /obj/item/reagent_containers/glass/bottle, /obj/item/cultivator, /obj/item/reagent_containers/spray/pestspray, /obj/item/hatchet, /obj/item/storage/bag/plants, /obj/item/toy, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
hoodtype = /obj/item/clothing/head/hooded/winterhood/hydro
+ allowed = list(
+ /obj/item/reagent_containers/spray/plantbgone,
+ /obj/item/plant_analyzer,
+ /obj/item/seeds,
+ /obj/item/reagent_containers/glass/bottle,
+ /obj/item/cultivator,
+ /obj/item/reagent_containers/spray/pestspray,
+ /obj/item/hatchet,
+ /obj/item/storage/bag/plants,
+ /obj/item/toy,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/plasmaman,
+ /obj/item/storage/fancy/cigarettes,
+ /obj/item/lighter,
+ )
/obj/item/clothing/head/hooded/winterhood/hydro
icon_state = "hood_hydro"
@@ -138,13 +197,18 @@
name = "mining winter coat"
icon_state = "coatminer"
item_state = "coatminer"
- allowed = list(/obj/item/pickaxe, /obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
hoodtype = /obj/item/clothing/head/hooded/winterhood/miner
+ allowed = list(
+ /obj/item/pickaxe,
+ /obj/item/flashlight,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/toy,
+ /obj/item/storage/fancy/cigarettes,
+ /obj/item/lighter,
+ )
/obj/item/clothing/head/hooded/winterhood/miner
icon_state = "hood_miner"
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
// Inteq
@@ -154,18 +218,17 @@
icon_state = "coatinteq"
item_state = "coatinteq"
hoodtype = /obj/item/clothing/head/hooded/winterhood/security/inteq
- supports_variations = KEPORI_VARIATION
+ //supports_variations = KEPORI_VARIATION
/obj/item/clothing/head/hooded/winterhood/security/inteq
icon_state = "hood_inteq"
- supports_variations = KEPORI_VARIATION
+ //supports_variations = KEPORI_VARIATION
/obj/item/clothing/suit/hooded/wintercoat/security/inteq/alt
name = "inteq hooded coat"
desc = "A hooded coat with a fur trim around the hood, comfy! It has a small 'IRMG' embroidered onto the shoulder."
icon_state = "coatinteq_alt"
item_state = "coatinteq_alt"
- armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45)
hoodtype = /obj/item/clothing/head/hooded/winterhood/security/inteq/alt
/obj/item/clothing/head/hooded/winterhood/security/inteq/alt
@@ -173,15 +236,14 @@
desc = "A comfortable looking brown hood."
icon_state = "hood_inteq_alt"
item_state = "hood_inteq_alt"
- armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45)
// CentCom
+
/obj/item/clothing/suit/hooded/wintercoat/centcom
name = "centcom winter coat"
desc = "A luxurious winter coat woven in the bright green and gold colours of Central Command. It has a small pin in the shape of the Nanotrasen logo for a zipper."
icon_state = "coatcentcom"
item_state = "coatcentcom"
- armor = list("melee" = 35, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 35, "bio" = 10, "rad" = 10, "fire" = 10, "acid" = 60)
hoodtype = /obj/item/clothing/head/hooded/winterhood/centcom
/obj/item/clothing/suit/hooded/wintercoat/centcom/Initialize(mapload)
@@ -190,7 +252,6 @@
/obj/item/clothing/head/hooded/winterhood/centcom
icon_state = "hood_centcom"
- armor = list("melee" = 35, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 35, "bio" = 10, "rad" = 10, "fire" = 10, "acid" = 60)
// SolGov
@@ -199,9 +260,7 @@
desc = "An environment-resistant wintercoat in the colors of the Solarian Confederation."
icon_state = "coatsolgov"
item_state = "coatsolgov"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45)
hoodtype = /obj/item/clothing/head/hooded/winterhood/solgov
/obj/item/clothing/head/hooded/winterhood/solgov
icon_state = "hood_solgov"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45)
diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm
index 8bc5646f2218..451d428760f3 100644
--- a/code/modules/clothing/suits/wiz_robe.dm
+++ b/code/modules/clothing/suits/wiz_robe.dm
@@ -55,6 +55,8 @@
/obj/item/clothing/head/wizard/santa
name = "Santa's hat"
desc = "Ho ho ho. Merrry X-mas!"
+ icon = 'icons/obj/clothing/head/spacesuits.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/spacesuits.dmi'
icon_state = "santahat"
flags_inv = HIDEHAIR|HIDEFACIALHAIR
dog_fashion = null
@@ -146,39 +148,6 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
resistance_flags = FLAMMABLE
-/obj/item/clothing/suit/wizrobe/paper
- name = "papier-mache robe" // no non-latin characters!
- desc = "A robe held together by various bits of clear-tape and paste."
- icon_state = "wizard-paper"
- item_state = "wizard-paper"
- var/robe_charge = TRUE
- actions_types = list(/datum/action/item_action/stickmen)
-
-
-/obj/item/clothing/suit/wizrobe/paper/ui_action_click(mob/user, action)
- stickmen()
-
-
-/obj/item/clothing/suit/wizrobe/paper/verb/stickmen()
- set category = "Object"
- set name = "Summon Stick Minions"
- set src in usr
- if(!isliving(usr))
- return
- if(!robe_charge)
- to_chat(usr, "The robe's internal magic supply is still recharging!")
- return
-
- usr.say("Rise, my creation! Off your page into this realm!", forced = "stickman summoning")
- playsound(src.loc, 'sound/magic/summon_magic.ogg', 50, TRUE, TRUE)
- var/mob/living/M = new /mob/living/simple_animal/hostile/stickman(get_turf(usr))
- var/list/factions = usr.faction
- M.faction = factions
- src.robe_charge = FALSE
- sleep(30)
- src.robe_charge = TRUE
- to_chat(usr, "The robe hums, its internal magic supply restored.")
-
/obj/item/clothing/suit/space/hardsuit/shielded/wizard
name = "battlemage armour"
desc = "Not all wizards are afraid of getting up close and personal."
diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index 7a8e21ae2bea..a28d6d323a83 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -86,7 +86,6 @@
if(attached_accessory && slot != ITEM_SLOT_HANDS && ishuman(user))
var/mob/living/carbon/human/H = user
attached_accessory.on_uniform_equip(src, user)
- H.fan_hud_set_fandom()
if(attached_accessory.above_suit)
H.update_inv_wear_suit()
@@ -101,7 +100,6 @@
attached_accessory.on_uniform_dropped(src, user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
- H.fan_hud_set_fandom()
if(attached_accessory.above_suit)
H.update_inv_wear_suit()
@@ -136,7 +134,6 @@
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform()
H.update_inv_wear_suit()
- H.fan_hud_set_fandom()
return TRUE
@@ -158,7 +155,6 @@
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform()
H.update_inv_wear_suit()
- H.fan_hud_set_fandom()
/obj/item/clothing/under/examine(mob/user)
diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm
index ed1d12be3fcb..f7710d52a12d 100644
--- a/code/modules/clothing/under/accessories.dm
+++ b/code/modules/clothing/under/accessories.dm
@@ -376,66 +376,18 @@
for(var/i in 1 to 3)
new /obj/item/lipstick/random(src)
-////////////////
-//REAL BIG FAN//
-////////////////
-
-/obj/item/clothing/accessory/fan_clown_pin
- name = "Clown Pin"
- desc = "A pin to show off your appreciation for clowns and clowning"
- icon_state = "fan_clown_pin"
- above_suit = FALSE
- minimize_when_attached = TRUE
- attachment_slot = CHEST
-
-/obj/item/clothing/accessory/fan_clown_pin/on_uniform_equip(obj/item/clothing/under/U, user)
- var/mob/living/L = user
- if(HAS_TRAIT(L, TRAIT_FAN_CLOWN))
- SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "fan_clown_pin", /datum/mood_event/fan_clown_pin)
-
-/obj/item/clothing/accessory/fan_clown_pin/on_uniform_dropped(obj/item/clothing/under/U, user)
- var/mob/living/L = user
- if(HAS_TRAIT(L, TRAIT_FAN_CLOWN))
- SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "fan_clown_pin")
-
-/obj/item/clothing/accessory/fan_mime_pin
- name = "Mime Pin"
- desc = "A pin to show off your appreciation for mimes and miming"
- icon_state = "fan_mime_pin"
- above_suit = FALSE
- minimize_when_attached = TRUE
- attachment_slot = CHEST
-
-/obj/item/clothing/accessory/fan_mime_pin/on_uniform_equip(obj/item/clothing/under/U, user)
- var/mob/living/L = user
- if(HAS_TRAIT(L, TRAIT_FAN_MIME))
- SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "fan_mime_pin", /datum/mood_event/fan_mime_pin)
-
-/obj/item/clothing/accessory/fan_mime_pin/on_uniform_dropped(obj/item/clothing/under/U, user)
- var/mob/living/L = user
- if(HAS_TRAIT(L, TRAIT_FAN_MIME))
- SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "fan_mime_pin")
////////////////
//OONGA BOONGA//
////////////////
-/obj/item/clothing/accessory/talisman
- name = "bone talisman"
- desc = "A hunter's talisman, some say the old gods smile on those who wear it."
- icon_state = "talisman"
- armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25)
+/obj/item/clothing/accessory/bonearmlet
+ name = "bone armlet"
+ desc = "An armlet made out of animal bone and sinew. According to a common Frontier superstition, it brings good luck to its wearer."
+ icon_state = "bone_armlet"
attachment_slot = ARMS
above_suit = TRUE
-/obj/item/clothing/accessory/wolftalisman
- name = "hunter's necklace"
- desc = "A thick necklace woven from sinew and bits of wolfhide, adorned with a carved fang. Slaying such beasts is rumoured to elate the gods of old, and such an item proves your worth."
- icon_state = "wolf_talisman"
- armor = list("melee" = 15 , "bullet" = 15, "laser" = 10, "energy" = 10, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 25, "acid" = 25)
- attachment_slot = CHEST
- above_suit = TRUE
-
/obj/item/clothing/accessory/skullcodpiece
name = "skull codpiece"
desc = "A legion skull fitted to a codpiece, intended to protect the important things in life."
diff --git a/code/modules/clothing/under/jobs/cargo.dm b/code/modules/clothing/under/jobs/cargo.dm
index c5426e63883e..0af578bfd452 100644
--- a/code/modules/clothing/under/jobs/cargo.dm
+++ b/code/modules/clothing/under/jobs/cargo.dm
@@ -1,7 +1,7 @@
/obj/item/clothing/under/rank/cargo
icon = 'icons/obj/clothing/under/cargo.dmi'
mob_overlay_icon = 'icons/mob/clothing/under/cargo.dmi'
- supports_variations = KEPORI_VARIATION
+ //supports_variations = KEPORI_VARIATION
/obj/item/clothing/under/rank/cargo/qm
name = "quartermaster's jumpsuit"
@@ -16,7 +16,7 @@
item_state = "lb_suit"
body_parts_covered = CHEST|GROIN|ARMS
can_adjust = FALSE
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
/obj/item/clothing/under/rank/cargo/tech
name = "cargo technician's jumpsuit"
@@ -24,7 +24,7 @@
icon_state = "cargotech"
item_state = "lb_suit"
body_parts_covered = CHEST|GROIN|ARMS
- supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION
alt_covers_chest = TRUE
/obj/item/clothing/under/rank/cargo/tech/skirt
@@ -33,7 +33,7 @@
icon_state = "cargo_skirt"
item_state = "lb_suit"
body_parts_covered = CHEST|GROIN|ARMS
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
can_adjust = FALSE
/obj/item/clothing/under/rank/cargo/miner
@@ -43,22 +43,22 @@
item_state = "miner"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 0)
resistance_flags = NONE
- supports_variations = KEPORI_VARIATION
+ //supports_variations = KEPORI_VARIATION
/obj/item/clothing/under/rank/cargo/miner/lavaland
- desc = "A light uniform for operating in hazardous environments, manufactured en-masse by EXOCON for the profitable frontier prospector market. Adventurous khaki jeans included."
+ desc = "A light uniform for operating in hazardous environments, manufactured en-masse by EXOCOM for the profitable frontier prospector market. Adventurous khaki jeans included."
name = "prospector jumpsuit"
icon_state = "explorer"
item_state = "explorer"
can_adjust = TRUE
- supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION
/obj/item/clothing/under/rank/cargo/miner/hazard
desc = "A thick jumpsuit with reflective stripes for hazardous, low-visibility environments. It's coated in a thick layer of asteroid dust."
name = "asteroid miner's jumpsuit"
icon_state = "hazard"
item_state = "hazard"
- supports_variations = DIGITIGRADE_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION
/obj/item/clothing/under/rank/cargo/miner/lavaland/old
icon_state = "explorerold"
diff --git a/code/modules/clothing/under/jobs/command.dm b/code/modules/clothing/under/jobs/command.dm
index 55b20b328ac8..c2584679cb5c 100644
--- a/code/modules/clothing/under/jobs/command.dm
+++ b/code/modules/clothing/under/jobs/command.dm
@@ -50,12 +50,6 @@
can_adjust = FALSE
supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
-/obj/item/clothing/under/rank/command/captain/parade
- name = "captain's parade uniform"
- desc = "A captain's luxury-wear, for special occasions."
- icon_state = "captain_parade"
- item_state = "b_suit"
- can_adjust = FALSE
//Head of Personnel
@@ -73,16 +67,6 @@
can_adjust = FALSE
supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
-/obj/item/clothing/under/rank/command/head_of_personnel/nt
- icon_state = "hop_nt"
-
-/obj/item/clothing/under/rank/command/head_of_personnel/nt/skirt
- name = "head of personnel's jumpskirt"
- desc = "It's a jumpskirt worn by someone who works in the position of \"Head of Personnel\"."
- icon_state = "hop_nt"
- body_parts_covered = CHEST|GROIN|ARMS
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
-
/obj/item/clothing/under/rank/command/head_of_personnel/suit
name = "head of personnel's suit"
desc = "A teal suit and yellow necktie. An authoritative yet tacky ensemble."
@@ -98,15 +82,3 @@
body_parts_covered = CHEST|GROIN|ARMS
can_adjust = FALSE
supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
-
-/obj/item/clothing/under/rank/command/captain/nt
- desc = "It's a blue jumpsuit with some gold markings denoting the rank of \"Captain\"."
- icon_state = "captain_nt"
- item_state = "b_suit"
-
-/obj/item/clothing/under/rank/command/captain/nt/skirt
- name = "captain's jumpskirt"
- desc = "It's a blue jumpskirt with some gold markings denoting the rank of \"Captain\"."
- icon_state = "captain_nt_skirt"
- body_parts_covered = CHEST|GROIN|ARMS
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
diff --git a/code/modules/clothing/under/jobs/medical.dm b/code/modules/clothing/under/jobs/medical.dm
index 7a95273c22f2..183e957d2338 100644
--- a/code/modules/clothing/under/jobs/medical.dm
+++ b/code/modules/clothing/under/jobs/medical.dm
@@ -136,7 +136,7 @@
/obj/item/clothing/under/rank/medical/paramedic
desc = "It's made of a special fiber that provides minor protection against biohazards. It has a dark blue cross on the chest denoting that the wearer is a trained paramedic."
name = "paramedic jumpsuit"
- icon_state = "paramedic"
+ icon_state = "pmedic"
item_state = "w_suit"
permeability_coefficient = 0.5
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
@@ -144,7 +144,7 @@
/obj/item/clothing/under/rank/medical/paramedic/skirt
name = "paramedic jumpskirt"
desc = "It's made of a special fiber that provides minor protection against biohazards. It has a dark blue cross on the chest denoting that the wearer is a trained paramedic."
- icon_state = "paramedic_skirt"
+ icon_state = "pmedic_skirt"
item_state = "w_suit"
body_parts_covered = CHEST|GROIN|ARMS
supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
@@ -174,7 +174,7 @@
desc = "A light white gown that allows easy access to any patient who wears this."
icon_state = "gownwhite"
item_state = "gownwhite"
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
can_adjust = FALSE
/obj/item/clothing/under/rank/medical/gown/green
diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm
index 29ee1c732399..46a1ff275d15 100644
--- a/code/modules/clothing/under/jobs/security.dm
+++ b/code/modules/clothing/under/jobs/security.dm
@@ -290,18 +290,18 @@
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
-/obj/item/clothing/under/rank/security/officer/frontier
+/obj/item/clothing/under/frontiersmen
name = "\improper Frontiersmen uniform"
desc = "Worn by members of the Frontiersmen pirate fleet. It's very uncomfortable to move around in."
icon_state = "frontier"
item_state = "gy_suit"
-/obj/item/clothing/under/rank/security/officer/frontier/officer
+/obj/item/clothing/under/frontiersmen/officer
name = "\improper Frontiersmen officer's uniform"
desc = "Worn by officers of the Frontiersmen pirate fleet. It's less comfortable than it looks."
icon_state = "frontier_officer"
-/obj/item/clothing/under/rank/security/officer/frontier/admiral
+/obj/item/clothing/under/frontiersmen/admiral
name = "\improper Frontiersmen admiral's uniform"
desc = "Worn by admirals of the Frontiersmen pirate fleet. It's the only Frontiersman uniform that isn't mass produced."
icon_state = "frontier_admiral"
diff --git a/code/modules/clothing/under/skirt_dress.dm b/code/modules/clothing/under/skirt_dress.dm
index 1dabceb6db24..f74748f71fbb 100644
--- a/code/modules/clothing/under/skirt_dress.dm
+++ b/code/modules/clothing/under/skirt_dress.dm
@@ -93,4 +93,4 @@
desc = "A pretty red dress with big pink ribbons attached. Intended to be worn by Kepori cosplayers, but also fits other species."
icon_state = "rilena_dress"
item_state = "rilena_dress"
- supports_variations = KEPORI_VARIATION
+ //supports_variations = KEPORI_VARIATION
diff --git a/code/modules/clothing/under/suits.dm b/code/modules/clothing/under/suits.dm
index 786f2dcd5fa3..a0ec0a4da5e5 100644
--- a/code/modules/clothing/under/suits.dm
+++ b/code/modules/clothing/under/suits.dm
@@ -29,7 +29,6 @@
item_state = "waiter"
/obj/item/clothing/under/suit/waiter/syndicate
- name = "syndicate waiter's outfit"
icon_state = "waiter_s"
item_state = "waiter_s"
@@ -140,12 +139,6 @@
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS|HEAD
flags_inv = HIDEGLOVES|HIDESHOES|HIDEEARS|HIDEEYES|HIDEHAIR
-/obj/item/clothing/under/suit/roumain
- name = "saint-roumain's worksuit"
- desc = "A simple, hard-wearing suit designed for the hardworking hunters of the Saint-Roumain Militia."
- icon_state = "rouma_work"
- item_state = "rouma_work"
-
/obj/item/clothing/under/suit/dresssuit
name = "navy dress-suit"
desc = "A very strange piece of clothing. Mostly navy, but with a pink undershirt. Who would even wear this?"
diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm
index 36cc7c96220e..2283e6a45b07 100644
--- a/code/modules/clothing/under/syndicate.dm
+++ b/code/modules/clothing/under/syndicate.dm
@@ -7,7 +7,7 @@
alt_covers_chest = TRUE
icon = 'icons/obj/clothing/under/syndicate.dmi'
mob_overlay_icon = 'icons/mob/clothing/under/syndicate.dmi'
- supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION
/obj/item/clothing/under/syndicate/skirt
name = "tactical skirtleneck"
@@ -17,7 +17,7 @@
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
alt_covers_chest = TRUE
can_adjust = FALSE
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
/obj/item/clothing/under/syndicate/bloodred
name = "blood-red sneaksuit"
@@ -27,7 +27,7 @@
armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 50, "acid" = 40)
resistance_flags = FIRE_PROOF | ACID_PROOF
can_adjust = FALSE
- supports_variations = DIGITIGRADE_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION
/obj/item/clothing/under/syndicate/bloodred/sleepytime
name = "blood-red pajamas"
@@ -35,7 +35,7 @@
icon_state = "bloodred_pajamas"
item_state = "bl_suit"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
- supports_variations = DIGITIGRADE_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION
/obj/item/clothing/under/syndicate/tacticool
name = "tacticool turtleneck"
@@ -43,7 +43,7 @@
icon_state = "tactifool"
item_state = "bl_suit"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
- supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION
/obj/item/clothing/under/syndicate/tacticool/skirt
name = "tacticool skirtleneck"
@@ -52,7 +52,7 @@
item_state = "bl_suit"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
can_adjust = FALSE
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON
/obj/item/clothing/under/syndicate/sniper
name = "Tactical turtleneck suit"
@@ -75,7 +75,7 @@
desc = "With a suit lined with this many pockets, you are ready to operate."
icon_state = "syndicate_combat"
can_adjust = FALSE
- supports_variations = DIGITIGRADE_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION
/obj/item/clothing/under/syndicate/rus_army
name = "advanced military tracksuit"
@@ -93,22 +93,6 @@
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
alt_covers_chest = TRUE
-/obj/item/clothing/under/syndicate/ngr/officer
- name = "NGR officer uniform"
- desc = "A black uniform worn by officers of the New Gorlex Republic."
- icon_state = "ngr_officer"
- can_adjust = FALSE
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
- alt_covers_chest = TRUE
-
-/obj/item/clothing/under/syndicate/ngr
- name = "NGR uniform"
- desc = "A button-up in a tasteful shade of gray with red pants, used as the basic uniform of the New Gorlex Republic."
- icon_state = "ngr_grunt"
- can_adjust = FALSE
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
- alt_covers_chest = TRUE
-
/obj/item/clothing/under/syndicate/gorlex
name = "Gorlex Marauder uniform"
desc = "Originally worn by the miners of the Gorlex VII colony, it is now donned by veteran Gorlex Marauders."
@@ -116,7 +100,7 @@
can_adjust = FALSE
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
alt_covers_chest = TRUE
- supports_variations = DIGITIGRADE_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION
/obj/item/clothing/under/syndicate/cybersun
name = "cybersun jumpsuit"
@@ -131,7 +115,7 @@
icon_state = "cybersun"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 100)
alt_covers_chest = TRUE
- supports_variations = DIGITIGRADE_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION
/obj/item/clothing/under/syndicate/cybersun/officer
name = "cybersun officer's suit"
@@ -146,7 +130,7 @@
icon_state = "cybersun_med"
permeability_coefficient = 0.5
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
/obj/item/clothing/under/syndicate/medic/skirt
name = "Cybersun medical jumpskirt"
@@ -154,7 +138,7 @@
icon_state = "cybersun_med_skirt"
body_parts_covered = CHEST|GROIN|ARMS
can_adjust = FALSE
- supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION_NO_NEW_ICON | VOX_VARIATION
/obj/item/clothing/under/syndicate/donk
name = "Donk! Co. employee uniform"
@@ -164,14 +148,14 @@
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
body_parts_covered = CHEST|GROIN|ARMS
alt_covers_chest = TRUE
- supports_variations = DIGITIGRADE_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION
/obj/item/clothing/under/syndicate/donk/qm
name = "Donk! Co. manager uniform"
desc = "The standard uniform of Donk Co. managers. Direct all complaints here."
icon_state = "donk_qm"
body_parts_covered = CHEST|GROIN|LEGS|ARMS
- supports_variations = DIGITIGRADE_VARIATION | KEPORI_VARIATION
+ supports_variations = DIGITIGRADE_VARIATION
/obj/item/clothing/suit/hazardvest/donk
name = "Donk! Co. employee vest"
@@ -222,7 +206,7 @@
head = /obj/item/clothing/head/helmet/space/syndicate/surplus
mask = /obj/item/clothing/mask/breath
shoes = /obj/item/clothing/shoes/laceup
- r_hand = /obj/item/gun/ballistic/automatic/ebr
+ r_hand = /obj/item/gun/ballistic/automatic/marksman/ebr
gloves = null
l_pocket = /obj/item/pinpointer/nuke/syndicate
r_pocket = /obj/item/ammo_box/magazine/ebr
diff --git a/code/modules/donator/_donator.dm b/code/modules/donator/_donator.dm
index b18dbe8f78b3..dd4df369cfea 100644
--- a/code/modules/donator/_donator.dm
+++ b/code/modules/donator/_donator.dm
@@ -23,7 +23,7 @@ GLOBAL_PROTECT(donators)
/client/proc/do_donator_redemption()
set name = "Redeem Donator Reward"
- set category = "Donator"
+ set category = "OOC.Donator"
set desc = "Redeem a reward"
var/mob/client_mob = mob
@@ -38,7 +38,7 @@ GLOBAL_PROTECT(donators)
/client/proc/do_donator_wcir()
set name = "What Can I Redeem"
- set category = "Donator"
+ set category = "OOC.Donator"
set desc = "Currently available redemptions"
donator?.what_can_i_redeem(src.mob)
diff --git a/code/modules/economy/account.dm b/code/modules/economy/account.dm
index 64280475664a..4213ae91376b 100644
--- a/code/modules/economy/account.dm
+++ b/code/modules/economy/account.dm
@@ -1,21 +1,23 @@
/datum/bank_account
var/account_holder = "Rusty Venture"
var/account_balance = 0
+ var/holder_age = 18
var/list/bank_cards = list()
var/add_to_accounts = TRUE
var/account_id
-/datum/bank_account/New(newname, job)
+/datum/bank_account/New(newname, age)
if(add_to_accounts)
SSeconomy.bank_accounts += src
account_holder = newname
+ holder_age = age
account_id = rand(111111,999999)
/datum/bank_account/Destroy()
if(add_to_accounts)
SSeconomy.bank_accounts -= src
- for(var/obj/item/card/id/id_card as anything in bank_cards)
- id_card.registered_account = null
+ for(var/obj/item/card/bank/bank_card as anything in bank_cards)
+ bank_card.registered_account = null
SSeconomy.bank_money -= account_balance
return ..()
@@ -49,10 +51,6 @@
return
for(var/obj/A in bank_cards)
var/icon_source = A
- if(istype(A, /obj/item/card/id))
- var/obj/item/card/id/id_card = A
- if(id_card.uses_overlays)
- icon_source = id_card.get_cached_flat_icon()
var/mob/card_holder = recursive_loc_check(A, /mob)
if(ismob(card_holder)) //If on a mob
if(!card_holder.client || (!(card_holder.client.prefs.chat_toggles & CHAT_BANKCARD) && !force))
diff --git a/code/modules/economy/pay_stand.dm b/code/modules/economy/pay_stand.dm
index af7d9be4b947..9382a03d062e 100644
--- a/code/modules/economy/pay_stand.dm
+++ b/code/modules/economy/pay_stand.dm
@@ -6,14 +6,14 @@
density = TRUE
anchored = TRUE
var/locked = FALSE
- var/obj/item/card/id/my_card
+ var/obj/item/card/bank/my_card
var/obj/item/assembly/signaler/signaler //attached signaler, let people attach signalers that get activated if the user's transaction limit is achieved.
var/signaler_threshold = 0 //signaler threshold amount
var/amount_deposited = 0 //keep track of the amount deposited over time so you can pay multiple times to reach the signaler threshold
var/force_fee = 0 //replaces the "pay whatever" functionality with a set amount when non-zero.
/obj/machinery/paystand/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/card/id))
+ if(istype(W, /obj/item/card/bank))
if(W == my_card)
if(user.a_intent == INTENT_DISARM)
var/rename_msg = stripped_input(user, "Rename the Paystand:", "Paystand Naming", name)
@@ -31,7 +31,7 @@
to_chat(user, "You [src.locked ? "lock" : "unlock"] the paystand, protecting the bolts from [anchored ? "loosening" : "tightening"].")
return
if(!my_card)
- var/obj/item/card/id/assistant_mains_need_to_die = W
+ var/obj/item/card/bank/assistant_mains_need_to_die = W
if(!assistant_mains_need_to_die.registered_account)
return
var/msg = stripped_input(user, "Name of pay stand:", "Paystand Naming", "[user]'s Awesome Paystand")
@@ -42,7 +42,7 @@
my_card = assistant_mains_need_to_die
to_chat(user, "You link the stand to your account.")
return
- var/obj/item/card/id/vbucks = W
+ var/obj/item/card/bank/vbucks = W
if(vbucks.registered_account)
var/momsdebitcard = 0
if(!force_fee)
diff --git a/code/modules/events/wizard/magicarp.dm b/code/modules/events/wizard/magicarp.dm
deleted file mode 100644
index 68a38f0479e1..000000000000
--- a/code/modules/events/wizard/magicarp.dm
+++ /dev/null
@@ -1,75 +0,0 @@
-/datum/round_event_control/wizard/magicarp //these fish is loaded
- name = "Magicarp"
- weight = 1
- typepath = /datum/round_event/wizard/magicarp
- max_occurrences = 1
- earliest_start = 0 MINUTES
-
-/datum/round_event/wizard/magicarp
- announceWhen = 3
- startWhen = 50
-
-/datum/round_event/wizard/magicarp/setup()
- startWhen = rand(40, 60)
-
-/datum/round_event/wizard/magicarp/announce(fake)
- priority_announce("Unknown magical entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
-
-/datum/round_event/wizard/magicarp/start()
- for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
- if(prob(5))
- new /mob/living/simple_animal/hostile/carp/ranged/chaos(C.loc)
- else
- new /mob/living/simple_animal/hostile/carp/ranged(C.loc)
-
-/mob/living/simple_animal/hostile/carp/ranged
- name = "magicarp"
- desc = "50% magic, 50% carp, 100% horrible."
- icon_state = "magicarp"
- icon_living = "magicarp"
- icon_dead = "magicarp_dead"
- icon_gib = "magicarp_gib"
- ranged = 1
- retreat_distance = 2
- minimum_distance = 0 //Between shots they can and will close in to nash
- projectiletype = /obj/projectile/magic
- projectilesound = 'sound/weapons/emitter.ogg'
- maxHealth = 50
- health = 50
- gold_core_spawnable = NO_SPAWN
- random_color = FALSE
- food_type = list()
- tame_chance = 0
- bonus_tame_chance = 0
- var/allowed_projectile_types = list(/obj/projectile/magic/change, /obj/projectile/magic/animate, /obj/projectile/magic/resurrection,
- /obj/projectile/magic/death, /obj/projectile/magic/teleport, /obj/projectile/magic/door, /obj/projectile/magic/aoe/fireball,
- /obj/projectile/magic/spellblade, /obj/projectile/magic/arcane_barrage)
-
-/mob/living/simple_animal/hostile/carp/ranged/Initialize()
- projectiletype = pick(allowed_projectile_types)
- . = ..()
-
-/mob/living/simple_animal/hostile/carp/ranged/chaos
- name = "chaos magicarp"
- desc = "50% carp, 100% magic, 150% horrible."
- color = "#00FFFF"
- maxHealth = 75
- health = 75
- gold_core_spawnable = NO_SPAWN
-
-/mob/living/simple_animal/hostile/carp/ranged/chaos/Shoot()
- projectiletype = pick(allowed_projectile_types)
- ..()
-
-/mob/living/simple_animal/hostile/carp/ranged/xenobiology // these are for the xenobio gold slime pool
- gold_core_spawnable = HOSTILE_SPAWN
- allowed_projectile_types = list(/obj/projectile/magic/animate, /obj/projectile/magic/teleport,
- /obj/projectile/magic/door, /obj/projectile/magic/aoe/fireball, /obj/projectile/magic/spellblade, /obj/projectile/magic/arcane_barrage,
- /obj/projectile/magic/spell/magic_missile, /obj/projectile/magic/aoe/lightning, /obj/projectile/magic/locker) //thanks Lett1 /finally, we can synthesize the lockerfish
-
-/mob/living/simple_animal/hostile/carp/ranged/chaos/xenobiology
- gold_core_spawnable = HOSTILE_SPAWN
- allowed_projectile_types = list(/obj/projectile/magic/change, /obj/projectile/magic/animate, /obj/projectile/magic/resurrection,
- /obj/projectile/magic/death, /obj/projectile/magic/teleport, /obj/projectile/magic/door, /obj/projectile/magic/aoe/fireball,
- /obj/projectile/magic/spellblade, /obj/projectile/magic/arcane_barrage, /obj/projectile/magic/locker, /obj/projectile/magic/nothing,
- /obj/projectile/magic/aoe/lightning, /obj/projectile/magic/necropotence, /obj/projectile/magic/fortify, /obj/projectile/magic/spell/magic_missile)//now THIS is chaos
diff --git a/code/modules/fishing/fishing_portal_machine.dm b/code/modules/fishing/fishing_portal_machine.dm
index 0cbeae7c3dac..a070e7b7f797 100644
--- a/code/modules/fishing/fishing_portal_machine.dm
+++ b/code/modules/fishing/fishing_portal_machine.dm
@@ -6,7 +6,7 @@
icon_state = "portal_off"
idle_power_usage = 0
- active_power_usage = 2000
+ active_power_usage = ACTIVE_DRAW_HIGH
anchored = FALSE
density = TRUE
@@ -35,12 +35,12 @@
/obj/machinery/fishing_portal_generator/proc/activate()
active = AddComponent(/datum/component/fishing_spot, fishing_source)
- use_power = ACTIVE_POWER_USE
+ set_active_power()
update_appearance()
/obj/machinery/fishing_portal_generator/proc/deactivate()
QDEL_NULL(active)
- use_power = IDLE_POWER_USE
+ set_idle_power()
update_appearance()
/obj/machinery/fishing_portal_generator/on_set_is_operational(old_value)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 258e9a56217f..4774ea852424 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -476,15 +476,15 @@ GLOBAL_LIST_INIT(hallucination_list, list(
A = image(image_file,H,"dualsaberred1", layer=ABOVE_MOB_LAYER)
if("taser")
if(side == "right")
- image_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ image_file = GUN_RIGHTHAND_ICON
else
- image_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
+ image_file = GUN_LEFTHAND_ICON
A = image(image_file,H,"advtaserstun4", layer=ABOVE_MOB_LAYER)
if("ebow")
if(side == "right")
- image_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ image_file = GUN_RIGHTHAND_ICON
else
- image_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
+ image_file = GUN_LEFTHAND_ICON
A = image(image_file,H,"crossbow", layer=ABOVE_MOB_LAYER)
if("baton")
if(side == "right")
@@ -525,11 +525,11 @@ GLOBAL_LIST_INIT(hallucination_list, list(
/datum/hallucination/delusion
var/list/image/delusions = list()
-/datum/hallucination/delusion/New(mob/living/carbon/C, forced, force_kind = null , duration = 300,skip_nearby = TRUE, custom_icon = null, custom_icon_file = null, custom_name = null)
+/datum/hallucination/delusion/New(mob/living/carbon/C, forced, force_kind = null , duration = rand(30,300),skip_nearby = TRUE, custom_icon = null, custom_icon_file = null, custom_name = null)
set waitfor = FALSE
. = ..()
var/image/A = null
- var/kind = force_kind ? force_kind : pick("nothing","monkey","corgi","carp","skeleton","demon","zombie")
+ var/kind = force_kind ? force_kind : pick("doe","mi-go","carp","hermit","frontiersman","ramzi")
feedback_details += "Type: [kind]"
var/list/nearby
if(skip_nearby)
@@ -540,27 +540,24 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if(skip_nearby && (H in nearby))
continue
switch(kind)
- if("nothing")
- A = image('icons/effects/effects.dmi',H,"nothing")
- A.name = "..."
- if("monkey")//Monkey
- A = image('icons/mob/monkey.dmi',H,"monkey1")
- A.name = "Monkey ([rand(1,999)])"
+ if("doe")//Doe
+ A = image('icons/mob/animal.dmi',H,"deer-doe")
+ A.name = "Doe"
if("carp")//Carp
A = image('icons/mob/carp.dmi',H,"carp")
A.name = "Space Carp"
- if("corgi")//Corgi
- A = image('icons/mob/pets.dmi',H,"corgi")
- A.name = "Corgi"
- if("skeleton")//Skeletons
- A = image('icons/mob/human.dmi',H,"skeleton")
- A.name = "Skeleton"
- if("zombie")//Zombies
- A = image('icons/mob/human.dmi',H,"zombie")
- A.name = "Zombie"
- if("demon")//Demon
- A = image('icons/mob/mob.dmi',H,"daemon")
- A.name = "Demon"
+ if("mi-go")//Mi-go
+ A = image('icons/mob/animal.dmi',H,"mi-go")
+ A.name = "Mi-go"
+ if("hermit")//Hermit
+ A = image('icons/mob/simple_human.dmi',H,"survivor_gunslinger")
+ A.name = "Hermit Soldier"
+ if("frontiersman")//Frontiersman
+ A = image('icons/mob/simple_human.dmi',H,"frontiersmanrangedminigun")
+ A.name = "Frontiersman"
+ if("ramzi")//Ramzi
+ A = image('icons/mob/simple_human.dmi',H,"ramzi_base")
+ A.name = "Ramzi Commando"
if("custom")
A = image(custom_icon_file, H, custom_icon)
A.name = custom_name
@@ -568,8 +565,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if(target.client)
delusions |= A
target.client.images |= A
- if(duration)
- QDEL_IN(src, duration)
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), duration)
/datum/hallucination/delusion/Destroy()
for(var/image/I in delusions)
@@ -580,25 +576,28 @@ GLOBAL_LIST_INIT(hallucination_list, list(
/datum/hallucination/self_delusion
var/image/delusion
-/datum/hallucination/self_delusion/New(mob/living/carbon/C, forced, force_kind = null , duration = 300, custom_icon = null, custom_icon_file = null, wabbajack = TRUE) //set wabbajack to false if you want to use another fake source
+/datum/hallucination/self_delusion/New(mob/living/carbon/C, forced, force_kind = null , duration = rand(30,300), custom_icon = null, custom_icon_file = null, wabbajack = TRUE) //set wabbajack to false if you want to use another fake source
set waitfor = FALSE
..()
var/image/A = null
- var/kind = force_kind ? force_kind : pick("monkey","corgi","carp","skeleton","demon","zombie","robot")
+ var/kind = force_kind ? force_kind : pick("doe","mi-go","carp","hermit","frontiersman","ramzi","pai","robot")
feedback_details += "Type: [kind]"
switch(kind)
- if("monkey")//Monkey
- A = image('icons/mob/monkey.dmi',target,"monkey1")
+ if("doe")//Doe
+ A = image('icons/mob/animal.dmi',target,"deer-doe")
if("carp")//Carp
A = image('icons/mob/animal.dmi',target,"carp")
- if("corgi")//Corgi
- A = image('icons/mob/pets.dmi',target,"corgi")
- if("skeleton")//Skeletons
- A = image('icons/mob/human.dmi',target,"skeleton")
- if("zombie")//Zombies
- A = image('icons/mob/human.dmi',target,"zombie")
- if("demon")//Demon
- A = image('icons/mob/mob.dmi',target,"daemon")
+ if("mi-go")//Mi-go
+ A = image('icons/mob/animal.dmi',target,"mi-go")
+ if("hermit")//Hermit
+ A = image('icons/mob/simple_human.dmi',target,"survivor_base")
+ if("frontiersman")//Frontiersman
+ A = image('icons/mob/simple_human.dmi',target,"frontiersmanranged")
+ if("ramzi")//Ramzi
+ A = image('icons/mob/simple_human.dmi',target,"ramzi_base")
+ if("pai")//pAI
+ A = image('icons/mob/pai.dmi',target,"repairbot")
+ target.playsound_local(target,'sound/effects/pai_boot.ogg', 75, 1)
if("robot")//Cyborg
A = image('icons/mob/robots.dmi',target,"robot")
target.playsound_local(target,'sound/voice/liveagain.ogg', 75, 1)
@@ -610,7 +609,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
to_chat(target, "...you look down and notice... you aren't the same as you used to be...")
delusion = A
target.client.images |= A
- QDEL_IN(src, duration)
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), duration)
/datum/hallucination/self_delusion/Destroy()
if(target.client)
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index 8f88924930f4..32c4b1a9a09f 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -39,7 +39,7 @@
else
M.visible_message("[user] attempts to feed [M] the contents of [src].", \
"[user] attempts to feed you the contents of [src].")
- if(!do_mob(user, M))
+ if(!do_after(user, target = M))
return
if(!reagents || !reagents.total_volume)
return // The drink might be empty after the delay, such as by spam-feeding
@@ -120,27 +120,36 @@
if(!.) //if the bottle wasn't caught
smash(hit_atom, throwingdatum?.thrower, TRUE)
-/obj/item/reagent_containers/food/drinks/proc/smash(atom/target, mob/thrower, ranged = FALSE)
+/obj/item/reagent_containers/food/drinks/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
+ smash()
+ ..()
+
+/obj/item/reagent_containers/food/drinks/proc/smash(atom/target = FALSE, mob/thrower = FALSE, ranged = FALSE)
if(!isGlass)
return
- if(QDELING(src) || !target || !(flags_1 & INITIALIZED_1)) //Invalid loc
- return
- if(bartender_check(target) && ranged)
+ if(QDELING(src) || !(flags_1 & INITIALIZED_1)) //Invalid loc
return
- var/obj/item/broken_bottle/B = new (loc)
- B.icon_state = icon_state
- var/icon/I = new(icon, icon_state)
- I.Blend(B.broken_outline, ICON_OVERLAY, rand(5), 1)
- I.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0))
- B.icon = I
- B.name = "broken [name]"
+ if(target)
+ if(bartender_check(target) && ranged)
+ return
+ var/obj/item/broken_bottle/smashed_bottle = new (loc)
+ if(!ranged && thrower)
+ thrower.put_in_hands(smashed_bottle)
+ smashed_bottle.icon_state = icon_state
+ var/icon/new_icon = new(icon, icon_state)
+ new_icon.Blend(smashed_bottle.broken_outline, ICON_OVERLAY, rand(5), 1)
+ new_icon.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0))
+ smashed_bottle.icon = new_icon
+ smashed_bottle.name = "broken [name]"
if(prob(33))
- var/obj/item/shard/S = new(drop_location())
- target.Bumped(S)
+ var/obj/item/shard/new_shard = new(drop_location())
+ if(target)
+ target.Bumped(new_shard)
playsound(src, "shatter", 70, TRUE)
- transfer_fingerprints_to(B)
+ transfer_fingerprints_to(smashed_bottle)
qdel(src)
- target.Bumped(B)
+ if(target)
+ target.Bumped(smashed_bottle)
/obj/item/reagent_containers/food/drinks/bullet_act(obj/projectile/P)
. = ..()
@@ -212,8 +221,8 @@
// Formatting is the same as food.
/obj/item/reagent_containers/food/drinks/coffee
- name = "robust coffee"
- desc = "Careful, the beverage you're about to enjoy is extremely hot."
+ name = "Solar's Best black coffee"
+ desc = "A cup of piping hot black coffee. Made from beans grown across the solar cantons for the caffeine that every spacer needs."
icon_state = "coffee"
list_reagents = list(/datum/reagent/consumable/coffee = 30)
spillable = TRUE
@@ -249,13 +258,13 @@
icon_state = "tea_empty"
/obj/item/reagent_containers/food/drinks/mug/tea
- name = "Duke Purple tea"
- desc = "An insult to Duke Purple is an insult to the Space Queen! Any proper gentleman will fight you, if you sully this tea."
+ name = "Guildmaiden's tea"
+ desc = "Dark tea, made from pressed, fermented tea leaves. Originally from Sol, it became wildly popular among the Rachnid Guilds, and has become a staple."
list_reagents = list(/datum/reagent/consumable/tea = 30)
/obj/item/reagent_containers/food/drinks/mug/coco
- name = "Pearl Hot Chocolate"
- desc = "A rich delicacy from the humid regions of Terra."
+ name = "Solar's Best Hot Cocoa"
+ desc = "A cup of hot water mixed with chocolate and malted milk powder. A classic hot drink from the Solarian Confederation."
list_reagents = list(/datum/reagent/consumable/hot_coco = 15, /datum/reagent/consumable/sugar = 5)
foodtype = SUGAR
resistance_flags = FREEZE_PROOF
@@ -277,7 +286,7 @@
/obj/item/reagent_containers/food/drinks/dry_ramen
name = "cup ramen"
- desc = "Just add 5ml of water, self heats! A taste that reminds you of your school years. Now new with salty flavour!"
+ desc = "A cup full of dried noodles, premixed with a flavor powder. Adding 5 units of water will cause the cup to self-heat, cooking it rapidly. Commonly eaten under dozens of brands, from students to eating on a budget. Always umami!"
icon_state = "ramen"
list_reagents = list(/datum/reagent/consumable/dry_ramen = 15, /datum/reagent/consumable/sodiumchloride = 3)
foodtype = GRAIN
@@ -285,12 +294,12 @@
custom_price = 95
/obj/item/reagent_containers/food/drinks/waterbottle
- name = "bottle of water"
- desc = "A bottle of water filled at an old Earth bottling facility."
+ name = "Ryuunosuke Reserve" //we still have to find a way to make multiple variants as per the plan
+ desc = "Water bottled from a plant somewhere on Ryuunosuke. It has a mild, mineral-y flavor."
icon = 'icons/obj/drinks/drinks.dmi'
icon_state = "smallbottle"
item_state = "bottle"
- list_reagents = list(/datum/reagent/water = 49.5, /datum/reagent/fluorine = 0.5)//see desc, don't think about it too hard
+ list_reagents = list(/datum/reagent/water = 50)
custom_materials = list(/datum/material/plastic=1000)
volume = 50
amount_per_transfer_from_this = 10
@@ -360,8 +369,8 @@
update_appearance()
/obj/item/reagent_containers/food/drinks/beer
- name = "space beer"
- desc = "Beer. In space."
+ name = "Bizircan Brewery GDM" //ditto the plan for bottled water, need to find a way to make multiple variants
+ desc = "A popular Gezenan drink made of fermented honey and spices, known as Gezenan Dark Mead, or GDM for short."
icon_state = "beer"
list_reagents = list(/datum/reagent/consumable/ethanol/beer = 30)
foodtype = GRAIN | ALCOHOL
@@ -373,8 +382,8 @@
list_reagents = list(/datum/reagent/consumable/ethanol/beer/light = 30)
/obj/item/reagent_containers/food/drinks/ale
- name = "Magm-Ale"
- desc = "A true dorf's drink of choice."
+ name = "RHIMBASA TAP"
+ desc = "An ale that is brewed on Reh'himl, named after the planet that shields it from their sun. Telh'aim Pale Ales are shortened to TAP, with most breweries reducing their names to acronyms alongside it."
icon_state = "alebottle"
item_state = "beer"
list_reagents = list(/datum/reagent/consumable/ethanol/ale = 30)
@@ -445,17 +454,17 @@
if(/datum/reagent/consumable/pineapplejuice)
icon_state = "pineapplebox"
name = "pineapple juice box"
- desc = "Why would you even want this?"
+ desc = "Sweet, tart pineapple juice."
foodtype = FRUIT | PINEAPPLE
if(/datum/reagent/consumable/milk/chocolate_milk)
icon_state = "chocolatebox"
name = "carton of chocolate milk"
- desc = "Milk for cool kids!"
+ desc = "Milk mixed with chocolate, a common childhood favorite!"
foodtype = SUGAR
if(/datum/reagent/consumable/ethanol/eggnog)
icon_state = "nog2"
name = "carton of eggnog"
- desc = "For enjoying the most wonderful time of the year."
+ desc = "A carton of eggnog, a drink of choice for celebrating Winter Solstice."
foodtype = MEAT
else
icon_state = "juicebox"
@@ -502,7 +511,7 @@
/obj/item/reagent_containers/food/drinks/flask
name = "flask"
- desc = "Every good spaceman knows it's a good idea to bring along a couple of pints of whiskey wherever they go."
+ desc = "Every good spacer knows it's a good idea to bring along a couple of pints of whiskey wherever they go."
custom_price = 200
icon_state = "flask"
custom_materials = list(/datum/material/iron=250)
@@ -521,10 +530,10 @@
icon_state = "detflask"
list_reagents = list(/datum/reagent/consumable/ethanol/whiskey = 30)
-/obj/item/reagent_containers/food/drinks/britcup
+/obj/item/reagent_containers/food/drinks/mug
name = "cup"
- desc = "A cup with the british flag emblazoned on it."
- icon_state = "britcup"
+ desc = "A mug. Stylishly plain."
+ icon_state = "tea_empty"
volume = 30
spillable = TRUE
@@ -634,39 +643,35 @@
. = ..()
/obj/item/reagent_containers/food/drinks/soda_cans/cola
- name = "Space Cola"
- desc = "Cola. in space."
+ name = "Master Cola"
+ desc = "Originally a commission to the Rachnid culinary guilds from Solarian historical reenactors on creating an authentic cola that, at some point, dominated the globe in popularity, this soft drink comes as close to anyone might be able to taste the sodas of yore... But it's still a pretty alright drink."
icon_state = "cola"
list_reagents = list(/datum/reagent/consumable/space_cola = 30)
foodtype = SUGAR
/obj/item/reagent_containers/food/drinks/soda_cans/tonic
- name = "T-Borg's tonic water"
- desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away."
+ name = "Sixikirtchia's Tonic"
+ desc = "A can of water mixed with quinine, which the label purportedly states that it has more health benefits for the Vox than fending off malaria. Most people use it for mixing drinks, Vox or otherwise."
icon_state = "tonic"
list_reagents = list(/datum/reagent/consumable/tonic = 50)
foodtype = ALCOHOL
/obj/item/reagent_containers/food/drinks/soda_cans/sodawater
- name = "soda water"
- desc = "A can of soda water. Why not make a scotch and soda?"
+ name = "Stitiamix Club"
+ desc = "Mineral-flavored carbonated water, infused on some part of The Shoal. Touts being made out of minerals from embedded asteroids, apparently!"
icon_state = "sodawater"
list_reagents = list(/datum/reagent/consumable/sodawater = 50)
-/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime
- name = "orange soda"
- desc = "You wanted ORANGE. It gave you Lemon Lime."
- icon_state = "lemon-lime"
- list_reagents = list(/datum/reagent/consumable/lemon_lime = 30)
+/obj/item/reagent_containers/food/drinks/soda_cans/orange_soda
+ name = "Sol Sparkler: Orange Remembrance"
+ desc = "A line of flavored seltzer water from the Solarian Confederation. Its infamy stems from being flavored sparingly enough to warrant it being referred to as being vague memories of the fruit in question."
+ icon_state = "orange_soda"
+ list_reagents = list(/datum/reagent/consumable/orangejuice = 5, /datum/reagent/consumable/sodawater = 25)
foodtype = FRUIT
-/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime/Initialize()
- . = ..()
- name = "lemon-lime soda"
-
/obj/item/reagent_containers/food/drinks/soda_cans/sol_dry
name = "Sol Dry"
- desc = "Maybe this will help your tummy feel better. Maybe not."
+ desc = "A can of ginger ale, known for helping those with upset stomachs. Popularized due to a widespread belief from Solarians that drinking it will alleviate the nausea from bluespace travel."
icon_state = "sol_dry"
list_reagents = list(/datum/reagent/consumable/sol_dry = 30)
foodtype = SUGAR
@@ -678,86 +683,79 @@
list_reagents = list(/datum/reagent/consumable/space_up = 30)
foodtype = SUGAR | JUNKFOOD
-/obj/item/reagent_containers/food/drinks/soda_cans/starkist
- name = "Star-kist"
- desc = "The taste of a star in liquid form. And, a bit of tuna...?"
- icon_state = "starkist"
- list_reagents = list(/datum/reagent/consumable/space_cola = 15, /datum/reagent/consumable/orangejuice = 15)
+/obj/item/reagent_containers/food/drinks/soda_cans/lunapunch
+ name = "Lunapunch"
+ desc = "A soda with a distinctly herbal sweetness and a bitter aftertaste, popular across the C.L.I.P. colonies. Originally marketed as a health soft-drink for members of the CMM, the herbs used in its recipe claim to have health benefits... to dubious results."
+ icon_state = "lunapunch"
+ list_reagents = list(/datum/reagent/consumable/lunapunch = 30)
foodtype = SUGAR | FRUIT | JUNKFOOD
-/obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind
- name = "Space Mountain Wind"
- desc = "Blows right through you like a space wind."
- icon_state = "space_mountain_wind"
- list_reagents = list(/datum/reagent/consumable/spacemountainwind = 30)
+/obj/item/reagent_containers/food/drinks/soda_cans/comet_trail
+ name = "Comet Trail"
+ desc = "A citrusy drink from the Kepori space installation known as The Ring. Known for its sharp flavor and refreshing carbonation -- best served cold."
+ icon_state = "comet_trail"
+ list_reagents = list(/datum/reagent/consumable/comet_trail = 30)
foodtype = SUGAR | JUNKFOOD
-/obj/item/reagent_containers/food/drinks/soda_cans/thirteenloko
- name = "Thirteen Loko"
- desc = "The CMO has advised crew members that consumption of Thirteen Loko may result in seizures, blindness, drunkenness, or even death. Please Drink Responsibly."
+/obj/item/reagent_containers/food/drinks/soda_cans/vimukti
+ name = "Vimukti"
+ desc = "A liquor brewed from sweet lichen scraped off the walls of Shoal water condensers. Stamped with the thirteen-spoked wheel of enlightenment. Spiritual Vox consider it to open the mind's boundaries."
icon_state = "thirteen_loko"
- list_reagents = list(/datum/reagent/consumable/ethanol/thirteenloko = 30)
+ list_reagents = list(/datum/reagent/consumable/ethanol/vimukti = 30)
foodtype = SUGAR | JUNKFOOD
-/obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb
- name = "Dr. Gibb"
- desc = "A delicious mixture of 42 different flavors."
- icon_state = "dr_gibb"
- list_reagents = list(/datum/reagent/consumable/dr_gibb = 30)
+/obj/item/reagent_containers/food/drinks/soda_cans/tadrixx
+ name = "Tadrixx"
+ desc = "A Kalixcian drink made from a plant that tastes similar to sassafrass, which is used in root beer. A stumpy drake holding a mug of it is on the front."
+ icon_state = "tadrixx"
+ list_reagents = list(/datum/reagent/consumable/tadrixx = 30)
foodtype = SUGAR | JUNKFOOD
-/obj/item/reagent_containers/food/drinks/soda_cans/pwr_game
- name = "Pwr Game"
- desc = "The only drink with the PWR that true gamers crave. When a gamer talks about gamerfuel, this is what they're literally referring to."
+/obj/item/reagent_containers/food/drinks/soda_cans/pacfuel
+ name = "PAC-Fuel"
+ desc = "A carbonated energy drink themed after the purple coloration, similar to plasma. It seems to have gotten a sponsorship with the the G.E.C., with a special offer for some sort of deal on... gaming gear and industrial equipment?"
icon_state = "purple_can"
- list_reagents = list(/datum/reagent/consumable/pwr_game = 30)
+ list_reagents = list(/datum/reagent/consumable/pacfuel = 30)
-/obj/item/reagent_containers/food/drinks/soda_cans/shamblers
- name = "Shambler's juice"
- desc = "~Shake me up some of that Shambler's Juice!~"
- icon_state = "shamblers"
- list_reagents = list(/datum/reagent/consumable/shamblers = 30)
+/obj/item/reagent_containers/food/drinks/soda_cans/shoal_punch
+ name = "Shoal Punch"
+ desc = "Carbonated fruit soda, made from a mix of dozens of fruits collected and grown on The Shoal. There's an extensive list of potential allergens on the back."
+ icon_state = "shoal_punch"
+ list_reagents = list(/datum/reagent/consumable/shoal_punch = 30)
foodtype = SUGAR | JUNKFOOD
-/obj/item/reagent_containers/food/drinks/soda_cans/grey_bull
- name = "Grey Bull"
- desc = "Grey Bull, it gives you gloves!"
+/obj/item/reagent_containers/food/drinks/soda_cans/crosstalk
+ name = "Crosstalk"
+ desc = "Crosstalk! Share the energy with everyone! The can is a little thin to be passing it around to actually share the energy drink around, though."
icon_state = "energy_drink"
- list_reagents = list(/datum/reagent/consumable/grey_bull = 20)
+ list_reagents = list(/datum/reagent/consumable/crosstalk = 20)
foodtype = SUGAR | JUNKFOOD
-/obj/item/reagent_containers/food/drinks/soda_cans/monkey_energy
- name = "Monkey Energy"
- desc = "Unleash the ape!"
- icon_state = "monkey_energy"
- item_state = "monkey_energy"
- list_reagents = list(/datum/reagent/consumable/monkey_energy = 40, /datum/reagent/consumable/electrolytes = 10)
+/obj/item/reagent_containers/food/drinks/soda_cans/xeno_energy
+ name = "Xeno-Energy"
+ desc = "A sickly green energy drink that poses itself as made from the real blood of xenomorphs. Deeply controversial among the BARD ranks."
+ icon_state = "xeno_energy"
+ item_state = "xeno_energy"
+ list_reagents = list(/datum/reagent/consumable/xeno_energy = 40, /datum/reagent/consumable/electrolytes = 10)
foodtype = SUGAR | JUNKFOOD
-/obj/item/reagent_containers/food/drinks/soda_cans/efuel
- name = "E-Fuel"
- desc = "Shocking for the Elzu!"
- icon_state = "monkey_energy"
- item_state = "monkey_energy"
- list_reagents = list(/datum/reagent/consumable/electrolytes = 50)
-
/obj/item/reagent_containers/food/drinks/soda_cans/air
- name = "canned air"
- desc = "There is no air shortage. Do not drink."
+ name = "Tradewind Canned"
+ desc = "Intended to be filled with air from home planets for the sake of nostalgia after it's initial failure as an emergency method of 'canning air'. Tradewind Canned - a breath from home."
icon_state = "air"
list_reagents = list(/datum/reagent/nitrogen = 24, /datum/reagent/oxygen = 6)
/obj/item/reagent_containers/food/drinks/soda_cans/molten
name = "Molten Bubbles"
- desc = "A spicy cola to cool the nerves and burn the soul."
+ desc = "A spicy soft drink made from a coca-like plant from Kalixcis. Popularly served both cold -and- hot, depending on the weather."
icon_state = "molten"
- list_reagents = list(/datum/reagent/medicine/molten_bubbles = 50)
+ list_reagents = list(/datum/reagent/consumable/molten = 50)
/obj/item/reagent_containers/food/drinks/soda_cans/plasma
name = "Plasma Fizz"
- desc = "A dangerous fusion of flavors!"
+ desc = "A spinoff of the popular Molten Bubbles drink from Kalixcis, made to emulate the flavor of spiced grape instead. It's... not exactly convincing or a very good mix."
icon_state = "plasma"
- list_reagents = list(/datum/reagent/medicine/molten_bubbles/plasma = 50)
+ list_reagents = list(/datum/reagent/consumable/molten/plasma_fizz = 50)
/obj/item/reagent_containers/food/drinks/ration
name = "empty ration pouch"
diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
index 4da78a5989a1..57d84ee22397 100644
--- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
@@ -34,39 +34,7 @@
volume = 50
custom_price = 55
-/obj/item/reagent_containers/food/drinks/bottle/smash(mob/living/target, mob/thrower, ranged = FALSE)
- if(QDELING(src) || !target || !(flags_1 & INITIALIZED_1)) //Invalid loc
- return
- //Creates a shattering noise and replaces the bottle with a broken_bottle
- if(bartender_check(target) && ranged)
- return
- var/obj/item/broken_bottle/B = new (loc)
- if(!ranged && thrower)
- thrower.put_in_hands(B)
- B.icon_state = icon_state
-
- var/icon/I = new('icons/obj/drinks/drinks.dmi', src.icon_state)
- I.Blend(B.broken_outline, ICON_OVERLAY, rand(5), 1)
- I.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0))
- B.icon = I
-
- if(isGlass)
- if(prob(33))
- var/obj/item/shard/S = new(drop_location())
- target.Bumped(S)
- playsound(src, "shatter", 70, TRUE)
- else
- B.force = 0
- B.throwforce = 0
- B.desc = "A carton with the bottom half burst open. Might give you a papercut."
- B.name = "broken [name]"
- transfer_fingerprints_to(B)
-
- qdel(src)
- target.Bumped(B)
-
/obj/item/reagent_containers/food/drinks/bottle/attack(mob/living/target, mob/living/user)
-
if(!target)
return
@@ -156,20 +124,20 @@
AddComponent(/datum/component/butchering, 200, 55)
/obj/item/reagent_containers/food/drinks/bottle/gin
- name = "Griffeater gin"
- desc = "A bottle of high quality gin, produced in the New London Space Station."
+ name = "Neue Wacholder Gin"
+ desc = "A bottle of high quality gin, cultivated from juniper berries grown across the Solar cantons. Brewed in Stuteföhle."
icon_state = "ginbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/gin = 100)
/obj/item/reagent_containers/food/drinks/bottle/whiskey
- name = "Uncle Git's special reserve"
- desc = "A premium single-malt whiskey, gently matured inside the tunnels of a nuclear shelter. TUNNEL WHISKEY RULES."
+ name = "Kadi-Witka Reserve"
+ desc = "An equivalent to single-malt whiskey, commonly enjoyed and brewed in a brewery originally founded Zohil. While different from traditionally used wheat, it can be safely enjoyed by every species."
icon_state = "whiskeybottle"
list_reagents = list(/datum/reagent/consumable/ethanol/whiskey = 100)
/obj/item/reagent_containers/food/drinks/bottle/kong
name = "Kong"
- desc = "Makes You Go Ape!®"
+ desc = "Makes You Go Ape!"
list_reagents = list(/datum/reagent/consumable/ethanol/whiskey/kong = 100)
/obj/item/reagent_containers/food/drinks/bottle/candycornliquor
@@ -178,8 +146,8 @@
list_reagents = list(/datum/reagent/consumable/ethanol/whiskey/candycorn = 100)
/obj/item/reagent_containers/food/drinks/bottle/vodka
- name = "Tunguska triple distilled"
- desc = "Vodka, prime choice of drink and fuel."
+ name = "Triple Horned"
+ desc = "Potato-based liquor commonly known as Vodka, distilled thrice to the standards of the PGF's requirements for their rations."
icon_state = "vodkabottle"
list_reagents = list(/datum/reagent/consumable/ethanol/vodka = 100)
@@ -190,8 +158,8 @@
list_reagents = list(/datum/reagent/consumable/ethanol/vodka = 100)
/obj/item/reagent_containers/food/drinks/bottle/tequila
- name = "Caccavo guaranteed quality tequila"
- desc = "Made from premium petroleum distillates, pure thalidomide and other fine quality ingredients!"
+ name = "Rimeki Letisa"
+ desc = "Originally made from fermented succulents growing near Teceti's equator-deserts, this brand considers itself equivalent to the original tequila."
icon_state = "tequilabottle"
list_reagents = list(/datum/reagent/consumable/ethanol/tequila = 100)
@@ -205,19 +173,19 @@
/obj/item/reagent_containers/food/drinks/bottle/patron
name = "Wrapp Artiste Patron"
- desc = "Silver laced tequila, served in space night clubs across the galaxy."
+ desc = "Tequila laced with silver, showy enough to impress when ordered in nightclubs across the galaxy."
icon_state = "patronbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/patron = 100)
/obj/item/reagent_containers/food/drinks/bottle/rum
- name = "Captain Pete's Cuban spiced rum"
- desc = "This isn't just rum, oh no. It's practically GRIFF in a bottle."
+ name = "Ahkskra Spiced"
+ desc = "Ahkskra Spiced - a spiced rum for the vox folkhero in everyone. Features a gallant-looking vox on the front of the bottle."
icon_state = "rumbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/rum = 100)
/obj/item/reagent_containers/food/drinks/bottle/holywater
name = "flask of holy water"
- desc = "A flask of the chaplain's holy water."
+ desc = "A flask of water, sanctified in some way by the supertitious."
icon_state = "holyflask"
list_reagents = list(/datum/reagent/water/holywater = 100)
foodtype = NONE
@@ -227,144 +195,108 @@
list_reagents = list(/datum/reagent/hellwater = 100)
/obj/item/reagent_containers/food/drinks/bottle/vermouth
- name = "Goldeneye vermouth"
- desc = "Sweet, sweet dryness~"
+ name = "Whitespear Dry"
+ desc = "Dry and sweet vermouth, commonly used for mixed drinks. Some Solarians drink it as a digestive before meals."
icon_state = "vermouthbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/vermouth = 100)
/obj/item/reagent_containers/food/drinks/bottle/kahlua
- name = "Robert Robust's coffee liqueur"
- desc = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936, HONK."
+ name = "Keh'Lu'Tex Liqueur"
+ desc = "An adapted recipe of a caffeine-mixed liqueur originating from Reh'himl, which replaces it's original ingredient with coffee from Terra."
icon_state = "kahluabottle"
list_reagents = list(/datum/reagent/consumable/ethanol/kahlua = 100)
foodtype = VEGETABLES
/obj/item/reagent_containers/food/drinks/bottle/goldschlager
- name = "College Girl goldschlager"
- desc = "Because they are the only ones who will drink 100 proof cinnamon schnapps."
+ name = "Student-Union's Gold Standard"
+ desc = "Extremely high-proof cinnamon schnapps, typically found in commemorative bottles by those in the Student-Union Association of Naturalistic Sciences. Nigh-undrinkable and with a tasteless amount of gold flakes floating within."
icon_state = "goldschlagerbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/goldschlager = 100)
/obj/item/reagent_containers/food/drinks/bottle/cognac
- name = "Chateau de Baton premium cognac"
- desc = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing. You might as well not scream 'SHITCURITY' this time."
+ name = "Geheimnis Cognac"
+ desc = "While the origins of the name 'cognac' are lost to time, this type of brandy is reserved as a high-class drink with particular methods of brewing."
icon_state = "cognacbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/cognac = 100)
/obj/item/reagent_containers/food/drinks/bottle/wine
- name = "Doublebeard's bearded special wine"
- desc = "A faint aura of unease and asspainery surrounds the bottle."
+ name = "Waldstätte Sauvignon"
+ desc = "A bottle of wine, brewed from grapes specifically grown in Neue Waldstätte. You've mostly seen these in bottles sold specifically for tourists."
icon_state = "winebottle"
list_reagents = list(/datum/reagent/consumable/ethanol/wine = 100)
foodtype = FRUIT | ALCOHOL
/obj/item/reagent_containers/food/drinks/bottle/absinthe
- name = "extra-strong absinthe"
- desc = "An strong alcoholic drink brewed and distributed by"
+ name = "Severtail Green"
+ desc = "Strong absinthe brewed in the Pan-Gezenan Federation, with their own transplants of Wormwood gifted to them during the first contact with humankind. If the legend (and label) means anything, the first attempt at brewing this caused some poor sarathi's tail to fall off."
icon_state = "absinthebottle"
list_reagents = list(/datum/reagent/consumable/ethanol/absinthe = 100)
-/obj/item/reagent_containers/food/drinks/bottle/absinthe/Initialize()
- . = ..()
- redact()
-
-/obj/item/reagent_containers/food/drinks/bottle/absinthe/proc/redact()
- // There was a large fight in the coderbus about a player reference
- // in absinthe. Ergo, this is why the name generation is now so
- // complicated. Judge us kindly.
- var/shortname = pickweight(
- list("T&T" = 1, "A&A" = 1, "Generic" = 1))
- var/fullname
- switch(shortname)
- if("T&T")
- fullname = "Teal and Tealer"
- if("A&A")
- fullname = "Ash and Asher"
- if("Generic")
- fullname = "Nanotrasen Cheap Imitations"
- var/removals = list("\[REDACTED\]", "\[EXPLETIVE DELETED\]",
- "\[EXPUNGED\]", "\[INFORMATION ABOVE YOUR SECURITY CLEARANCE\]",
- "\[MOVE ALONG CITIZEN\]", "\[NOTHING TO SEE HERE\]")
- var/chance = 50
-
- if(prob(chance))
- shortname = pick_n_take(removals)
-
- var/list/final_fullname = list()
- for(var/word in splittext(fullname, " "))
- if(prob(chance))
- word = pick_n_take(removals)
- final_fullname += word
-
- fullname = jointext(final_fullname, " ")
-
- // Actually finally setting the new name and desc
- name = "[shortname] [name]"
- desc = "[desc] [fullname] Inc."
-
-
/obj/item/reagent_containers/food/drinks/bottle/absinthe/premium
- name = "Gwyn's premium absinthe"
- desc = "A potent alcoholic beverage, almost makes you forget the ash in your lungs."
+ name = "Chacheyi Gold"
+ desc = "A higher shelf absinthe, distributed primarily from The Shoal. Features the folkhero Chacheyi on the label, alongside their goldgrub companions."
icon_state = "absinthepremium"
-/obj/item/reagent_containers/food/drinks/bottle/absinthe/premium/redact()
- return
-
/obj/item/reagent_containers/food/drinks/bottle/lizardwine
- name = "bottle of 'kalixcis' wine"
- desc = "An alcoholic beverage of sarathi origin, now so widespread that knock-offs can be found everywhere. Check the label for point of origin."
+ name = "bottle of Blueflame Pyrecask"
+ desc = "An alcoholic beverage originating from isolated vineyards on Zohil, maintained by the reclusive religious sects of the Blueflame. Now considered so popular and high quality, imitation bottles can be found everywhere. Check the label for point of origin."
icon_state = "lizardwine"
list_reagents = list(/datum/reagent/consumable/ethanol/lizardwine = 100)
foodtype = FRUIT | ALCOHOL
/obj/item/reagent_containers/food/drinks/bottle/hcider
- name = "Jian Hard Cider"
- desc = "Apple juice for adults."
+ name = "Neue Hamburg Spiced"
+ desc = "One of the main exports of Neue Hamburg - hard, spiced cider. Enjoyed all across the cantons and beyond."
icon_state = "hcider"
volume = 50
list_reagents = list(/datum/reagent/consumable/ethanol/hcider = 50)
/obj/item/reagent_containers/food/drinks/bottle/amaretto
- name = "Luini Amaretto"
- desc = "A gentle and syrup like drink, tastes of almonds and apricots"
+ name = "Lu'Ni'Xer'Nan Amaretto"
+ desc = "A popular Rachnid take on the recipe for Amaretto, which fell to obscurity after only being semi-rediscovered by Solarian historians. Features a semi-reconstructed depiction of a supposed origin story, with the painter Lu'Ni'Xer'Nan and her muse, an innkeeper."
icon_state = "disaronno"
list_reagents = list(/datum/reagent/consumable/ethanol/amaretto = 100)
/obj/item/reagent_containers/food/drinks/bottle/grappa
- name = "Phillipes well-aged Grappa"
- desc = "Bottle of Grappa."
+ name = "Neue Maynila Grappamiel"
+ desc = "A bottle of Grappa, premixed with honey-based spirits. Commonly seen as a drink for recycling grapes after their use in winemaking, and commonly seen as a winter drink."
icon_state = "grappabottle"
list_reagents = list(/datum/reagent/consumable/ethanol/grappa = 100)
/obj/item/reagent_containers/food/drinks/bottle/sake
- name = "Ryo's traditional sake"
- desc = "Sweet as can be, and burns like fire going down."
+ name = "Sakamai Sake"
+ desc = "An alcoholic drink derived from rice, rediscovered by Solarian historians and reintroduced to the best of their ability to reproduce it."
icon_state = "sakebottle"
list_reagents = list(/datum/reagent/consumable/ethanol/sake = 100)
/obj/item/reagent_containers/food/drinks/bottle/sake/Initialize()
. = ..()
if(prob(10))
- name = "Fluffy Tail Sake"
- desc += " On the bottle is a picture of a kitsune with nine touchable tails."
+ name = "Fluffy Tail"
+ desc += "This particular brand's mascot is a human with nine fox tails - which is an impressive amount of genemodding."
icon_state = "sakebottle_k"
else if(prob(10))
name = "Inubashiri's Home Brew"
- desc += " Awoo."
+ desc += "This particular brand's mascot is a human with vaguely canine ears and a tail."
icon_state = "sakebottle_i"
/obj/item/reagent_containers/food/drinks/bottle/fernet
name = "Fernet Bronca"
- desc = "A bottle of pure Fernet Bronca, produced in Cordoba Space Station"
+ desc = "A bitter and aromatic drink, commonly enjoyed in the intersolar cantons due to relaxed alcoholic tariffs from being technically classified as a medicinal beverage. Commonly mixed with cola-based soft drinks."
icon_state = "fernetbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/fernet = 100)
+/obj/item/reagent_containers/food/drinks/bottle/triplesec
+ name = "Teeka-Gih's triple sec liqueur"
+ desc = "A bottle of triple sec originating from Bezuts."
+ icon_state = "triplesecbottle"
+ list_reagents = list(/datum/reagent/consumable/ethanol/triple_sec = 100)
+
//////////////////////////JUICES AND STUFF ///////////////////////
/obj/item/reagent_containers/food/drinks/bottle/orangejuice
name = "orange juice"
- desc = "Full of vitamins and deliciousness!"
+ desc = "Sweet and tart orange juice. Usually found fortified to make it more nutritious. Full of vitamin C!"
custom_price = 100
icon_state = "orangejuice"
item_state = "carton"
@@ -374,9 +306,21 @@
list_reagents = list(/datum/reagent/consumable/orangejuice = 100)
foodtype = FRUIT | BREAKFAST
+/obj/item/reagent_containers/food/drinks/bottle/lemonjuice
+ name = "lemon juice"
+ desc = "Lemonade for everyone!"
+ custom_price = 100
+ icon_state = "lemonjuice"
+ item_state = "carton"
+ lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
+ isGlass = FALSE
+ list_reagents = list(/datum/reagent/consumable/lemonjuice = 100)
+ foodtype = FRUIT
+
/obj/item/reagent_containers/food/drinks/bottle/cream
name = "milk cream"
- desc = "It's cream. Made from milk. What else did you think you'd find in there?"
+ desc = "Cream made from milk. It's thicker than milk, which hopefully prevents any mixups."
custom_price = 100
icon_state = "cream"
item_state = "carton"
@@ -388,7 +332,7 @@
/obj/item/reagent_containers/food/drinks/bottle/tomatojuice
name = "tomato juice"
- desc = "Well, at least it LOOKS like tomato juice. You can't tell with all that redness."
+ desc = "Juice from tomatoes and salt. You'll often find some technicians soaking in this if they've been working with plasma."
custom_price = 100
icon_state = "tomatojuice"
item_state = "carton"
@@ -400,7 +344,7 @@
/obj/item/reagent_containers/food/drinks/bottle/limejuice
name = "lime juice"
- desc = "Sweet-sour goodness."
+ desc = "Lime juice. You might want to mix something with this instead of drinking it straight..."
custom_price = 100
icon_state = "limejuice"
item_state = "carton"
@@ -412,7 +356,7 @@
/obj/item/reagent_containers/food/drinks/bottle/pineapplejuice
name = "pineapple juice"
- desc = "Extremely tart, yellow juice."
+ desc = "Tart, sweet juice from the tropical pineapple."
custom_price = 100
icon_state = "pineapplejuice"
item_state = "carton"
@@ -435,8 +379,8 @@
list_reagents = list(/datum/reagent/consumable/menthol = 100)
/obj/item/reagent_containers/food/drinks/bottle/grenadine
- name = "Jester Grenadine"
- desc = "Contains 0% real cherries!"
+ name = "Three-Star Grenadine"
+ desc = "A commonly seen bottle of grenadine - or sweet fruit syrup. It might even contain real cherries, as well as some blackcurrant for color."
custom_price = 100
icon_state = "grenadine"
isGlass = TRUE
@@ -445,8 +389,8 @@
/obj/item/reagent_containers/food/drinks/bottle/applejack
- name = "Buckin' Bronco's Applejack"
- desc = "Kicks like a horse, tastes like an apple!"
+ name = "Mars Lightning"
+ desc = "A strong brandy originating from apples, considered the older sibling to hard cider. Mars Lightning is often partnered with anti-gravity racing companies, leading to it often being served straight or for impromptu mixes."
custom_price = 100
icon_state = "applejack_bottle"
isGlass = TRUE
@@ -454,22 +398,22 @@
foodtype = FRUIT
/obj/item/reagent_containers/food/drinks/bottle/champagne
- name = "Eau d' Dandy Brut Champagne"
- desc = "Finely sourced from only the most pretentious French vineyards."
+ name = "Treu Champagne"
+ desc = "Finely sourced from entire canton planets dedicated to faithful reproduction of pre-Night Of Fire vineyards. Typically enjoyed for celebrations and the turn of new years."
custom_premium_price = 250
icon_state = "champagne_bottle"
isGlass = TRUE
list_reagents = list(/datum/reagent/consumable/ethanol/champagne = 100)
/obj/item/reagent_containers/food/drinks/bottle/blazaam
- name = "Ginbad's Blazaam"
- desc = "You feel like you should give the bottle a good rub before opening."
+ name = "Hyperspace Highball"
+ desc = "Infamously expensive, infamously contains bluespace 'flakes' for bragging rights, and infamously removed from most shelves due to accidents involving teleportation accidents upon ingestion."
icon_state = "blazaambottle"
list_reagents = list(/datum/reagent/consumable/ethanol/blazaam = 100)
/obj/item/reagent_containers/food/drinks/bottle/trappist
- name = "Mont de Requin Trappistes Bleu"
- desc = "Brewed in space-Belgium. Fancy!"
+ name = "Roumain Trapper's"
+ desc = "Traditionally (and heavily monitored for authenticity) made beer brewed on Illestren. Trapper's beer must be brewed by Saint Roumain Hunters or Shadows, made to fit the needs of their community first, and must never be made for profit... which makes it a common sight in the Frontier."
custom_premium_price = 170
icon_state = "trappistbottle"
volume = 50
@@ -477,27 +421,41 @@
/obj/item/reagent_containers/food/drinks/bottle/hooch
name = "hooch bottle"
- desc = "A bottle of rotgut. Its owner has applied some street wisdom to cleverly disguise it as a brown paper bag."
+ desc = "A bottle of homebrewed, low quality alcohol. The paper wrapping is covered in little signatures and messages - how many hands have passed this bottle before you came around?"
icon_state = "hoochbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/hooch = 100)
/obj/item/reagent_containers/food/drinks/bottle/moonshine
name = "moonshine jug"
- desc = "It is said that the ancient Applalacians used these stoneware jugs to capture lightning in a bottle."
+ desc = "High-proof hard liquor, most likely made in the privacy of a bootlegger's ship. Permanent marker on packaging tape is the most you'll get for a label. Remember: if it doesn't burn blue, don't drink it!"
icon_state = "moonshinebottle"
list_reagents = list(/datum/reagent/consumable/ethanol/moonshine = 100)
/obj/item/reagent_containers/food/drinks/bottle/coconut
- name = "Tali's Pure Coconut Delight"
- desc = "Seems to be some promotional product for a Teceti video game. You're pretty certain this stuff is synthetic."
+ name = "T4l1's Pure Coconut Delight"
+ desc = "A fanmade, promotional bottle of coconut cream liquor. There's a stylized picture of a synthetic kepori on the side, along with a blurb about whoever she is. You're pretty certain this stuff is synthetic, despite Teceti growing actual coconut trees..." //if i have to recognize rilena here, I'm going to have fun with it
icon_state = "coconutbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/creme_de_coconut = 100)
isGlass = TRUE
+/obj/item/reagent_containers/food/drinks/bottle/cacao
+ name = "Sharai's Pure Cacao Delight"
+ desc = "Seems to be some promotional product for a Teceti video game. You're pretty certain this stuff is synthetic."
+ icon_state = "cacaobottle"
+ list_reagents = list(/datum/reagent/consumable/ethanol/creme_de_cacao = 100)
+ isGlass = TRUE
+
+/obj/item/reagent_containers/food/drinks/bottle/menthe
+ name = "Mora's Pure Mint Delight"
+ desc = "Seems to be some promotional product for a Teceti video game. You're pretty certain this stuff is synthetic."
+ icon_state = "mintbottle"
+ list_reagents = list(/datum/reagent/consumable/ethanol/creme_de_menthe = 100)
+ isGlass = TRUE
+
////////////////////////// MOLOTOV ///////////////////////
/obj/item/reagent_containers/food/drinks/bottle/molotov
name = "molotov cocktail"
- desc = "A throwing weapon used to ignite things, typically filled with an accelerant. Recommended highly by rioters and revolutionaries. Light and toss."
+ desc = "A throwing weapon used to ignite things, typically filled with an accelerant. Recommended highly by desperate militias and revolutionaries. Light and toss."
icon_state = "vodkabottle"
list_reagents = list()
var/active = 0
@@ -557,7 +515,7 @@
/obj/item/reagent_containers/food/drinks/bottle/pruno
name = "pruno mix"
- desc = "A trash bag filled with fruit, sugar, yeast, and water, pulped together into a pungent slurry to be fermented in an enclosed space, traditionally the toilet. Security would love to confiscate this, one of the many things wrong with them."
+ desc = "A trash bag filled with fruit, sugar, yeast, and water, pulped together into a pungent slurry to be fermented in an enclosed space, traditionally the toilet."
icon = 'icons/obj/janitor.dmi'
icon_state = "trashbag"
list_reagents = list(/datum/reagent/consumable/prunomix = 50)
@@ -601,7 +559,7 @@
else
reagents.add_reagent(/datum/reagent/consumable/ethanol/pruno, 50)
name = "bag of pruno"
- desc = "Fermented prison wine made from fruit, sugar, and despair. You probably shouldn't drink this around Security."
+ desc = "Fermented prison wine made from fruit, sugar, and despair."
icon_state = "trashbag1" // pruno releases air as it ferments, we don't want to simulate this in atmos, but we can make it look like it did
for (var/mob/living/M in view(2, get_turf(src))) // letting people and/or narcs know when the pruno is done
to_chat(M, "A pungent smell emanates from [src], like fruit puking out its guts.")
@@ -609,7 +567,7 @@
/obj/item/reagent_containers/food/drinks/colocup/lean
name = "lean"
- desc = "A cup of that purple drank, the stuff that makes you go WHEEZY BABY."
+ desc = "Despite this mix of codeine-based cough syrup and a soft drink of choice being popular online, you're not sure anyone talking about ever tried it. First time for everything?"
icon_state = "lean"
list_reagents = list(/datum/reagent/consumable/lean = 50)
random_sprite = FALSE
@@ -619,7 +577,7 @@
desc = "Sealed for a guaranteed fresh taste in every bottle."
icon_state = "sandbottle"
volume = 50
- list_reagents = list(/datum/reagent/medicine/molten_bubbles/sand = 50)
+ list_reagents = list(/datum/reagent/consumable/molten/sand = 50)
reagent_flags = null //Cap's on
/obj/item/reagent_containers/food/drinks/bottle/sarsaparilla/attack_self(mob/user)
@@ -694,7 +652,7 @@
. = ..()
if(sealed)
var/datum/component/storage/S = GetComponent(/datum/component/storage)
- user.visible_message("[user] prys open \the [src].", "You pry open \the [src]")
+ user.visible_message("[user] pries open \the [src].", "You pry open \the [src]")
playsound(src, 'sound/machines/wooden_closet_close.ogg', 20, 1)
sealed = FALSE
S.locked = FALSE
@@ -704,7 +662,7 @@
/obj/item/storage/bottles/sandblast
name = "sarsaparilla bottle crate"
- desc = "Holds six bottles of the finest sarsaparilla this side of the sector."
+ desc = "Holds six bottles of the finest sarsaparilla this side of the Frontier."
sealed = TRUE
/obj/item/storage/bottles/sandblast/PopulateContents()
diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
index 1d7adb7db4f2..2f73f7678e38 100644
--- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
@@ -100,10 +100,6 @@
name = "Space Cola"
list_reagents = list(/datum/reagent/consumable/space_cola = 50)
-/obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola
- name = "Nuka Cola"
- list_reagents = list(/datum/reagent/consumable/nuka_cola = 50)
-
/obj/item/reagent_containers/food/drinks/drinkingglass/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs
var/obj/item/reagent_containers/food/snacks/egg/E = I
diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm
index 589e986aaeeb..0adf98ba5666 100644
--- a/code/modules/food_and_drinks/food/condiment.dm
+++ b/code/modules/food_and_drinks/food/condiment.dm
@@ -79,7 +79,7 @@
else
M.visible_message("[user] attempts to feed [M] from [src].", \
"[user] attempts to feed you from [src].")
- if(!do_mob(user, M))
+ if(!do_after(user, target = M))
return
if(!reagents || !reagents.total_volume)
return // The condiment might be empty after the delay.
@@ -322,14 +322,3 @@
desc = "A delicious oil used in cooking"
icon_state = "oliveoil"
list_reagents = list(/datum/reagent/consumable/cornoil = 50)
-
-/obj/item/reagent_containers/food/condiment/pack/sugar
- name = "sugar pack"
- originalname = "sugar"
- list_reagents = list(/datum/reagent/consumable/sugar = 5)
-
-/obj/item/reagent_containers/food/condiment/pack/creamer
- name = "creamer" /// dont laugh you child
- originalname = "cream"
- list_reagents = list(/datum/reagent/consumable/cream = 5)
-
diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm
index c4daa88869a7..fc3df2f74713 100644
--- a/code/modules/food_and_drinks/food/customizables.dm
+++ b/code/modules/food_and_drinks/food/customizables.dm
@@ -24,7 +24,7 @@
/obj/item/reagent_containers/food/snacks/customizable/examine(mob/user)
. = ..()
var/ingredients_listed = ""
- for(var/obj/item/reagent_containers/food/snacks/ING in ingredients)
+ for(var/obj/item/ING in ingredients)
ingredients_listed += "[ING.name], "
var/size = "standard"
if(ingredients.len<2)
@@ -36,8 +36,11 @@
. += "It contains [ingredients.len?"[ingredients_listed]":"no ingredient, "]making a [size]-sized [initial(name)]."
/obj/item/reagent_containers/food/snacks/customizable/attackby(obj/item/I, mob/user, params)
- if(!istype(I, /obj/item/reagent_containers/food/snacks/customizable) && istype(I, /obj/item/reagent_containers/food/snacks))
- var/obj/item/reagent_containers/food/snacks/S = I
+ if(istype(I, /obj/item/reagent_containers/food/snacks/customizable))
+ return
+ var/datum/component/edible/E = I.GetComponent(/datum/component/edible)
+ var/obj/item/reagent_containers/food/snacks/S = I
+ if(istype(S) || E)
if(I.w_class > WEIGHT_CLASS_SMALL)
to_chat(user, "The ingredient is too big for [src]!")
else if((ingredients.len >= ingMax) || (reagents.total_volume >= volume))
@@ -47,20 +50,25 @@
else
if(!user.transferItemToLoc(I, src))
return
- if(S.trash)
- S.generate_trash(get_turf(user))
- ingredients += S
- mix_filling_color(S)
- S.reagents.trans_to(src,min(S.reagents.total_volume, 15), transfered_by = user) //limit of 15, we don't want our custom food to be completely filled by just one ingredient with large reagent volume.
- foodtype |= S.foodtype
- update_customizable_overlays(S)
+ ingredients += I
+ I.reagents.trans_to(src,min(S.reagents.total_volume, 15), transfered_by = user) //limit of 15, we don't want our custom food to be completely filled by just one ingredient with large reagent volume.
+ if(istype(S))
+ if(S.trash)
+ S.generate_trash(get_turf(user))
+ mix_filling_color(S.filling_color)
+ foodtype |= S.foodtype
+ update_customizable_overlays(S.filling_color)
+ else
+ mix_filling_color(E.filling_color)
+ foodtype |= E.foodtypes
+ update_customizable_overlays(E.filling_color)
to_chat(user, "You add the [I.name] to the [name].")
- update_food_name(S)
+ update_food_name(I)
else
. = ..()
-/obj/item/reagent_containers/food/snacks/customizable/proc/update_food_name(obj/item/reagent_containers/food/snacks/S)
+/obj/item/reagent_containers/food/snacks/customizable/proc/update_food_name(obj/item/S)
for(var/obj/item/I in ingredients)
if(!istype(S, I.type))
customname = "custom"
@@ -88,25 +96,25 @@
attackby(I, user)
qdel(BASE)
-/obj/item/reagent_containers/food/snacks/customizable/proc/mix_filling_color(obj/item/reagent_containers/food/snacks/S)
+/obj/item/reagent_containers/food/snacks/customizable/proc/mix_filling_color(newcolor)
if(ingredients.len == 1)
- filling_color = S.filling_color
+ filling_color = newcolor
else
var/list/rgbcolor = list(0,0,0,0)
var/customcolor = GetColors(filling_color)
- var/ingcolor = GetColors(S.filling_color)
+ var/ingcolor = GetColors(newcolor)
rgbcolor[1] = (customcolor[1]+ingcolor[1])/2
rgbcolor[2] = (customcolor[2]+ingcolor[2])/2
rgbcolor[3] = (customcolor[3]+ingcolor[3])/2
rgbcolor[4] = (customcolor[4]+ingcolor[4])/2
filling_color = rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3], rgbcolor[4])
-/obj/item/reagent_containers/food/snacks/customizable/update_customizable_overlays(obj/item/reagent_containers/food/snacks/S)
+/obj/item/reagent_containers/food/snacks/customizable/update_customizable_overlays(filling_color = "#FFFFFF")
var/mutable_appearance/filling = mutable_appearance(icon, "[initial(icon_state)]_filling")
- if(S.filling_color == "#FFFFFF")
+ if(filling_color == "#FFFFFF")
filling.color = pick("#FF0000","#0000FF","#008000","#FFFF00")
else
- filling.color = S.filling_color
+ filling.color = filling_color
switch(ingredients_placement)
if(INGREDIENTS_SCATTER)
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 2dd04174ba85..61121a3ca950 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -126,7 +126,7 @@ All foods are distributed among various categories. Use common sense.
"[user] cannot force any more of [src] down your throat!")
return FALSE
- if(!do_mob(user, M))
+ if(!do_after(user, target = M))
return
log_combat(user, M, "fed", reagents.log_list())
M.visible_message("[user] forces [M] to eat [src]!", \
@@ -167,26 +167,27 @@ All foods are distributed among various categories. Use common sense.
/obj/item/reagent_containers/food/snacks/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/storage))
..() // -> item/attackby()
- return 0
- if(istype(W, /obj/item/reagent_containers/food/snacks))
+ return FALSE
+ var/datum/component/edible/E = W.GetComponent(/datum/component/edible)
+ if(istype(W, /obj/item/reagent_containers/food/snacks) || E)
var/obj/item/reagent_containers/food/snacks/S = W
if(custom_food_type && ispath(custom_food_type))
- if(S.w_class > WEIGHT_CLASS_SMALL)
- to_chat(user, "[S] is too big for [src]!")
- return 0
- if(!S.customfoodfilling || istype(W, /obj/item/reagent_containers/food/snacks/customizable) || istype(W, /obj/item/reagent_containers/food/snacks/pizzaslice/custom) || istype(W, /obj/item/reagent_containers/food/snacks/cakeslice/custom))
- to_chat(user, "[src] can't be filled with [S]!")
- return 0
+ if(W.w_class > WEIGHT_CLASS_SMALL)
+ to_chat(user, span_warning("[S] is too big for [src]!"))
+ return FALSE
+ if(istype(S) && (!S.customfoodfilling || istype(W, /obj/item/reagent_containers/food/snacks/customizable) || istype(W, /obj/item/reagent_containers/food/snacks/pizzaslice/custom) || istype(W, /obj/item/reagent_containers/food/snacks/cakeslice/custom)))
+ to_chat(user, span_warning("[src] can't be filled with [S]!"))
+ return FALSE
if(contents.len >= 20)
- to_chat(user, "You can't add more ingredients to [src]!")
- return 0
+ to_chat(user, span_warning("You can't add more ingredients to [src]!"))
+ return FALSE
var/obj/item/reagent_containers/food/snacks/customizable/C = new custom_food_type(get_turf(src))
- C.initialize_custom_food(src, S, user)
- return 0
+ C.initialize_custom_food(src, W, user)
+ return FALSE
var/sharp = W.get_sharpness()
if(sharp)
if(slice(sharp, W, user))
- return 1
+ return TRUE
else
..()
diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm
index e4ccbd1c8f90..6cc7413cbfdd 100644
--- a/code/modules/food_and_drinks/food/snacks/meat.dm
+++ b/code/modules/food_and_drinks/food/snacks/meat.dm
@@ -279,7 +279,7 @@
/obj/item/reagent_containers/food/snacks/meat/slab/gondola
name = "gondola meat"
desc = "According to legends of old, consuming raw gondola flesh grants one inner peace."
- list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/tranquility = 5, /datum/reagent/consumable/cooking_oil = 3)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/cooking_oil = 3)
tastes = list("meat" = 4, "tranquility" = 1)
filling_color = "#9A6750"
cooked_type = /obj/item/reagent_containers/food/snacks/meat/steak/gondola
diff --git a/code/modules/food_and_drinks/food/snacks_cake.dm b/code/modules/food_and_drinks/food/snacks_cake.dm
index a048fb0e4371..d6f6151d47ac 100644
--- a/code/modules/food_and_drinks/food/snacks_cake.dm
+++ b/code/modules/food_and_drinks/food/snacks_cake.dm
@@ -195,7 +195,7 @@
force = 5
hitsound = 'sound/weapons/blade1.ogg'
slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy
- list_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/pwr_game = 10, /datum/reagent/consumable/liquidelectricity = 10)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/pacfuel = 10, /datum/reagent/consumable/liquidelectricity = 10)
tastes = list("cake" = 3, "a Vlad's Salad" = 1)
/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy/proc/energy_bite(mob/living/user)
@@ -220,7 +220,7 @@
force = 2
hitsound = 'sound/weapons/blade1.ogg'
filling_color = "#00FF00"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sprinkles = 2, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/pwr_game = 2, /datum/reagent/consumable/liquidelectricity = 2)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sprinkles = 2, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/pacfuel = 2, /datum/reagent/consumable/liquidelectricity = 2)
tastes = list("cake" = 3, "a Vlad's Salad" = 1)
/obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy/proc/energy_bite(mob/living/user)
diff --git a/code/modules/food_and_drinks/food/snacks_frozen.dm b/code/modules/food_and_drinks/food/snacks_frozen.dm
index 930fabc31775..e35cb7eeb5fe 100644
--- a/code/modules/food_and_drinks/food/snacks_frozen.dm
+++ b/code/modules/food_and_drinks/food/snacks_frozen.dm
@@ -178,7 +178,7 @@
name = "Space Mountain Wind snowcone"
desc = "Space Mountain Wind drizzled over a snowball in a paper cup."
icon_state = "mountainwind_sc"
- list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/spacemountainwind = 5)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/comet_trail = 5)
tastes = list("ice" = 1, "water" = 1, "mountain wind" = 5)
@@ -186,7 +186,7 @@
name = "pwrgame snowcone"
desc = "Pwrgame soda drizzled over a snowball in a paper cup."
icon_state = "pwrgame_sc"
- list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/pwr_game = 5)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/pacfuel = 5)
tastes = list("ice" = 1, "water" = 1, "valid" = 5, "salt" = 5, "wats" = 5)
/obj/item/reagent_containers/food/snacks/snowcones/honey
diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm
index 3d5adf18e6fd..361e36ae9544 100644
--- a/code/modules/food_and_drinks/food/snacks_other.dm
+++ b/code/modules/food_and_drinks/food/snacks_other.dm
@@ -112,19 +112,6 @@
. = ..()
AddElement(/datum/element/dunkable, 10)
-/obj/item/reagent_containers/food/snacks/tatortot
- name = "tator tot"
- desc = "A large fried potato nugget that may or may not try to valid you."
- icon_state = "tatortot"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4)
- filling_color = "FFD700"
- tastes = list("potato" = 3, "valids" = 1)
- foodtype = FRIED | VEGETABLES
-
-/obj/item/reagent_containers/food/snacks/tatortot/Initialize()
- . = ..()
- AddElement(/datum/element/dunkable, 10)
-
/obj/item/reagent_containers/food/snacks/soydope
name = "soy dope"
desc = "Dope from a soy."
@@ -520,6 +507,7 @@
name = "bubblegum"
desc = "A rubbery strip of gum. Not exactly filling, but it keeps you busy."
icon_state = "bubblegum"
+ supports_variations = VOX_VARIATION
item_state = "bubblegum"
color = "#E48AB5" // craftable custom gums someday?
list_reagents = list(/datum/reagent/consumable/sugar = 5)
diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm
index 318de66636e7..ee0dd7ab58de 100644
--- a/code/modules/food_and_drinks/food/snacks_pastry.dm
+++ b/code/modules/food_and_drinks/food/snacks_pastry.dm
@@ -538,7 +538,7 @@
name = "\improper Gondola-pocket"
desc = "The choice to use real gondola meat in the recipe is controversial, to say the least." //Only a monster would craft this.
icon_state = "donkpocketgondola"
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/tranquility = 5)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4)
cooked_type = /obj/item/reagent_containers/food/snacks/donkpocket/warm/gondola
filling_color = "#CD853F"
tastes = list("meat" = 2, "dough" = 2, "inner peace" = 1)
@@ -548,8 +548,8 @@
name = "warm Gondola-pocket"
desc = "The choice to use real gondola meat in the recipe is controversial, to say the least."
icon_state = "donkpocketgondola"
- bonus_reagents = list(/datum/reagent/medicine/omnizine = 1, /datum/reagent/tranquility = 5)
- list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1, /datum/reagent/tranquility = 5)
+ bonus_reagents = list(/datum/reagent/medicine/omnizine = 1)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/omnizine = 1)
tastes = list("meat" = 2, "dough" = 2, "inner peace" = 1)
foodtype = GRAIN
diff --git a/code/modules/food_and_drinks/food/snacks_vend.dm b/code/modules/food_and_drinks/food/snacks_vend.dm
index 8bff9db3384f..94477d1932aa 100644
--- a/code/modules/food_and_drinks/food/snacks_vend.dm
+++ b/code/modules/food_and_drinks/food/snacks_vend.dm
@@ -140,7 +140,7 @@
/obj/item/reagent_containers/food/snacks/energybar
name = "High-power energy bars"
icon_state = "energybar"
- desc = "An energy bar with a lot of punch, you probably shouldn't eat this if you're not an Ethereal."
+ desc = "An energy bar with a lot of punch, you probably shouldn't eat this if you're not an Elzuosa."
trash = /obj/item/trash/energybar
list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/liquidelectricity = 3)
filling_color = "#97ee63"
diff --git a/code/modules/food_and_drinks/kitchen_machinery/coffeemaker.dm b/code/modules/food_and_drinks/kitchen_machinery/coffeemaker.dm
deleted file mode 100644
index 7b98be6a16c4..000000000000
--- a/code/modules/food_and_drinks/kitchen_machinery/coffeemaker.dm
+++ /dev/null
@@ -1,689 +0,0 @@
-#define BEAN_CAPACITY 10 //amount of coffee beans that can fit inside the impressa coffeemaker
-
-/obj/machinery/coffeemaker
- name = "coffeemaker"
- desc = "A Modello 3 Coffeemaker that brews coffee and holds it at the perfect temperature of 176 fahrenheit. Made by Piccionaia Home Appliances."
- icon = 'icons/obj/machines/coffeemaker.dmi'
- icon_state = "coffeemaker_nopot_nocart"
- base_icon_state = "coffeemaker"
- resistance_flags = FIRE_PROOF | ACID_PROOF
- circuit = /obj/item/circuitboard/machine/coffeemaker
- var/obj/item/reagent_containers/food/drinks/bottle/coffeepot/coffeepot = null
- var/brewing = FALSE
- var/brew_time = 20 SECONDS
- var/speed = 1
- /// The coffee cartridge to make coffee from. In the future, coffee grounds are like printer ink.
- var/obj/item/coffee_cartridge/cartridge = null
- /// The type path to instantiate for the coffee cartridge the device initially comes with, eg. /obj/item/coffee_cartridge
- var/initial_cartridge = /obj/item/coffee_cartridge
- /// The number of cups left
- var/coffee_cups = 15
- var/max_coffee_cups = 15
- /// The amount of sugar packets left
- var/sugar_packs = 10
- var/max_sugar_packs = 10
- /// The amount of sweetener packets left
- var/sweetener_packs = 10
- var/max_sweetener_packs = 10
- /// The amount of creamer packets left
- var/creamer_packs = 10
- var/max_creamer_packs = 10
-
- var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
- var/static/radial_brew = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_brew")
- var/static/radial_eject_pot = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_pot")
- var/static/radial_eject_cartridge = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject_cartridge")
- var/static/radial_take_cup = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_take_cup")
- var/static/radial_take_sugar = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_take_sugar")
- var/static/radial_take_sweetener = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_take_sweetener")
- var/static/radial_take_creamer = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_take_creamer")
-
-/obj/machinery/coffeemaker/Initialize(mapload)
- . = ..()
- if(mapload)
- coffeepot = new /obj/item/reagent_containers/food/drinks/bottle/coffeepot(src)
- cartridge = new /obj/item/coffee_cartridge(src)
-
-/obj/machinery/coffeemaker/deconstruct()
- coffeepot?.forceMove(drop_location())
- cartridge?.forceMove(drop_location())
- return ..()
-
-/obj/machinery/coffeemaker/Destroy()
- QDEL_NULL(coffeepot)
- QDEL_NULL(cartridge)
- return ..()
-
-/obj/machinery/coffeemaker/Exited(atom/movable/gone, direction)
- . = ..()
- if(gone == coffeepot)
- coffeepot = null
- update_appearance(UPDATE_OVERLAYS)
- if(gone == cartridge)
- cartridge = null
- update_appearance(UPDATE_OVERLAYS)
-/obj/machinery/coffeemaker/examine(mob/user)
- . = ..()
- if(!in_range(user, src) && !issilicon(user) && !isobserver(user))
- . += span_warning("You're too far away to examine [src]'s contents and display!")
- return
-
- if(brewing)
- . += span_warning("\The [src] is brewing.")
- return
-
- if(panel_open)
- . += span_notice("[src]'s maintenance hatch is open!")
- return
-
- if(coffeepot || cartridge)
- . += span_notice("\The [src] contains:")
- if(coffeepot)
- . += span_notice("- \A [coffeepot].")
- if(cartridge)
- . += span_notice("- \A [cartridge].")
- return
-
- if(!(machine_stat & (NOPOWER|BROKEN)))
- . += "[span_notice("The status display reads:")]\n"+\
- span_notice("- Brewing coffee at [speed*100]%.")
- if(coffeepot)
- for(var/datum/reagent/consumable/cawfee as anything in coffeepot.reagents.reagent_list)
- . += span_notice("- [cawfee.volume] units of coffee in pot.")
- if(cartridge)
- if(cartridge.charges < 1)
- . += span_notice("- grounds cartridge is empty.")
- else
- . += span_notice("- grounds cartridge has [cartridge.charges] charges remaining.")
-
- if (coffee_cups >= 1)
- . += span_notice("There [coffee_cups == 1 ? "is" : "are"] [coffee_cups] coffee cup[coffee_cups != 1 && "s"] left.")
- else
- . += span_notice("There are no cups left.")
-
- if (sugar_packs >= 1)
- . += span_notice("There [sugar_packs == 1 ? "is" : "are"] [sugar_packs] packet[sugar_packs != 1 && "s"] of sugar left.")
- else
- . += span_notice("There is no sugar left.")
-
- if (sweetener_packs >= 1)
- . += span_notice("There [sweetener_packs == 1 ? "is" : "are"] [sweetener_packs] packet[sweetener_packs != 1 && "s"] of sweetener left.")
- else
- . += span_notice("There is no sweetener left.")
-
- if (creamer_packs > 1)
- . += span_notice("There [creamer_packs == 1 ? "is" : "are"] [creamer_packs] packet[creamer_packs != 1 && "s"] of creamer left.")
- else
- . += span_notice("There is no creamer left.")
-
-
-/obj/machinery/coffeemaker/update_overlays()
- . = ..()
- . += overlay_checks()
-
-/obj/machinery/coffeemaker/proc/overlay_checks()
- . = list()
- if(coffeepot)
- . += "coffeemaker_pot"
- if(cartridge)
- . += "coffeemaker_cartidge"
- return .
-
-/obj/machinery/coffeemaker/proc/replace_pot(mob/living/user, /obj/item/reagent_containers/food/drinks/bottle/coffeepot)
- if(!user)
- return FALSE
- if(coffeepot)
- try_put_in_hand(coffeepot, user)
- balloon_alert(user, "replaced pot")
- update_appearance(UPDATE_OVERLAYS)
- return TRUE
-
-/obj/machinery/coffeemaker/proc/replace_cartridge(mob/living/user, obj/item/coffee_cartridge/new_cartridge)
- if(!user)
- return FALSE
- if(cartridge)
- try_put_in_hand(cartridge, user)
- if(new_cartridge)
- cartridge = new_cartridge
- update_appearance(UPDATE_OVERLAYS)
- return TRUE
-
-/obj/machinery/coffeemaker/wrench_act(mob/living/user, obj/item/tool)
- . = ..()
- default_unfasten_wrench(user, tool)
- return TOOL_ACT_TOOLTYPE_SUCCESS
-
-/obj/machinery/coffeemaker/attackby(obj/item/attack_item, mob/living/user, params)
- //You can only screw open empty grinder
- if(!coffeepot && default_deconstruction_screwdriver(user, icon_state, icon_state, attack_item))
- return FALSE
-
- if(default_deconstruction_crowbar(attack_item))
- return
-
- if(panel_open) //Can't insert objects when its screwed open
- return TRUE
-
- if (istype(attack_item, /obj/item/reagent_containers/food/drinks/bottle/coffeepot) && !(attack_item.item_flags & ABSTRACT) && attack_item.is_open_container())
- var/obj/item/reagent_containers/food/drinks/bottle/coffeepot/new_pot = attack_item
- . = TRUE //no afterattack
- if(!user.transferItemToLoc(new_pot, src))
- return TRUE
- replace_pot(user, new_pot)
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/glass/coffee_cup) && !(attack_item.item_flags & ABSTRACT) && attack_item.is_open_container())
- var/obj/item/reagent_containers/glass/coffee_cup/new_cup = attack_item
- if(new_cup.reagents.total_volume > 0)
- balloon_alert(user, "the cup must be empty!")
- return
- if(coffee_cups >= max_coffee_cups)
- balloon_alert(user, "the cup holder is full!")
- return
- if(!user.transferItemToLoc(attack_item, src))
- return
- coffee_cups++
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/food/condiment/pack/sugar))
- var/obj/item/reagent_containers/food/condiment/pack/sugar/new_pack = attack_item
- if(new_pack.reagents.total_volume < new_pack.reagents.maximum_volume)
- balloon_alert(user, "the pack must be full!")
- return
- if(sugar_packs >= max_sugar_packs)
- balloon_alert(user, "the sugar compartment is full!")
- return
- if(!user.transferItemToLoc(attack_item, src))
- return
- sugar_packs++
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/food/condiment/pack/creamer))
- var/obj/item/reagent_containers/food/condiment/pack/creamer/new_pack = attack_item
- if(new_pack.reagents.total_volume < new_pack.reagents.maximum_volume)
- balloon_alert(user, "the pack must be full!")
- return
- if(creamer_packs >= max_creamer_packs)
- balloon_alert(user, "the creamer compartment is full!")
- return
- if(!user.transferItemToLoc(attack_item, src))
- return
- creamer_packs++
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/food/condiment/pack/astrotame))
- var/obj/item/reagent_containers/food/condiment/pack/astrotame/new_pack = attack_item
- if(new_pack.reagents.total_volume < new_pack.reagents.maximum_volume)
- balloon_alert(user, "the pack must be full!")
- return
- else if(sweetener_packs >= max_sweetener_packs)
- balloon_alert(user, "the sweetener compartment is full!")
- return
- else if(!user.transferItemToLoc(attack_item, src))
- return
- sweetener_packs++
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/coffee_cartridge) && !(attack_item.item_flags & ABSTRACT))
- var/obj/item/coffee_cartridge/new_cartridge = attack_item
- if(!user.transferItemToLoc(new_cartridge, src))
- return
- replace_cartridge(user, new_cartridge)
- balloon_alert(user, "added cartridge")
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
-/obj/machinery/coffeemaker/proc/try_brew()
- if(!cartridge)
- balloon_alert(usr, "no coffee cartridge inserted!")
- return FALSE
- if(cartridge.charges < 1)
- balloon_alert(usr, "coffee cartridge empty!")
- return FALSE
- if(!coffeepot)
- balloon_alert(usr, "no coffeepot inside!")
- return FALSE
- if(machine_stat & (NOPOWER|BROKEN))
- balloon_alert(usr, "machine unpowered!")
- return FALSE
- if(coffeepot.reagents.total_volume >= coffeepot.reagents.maximum_volume)
- balloon_alert(usr, "the coffeepot is already full!")
- return FALSE
- return TRUE
-
-/obj/machinery/coffeemaker/ui_interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave //I am positively certain that this is not a microwave
- . = ..()
-
- if(brewing || panel_open || !anchored || !user.canUseTopic(src, !issilicon(user)))
- return
-
- var/list/options = list()
-
- if(coffeepot)
- options["Eject Pot"] = radial_eject_pot
-
- if(cartridge)
- options["Eject Cartridge"] = radial_eject_cartridge
-
- options["Brew"] = radial_brew //brew is always available as an option, when the machine is unable to brew the player is told by balloon alerts whats exactly wrong
-
- if(coffee_cups > 0)
- options["Take Cup"] = radial_take_cup
-
- if(sugar_packs > 0)
- options["Take Sugar"] = radial_take_sugar
-
- if(sweetener_packs > 0)
- options["Take Sweetener"] = radial_take_sweetener
-
- if(creamer_packs > 0)
- options["Take Creamer"] = radial_take_creamer
-
- if(isAI(user))
- if(machine_stat & NOPOWER)
- return
- options["Examine"] = radial_examine
-
- var/choice
-
- if(length(options) < 1)
- return
- if(length(options) == 1)
- choice = options[1]
- else
- choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
-
- // post choice verification
- if(brewing || panel_open || !anchored || !user.canUseTopic(src, !issilicon(user)))
- return
-
- switch(choice)
- if("Brew")
- brew(user)
- if("Eject Pot")
- eject_pot(user)
- if("Eject Cartridge")
- eject_cartridge(user)
- if("Examine")
- examine(user)
- if("Take Cup")
- take_cup(user)
- if("Take Sugar")
- take_sugar(user)
- if("Take Sweetener")
- take_sweetener(user)
- if("Take Creamer")
- take_creamer(user)
-
-/obj/machinery/coffeemaker/proc/eject_pot(mob/user)
- if(coffeepot)
- replace_pot(user)
-
-/obj/machinery/coffeemaker/proc/eject_cartridge(mob/user)
- if(cartridge)
- replace_cartridge(user)
-
-/obj/machinery/coffeemaker/proc/take_cup(mob/user)
- if(!coffee_cups) //shouldn't happen, but we all know how stuff manages to break
- balloon_alert(user, "no cups left!")
- return
- var/obj/item/reagent_containers/glass/coffee_cup/new_cup = new(get_turf(src))
- user.put_in_hands(new_cup)
- coffee_cups--
- update_appearance(UPDATE_OVERLAYS)
-
-/obj/machinery/coffeemaker/proc/take_sugar(mob/user)
- if(!sugar_packs)
- balloon_alert(user, "no sugar left!")
- return
- var/obj/item/reagent_containers/food/condiment/pack/sugar/new_pack = new(get_turf(src))
- user.put_in_hands(new_pack)
- sugar_packs--
- update_appearance(UPDATE_OVERLAYS)
-
-/obj/machinery/coffeemaker/proc/take_sweetener(mob/user)
- if(!sweetener_packs)
- balloon_alert(user, "no sweetener left!")
- return
- var/obj/item/reagent_containers/food/condiment/pack/astrotame/new_pack = new(get_turf(src))
- user.put_in_hands(new_pack)
- sweetener_packs--
- update_appearance(UPDATE_OVERLAYS)
-
-/obj/machinery/coffeemaker/proc/take_creamer(mob/user)
- if(!creamer_packs)
- balloon_alert(user, "no creamer left!")
- return
- var/obj/item/reagent_containers/food/condiment/pack/creamer/new_pack = new(drop_location())
- user.put_in_hands(new_pack)
- creamer_packs--
- update_appearance(UPDATE_OVERLAYS)
-
-///Updates the smoke state to something else, setting particles if relevant
-/obj/machinery/coffeemaker/proc/toggle_steam()
- QDEL_NULL(particles)
- if(brewing)
- particles.position = list(-6, 0, 0)
-
-/obj/machinery/coffeemaker/proc/operate_for(time, silent = FALSE)
- brewing = TRUE
- if(!silent)
- playsound(src, 'sound/machines/coffeemaker_brew.ogg', 20, vary = TRUE)
- toggle_steam()
- use_power(active_power_usage * time * 0.1) // .1 needed here to convert time (in deciseconds) to seconds such that watts * seconds = joules
- addtimer(CALLBACK(src, PROC_REF(stop_operating)), time / speed)
-
-/obj/machinery/coffeemaker/proc/stop_operating()
- brewing = FALSE
- toggle_steam()
-
-/obj/machinery/coffeemaker/proc/brew()
- power_change()
- if(!try_brew())
- return
- operate_for(brew_time)
- coffeepot.reagents.add_reagent_list(cartridge.drink_type)
- cartridge.charges--
-
-//Coffee Cartridges: like toner, but for your coffee!
-/obj/item/coffee_cartridge
- name = "coffeemaker cartridge- Caffè Generico"
- desc = "A coffee cartridge manufactured by Piccionaia Coffee, for use with the Modello 3 system."
- icon = 'icons/obj/machines/coffeemaker.dmi'
- icon_state = "cartridge_basic"
- var/charges = 4
- var/list/drink_type = list(/datum/reagent/consumable/coffee = 120)
-
-/obj/item/coffee_cartridge/examine(mob/user)
- . = ..()
- if(charges)
- . += span_warning("The cartridge has [charges] portions of grounds remaining.")
- else
- . += span_warning("The cartridge has no unspent grounds remaining.")
-
-/obj/item/coffee_cartridge/fancy
- name = "coffeemaker cartridge - Caffè Fantasioso"
- desc = "A fancy coffee cartridge manufactured by Piccionaia Coffee, for use with the Modello 3 system."
- icon_state = "cartridge_blend"
-
-//Here's the joke before I get 50 issue reports: they're all the same, and that's intentional
-/obj/item/coffee_cartridge/fancy/Initialize(mapload)
- . = ..()
- var/coffee_type = pick("blend", "blue_mountain", "kilimanjaro", "mocha")
- switch(coffee_type)
- if("blend")
- name = "coffeemaker cartridge - Miscela di Piccione"
- icon_state = "cartridge_blend"
- if("blue_mountain")
- name = "coffeemaker cartridge - Montagna Blu"
- icon_state = "cartridge_blue_mtn"
- if("kilimanjaro")
- name = "coffeemaker cartridge - Kilimangiaro"
- icon_state = "cartridge_kilimanjaro"
- if("mocha")
- name = "coffeemaker cartridge - Moka Arabica"
- icon_state = "cartridge_mocha"
-
-/obj/item/coffee_cartridge/decaf
- name = "coffeemaker cartridge - Caffè Decaffeinato"
- desc = "A decaf coffee cartridge manufactured by Piccionaia Coffee, for use with the Modello 3 system."
- icon_state = "cartridge_decaf"
-
-// no you can't just squeeze the juice bag into a glass!
-/obj/item/coffee_cartridge/bootleg
- name = "coffeemaker cartridge - Botany Blend"
- desc = "A jury-rigged coffee cartridge. Should work with a Modello 3 system, though it might void the warranty."
- icon_state = "cartridge_bootleg"
-
-// blank cartridge for crafting's sake, can be made at the service lathe
-/obj/item/blank_coffee_cartridge
- name = "blank coffee cartridge"
- desc = "A blank coffee cartridge, ready to be filled with coffee paste."
- icon = 'icons/obj/machines/coffeemaker.dmi'
- icon_state = "cartridge_blank"
-
-//now, how do you store coffee carts? well, in a rack, of course!
-/obj/item/storage/box/coffee_cart_rack
- name = "coffeemaker cartridge box"
- desc = "A small rack for storing coffeemaker cartridges."
- var/cartridge_type = /obj/item/coffee_cartridge
-
-/obj/item/storage/box/coffee_cart_rack/Initialize(mapload)
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_items = 8
- STR.can_hold = typecacheof(list(/obj/item/coffee_cartridge))
-
-
-/obj/item/storage/box/coffee_cart_rack/PopulateContents()
- for(var/i in 1 to 4)
- new cartridge_type(src)
- new /obj/item/coffee_cartridge/decaf(src)
- new /obj/item/coffee_cartridge/fancy(src)
- new /obj/item/coffee_cartridge(src)
-
-/*
- * impressa coffee maker
- * its supposed to be a premium line product, so its cargo-only, the board cant be therefore researched
- */
-
-/obj/machinery/coffeemaker/impressa
- name = "impressa coffeemaker"
- desc = "An industry-grade Impressa Modello 5 Coffeemaker of the Piccionaia Home Appliances premium coffeemakers product line. Makes coffee from fresh dried whole beans."
- icon = 'icons/obj/machines/coffeemaker.dmi'
- icon_state = "coffeemaker_impressa"
- circuit = /obj/item/circuitboard/machine/coffeemaker/impressa
- initial_cartridge = null //no cartridge, just coffee beans
- brew_time = 15 SECONDS //industrial grade, its faster than the regular one
- density = TRUE
- pass_flags = PASSTABLE
- /// Current amount of coffee beans stored
- var/coffee_amount = 0
- /// List of coffee bean objects are stored
- var/list/coffee = list()
-
-/obj/machinery/coffeemaker/impressa/Initialize(mapload)
- . = ..()
- if(mapload)
- coffeepot = new /obj/item/reagent_containers/food/drinks/bottle/coffeepot(src)
- cartridge = null
-
-/obj/machinery/coffeemaker/impressa/Destroy()
- QDEL_NULL(coffeepot)
- QDEL_NULL(coffee)
- return ..()
-
-/obj/machinery/coffeemaker/impressa/examine(mob/user)
- . = ..()
- if(coffee)
- . += span_notice("The internal grinder contains [length(coffee)] scoop\s of coffee beans")
-
-/obj/machinery/coffeemaker/impressa/update_overlays()
- . = ..()
- . += overlay_checks()
-
-/obj/machinery/coffeemaker/impressa/overlay_checks()
- . = list()
- if(coffeepot)
- if(coffeepot.reagents.total_volume > 0)
- . += "pot_full"
- else
- . += "pot_empty"
- if(coffee_cups > 0)
- if(coffee_cups >= max_coffee_cups/3)
- if(coffee_cups > max_coffee_cups/1.5)
- . += "cups_3"
- else
- . += "cups_2"
- else
- . += "cups_1"
- if(sugar_packs)
- . += "extras_1"
- if(creamer_packs)
- . += "extras_2"
- if(sweetener_packs)
- . += "extras_3"
- if(coffee_amount)
- if(coffee_amount < 0.7*BEAN_CAPACITY)
- . += "grinder_half"
- else
- . += "grinder_full"
- return .
-
-/obj/machinery/coffeemaker/impressa/Exited(atom/movable/gone, direction)
- . = ..()
- if(gone in coffee)
- coffee -= gone
- update_appearance(UPDATE_OVERLAYS)
-
-/obj/machinery/coffeemaker/impressa/try_brew(mob/living/user)
- if(coffee_amount <= 0)
- balloon_alert(user, "no coffee beans added!")
- return FALSE
- if(!coffeepot)
- balloon_alert(user, "no coffeepot inside!")
- return FALSE
- if(machine_stat & (NOPOWER|BROKEN))
- balloon_alert(user, "machine unpowered!")
- return FALSE
- if(coffeepot.reagents.total_volume >= coffeepot.reagents.maximum_volume)
- balloon_alert(user, "the coffeepot is already full!")
- return FALSE
- return TRUE
-
-/obj/machinery/coffeemaker/impressa/attackby(obj/item/attack_item, mob/living/user, params)
- //You can only screw open empty grinder
- if(!coffeepot && default_deconstruction_screwdriver(user, icon_state, icon_state, attack_item))
- return
-
- if(default_deconstruction_crowbar(attack_item))
- return
-
- if(panel_open) //Can't insert objects when its screwed open
- return TRUE
-
- if (istype(attack_item, /obj/item/reagent_containers/food/drinks/bottle/coffeepot) && !(attack_item.item_flags & ABSTRACT) && attack_item.is_open_container())
- var/obj/item/reagent_containers/food/drinks/bottle/coffeepot/new_pot = attack_item
- if(!user.transferItemToLoc(new_pot, src))
- return TRUE
- replace_pot(user, new_pot)
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/glass/coffee_cup) && !(attack_item.item_flags & ABSTRACT) && attack_item.is_open_container())
- var/obj/item/reagent_containers/glass/coffee_cup/new_cup = attack_item //different type of cup
- if(new_cup.reagents.total_volume > 0)
- balloon_alert(user, "the cup must be empty!")
- return
- if(coffee_cups >= max_coffee_cups)
- balloon_alert(user, "the cup holder is full!")
- return
- if(!user.transferItemToLoc(attack_item, src))
- return
- coffee_cups++
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/food/condiment/pack/sugar))
- var/obj/item/reagent_containers/food/condiment/pack/sugar/new_pack = attack_item
- if(new_pack.reagents.total_volume < new_pack.reagents.maximum_volume)
- balloon_alert(user, "the pack must be full!")
- return
- if(sugar_packs >= max_sugar_packs)
- balloon_alert(user, "the sugar compartment is full!")
- return
- if(!user.transferItemToLoc(attack_item, src))
- return
- sugar_packs++
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/food/condiment/pack/creamer))
- var/obj/item/reagent_containers/food/condiment/pack/creamer/new_pack = attack_item
- if(new_pack.reagents.total_volume < new_pack.reagents.maximum_volume)
- balloon_alert(user, "the pack must be full!")
- return
- if(creamer_packs >= max_creamer_packs)
- balloon_alert(user, "the creamer compartment is full!")
- return
- if(!user.transferItemToLoc(attack_item, src))
- return
- creamer_packs++
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/food/condiment/pack/astrotame))
- var/obj/item/reagent_containers/food/condiment/pack/astrotame/new_pack = attack_item
- if(new_pack.reagents.total_volume < new_pack.reagents.maximum_volume)
- balloon_alert(user, "the pack must be full!")
- return
- if(sweetener_packs >= max_sweetener_packs)
- balloon_alert(user, "the sweetener compartment is full!")
- return
- if(!user.transferItemToLoc(attack_item, src))
- return
- sweetener_packs++
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
- if (istype(attack_item, /obj/item/reagent_containers/food/snacks/grown/coffee) && !(attack_item.item_flags & ABSTRACT))
- if(coffee_amount >= BEAN_CAPACITY)
- balloon_alert(user, "the coffee container is full!")
- return
- var/obj/item/reagent_containers/food/snacks/grown/coffee/new_coffee = attack_item
- if(!user.transferItemToLoc(new_coffee, src))
- return
- coffee += new_coffee
- coffee_amount++
- balloon_alert(user, "added coffee")
-
-
- if (istype(attack_item, /obj/item/storage/box/coffeepack))
- if(coffee_amount >= BEAN_CAPACITY)
- balloon_alert(user, "the coffee container is full!")
- return
- var/obj/item/storage/box/coffeepack/new_coffee_pack = attack_item
- for(var/obj/item/reagent_containers/food/snacks/grown/coffee/new_coffee in new_coffee_pack.contents)
- if(coffee_amount < BEAN_CAPACITY)
- if(user.transferItemToLoc(new_coffee, src))
- coffee += new_coffee
- coffee_amount++
- new_coffee.forceMove(src)
- balloon_alert(user, "added coffee")
- update_appearance(UPDATE_OVERLAYS)
- else
- return
- update_appearance(UPDATE_OVERLAYS)
- return TRUE //no afterattack
-
-/obj/machinery/coffeemaker/impressa/take_cup(mob/user)
- if(!coffee_cups) //shouldn't happen, but we all know how stuff manages to break
- balloon_alert(user, "no cups left!")
- return
- balloon_alert_to_viewers("took cup")
- var/obj/item/reagent_containers/food/drinks/coffee/new_cup = new(get_turf(src))
- user.put_in_hands(new_cup)
- coffee_cups--
- update_appearance(UPDATE_OVERLAYS)
-
-/obj/machinery/coffeemaker/impressa/toggle_steam()
- QDEL_NULL(particles)
- if(brewing)
- particles.position = list(-2, 1, 0)
-
-/obj/machinery/coffeemaker/impressa/brew()
- power_change()
- if(!try_brew())
- return
- operate_for(brew_time)
- coffeepot.reagents.add_reagent_list(list(/datum/reagent/consumable/coffee = 120))
- coffee.Cut(1,2) //remove the first item from the list
- coffee_amount--
- update_appearance(UPDATE_OVERLAYS)
-
-#undef BEAN_CAPACITY
diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
index 4fa5354339c5..8eccd04c8404 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
@@ -25,7 +25,7 @@
icon_state = "fryer_off"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 5
+ idle_power_usage = IDLE_DRAW_LOW
layer = BELOW_OBJ_LAYER
var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW?
var/cook_time = 0
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index fad3c3bc963f..7be027c012f4 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -5,8 +5,8 @@
icon_state = "grinder"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 500
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
circuit = /obj/item/circuitboard/machine/gibber
var/operating = FALSE //Is it on?
diff --git a/code/modules/food_and_drinks/kitchen_machinery/grill.dm b/code/modules/food_and_drinks/kitchen_machinery/grill.dm
index 4c1a8695d838..c349c7511752 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/grill.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/grill.dm
@@ -61,10 +61,10 @@
grill_loop.start()
return
else
- if(I.reagents.has_reagent(/datum/reagent/consumable/monkey_energy))
- grill_fuel += (20 * (I.reagents.get_reagent_amount(/datum/reagent/consumable/monkey_energy)))
+ if(I.reagents.has_reagent(/datum/reagent/consumable/xeno_energy))
+ grill_fuel += (20 * (I.reagents.get_reagent_amount(/datum/reagent/consumable/xeno_energy)))
to_chat(user, "You pour the Monkey Energy in [src].")
- I.reagents.remove_reagent(/datum/reagent/consumable/monkey_energy, I.reagents.get_reagent_amount(/datum/reagent/consumable/monkey_energy))
+ I.reagents.remove_reagent(/datum/reagent/consumable/xeno_energy, I.reagents.get_reagent_amount(/datum/reagent/consumable/xeno_energy))
update_appearance()
return
..()
@@ -82,7 +82,6 @@
smoke.start()
if(grilled_item)
grill_time += 1
- grilled_item.reagents.add_reagent(/datum/reagent/consumable/char, 1)
grill_fuel -= 10
grilled_item.AddComponent(/datum/component/sizzle)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm
index 4a739d2ab7fc..2762892110f8 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm
@@ -8,8 +8,8 @@
layer = BELOW_OBJ_LAYER
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
circuit = /obj/item/circuitboard/machine/microwave
pass_flags = PASSTABLE
light_color = LIGHT_COLOR_YELLOW
@@ -275,6 +275,7 @@
/obj/machinery/microwave/proc/start()
wzhzhzh()
+ set_active_power()
loop(MICROWAVE_NORMAL, 10)
/obj/machinery/microwave/proc/start_can_fail()
@@ -303,11 +304,11 @@
pre_success()
return
time--
- use_power(500)
addtimer(CALLBACK(src, PROC_REF(loop), type, time, wait), wait)
/obj/machinery/microwave/proc/loop_finish()
operating = FALSE
+ set_idle_power()
var/metal = 0
for(var/obj/item/O in ingredients)
@@ -330,6 +331,7 @@
/obj/machinery/microwave/proc/pre_fail()
broken = 2
operating = FALSE
+ set_idle_power()
spark()
after_finish_loop()
@@ -338,6 +340,7 @@
/obj/machinery/microwave/proc/muck_finish()
visible_message("\The [src] gets covered in muck!")
+ set_idle_power()
dirty = 100
dirty_anim_playing = FALSE
@@ -382,6 +385,12 @@
playsound(src, 'sound/items/cig_light.ogg', 50, 1)
moveToNullspace()
+
+/obj/item/ration_heater/get_temperature()
+ if(!uses)
+ return 0
+ . = ..()
+
/obj/item/ration_heater/proc/clear_cooking(datum/source)
SIGNAL_HANDLER
UnregisterSignal(tocook, COMSIG_PARENT_QDELETING)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
index 005ffa7632ba..79382343e1ae 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
@@ -8,8 +8,8 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
layer = BELOW_OBJ_LAYER
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
circuit = /obj/item/circuitboard/machine/monkey_recycler
var/stored_matter = 0
var/cube_production = 0.2
diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
index ba26a265f8ee..bc17a9fd22af 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
@@ -7,8 +7,8 @@
layer = BELOW_OBJ_LAYER
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 50
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
circuit = /obj/item/circuitboard/machine/processor
var/broken = FALSE
var/processing = FALSE
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index ed1347fb5124..5852ea34742b 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -9,8 +9,8 @@
layer = BELOW_OBJ_LAYER
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/machine/smartfridge
var/max_n_of_items = 1500
@@ -245,8 +245,9 @@
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "drying_rack"
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 200
+ circuit = null
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
visible_contents = FALSE
var/drying = FALSE
@@ -258,7 +259,6 @@
/obj/machinery/smartfridge/drying_rack/on_deconstruction()
new /obj/item/stack/sheet/mineral/wood(drop_location(), 10)
- ..()
/obj/machinery/smartfridge/drying_rack/RefreshParts()
/obj/machinery/smartfridge/drying_rack/default_deconstruction_screwdriver()
@@ -326,10 +326,10 @@
/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff)
if(drying || forceoff)
drying = FALSE
- use_power = IDLE_POWER_USE
+ set_idle_power()
else
drying = TRUE
- use_power = ACTIVE_POWER_USE
+ set_active_power()
update_appearance()
/obj/machinery/smartfridge/drying_rack/proc/rack_dry()
diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm
index acd768347327..2474d1d53501 100644
--- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm
+++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm
@@ -25,10 +25,6 @@
results = list(/datum/reagent/consumable/hot_ice_coffee = 3)
required_reagents = list(/datum/reagent/toxin/hot_ice = 1, /datum/reagent/consumable/coffee = 2)
-/datum/chemical_reaction/nuka_cola
- results = list(/datum/reagent/consumable/nuka_cola = 6)
- required_reagents = list(/datum/reagent/uranium = 1, /datum/reagent/consumable/space_cola = 6)
-
/datum/chemical_reaction/moonshine
results = list(/datum/reagent/consumable/ethanol/moonshine = 10)
required_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/sugar = 5)
@@ -173,16 +169,12 @@
/datum/chemical_reaction/hiveminderaser
results = list(/datum/reagent/consumable/ethanol/hiveminderaser = 4)
- required_reagents = list(/datum/reagent/consumable/ethanol/black_russian = 2, /datum/reagent/consumable/ethanol/thirteenloko = 1, /datum/reagent/consumable/grenadine = 1)
+ required_reagents = list(/datum/reagent/consumable/ethanol/black_russian = 2, /datum/reagent/consumable/ethanol/vimukti = 1, /datum/reagent/consumable/grenadine = 1)
/datum/chemical_reaction/manhattan
results = list(/datum/reagent/consumable/ethanol/manhattan = 3)
required_reagents = list(/datum/reagent/consumable/ethanol/whiskey = 2, /datum/reagent/consumable/ethanol/vermouth = 1)
-/datum/chemical_reaction/manhattan_proj
- results = list(/datum/reagent/consumable/ethanol/manhattan_proj = 10)
- required_reagents = list(/datum/reagent/consumable/ethanol/manhattan = 10, /datum/reagent/uranium = 1)
-
/datum/chemical_reaction/vodka_tonic
results = list(/datum/reagent/consumable/ethanol/vodkatonic = 3)
required_reagents = list(/datum/reagent/consumable/ethanol/vodka = 2, /datum/reagent/consumable/tonic = 1)
@@ -205,7 +197,7 @@
/datum/chemical_reaction/demonsblood
results = list(/datum/reagent/consumable/ethanol/demonsblood = 4)
- required_reagents = list(/datum/reagent/consumable/ethanol/rum = 1, /datum/reagent/consumable/spacemountainwind = 1, /datum/reagent/blood = 1, /datum/reagent/consumable/dr_gibb = 1)
+ required_reagents = list(/datum/reagent/consumable/ethanol/rum = 1, /datum/reagent/consumable/comet_trail = 1, /datum/reagent/blood = 1, /datum/reagent/consumable/tadrixx = 1)
/datum/chemical_reaction/booger
results = list(/datum/reagent/consumable/ethanol/booger = 4)
@@ -340,8 +332,8 @@
results = list(/datum/reagent/consumable/ethanol/driestmartini = 2)
required_reagents = list(/datum/reagent/consumable/nothing = 1, /datum/reagent/consumable/ethanol/gin = 1)
-/datum/chemical_reaction/thirteenloko
- results = list(/datum/reagent/consumable/ethanol/thirteenloko = 3)
+/datum/chemical_reaction/vimukti
+ results = list(/datum/reagent/consumable/ethanol/vimukti = 3)
required_reagents = list(/datum/reagent/consumable/ethanol/vodka = 1, /datum/reagent/consumable/coffee = 1, /datum/reagent/consumable/limejuice = 1)
/datum/chemical_reaction/chocolatepudding
@@ -368,9 +360,9 @@
results = list(/datum/reagent/consumable/pumpkin_latte = 15)
required_reagents = list(/datum/reagent/consumable/pumpkinjuice = 5, /datum/reagent/consumable/coffee = 5, /datum/reagent/consumable/cream = 5)
-/datum/chemical_reaction/gibbfloats
- results = list(/datum/reagent/consumable/gibbfloats = 15)
- required_reagents = list(/datum/reagent/consumable/dr_gibb = 5, /datum/reagent/consumable/ice = 5, /datum/reagent/consumable/cream = 5)
+/datum/chemical_reaction/tadrixxfloat
+ results = list(/datum/reagent/consumable/tadrixxfloat = 15)
+ required_reagents = list(/datum/reagent/consumable/tadrixx = 5, /datum/reagent/consumable/ice = 5, /datum/reagent/consumable/cream = 5)
/datum/chemical_reaction/triple_citrus
results = list(/datum/reagent/consumable/triple_citrus = 5)
@@ -390,11 +382,6 @@
required_reagents = list(/datum/reagent/consumable/ethanol/whiskey = 1, /datum/reagent/consumable/lemonjuice = 1, /datum/reagent/consumable/sugar = 1)
mix_message = "The mixture darkens to a rich gold hue."
-/datum/chemical_reaction/fetching_fizz
- results = list(/datum/reagent/consumable/ethanol/fetching_fizz = 3)
- required_reagents = list(/datum/reagent/consumable/nuka_cola = 1, /datum/reagent/iron = 1) //Manufacturable from only the mining station
- mix_message = "The mixture slightly vibrates before settling."
-
/datum/chemical_reaction/hearty_punch
results = list(/datum/reagent/consumable/ethanol/hearty_punch = 1) //Very little, for balance reasons
required_reagents = list(/datum/reagent/consumable/ethanol/brave_bull = 5, /datum/reagent/consumable/ethanol/syndicatebomb = 5, /datum/reagent/consumable/ethanol/absinthe = 5)
@@ -438,12 +425,6 @@
results = list(/datum/reagent/consumable/ethanol/eggnog = 15)
required_reagents = list(/datum/reagent/consumable/ethanol/rum = 5, /datum/reagent/consumable/cream = 5, /datum/reagent/consumable/eggyolk = 5)
-/datum/chemical_reaction/narsour
- results = list(/datum/reagent/consumable/ethanol/narsour = 1)
- required_reagents = list(/datum/reagent/blood = 1, /datum/reagent/consumable/lemonjuice = 1, /datum/reagent/consumable/ethanol/demonsblood = 1)
- mix_message = "The mixture develops a sinister glow."
- mix_sound = 'sound/effects/singlebeat.ogg'
-
/datum/chemical_reaction/quadruplesec
results = list(/datum/reagent/consumable/ethanol/quadruple_sec = 15)
required_reagents = list(/datum/reagent/consumable/ethanol/triple_sec = 5, /datum/reagent/consumable/triple_citrus = 5, /datum/reagent/consumable/ethanol/creme_de_menthe = 5)
@@ -525,7 +506,6 @@
results = list(/datum/reagent/consumable/ethanol/fernet_cola = 2)
required_reagents = list(/datum/reagent/consumable/ethanol/fernet = 1, /datum/reagent/consumable/space_cola = 1)
-
/datum/chemical_reaction/fanciulli
results = list(/datum/reagent/consumable/ethanol/fanciulli = 2)
required_reagents = list(/datum/reagent/consumable/ethanol/manhattan = 1, /datum/reagent/consumable/ethanol/fernet = 1)
@@ -536,8 +516,7 @@
/datum/chemical_reaction/blank_paper
results = list(/datum/reagent/consumable/ethanol/blank_paper = 3)
- required_reagents = list(/datum/reagent/consumable/ethanol/silencer = 1, /datum/reagent/consumable/nothing = 1, /datum/reagent/consumable/nuka_cola = 1)
-
+ required_reagents = list(/datum/reagent/consumable/ethanol/silencer = 1, /datum/reagent/consumable/nothing = 1)
/datum/chemical_reaction/wizz_fizz
results = list(/datum/reagent/consumable/ethanol/wizz_fizz = 3)
@@ -545,7 +524,6 @@
mix_message = "The beverage starts to froth with an almost mystical zeal!"
mix_sound = 'sound/effects/bubbles2.ogg'
-
/datum/chemical_reaction/bug_spray
results = list(/datum/reagent/consumable/ethanol/bug_spray = 5)
required_reagents = list(/datum/reagent/consumable/ethanol/triple_sec = 2, /datum/reagent/consumable/lemon_lime = 1, /datum/reagent/consumable/ethanol/rum = 2, /datum/reagent/consumable/ethanol/vodka = 1)
@@ -559,7 +537,7 @@
/datum/chemical_reaction/turbo
results = list(/datum/reagent/consumable/ethanol/turbo = 5)
- required_reagents = list(/datum/reagent/consumable/ethanol/moonshine = 2, /datum/reagent/nitrous_oxide = 1, /datum/reagent/consumable/ethanol/sugar_rush = 1, /datum/reagent/consumable/pwr_game = 1)
+ required_reagents = list(/datum/reagent/consumable/ethanol/moonshine = 2, /datum/reagent/nitrous_oxide = 1, /datum/reagent/consumable/ethanol/sugar_rush = 1, /datum/reagent/consumable/pacfuel = 1)
/datum/chemical_reaction/old_timer
results = list(/datum/reagent/consumable/ethanol/old_timer = 6)
@@ -567,7 +545,7 @@
/datum/chemical_reaction/rubberneck
results = list(/datum/reagent/consumable/ethanol/rubberneck = 10)
- required_reagents = list(/datum/reagent/consumable/ethanol = 4, /datum/reagent/consumable/grey_bull = 5, /datum/reagent/consumable/astrotame = 1)
+ required_reagents = list(/datum/reagent/consumable/ethanol = 4, /datum/reagent/consumable/crosstalk = 5, /datum/reagent/consumable/astrotame = 1)
/datum/chemical_reaction/duplex
results = list(/datum/reagent/consumable/ethanol/duplex = 4)
@@ -629,22 +607,11 @@
required_reagents = list(/datum/reagent/consumable/ethanol/black_russian = 2, /datum/reagent/consumable/ethanol/creme_de_cacao = 2, /datum/reagent/consumable/ethanol/irishcarbomb = 1)
mix_message = "The area around the glass seems to darken as the mixture forms!"
-/datum/chemical_reaction/archmagus_brew
- results = list(/datum/reagent/consumable/ethanol/archmagus_brew = 4)
- required_reagents = list(/datum/reagent/consumable/ethanol/wizz_fizz = 2, /datum/reagent/consumable/ethanol/crevice_spike = 1, /datum/reagent/consumable/ethanol/stinger = 1)
- mix_message = "The mixture bubbles intensely before settling in the glass."
-
/datum/chemical_reaction/out_of_lime
results = list(/datum/reagent/consumable/ethanol/out_of_lime = 4)
required_reagents = list(/datum/reagent/consumable/lemonade = 1, /datum/reagent/consumable/ethanol/beer/green = 1, /datum/reagent/consumable/orangejuice = 1, /datum/reagent/consumable/ethanol/out_of_touch = 1)
mix_message = "The glass cycles through different colors before settling on one."
-/datum/chemical_reaction/cogchamp
- results = list(/datum/reagent/consumable/ethanol/cogchamp = 3)
- required_reagents = list(/datum/reagent/consumable/ethanol/cognac = 1, /datum/reagent/fuel = 1, /datum/reagent/consumable/ethanol/screwdrivercocktail = 1)
- mix_message = "You hear faint sounds of gears turning as it mixes."
- mix_sound = 'sound/effects/clockcult_gateway_closing.ogg'
-
/datum/chemical_reaction/ash_wine
results = list(/datum/reagent/consumable/ethanol/trickwine/ash_wine = 5)
required_reagents = list(/datum/reagent/consumable/ethanol/absinthe = 3, /datum/reagent/ash = 1, /datum/reagent/drug/mushroomhallucinogen = 1)
@@ -671,7 +638,7 @@
/datum/chemical_reaction/force_wine
results = list(/datum/reagent/consumable/ethanol/trickwine/force_wine = 5)
- required_reagents = list(/datum/reagent/consumable/ethanol/tequila = 3, /datum/reagent/calcium = 1, /datum/reagent/consumable/spacemountainwind = 1)
+ required_reagents = list(/datum/reagent/consumable/ethanol/tequila = 3, /datum/reagent/calcium = 1, /datum/reagent/consumable/comet_trail = 1)
required_container = /obj/structure/fermenting_barrel/distiller
mix_sound ='sound/magic/forcewall.ogg'
@@ -680,3 +647,18 @@
required_reagents = list(/datum/reagent/consumable/ethanol/gin = 3, /datum/reagent/toxin/plasma = 1, /datum/reagent/consumable/tinlux = 1)
required_container = /obj/structure/fermenting_barrel/distiller
mix_sound ='sound/weapons/laser.ogg'
+
+/datum/chemical_reaction/molten_bubbles
+ results = list(/datum/reagent/consumable/molten = 30)
+ required_reagents = list(/datum/reagent/clf3 = 10, /datum/reagent/consumable/space_cola = 20, /datum/reagent/medicine/leporazine = 1, /datum/reagent/medicine/lavaland_extract = 1)
+
+/datum/chemical_reaction/plasma_bubbles
+ results = list(/datum/reagent/consumable/molten/plasma_fizz = 3)
+ required_reagents = list(/datum/reagent/consumable/molten = 3, /datum/reagent/toxin/plasma = 2)
+
+/datum/chemical_reaction/sand_bubbles
+ results = list(/datum/reagent/consumable/molten/sand = 3)
+ required_reagents = list(/datum/reagent/consumable/molten = 3, /datum/reagent/silicon = 2)
+
+/datum/chemical_reaction/sand_bubbles/plasma // Subbing plasma bubbles for reg
+ required_reagents = list(/datum/reagent/consumable/molten/plasma_fizz = 3, /datum/reagent/silicon = 2)
diff --git a/code/modules/food_and_drinks/recipes/processor_recipes.dm b/code/modules/food_and_drinks/recipes/processor_recipes.dm
index 55db7cf06b84..98c5fa053c8f 100644
--- a/code/modules/food_and_drinks/recipes/processor_recipes.dm
+++ b/code/modules/food_and_drinks/recipes/processor_recipes.dm
@@ -13,17 +13,13 @@
input = /obj/item/reagent_containers/food/snacks/meat/rawcutlet
output = /obj/item/reagent_containers/food/snacks/meat/rawbacon
-/datum/food_processor_process/potatowedges
- input = /obj/item/reagent_containers/food/snacks/grown/potato/wedges
- output = /obj/item/reagent_containers/food/snacks/fries
-
/datum/food_processor_process/sweetpotato
input = /obj/item/reagent_containers/food/snacks/grown/potato/sweet
output = /obj/item/reagent_containers/food/snacks/yakiimo
/datum/food_processor_process/potato
input = /obj/item/reagent_containers/food/snacks/grown/potato
- output = /obj/item/reagent_containers/food/snacks/tatortot
+ output = /obj/item/reagent_containers/food/snacks/fries
/datum/food_processor_process/carrot
input = /obj/item/reagent_containers/food/snacks/grown/carrot
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm
index 92647559d9cd..edca42fda076 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_frozen.dm
@@ -27,7 +27,7 @@
name ="Space freezy"
reqs = list(
/datum/reagent/consumable/bluecherryjelly = 5,
- /datum/reagent/consumable/spacemountainwind = 15,
+ /datum/reagent/consumable/comet_trail = 15,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/spacefreezy
@@ -217,7 +217,7 @@
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/consumable/ice = 15,
- /datum/reagent/consumable/spacemountainwind = 5
+ /datum/reagent/consumable/comet_trail = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/spacemountainwind
subcategory = CAT_ICE
@@ -227,7 +227,7 @@
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/consumable/ice = 15,
- /datum/reagent/consumable/pwr_game = 15
+ /datum/reagent/consumable/pacfuel = 15
)
result = /obj/item/reagent_containers/food/snacks/snowcones/pwrgame
subcategory = CAT_ICE
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
index ec04dcaa4ec9..cc61c7048fdc 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm
@@ -396,8 +396,7 @@
name = "Gondola-pocket"
reqs = list(
/obj/item/reagent_containers/food/snacks/pastrybase = 1,
- /obj/item/reagent_containers/food/snacks/meatball = 1,
- /datum/reagent/tranquility = 5
+ /obj/item/reagent_containers/food/snacks/meatball = 1
)
result = /obj/item/reagent_containers/food/snacks/donkpocket/gondola
subcategory = CAT_PASTRY
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm
index 0d7f403b538d..d0558f94fdb5 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm
@@ -152,7 +152,7 @@
/datum/reagent/water = 10,
/obj/item/reagent_containers/glass/bowl = 1,
/obj/item/reagent_containers/food/snacks/grown/banana = 1,
- /obj/item/stack/ore/bananium = 1
+ /obj/item/stack/sheet/mineral/hidden/hellstone = 1
)
result = /obj/item/reagent_containers/food/snacks/soup/clownstears
subcategory = CAT_SOUP
diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween.dm
index e95bdb2063a8..4c2586b7dd4b 100644
--- a/code/modules/holiday/halloween.dm
+++ b/code/modules/holiday/halloween.dm
@@ -243,17 +243,6 @@
if(prob(5))
playsound(loc, 'sound/spookoween/insane_low_laugh.ogg', 300, TRUE)
-/mob/living/simple_animal/hostile/clown_insane/attackby(obj/item/O, mob/user)
- if(istype(O, /obj/item/nullrod))
- if(prob(5))
- visible_message("[src] finally found the peace it deserves. You hear honks echoing off into the distance.")
- playsound(loc, 'sound/spookoween/insane_low_laugh.ogg', 300, TRUE)
- qdel(src)
- else
- visible_message("[src] seems to be resisting the effect!")
- return
- return ..()
-
/mob/living/simple_animal/hostile/clown_insane/handle_temperature_damage()
return
@@ -261,13 +250,6 @@
// Spooky Uplink Items //
/////////////////////////
-/datum/uplink_item/dangerous/crossbow/candy
- name = "Candy Corn Crossbow"
- desc = "A standard miniature energy crossbow that uses a hard-light projector to transform bolts into candy corn. Happy Halloween!"
- category = "Holiday"
- item = /obj/item/gun/energy/kinetic_accelerator/crossbow/halloween
- surplus = 0
-
/datum/uplink_item/device_tools/emag/hack_o_lantern
name = "Hack-o'-Lantern"
desc = "An emag fitted to support the Halloween season. Candle not included."
diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm
index f1a5862649a4..d56fd4f9c32c 100644
--- a/code/modules/holodeck/items.dm
+++ b/code/modules/holodeck/items.dm
@@ -152,8 +152,8 @@
var/eventstarted = FALSE
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 6
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
power_channel = AREA_USAGE_ENVIRON
/obj/machinery/readybutton/attack_ai(mob/user as mob)
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index e9e40fd167b8..c3bcc09940d0 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -5,7 +5,7 @@
icon_state = "biogen-empty"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 40
+ idle_power_usage = IDLE_DRAW_LOW
circuit = /obj/item/circuitboard/machine/biogenerator
var/processing = FALSE
var/obj/item/reagent_containers/glass/beaker = null
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 7fa710323207..ed58e86e16dc 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -69,20 +69,19 @@
/obj/item/reagent_containers/food/snacks/grown/attackby(obj/item/O, mob/user, params)
..()
if (istype(O, /obj/item/plant_analyzer))
- var/msg = "*---------*\n This is \a [src].\n"
+ var/msg = "This is \a [src].\n"
if(seed)
- msg += seed.get_analyzer_text()
+ msg += "[seed.get_analyzer_text()]\n"
var/reag_txt = ""
if(seed)
for(var/reagent_id in seed.reagents_add)
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent_id]
var/amt = reagents.get_reagent_amount(reagent_id)
- reag_txt += "\n- [R.name]: [amt]"
+ reag_txt += "- [R.name]: [amt]\n"
if(reag_txt)
msg += reag_txt
- msg += " *---------*"
- to_chat(user, msg)
+ to_chat(user, examine_block(msg))
else
if(seed)
for(var/datum/plant_gene/trait/T in seed.genes)
diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm
index a8b9d5f8d034..a93d706a99b9 100644
--- a/code/modules/hydroponics/grown/kudzu.dm
+++ b/code/modules/hydroponics/grown/kudzu.dm
@@ -39,7 +39,7 @@
/obj/item/seeds/kudzu/attack_self(mob/user)
user.visible_message("[user] begins throwing seeds on the ground...")
- if(do_after(user, 50, needhand = TRUE, target = user.drop_location(), progress = TRUE))
+ if(do_after(user, 50, target = user.drop_location(), progress = TRUE))
plant(user)
to_chat(user, "You plant the kudzu. You monster.")
diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm
index 1378fb0253fc..1c6b19313ee4 100644
--- a/code/modules/hydroponics/grown/melon.dm
+++ b/code/modules/hydroponics/grown/melon.dm
@@ -52,19 +52,3 @@
dried_type = null
wine_power = 70 //Water to wine, baby.
wine_flavor = "divinity"
-
-/obj/item/reagent_containers/food/snacks/grown/holymelon/Initialize()
- . = ..()
- var/uses = 1
- if(seed)
- uses = round(seed.potency / 20)
- AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_HANDS, uses, TRUE, CALLBACK(src, PROC_REF(block_magic)), CALLBACK(src, PROC_REF(expire))) //deliver us from evil o melon god
-
-/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/block_magic(mob/user, major)
- if(major)
- to_chat(user, "[src] hums slightly, and seems to decay a bit.")
-
-/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/expire(mob/user)
- to_chat(user, "[src] rapidly turns into ash!")
- qdel(src)
- new /obj/effect/decal/cleanable/ash(drop_location())
diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm
index f614533d2fd5..73a322ce81ae 100644
--- a/code/modules/hydroponics/grown/misc.dm
+++ b/code/modules/hydroponics/grown/misc.dm
@@ -163,7 +163,7 @@
name = "gatfruit"
desc = "It smells like burning."
icon_state = "gatfruit"
- trash = /obj/item/gun/ballistic/revolver
+ trash = /obj/item/gun/ballistic/revolver/syndicate
bitesize_mod = 2
foodtype = FRUIT
tastes = list("gunpowder" = 1)
diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm
index 703df831552e..44a987dc86ac 100644
--- a/code/modules/hydroponics/grown/potato.dm
+++ b/code/modules/hydroponics/grown/potato.dm
@@ -29,25 +29,6 @@
juice_results = list(/datum/reagent/consumable/potato_juice = 0)
distill_reagent = /datum/reagent/consumable/ethanol/vodka
-/obj/item/reagent_containers/food/snacks/grown/potato/wedges
- name = "potato wedges"
- desc = "Slices of neatly cut potato."
- icon_state = "potato_wedges"
- filling_color = "#E9967A"
- bitesize = 100
-
-
-/obj/item/reagent_containers/food/snacks/grown/potato/attackby(obj/item/W, mob/user, params)
- if(W.get_sharpness())
- to_chat(user, "You cut the potato into wedges with [W].")
- var/obj/item/reagent_containers/food/snacks/grown/potato/wedges/Wedges = new /obj/item/reagent_containers/food/snacks/grown/potato/wedges
- remove_item_from_storage(user)
- qdel(src)
- user.put_in_hands(Wedges)
- else
- return ..()
-
-
// Sweet Potato
/obj/item/seeds/potato/sweet
name = "pack of sweet potato seeds"
diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm
index 3ecb34762ae1..f97596c348f2 100644
--- a/code/modules/hydroponics/growninedible.dm
+++ b/code/modules/hydroponics/growninedible.dm
@@ -35,11 +35,10 @@
/obj/item/grown/attackby(obj/item/O, mob/user, params)
..()
if (istype(O, /obj/item/plant_analyzer))
- var/msg = "*---------*\n This is \a [src]\n"
+ var/msg = "This is \a [src]\n"
if(seed)
msg += seed.get_analyzer_text()
- msg += ""
- to_chat(usr, msg)
+ to_chat(usr, examine_block(msg))
return
/obj/item/grown/proc/add_juice()
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index a5e66f6df4ef..bbfeaeeb5b5a 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -1,3 +1,6 @@
+#define HYDRO_MAX_PEST 10
+#define HYDRO_MAX_WEED 10
+#define HYDRO_MAX_TOXIC 100
/obj/machinery/hydroponics
name = "hydroponics tray"
icon = 'icons/obj/hydroponics/equipment.dmi'
@@ -6,7 +9,9 @@
pixel_z = 1
obj_flags = CAN_BE_HIT | UNIQUE_RENAME
circuit = /obj/item/circuitboard/machine/hydroponics
- idle_power_usage = 0
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_HIGH
var/waterlevel = 100 //The amount of water in the tray (max 100)
var/maxwater = 100 //The maximum amount of water in the tray
var/nutridrain = 1 // How many units of nutrient will be drained in the tray
@@ -114,7 +119,7 @@
if(!powered() && self_sustaining)
visible_message("[name]'s auto-grow functionality shuts off!")
- idle_power_usage = 0
+ set_idle_power()
self_sustaining = FALSE
update_appearance()
@@ -253,7 +258,7 @@
adjustWeeds(1 / rating)
// Weeeeeeeeeeeeeeedddssss
- if(weedlevel >= 10 && prob(50)) // At this point the plant is kind of fucked. Weeds can overtake the plant spot.
+ if(weedlevel >= HYDRO_MAX_WEED && prob(50)) // At this point the plant is kind of fucked. Weeds can overtake the plant spot.
if(myseed)
if(!myseed.get_gene(/datum/plant_gene/trait/plant_type/weed_hardy) && !myseed.get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) // If a normal plant
weedinvasion()
@@ -549,25 +554,26 @@
else if(istype(O, /obj/item/plant_analyzer))
var/obj/item/plant_analyzer/P_analyzer = O
+ var/msg = ""
if(myseed)
if(P_analyzer.scan_mode == PLANT_SCANMODE_STATS)
- to_chat(user, examine_block("[myseed.plantname]"))
- to_chat(user, examine_block("Plant Age: [age]"))
+ msg += "[myseed.plantname]\n"
+ msg += "- Plant Age: [span_notice("[age]\n")]"
var/list/text_string = myseed.get_analyzer_text()
if(text_string)
- to_chat(user, examine_block(text_string))
+ msg += "[text_string]\n"
if(myseed.reagents_add && P_analyzer.scan_mode == PLANT_SCANMODE_CHEMICALS)
- to_chat(user, examine_block("Plant Reagents"))
+ msg += "Plant Reagents\n"
for(var/datum/plant_gene/reagent/Gene in myseed.genes)
- to_chat(user, examine_block("- [Gene.get_name()] -"))
+ msg += "[span_notice("- [Gene.get_name()] -")]\n"
else
- to_chat(user, examine_block( "No plant found."))
- to_chat(user, examine_block("\nWeed level: [weedlevel] / 10"))
- to_chat(user, examine_block("\nPest level: [pestlevel] / 10"))
- to_chat(user, examine_block("\nToxicity level: [toxic] / 100"))
- to_chat(user, examine_block("\nWater level: [waterlevel] / [maxwater]"))
- to_chat(user, examine_block("\nNutrition level: [reagents.total_volume] / [maxnutri]"))
- to_chat(user, examine_block(" "))
+ msg += "No plant found.\n"
+ msg += "Weed level: [span_notice("[weedlevel] / [HYDRO_MAX_WEED]")]\n"
+ msg += "Pest level: [span_notice("[pestlevel] / [HYDRO_MAX_PEST]")]\n"
+ msg += "Toxicity level: [span_notice("[toxic] / [HYDRO_MAX_TOXIC]")]\n"
+ msg += "Water level: [span_notice("[waterlevel] / [maxwater]")]\n"
+ msg += "Nutrition level: [span_notice("[reagents.total_volume] / [maxnutri]")]\n"
+ to_chat(user, examine_block(msg))
return
else if(istype(O, /obj/item/cultivator))
@@ -671,7 +677,10 @@
if(!anchored)
return
self_sustaining = !self_sustaining
- idle_power_usage = self_sustaining ? 1250 : 0
+ if(self_sustaining)
+ set_active_power()
+ else
+ set_idle_power()
to_chat(user, "You [self_sustaining ? "activate" : "deactivated"] [src]'s autogrow function[self_sustaining ? ", maintaining the tray's health while using high amounts of power" : ""].")
update_appearance()
@@ -702,7 +711,7 @@
desc = initial(desc)
TRAY_NAME_UPDATE
if(self_sustaining) //No reason to pay for an empty tray.
- idle_power_usage = 0
+ set_idle_power()
self_sustaining = FALSE
update_appearance()
@@ -718,13 +727,13 @@
plant_health = clamp(plant_health + adjustamt, 0, myseed.endurance)
/obj/machinery/hydroponics/proc/adjustToxic(adjustamt)
- toxic = clamp(toxic + adjustamt, 0, 100)
+ toxic = clamp(toxic + adjustamt, 0, HYDRO_MAX_TOXIC)
/obj/machinery/hydroponics/proc/adjustPests(adjustamt)
- pestlevel = clamp(pestlevel + adjustamt, 0, 10)
+ pestlevel = clamp(pestlevel + adjustamt, 0, HYDRO_MAX_PEST)
/obj/machinery/hydroponics/proc/adjustWeeds(adjustamt)
- weedlevel = clamp(weedlevel + adjustamt, 0, 10)
+ weedlevel = clamp(weedlevel + adjustamt, 0, HYDRO_MAX_WEED)
/obj/machinery/hydroponics/proc/spawnplant() // why would you put strange reagent in a hydro tray you monster I bet you also feed them blood
var/list/livingplants = list(/mob/living/simple_animal/hostile/tree, /mob/living/simple_animal/hostile/killertomato)
diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm
index 008009a35765..ad24dccff43d 100644
--- a/code/modules/hydroponics/seeds.dm
+++ b/code/modules/hydroponics/seeds.dm
@@ -390,29 +390,29 @@
/obj/item/seeds/proc/get_analyzer_text() //in case seeds have something special to tell to the analyzer
var/text = ""
if(!get_gene(/datum/plant_gene/trait/plant_type/weed_hardy) && !get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism) && !get_gene(/datum/plant_gene/trait/plant_type/alien_properties))
- text += "- Plant type: Normal plant\n"
+ text += "- Plant type: [span_notice("Normal plant\n")]"
if(get_gene(/datum/plant_gene/trait/plant_type/weed_hardy))
- text += "- Plant type: Weed. Can grow in nutrient-poor soil.\n"
+ text += "- Plant type: [span_notice("Weed. Can grow in nutrient-poor soil.\n")]"
if(get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism))
- text += "- Plant type: Mushroom. Can grow in dry soil.\n"
+ text += "- Plant type: [span_notice("Mushroom. Can grow in dry soil.\n")]"
if(get_gene(/datum/plant_gene/trait/plant_type/crystal))
- text += "- Plant type: Crystal. Revitalizes soil.\n"
+ text += "- Plant type: [span_notice("Crystal. Revitalizes soil.\n")]"
if(get_gene(/datum/plant_gene/trait/plant_type/alien_properties))
- text += "- Plant type: UNKNOWN \n"
+ text += "- Plant type: [span_warning("UNKNOWN\n")]"
if(potency != UNHARVESTABLE)
- text += "- Potency: [potency]\n"
+ text += "- Potency: [span_notice("[potency]\n")]"
if(yield != UNHARVESTABLE)
- text += "- Yield: [yield]\n"
- text += "- Maturation speed: [maturation]\n"
+ text += "- Yield: [span_notice("[yield]\n")]"
+ text += "- Maturation speed: [span_notice("[maturation]\n")]"
if(yield != UNHARVESTABLE)
- text += "- Production speed: [production]\n"
- text += "- Endurance: [endurance]\n"
- text += "- Lifespan: [lifespan]\n"
- text += "- Instability: [instability]\n"
- text += "- Weed Growth Rate: [weed_rate]\n"
- text += "- Weed Vulnerability: [weed_chance]\n"
+ text += "- Production speed: [span_notice("[production]\n")]"
+ text += "- Endurance: [span_notice("[endurance]\n")]"
+ text += "- Lifespan: [span_notice("[lifespan]\n")]"
+ text += "- Instability: [span_notice("[instability]\n")]"
+ text += "- Weed Growth Rate: [span_notice("[weed_rate]\n")]"
+ text += "- Weed Vulnerability: [span_notice("[weed_chance]\n")]"
if(rarity)
- text += "- Species Discovery Value: [rarity]\n"
+ text += "- Species Discovery Value: [span_notice("[rarity]\n")]"
var/all_traits = ""
for(var/datum/plant_gene/trait/traits in genes)
if(istype(traits, /datum/plant_gene/trait/plant_type))
@@ -427,20 +427,20 @@
/obj/item/seeds/attackby(obj/item/O, mob/user, params)
if (istype(O, /obj/item/plant_analyzer))
- to_chat(user, "*---------*\n This is \a [src].")
+ var/msg = "This is \a [src]."
var/text
var/obj/item/plant_analyzer/P_analyzer = O
if(P_analyzer.scan_mode == PLANT_SCANMODE_STATS)
text = get_analyzer_text()
if(text)
- to_chat(user, "[text]")
+ msg += "\n[text]"
if(reagents_add && P_analyzer.scan_mode == PLANT_SCANMODE_CHEMICALS)
- to_chat(user, "- Plant Reagents -")
- to_chat(user, "*---------*")
+ msg += "\n- Plant Reagents -"
+ msg += "\n*---------*"
for(var/datum/plant_gene/reagent/Gene in genes)
- to_chat(user, "- [Gene.get_name()] -")
- to_chat(user, "*---------*")
-
+ msg += "\n- [Gene.get_name()] -"
+ msg += "\n*---------*"
+ to_chat(user, examine_block(msg))
return
diff --git a/code/modules/instruments/items.dm b/code/modules/instruments/items.dm
index 022b3278e92b..490742d7cdf7 100644
--- a/code/modules/instruments/items.dm
+++ b/code/modules/instruments/items.dm
@@ -271,9 +271,8 @@
hitsound = 'sound/items/bikehorn.ogg'
/obj/item/choice_beacon/music
- name = "instrument delivery beacon"
- desc = "Summon your tool of art."
- icon_state = "gangtool-red"
+ name = "instrument box"
+ desc = "Contains your tool of art."
/obj/item/choice_beacon/music/generate_display_names()
var/static/list/instruments
@@ -299,9 +298,8 @@
return instruments
/obj/item/choice_beacon/rnd
- name = "C.R.E.W.M.A.T.E type R&D Choice Beacon"
- desc = "This aging launch beacon summons a limited production RND package from a nearby orbital satellite, delivered via impact pod."
- icon_state = "gangtool-sus"
+ name = "C.R.E.W.M.A.T.E type R&D box"
+ desc = "This box contains a limited production RND package."
/obj/item/choice_beacon/rnd/generate_display_names()
var/static/list/rndboxes
diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm
index cdd44cab9ae8..39eb08749872 100644
--- a/code/modules/jobs/access.dm
+++ b/code/modules/jobs/access.dm
@@ -44,6 +44,9 @@
/obj/item/proc/InsertID()
return FALSE
+/obj/item/proc/GetBankCard()
+ return null
+
/obj/proc/text2access(access_text)
. = list()
if(!access_text)
@@ -114,6 +117,8 @@
if (gen_ship_access(ship))
return TRUE
+ if(!item)
+ return FALSE
var/obj/item/card/id/id = item?.GetID()
if (id?.has_ship_access(ship))
return TRUE
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index ee0d7789355e..ee953b0fb74d 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -25,7 +25,6 @@
var/display_order = JOB_DISPLAY_ORDER_DEFAULT
-
///Levels unlocked at roundstart in physiology
var/list/roundstart_experience
@@ -123,7 +122,7 @@
if(!H)
return FALSE
if(!visualsOnly)
- var/datum/bank_account/bank_account = new(H.real_name, src)
+ var/datum/bank_account/bank_account = new(H.real_name, H.age)
bank_account.adjust_money(officer ? 250 : 100, "starting_money") //just a little bit of money for you
H.account_id = bank_account.account_id
@@ -180,7 +179,9 @@
var/jobtype = null
uniform = /obj/item/clothing/under/color/grey
+ wallet = /obj/item/storage/wallet
id = /obj/item/card/id
+ bank_card = /obj/item/card/bank
back = /obj/item/storage/backpack
shoes = /obj/item/clothing/shoes/sneakers/black
box = /obj/item/storage/box/survival
@@ -269,9 +270,10 @@
if(!J)
J = GLOB.name_occupations[H.job]
- var/obj/item/card/id/C = H.wear_id
+ var/obj/item/card/id/C = H.get_idcard(TRUE)
if(istype(C))
C.access = J.get_access()
+ SEND_SIGNAL(C, COSMIG_ACCESS_UPDATED)
shuffle_inplace(C.access) // Shuffle access list to make NTNet passkeys less predictable
C.registered_name = H.real_name
if(H.job)
@@ -286,14 +288,17 @@
if(id_assignment)
C.assignment = id_assignment
C.update_label()
- for(var/A in SSeconomy.bank_accounts)
- var/datum/bank_account/B = A
- if(B.account_id == H.account_id)
- C.registered_account = B
- B.bank_cards += C
- break
H.sec_hud_set_ID()
+ var/obj/item/card/bank/bank_card = H.get_bankcard()
+ if(istype(bank_card))
+ for(var/account in SSeconomy.bank_accounts)
+ var/datum/bank_account/bank_account = account
+ if(bank_account.account_id == H.account_id)
+ bank_card.registered_account = bank_account
+ bank_account.bank_cards += bank_card
+ break
+
var/obj/item/pda/PDA = H.get_item_by_slot(pda_slot)
if(istype(PDA))
PDA.owner = H.real_name
diff --git a/code/modules/jobs/job_types/bartender.dm b/code/modules/jobs/job_types/bartender.dm
index 9c5d28e693e8..994f34404efc 100644
--- a/code/modules/jobs/job_types/bartender.dm
+++ b/code/modules/jobs/job_types/bartender.dm
@@ -27,7 +27,7 @@
/datum/outfit/job/bartender/post_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
- var/obj/item/card/id/W = H.wear_id
+ var/obj/item/card/id/W = H.get_idcard()
if(H.age < AGE_MINOR)
W.registered_age = AGE_MINOR
to_chat(H, "You're not technically old enough to access or serve alcohol, but your ID has been discreetly modified to display your age as [AGE_MINOR]. Try to keep that a secret!")
diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm
index 786f9e798e43..a5fed7b7fe91 100644
--- a/code/modules/jobs/job_types/captain.dm
+++ b/code/modules/jobs/job_types/captain.dm
@@ -27,8 +27,7 @@
gloves = /obj/item/clothing/gloves/color/captain
ears = /obj/item/radio/headset/heads/captain
uniform = /obj/item/clothing/under/rank/command/captain
- alt_uniform = /obj/item/clothing/under/rank/command/captain/parade //WS Edit - Alt Uniforms
- dcoat = /obj/item/clothing/suit/hooded/wintercoat/captain //WS Edit - Alt Uniforms
+ dcoat = /obj/item/clothing/suit/hooded/wintercoat/captain
shoes = /obj/item/clothing/shoes/sneakers/brown
head = /obj/item/clothing/head/caphat
backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1)
diff --git a/code/modules/jobs/job_types/cargo_technician.dm b/code/modules/jobs/job_types/cargo_technician.dm
index 3fa729969013..7e84efd98de7 100644
--- a/code/modules/jobs/job_types/cargo_technician.dm
+++ b/code/modules/jobs/job_types/cargo_technician.dm
@@ -4,7 +4,7 @@
outfit = /datum/outfit/job/cargo_tech
- access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_QM, ACCESS_MINING, ACCESS_MECH_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
+ access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_MINING, ACCESS_MECH_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_CARGO, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
display_order = JOB_DISPLAY_ORDER_CARGO_TECHNICIAN
diff --git a/code/modules/jobs/job_types/chaplain.dm b/code/modules/jobs/job_types/chaplain.dm
index 870697476794..ab4ceb6968c0 100644
--- a/code/modules/jobs/job_types/chaplain.dm
+++ b/code/modules/jobs/job_types/chaplain.dm
@@ -16,8 +16,6 @@
var/obj/item/storage/book/bible/booze/B = new
if(GLOB.religion)
- if(H.mind)
- H.mind.holy_role = HOLY_ROLE_PRIEST
B.deity_name = GLOB.deity
B.name = GLOB.bible_name
B.icon_state = GLOB.bible_icon_state
@@ -30,8 +28,6 @@
if(GLOB.religious_sect)
GLOB.religious_sect.on_conversion(H)
return
- if(H.mind)
- H.mind.holy_role = HOLY_ROLE_HIGHPRIEST
var/new_religion = DEFAULT_RELIGION
if(M.client && M.client.prefs.custom_names["religion"])
diff --git a/code/modules/jobs/job_types/janitor.dm b/code/modules/jobs/job_types/janitor.dm
index 8293c2bd663b..60c8ab9672b4 100644
--- a/code/modules/jobs/job_types/janitor.dm
+++ b/code/modules/jobs/job_types/janitor.dm
@@ -22,5 +22,5 @@
/datum/outfit/job/janitor/pre_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
if(GARBAGEDAY in SSevents.holidays)
- l_pocket = /obj/item/gun/ballistic/revolver
+ l_pocket = /obj/item/gun/ballistic/revolver/syndicate
r_pocket = /obj/item/ammo_box/a357
diff --git a/code/modules/jobs/job_types/shaft_miner.dm b/code/modules/jobs/job_types/shaft_miner.dm
index 2cf67b9bbf70..1469e592b4de 100644
--- a/code/modules/jobs/job_types/shaft_miner.dm
+++ b/code/modules/jobs/job_types/shaft_miner.dm
@@ -4,7 +4,7 @@
outfit = /datum/outfit/job/miner
- access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_QM, ACCESS_MINING, ACCESS_MECH_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
+ access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_MINING, ACCESS_MECH_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MINING, ACCESS_MECH_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
display_order = JOB_DISPLAY_ORDER_SHAFT_MINER
diff --git a/code/modules/library/lib_codex_gigas.dm b/code/modules/library/lib_codex_gigas.dm
index c4263a771b0d..69155c9230d8 100644
--- a/code/modules/library/lib_codex_gigas.dm
+++ b/code/modules/library/lib_codex_gigas.dm
@@ -48,7 +48,7 @@
correctness = 100
correctness -= U.getOrganLoss(ORGAN_SLOT_BRAIN) * 0.5 //Brain damage makes researching hard.
speed += U.getOrganLoss(ORGAN_SLOT_BRAIN) * 3
- if(do_after(user, speed, 0, user))
+ if(do_after(user, speed, user, timed_action_flags = IGNORE_HELD_ITEM))
var/usedName = devilName
if(!prob(correctness))
usedName += "x"
@@ -59,7 +59,7 @@
inUse = FALSE
/obj/item/book/codex_gigas/proc/display_devil(datum/antagonist/devil/devil, mob/reader, devilName)
- reader << browse("Information on [devilName]
[GLOB.lawlorify[LORE][devil.ban]] [GLOB.lawlorify[LORE][devil.bane]] [GLOB.lawlorify[LORE][devil.obligation]] [GLOB.lawlorify[LORE][devil.banish]] [devil.ascendable?"This devil may ascend given enough souls.":""]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
+ reader << browse("Information on [devilName]
[GLOB.lawlorify[LORE][devil.ban]] [GLOB.lawlorify[LORE][devil.obligation]] [GLOB.lawlorify[LORE][devil.banish]] [devil.ascendable?"This devil may ascend given enough souls.":""]", "window=book[window_size != null ? ";size=[window_size]" : ""]")
/obj/item/book/codex_gigas/proc/ask_name(mob/reader)
ui_interact(reader)
diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm
index 140b87c1707f..d86cfebf1197 100644
--- a/code/modules/mining/abandoned_crates.dm
+++ b/code/modules/mining/abandoned_crates.dm
@@ -192,7 +192,7 @@
if(77 to 78)
new /obj/item/toy/plush/lizardplushie(src)
if(79 to 80)
- new /obj/item/stack/sheet/mineral/bananium(src, 10)
+ new /obj/item/stack/sheet/mineral/hidden/hellstone(src, 10)
if(81 to 82)
new /obj/item/bikehorn/airhorn(src)
if(83 to 84)
@@ -222,16 +222,14 @@
if(96)
new /obj/item/banhammer(src)
for(var/i in 1 to 3)
- var/obj/effect/mine/sound/bwoink/mine = new (src)
- mine.set_anchored(FALSE)
- mine.move_resist = MOVE_RESIST_DEFAULT
+ new /obj/item/mine/pressure/sound(src)
if(97)
for(var/i in 1 to 4)
new /obj/item/clothing/mask/balaclava(src)
new /obj/item/gun/ballistic/shotgun/toy(src)
- new /obj/item/gun/ballistic/automatic/toy/pistol/unrestricted(src)
- new /obj/item/gun/ballistic/automatic/toy/unrestricted(src)
- new /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/unrestricted(src)
+ new /obj/item/gun/ballistic/automatic/toy/pistol(src)
+ new /obj/item/gun/ballistic/automatic/toy(src)
+ new /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy(src)
new /obj/item/ammo_box/foambox(src)
if(98)
for(var/i in 1 to 3)
diff --git a/code/modules/mining/drill.dm b/code/modules/mining/drill.dm
index 281097be7842..9a35c2b4bf11 100644
--- a/code/modules/mining/drill.dm
+++ b/code/modules/mining/drill.dm
@@ -218,7 +218,7 @@
/obj/machinery/drill/AltClick(mob/user)
if(active)
to_chat(user, "You begin the manual shutoff process.")
- if(do_after(user,10))
+ if(do_after(user, 10, src))
active = FALSE
soundloop.stop()
deltimer(current_timerid)
diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm
index 41fce675bf70..46c20dd02e1b 100644
--- a/code/modules/mining/equipment/explorer_gear.dm
+++ b/code/modules/mining/equipment/explorer_gear.dm
@@ -1,7 +1,7 @@
/****************Explorer's Suit and Mask****************/
/obj/item/clothing/suit/hooded/explorer
name = "explorer suit"
- desc = "A light, armor-plated softsuit, designed for exploration of dangerous planetary enviroments. An NT design by origin, later reappropriated by EXOCON for mass retail production."
+ desc = "A light, armor-plated softsuit, designed for exploration of dangerous planetary enviroments. An NT design by origin, later reappropriated by EXOCOM for mass retail production."
icon_state = "explorer"
item_state = "explorer"
body_parts_covered = CHEST|GROIN|LEGS|ARMS
@@ -10,7 +10,7 @@
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
heat_protection = CHEST|GROIN|LEGS|ARMS
hoodtype = /obj/item/clothing/head/hooded/explorer
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
+ armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
resistance_flags = FIRE_PROOF
supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION
@@ -23,7 +23,7 @@
flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
+ armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
resistance_flags = FIRE_PROOF
/obj/item/clothing/suit/hooded/explorer/Initialize()
@@ -36,7 +36,7 @@
/obj/item/clothing/mask/gas/explorer
name = "explorer gas mask"
- desc = "An advanced atmospheric scrubbing mask with a built-in pressure seal, manufactured by EXOCON. Can be connected to an air supply."
+ desc = "An advanced atmospheric scrubbing mask with a built-in pressure seal, manufactured by EXOCOM. Can be connected to an air supply."
icon_state = "gas_mining"
visor_flags = BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS
visor_flags_inv = HIDEFACIALHAIR
@@ -166,7 +166,7 @@
max_heat_protection_temperature = (FIRE_SUIT_MAX_TEMP_PROTECT / 2)
heat_protection = CHEST|GROIN|LEGS|ARMS
hoodtype = /obj/item/clothing/head/hooded/survivor_hood
- armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 15, "bomb" = 20, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 30)
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 10, "bomb" = 20, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 30)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
resistance_flags = FIRE_PROOF
supports_variations = DIGITIGRADE_VARIATION | VOX_VARIATION
@@ -180,7 +180,7 @@
flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
- armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 15, "bomb" = 20, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 30)
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 10, "bomb" = 20, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 30)
resistance_flags = FIRE_PROOF
/obj/item/clothing/suit/hooded/survivor/Initialize()
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index debdb2e2ea02..b6073d4c86a2 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -6,7 +6,7 @@
lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi'
name = "proto-magnetic crusher"
- desc = "A multipurpose disembarkation and self-defense tool designed by EXOCON using an incomplete Nanotrasen prototype. \
+ desc = "A multipurpose disembarkation and self-defense tool designed by EXOCOM using an incomplete Nanotrasen prototype. \
Found in the grime-stained hands of wannabee explorers across the frontier, it cuts rock and hews flora using magnetic osscilation and a heavy cleaving edge."
force = 0 //You can't hit stuff unless wielded
w_class = WEIGHT_CLASS_BULKY
@@ -24,7 +24,6 @@
light_range = 5
light_on = FALSE
custom_price = 800
- var/list/trophies = list()
var/charged = TRUE
var/charge_time = 15
var/detonation_damage = 20
@@ -41,10 +40,6 @@
AddComponent(/datum/component/butchering, 60, 110) //technically it's huge and bulky, but this provides an incentive to use it
AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=15)
-/obj/item/kinetic_crusher/Destroy()
- QDEL_LIST(trophies)
- return ..()
-
/// triggered on wield of two handed item
/obj/item/kinetic_crusher/proc/on_wield(obj/item/source, mob/user)
wielded = TRUE
@@ -57,30 +52,6 @@
. = ..()
. += "Induce magnetism in an enemy by striking them with a magnetospheric wave, then hit them in melee to force a waveform collapse for [force + detonation_damage] damage."
. += "Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage]."
- for(var/t in trophies)
- var/obj/item/crusher_trophy/T = t
- . += "It has \a [T] attached, which causes [T.effect_desc()]."
-
-/obj/item/kinetic_crusher/attackby(obj/item/I, mob/living/user)
- if(I.tool_behaviour == TOOL_CROWBAR)
- if(LAZYLEN(trophies))
- var/list/choose_options = list()
- for(var/obj/item/crusher_trophy/T in trophies)
- choose_options += list(T.name = image(icon = T.icon, icon_state = T.icon_state))
- var/picked_option = show_radial_menu(user, src, choose_options, radius = 38, require_near = TRUE)
- if(picked_option)
- to_chat(user, "You remove [picked_option].")
- I.play_tool_sound(src)
- for(var/obj/item/crusher_trophy/T in trophies)
- if(T.name == picked_option)
- T.remove_from(src, user)
- else
- to_chat(user, "There are no trophies on [src].")
- else if(istype(I, /obj/item/crusher_trophy))
- var/obj/item/crusher_trophy/T = I
- T.add_to(src, user)
- else
- return ..()
/obj/item/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
if(!wielded)
@@ -90,10 +61,6 @@
var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/target_health = target.health
..()
- for(var/t in trophies)
- if(!QDELETED(target))
- var/obj/item/crusher_trophy/T = t
- T.on_melee_hit(target, user)
if(!QDELETED(C) && !QDELETED(target))
C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did
@@ -106,9 +73,6 @@
if(!isturf(proj_turf))
return
var/obj/projectile/destabilizer/D = new /obj/projectile/destabilizer(proj_turf)
- for(var/t in trophies)
- var/obj/item/crusher_trophy/T = t
- T.on_projectile_fire(D, user)
D.preparePixelProjectile(target, user, clickparams)
D.firer = user
D.hammer_synced = src
@@ -125,9 +89,6 @@
return
var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/target_health = L.health
- for(var/t in trophies)
- var/obj/item/crusher_trophy/T = t
- T.on_mark_detonation(target, user)
if(!QDELETED(L))
if(!QDELETED(C))
C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did
@@ -152,7 +113,7 @@
/obj/item/kinetic_crusher/ui_action_click(mob/user, actiontype)
set_light_on(!light_on)
- playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
+ playsound(user, SOUND_EMPTY_MAG, 100, TRUE)
update_appearance()
@@ -186,12 +147,7 @@
/obj/projectile/destabilizer/on_hit(atom/target, blocked = FALSE)
if(isliving(target))
var/mob/living/L = target
- var/had_effect = (L.has_status_effect(STATUS_EFFECT_CRUSHERMARK)) //used as a boolean
- var/datum/status_effect/crusher_mark/CM = L.apply_status_effect(STATUS_EFFECT_CRUSHERMARK, hammer_synced)
- if(hammer_synced)
- for(var/t in hammer_synced.trophies)
- var/obj/item/crusher_trophy/T = t
- T.on_mark_application(target, CM, had_effect)
+ L.apply_status_effect(STATUS_EFFECT_CRUSHERMARK, hammer_synced)
var/target_turf = get_turf(target)
if(ismineralturf(target_turf))
var/turf/closed/mineral/M = target_turf
@@ -199,535 +155,6 @@
M.gets_drilled(firer, TRUE)
..()
-//trophies
-/obj/item/crusher_trophy
- name = "tail spike"
- desc = "A strange spike with no usage."
- icon = 'icons/obj/lavaland/artefacts.dmi'
- icon_state = "tail_spike"
- var/bonus_value = 10 //if it has a bonus effect, this is how much that effect is
- var/denied_type = /obj/item/crusher_trophy
-
-/obj/item/crusher_trophy/examine(mob/living/user)
- . = ..()
- . += "Causes [effect_desc()] when attached to a kinetic crusher."
-
-/obj/item/crusher_trophy/proc/effect_desc()
- return "errors"
-
-/obj/item/crusher_trophy/attackby(obj/item/A, mob/living/user)
- if(istype(A, /obj/item/kinetic_crusher))
- add_to(A, user)
- else
- ..()
-
-/obj/item/crusher_trophy/proc/add_to(obj/item/kinetic_crusher/H, mob/living/user)
- for(var/t in H.trophies)
- var/obj/item/crusher_trophy/T = t
- if(istype(T, denied_type) || istype(src, T.denied_type))
- to_chat(user, "You can't seem to attach [src] to [H]. Maybe remove a few trophies?")
- return FALSE
- if(!user.transferItemToLoc(src, H))
- return
- H.trophies += src
- to_chat(user, "You attach [src] to [H].")
- return TRUE
-
-/obj/item/crusher_trophy/proc/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
- forceMove(get_turf(H))
- H.trophies -= src
- return TRUE
-
-/obj/item/crusher_trophy/proc/on_melee_hit(mob/living/target, mob/living/user) //the target and the user
-/obj/item/crusher_trophy/proc/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user) //the projectile fired and the user
-/obj/item/crusher_trophy/proc/on_mark_application(mob/living/target, datum/status_effect/crusher_mark/mark, had_mark) //the target, the mark applied, and if the target had a mark before
-/obj/item/crusher_trophy/proc/on_mark_detonation(mob/living/target, mob/living/user) //the target and the user
-
-//goliath
-/obj/item/crusher_trophy/goliath_tentacle
- name = "goliath tentacle"
- desc = "A sliced-off goliath tentacle."
- icon_state = "goliath_tentacle"
- denied_type = /obj/item/crusher_trophy/goliath_tentacle
- bonus_value = 5
- var/missing_health_ratio = 0.1
- var/missing_health_desc = 10
-
-/obj/item/crusher_trophy/goliath_tentacle/effect_desc()
- return "waveform collapse to do [bonus_value] more damage for every [missing_health_desc] health you are missing"
-
-/obj/item/crusher_trophy/goliath_tentacle/on_mark_detonation(mob/living/target, mob/living/user)
- var/missing_health = user.maxHealth - user.health
- missing_health *= missing_health_ratio //bonus is active at all times, even if you're above 90 health
- missing_health *= bonus_value //multiply the remaining amount by bonus_value
- if(missing_health > 0)
- target.adjustBruteLoss(missing_health) //and do that much damage
-
-//ancient goliath
-/obj/item/crusher_trophy/elder_tentacle
- name = "elder tentacle"
- desc = "The barbed tip of a tentacle sliced from an incredibly ancient goliath."
- icon_state = "elder_tentacle"
- denied_type = /obj/item/crusher_trophy/elder_tentacle
- bonus_value = 3
- var/missing_health_ratio = 0.1
- var/missing_health_desc = 5
- icon = 'icons/obj/lavaland/elite_trophies.dmi'
-
-/obj/item/crusher_trophy/elder_tentacle/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/elder_tentacle/effect_desc()
- return "waveform collapse to do [bonus_value] more damage for every [missing_health_desc] health you are missing"
-
-/obj/item/crusher_trophy/elder_tentacle/on_mark_detonation(mob/living/target, mob/living/user)
- var/missing_health = user.maxHealth - user.health
- missing_health *= missing_health_ratio //bonus is active at all times, even if you're above 90 health
- missing_health *= bonus_value //multiply the remaining amount by bonus_value
- if(missing_health > 0)
- target.adjustBruteLoss(missing_health) //and do that much damage
-
-//crystal goliath
-/obj/item/crusher_trophy/goliath_crystal
- name = "goliath crystal"
- desc = "A crystal ripped off from a goliath infected by the strange crystals. You can see the original skin of the goliath deeply embeded in it."
- icon_state = "goliath_crystal"
- denied_type = /obj/item/crusher_trophy/elder_tentacle
- bonus_value = 4
- var/missing_health_ratio = 0.1
- var/missing_health_desc = 5
-
-/obj/item/crusher_trophy/goliath_crystal/effect_desc()
- return "waveform collapse to stun creatures for [bonus_value*0.1] second\s"
-
-/obj/item/crusher_trophy/goliath_crystal/on_mark_detonation(mob/living/simple_animal/target, mob/living/user)
- if(!ishostile(target))
- return
- var/mob/living/simple_animal/hostile/hostile_target = target
- var/hostile_ai_status = hostile_target.AIStatus
- hostile_target.AIStatus = AI_OFF
- addtimer(VARSET_CALLBACK(hostile_target, AIStatus, hostile_ai_status), bonus_value*0.1 SECONDS)
-
-//watcher
-/obj/item/crusher_trophy/watcher_wing
- name = "watcher wing"
- desc = "A wing ripped from a watcher."
- icon_state = "watcher_wing"
- denied_type = /obj/item/crusher_trophy/watcher_wing
- bonus_value = 5
-
-/obj/item/crusher_trophy/watcher_wing/effect_desc()
- return "waveform collapse to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s"
-
-/obj/item/crusher_trophy/watcher_wing/on_mark_detonation(mob/living/target, mob/living/user)
- if(ishostile(target))
- var/mob/living/simple_animal/hostile/H = target
- if(H.ranged) //briefly delay ranged attacks
- if(H.ranged_cooldown >= world.time)
- H.ranged_cooldown += bonus_value
- else
- H.ranged_cooldown = bonus_value + world.time
-
-//magmawing watcher
-/obj/item/crusher_trophy/magma_wing
- name = "magmatic sinew"
- desc = "A fuming organ, dropped by beings hotter then lava."
- icon_state = "magma_wing"
- denied_type = /obj/item/crusher_trophy/magma_wing
- gender = NEUTER
- bonus_value = 5
- var/deadly_shot = FALSE
-
-/obj/item/crusher_trophy/magma_wing/effect_desc()
- return "waveform collapse to make the next magnetic pulse deal [bonus_value] damage"
-
-/obj/item/crusher_trophy/magma_wing/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/magma_wing/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user)
- if(deadly_shot)
- marker.name = "superheated [marker.name]"
- marker.icon_state = "lava"
- marker.damage = bonus_value
- marker.nodamage = FALSE
- marker.speed = 2
- deadly_shot = FALSE
-
-/obj/item/crusher_trophy/magma_wing/on_mark_detonation(mob/living/target, mob/living/user)
- deadly_shot = TRUE
- addtimer(CALLBACK(src, PROC_REF(reset_deadly_shot)), 300, TIMER_UNIQUE|TIMER_OVERRIDE)
-
-/obj/item/crusher_trophy/magma_wing/proc/reset_deadly_shot()
- deadly_shot = FALSE
-
-//icewing watcher
-/obj/item/crusher_trophy/ice_wing
- name = "frigid sinew"
- desc = "A carefully-preserved freezing organ, dropped by chilling beings."
- icon_state = "ice_wing"
- bonus_value = 8
- denied_type = /obj/item/crusher_trophy/ice_wing
-
-/obj/item/crusher_trophy/ice_wing/effect_desc()
- return "waveform collapse to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s"
-
-/obj/item/crusher_trophy/ice_wing/on_mark_detonation(mob/living/target, mob/living/user)
- if(ishostile(target))
- var/mob/living/simple_animal/hostile/H = target
- if(H.ranged) //briefly delay ranged attacks
- if(H.ranged_cooldown >= world.time)
- H.ranged_cooldown += bonus_value
- else
- H.ranged_cooldown = bonus_value + world.time
-
-//forgotten watcher
-/obj/item/crusher_trophy/watcher_wing_forgotten
- name = "forgotten watcher wing"
- desc = "A wing with a terminal infection of the strange crystals."
- icon_state = "watcher_wing_crystal"
- denied_type = /obj/item/crusher_trophy/watcher_wing_forgotten
- gender = NEUTER
- bonus_value = 20
- var/deadly_shot = FALSE
-
-/obj/item/crusher_trophy/watcher_wing_forgotten/effect_desc()
- return "waveform collapse to make the next magnetic pulse deal [bonus_value] damage"
-
-/obj/item/crusher_trophy/watcher_wing_forgotten/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/watcher_wing_forgotten/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user)
- if(deadly_shot)
- marker.name = "crystal [marker.name]"
- marker.icon_state = "crystal_shard"
- marker.damage = bonus_value
- marker.nodamage = FALSE
- marker.speed = 2
- deadly_shot = FALSE
-
-/obj/item/crusher_trophy/watcher_wing_forgotten/on_mark_detonation(mob/living/target, mob/living/user)
- deadly_shot = TRUE
- addtimer(CALLBACK(src, PROC_REF(reset_deadly_shot)), 300, TIMER_UNIQUE|TIMER_OVERRIDE)
-
-/obj/item/crusher_trophy/watcher_wing_forgotten/proc/reset_deadly_shot()
- deadly_shot = FALSE
-
-//legion
-/obj/item/crusher_trophy/legion_skull
- name = "legion skull"
- desc = "A dead and lifeless legion skull. Could be used in crafting."
- icon_state = "legion_skull"
- denied_type = /obj/item/crusher_trophy/legion_skull
- bonus_value = 3
-
-/obj/item/crusher_trophy/legion_skull/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/legion_skull/effect_desc()
- return "a kinetic crusher to recharge [bonus_value*0.1] second\s faster"
-
-/obj/item/crusher_trophy/legion_skull/add_to(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.charge_time -= bonus_value
-
-/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.charge_time += bonus_value
-
-//dwarf legion
-/obj/item/crusher_trophy/dwarf_skull
- name = "shrunken skull"
- desc = "Looks like someone hasn't been drinking their milk. Could be used in crafting."
- icon = 'icons/obj/lavaland/elite_trophies.dmi'
- icon_state = "shrunk_skull"
- denied_type = /obj/item/crusher_trophy/dwarf_skull
- bonus_value = 6
-
-/obj/item/crusher_trophy/dwarf_skull/effect_desc()
- return "a kinetic crusher to recharge [bonus_value*0.1] second\s faster"
-
-/obj/item/crusher_trophy/dwarf_skull/add_to(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.charge_time -= bonus_value
-
-/obj/item/crusher_trophy/dwarf_skull/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.charge_time += bonus_value
-
-
-//disfigured legion
-/obj/item/crusher_trophy/legion_skull_crystal
- name = "disfigured legion skull"
- desc = "A dead and lifeless legion skull. The crystals keep it alive, even in agony."
- icon_state = "legion_skull_crystal"
- denied_type = /obj/item/crusher_trophy/legion_skull_crystal
- bonus_value = 1
-
-/obj/item/crusher_trophy/legion_skull_crystal/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/legion_skull_crystal/effect_desc()
- return "waveform collapse to shoot 3 projectiles that only hits hostile fauna"
-
-/obj/item/crusher_trophy/legion_skull_crystal/on_mark_detonation(mob/living/target, mob/living/user)
- for(var/i in 0 to 5)
- var/obj/projectile/projectile_to_shoot = new /obj/projectile/crystalline_crusher(get_turf(src))
- projectile_to_shoot.preparePixelProjectile(get_step(src, pick(GLOB.alldirs)), get_turf(src))
- projectile_to_shoot.firer = user
- projectile_to_shoot.fire(i*(360/5))
- return ..()
-
-/obj/projectile/crystalline_crusher
- name = "Crystalline Shard"
- icon_state = "crystal_shard"
- damage = 25
- damage_type = BRUTE
- speed = 3
-
-/obj/projectile/crystalline_crusher/on_hit(atom/target, blocked)
- . = ..()
- var/turf/turf_hit = get_turf(target)
- new /obj/effect/temp_visual/goliath_tentacle/crystal/visual_only(turf_hit,firer)
-
-/obj/projectile/crystalline_crusher/can_hit_target(atom/target, list/passthrough, direct_target, ignore_loc)
- if(!(istype(target,/mob/living/simple_animal/hostile/asteroid)))
- if(isturf(target))
- return ..()
- return FALSE
- return ..()
-
-//blood-drunk hunter
-/obj/item/crusher_trophy/miner_eye
- name = "eye of a blood-drunk hunter"
- desc = "Its pupil is collapsed and turned to mush."
- icon_state = "hunter_eye"
- denied_type = /obj/item/crusher_trophy/miner_eye
-
-/obj/item/crusher_trophy/miner_eye/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/miner_eye/effect_desc()
- return "waveform collapse to grant stun immunity and 90% damage reduction for 1 second"
-
-/obj/item/crusher_trophy/miner_eye/on_mark_detonation(mob/living/target, mob/living/user)
- user.apply_status_effect(STATUS_EFFECT_BLOODDRUNK)
-
-//whelp
-/obj/item/crusher_trophy/tail_spike
- desc = "A spike taken from a young dragon's tail. Sharp enough to stab someone with."
- denied_type = /obj/item/crusher_trophy/tail_spike
- bonus_value = 5
- force = 10
- throwforce = 15
- throw_speed = 4
- sharpness = IS_SHARP
- attack_verb = list("cut", "sliced", "diced")
- hitsound = 'sound/weapons/bladeslice.ogg'
-
-/obj/item/crusher_trophy/tail_spike/effect_desc()
- return "waveform collapse to do [bonus_value] damage to nearby creatures and push them back"
-
-/obj/item/crusher_trophy/tail_spike/on_mark_detonation(mob/living/target, mob/living/user)
- for(var/mob/living/L in oview(2, user))
- if(L.stat == DEAD)
- continue
- playsound(L, 'sound/magic/fireball.ogg', 20, TRUE)
- new /obj/effect/temp_visual/fire(L.loc)
- addtimer(CALLBACK(src, PROC_REF(pushback), L, user), 1) //no free backstabs, we push AFTER module stuff is done
- L.adjustFireLoss(bonus_value, forced = TRUE)
-
-/obj/item/crusher_trophy/tail_spike/proc/pushback(mob/living/target, mob/living/user)
- if(!QDELETED(target) && !QDELETED(user) && (!target.anchored || ismegafauna(target))) //megafauna will always be pushed
- step(target, get_dir(user, target))
-
-//ash drake
-/obj/item/crusher_trophy/ash_spike
- desc = "A molten spike taken from an ash drake's tail. Hot to the touch and extremely sharp."
- icon = 'icons/obj/lavaland/elite_trophies.dmi'
- icon_state = "ash_spike"
- denied_type = /obj/item/crusher_trophy/ash_spike
- bonus_value = 15
- force = 15
- throwforce = 20
- throw_speed = 4
- sharpness = IS_SHARP
- attack_verb = list("cut", "braised", "singed")
- hitsound = 'sound/weapons/bladeslice.ogg'
-
-/obj/item/crusher_trophy/ash_spike/effect_desc()
- return "waveform collapse to do [bonus_value] damage to nearby creatures and push them back"
-
-/obj/item/crusher_trophy/ash_spike/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/ash_spike/on_mark_detonation(mob/living/target, mob/living/user)
- for(var/mob/living/L in oview(2, user))
- if(L.stat == DEAD)
- continue
- playsound(L, 'sound/magic/fireball.ogg', 20, TRUE)
- new /obj/effect/temp_visual/fire(L.loc)
- addtimer(CALLBACK(src, PROC_REF(pushback), L, user), 1) //no free backstabs, we push AFTER module stuff is done
- L.adjustFireLoss(bonus_value, forced = TRUE)
-
-/obj/item/crusher_trophy/ash_spike/proc/pushback(mob/living/target, mob/living/user)
- if(!QDELETED(target) && !QDELETED(user) && (!target.anchored || ismegafauna(target))) //megafauna will always be pushed
- step(target, get_dir(user, target))
-
-//bubblegum
-/obj/item/crusher_trophy/demon_claws
- name = "demon claws"
- desc = "A set of blood-drenched claws from a massive demon's hand."
- icon_state = "demon_claws"
- gender = PLURAL
- denied_type = /obj/item/crusher_trophy/demon_claws
- bonus_value = 10
- var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
-
-/obj/item/crusher_trophy/demon_claws/effect_desc()
- return "melee hits to do [bonus_value * 0.2] more damage and heal you for [bonus_value * 0.1], with 5X effect on waveform collapse"
-
-/obj/item/crusher_trophy/demon_claws/add_to(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.force += bonus_value * 0.2
- H.detonation_damage += bonus_value * 0.8
- AddComponent(/datum/component/two_handed, force_wielded=(20 + bonus_value * 0.2))
-
-/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.force -= bonus_value * 0.2
- H.detonation_damage -= bonus_value * 0.8
- AddComponent(/datum/component/two_handed, force_wielded=20)
-
-/obj/item/crusher_trophy/demon_claws/on_melee_hit(mob/living/target, mob/living/user)
- user.heal_ordered_damage(bonus_value * 0.1, damage_heal_order)
-
-/obj/item/crusher_trophy/demon_claws/on_mark_detonation(mob/living/target, mob/living/user)
- user.heal_ordered_damage(bonus_value * 0.4, damage_heal_order)
-
-//colossus
-/obj/item/crusher_trophy/blaster_tubes
- name = "blaster tubes"
- desc = "The blaster tubes from a colossus's arm."
- icon_state = "blaster_tubes"
- gender = PLURAL
- denied_type = /obj/item/crusher_trophy/blaster_tubes
- bonus_value = 15
- var/deadly_shot = FALSE
-
-/obj/item/crusher_trophy/blaster_tubes/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/blaster_tubes/effect_desc()
- return "waveform collapse to make the next magnetic pulse deal [bonus_value] damage but move slower"
-
-/obj/item/crusher_trophy/blaster_tubes/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user)
- if(deadly_shot)
- marker.name = "ominous [marker.name]"
- marker.icon_state = "chronobolt"
- marker.damage = bonus_value
- marker.nodamage = FALSE
- marker.speed = 2
- deadly_shot = FALSE
-
-/obj/item/crusher_trophy/blaster_tubes/on_mark_detonation(mob/living/target, mob/living/user)
- deadly_shot = TRUE
- addtimer(CALLBACK(src, PROC_REF(reset_deadly_shot)), 300, TIMER_UNIQUE|TIMER_OVERRIDE)
-
-/obj/item/crusher_trophy/blaster_tubes/proc/reset_deadly_shot()
- deadly_shot = FALSE
-
-//hierophant
-/obj/item/crusher_trophy/vortex_talisman
- name = "vortex talisman"
- desc = "A glowing trinket that was originally the Hierophant's beacon."
- icon_state = "vortex_talisman"
- denied_type = /obj/item/crusher_trophy/vortex_talisman
-
-/obj/item/crusher_trophy/vortex_talisman/effect_desc()
- return "waveform collapse to create a barrier you can pass"
-
-/obj/item/crusher_trophy/vortex_talisman/on_mark_detonation(mob/living/target, mob/living/user)
- var/turf/current_location = get_turf(user)
- var/area/current_area = current_location.loc
- if(current_area.area_flags & NOTELEPORT)
- to_chat(user, "[src] fizzles uselessly.")
- return
- var/turf/T = get_turf(user)
- new /obj/effect/temp_visual/hierophant/wall/crusher(T, user) //a wall only you can pass!
- var/turf/otherT = get_step(T, turn(user.dir, 90))
- if(otherT)
- new /obj/effect/temp_visual/hierophant/wall/crusher(otherT, user)
- otherT = get_step(T, turn(user.dir, -90))
- if(otherT)
- new /obj/effect/temp_visual/hierophant/wall/crusher(otherT, user)
-
-/obj/effect/temp_visual/hierophant/wall/crusher
- duration = 75
-
-//I am afraid of this code. It also does not function(in terms of doing damage to enemies) as of my last test.
-/obj/item/crusher_trophy/king_goat
- name = "king goat hoof"
- desc = "A hoof from the king of all goats, it still glows with a fraction of its original power..."
- icon_state = "goat_hoof" //needs a better sprite but I cant sprite .
- denied_type = /obj/item/crusher_trophy/king_goat
-
-/obj/item/crusher_trophy/king_goat/examine(mob/user)
- . = ..()
- . += "Suitable as a trophy for a proto-kinetic crusher."
-
-/obj/item/crusher_trophy/king_goat/effect_desc()
- return "you also passively recharge pulses 5x as fast while this is equipped and do a decent amount of damage at the cost of dulling the blade"
-
-/obj/item/crusher_trophy/king_goat/on_projectile_fire(obj/projectile/destabilizer/marker, mob/living/user)
- marker.damage = 10 //in my testing only does damage to simple mobs so should be fine to have it high //it does damage to nobody. Please fix -M
-
-/obj/item/crusher_trophy/king_goat/add_to(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.charge_time = 3
- H.AddComponent(/datum/component/two_handed, force_wielded=5)
-
-/obj/item/crusher_trophy/king_goat/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.charge_time = 15
- H.AddComponent(/datum/component/two_handed, force_wielded=20)
-
-/obj/item/crusher_trophy/shiny
- name = "shiny nugget"
- icon = 'icons/obj/lavaland/elite_trophies.dmi'
- desc = "A glimmering nugget of dull metal. As it turns out, the fools were right- pyrite is a far rarer substance than gold in the space age. You could probably sell this for a fair price."
- icon_state = "nugget"
- gender = PLURAL
- denied_type = /obj/item/crusher_trophy/shiny
-
-/obj/item/crusher_trophy/shiny/effect_desc()
- return "empowered butchering chances"
-
-/obj/item/crusher_trophy/shiny/add_to(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.AddComponent(/datum/component/butchering, 60, 210)
-
-/obj/item/crusher_trophy/shiny/remove_from(obj/item/kinetic_crusher/H, mob/living/user)
- . = ..()
- if(.)
- H.AddComponent(/datum/component/butchering, 60, 110)
-
//outdated Nanotrasen prototype of the crusher. Incredibly heavy, but the blade was made at a premium. //to alter this I had to duplicate some code, big moment.
/obj/item/kinetic_crusher/old
icon_state = "crusherold"
@@ -820,16 +247,3 @@
. = ..()
if(wielded)
. += "[icon_state]_lit"
-
-/obj/item/crusher_trophy/lobster_claw
- name = "lobster claw"
- icon_state = "lobster_claw"
- desc = "A lobster claw."
- denied_type = /obj/item/crusher_trophy/lobster_claw
- bonus_value = 1
-
-/obj/item/crusher_trophy/lobster_claw/effect_desc()
- return "mark detonation to briefly stagger the target for [bonus_value] seconds"
-
-/obj/item/crusher_trophy/lobster_claw/on_mark_detonation(mob/living/target, mob/living/user)
- target.apply_status_effect(/datum/status_effect/stagger, bonus_value SECONDS)
diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm
index d334b0ce3de4..d38a3ce8b55b 100644
--- a/code/modules/mining/equipment/mining_tools.dm
+++ b/code/modules/mining/equipment/mining_tools.dm
@@ -53,6 +53,7 @@
force = 19
custom_price = 1500
custom_premium_price = 2000
+ custom_materials = list(/datum/material/diamond=2000)
/obj/item/pickaxe/drill
name = "mining drill"
@@ -79,8 +80,9 @@
icon_state = "diamonddrill"
item_state = "diamonddrill"
toolspeed = 0.2
- desc = "EXOCON's improvement on the NT autodrill design, featuring a premium diamond cutting head. Yours is the drill that will pierce the heavens!"
+ desc = "EXOCOM's improvement on the NT autodrill design, featuring a premium diamond cutting head. Yours is the drill that will pierce the heavens!"
force = 20
+ custom_materials = list(/datum/material/diamond=2000)
/obj/item/pickaxe/drill/cyborg/diamond //This is the BORG version!
name = "diamond-tipped integrated mining drill" //To inherit the NODROP_1 flag, and easier to change borg specific drill mechanics.
@@ -94,7 +96,7 @@
toolspeed = 0.1 //the epitome of powertools. extremely fast mining
usesound = 'sound/weapons/sonic_jackhammer.ogg'
hitsound = 'sound/weapons/sonic_jackhammer.ogg'
- desc = "The epitome of conventional rock-smashing technology, invented by NT and cost-optimized by EXOCON. Smashes rocks, objects, and unfortunate wildlife with sonic blasts."
+ desc = "The epitome of conventional rock-smashing technology, invented by NT and cost-optimized by EXOCOM. Smashes rocks, objects, and unfortunate wildlife with sonic blasts."
force = 25
attack_verb = list("blasted", "smashed", "slammed", "hammered")
diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm
index 87736c3438e4..4bd6824327f3 100644
--- a/code/modules/mining/equipment/regenerative_core.dm
+++ b/code/modules/mining/equipment/regenerative_core.dm
@@ -1,7 +1,7 @@
/*********************Hivelord stabilizer****************/
/obj/item/hivelordstabilizer
name = "stabilizing serum"
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/medicine.dmi'
icon_state = "bottle19"
desc = "Inject certain types of monster organs with this stabilizer to preserve their healing powers indefinitely."
w_class = WEIGHT_CLASS_TINY
diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm
index 5e012735b706..7ba30d327444 100644
--- a/code/modules/mining/equipment/survival_pod.dm
+++ b/code/modules/mining/equipment/survival_pod.dm
@@ -281,13 +281,15 @@
//Signs
/obj/structure/sign/mining
- name = "\improper Nanotrasen mining corps sign"
- desc = "A sign of relief for weary miners, and a warning for would-be competitors to Nanotrasen's mining claims."
- icon_state = "nanotrasen"
+ name = "\improper N+S mining corps sign"
+ desc = "A sign of relief for weary miners, and a warning for would-be competitors to N+S's mining claims."
+ icon = 'icons/obj/nanotrasen_logos.dmi'
+ icon_state = "ns"
/obj/structure/sign/mining/survival
name = "shelter sign"
desc = "A high visibility sign designating a safe shelter."
+ icon = 'icons/obj/structures/signs/sign.dmi'
icon_state = "secureareaold"
//Fluff
@@ -313,10 +315,6 @@
/obj/item/hierophant_club,
/obj/item/gun/energy/minigun,
/obj/item/gun/ballistic/automatic/hmg/l6_saw,
- /obj/item/gun/magic/staff/chaos,
- /obj/item/gun/magic/staff/spellblade,
- /obj/item/gun/magic/wand/death,
- /obj/item/gun/magic/wand/fireball,
/obj/item/stack/telecrystal/twenty,
/obj/item/nuke_core,
/obj/item/phylactery,
diff --git a/code/modules/mining/equipment/trophies.dm b/code/modules/mining/equipment/trophies.dm
new file mode 100644
index 000000000000..3510a0b59628
--- /dev/null
+++ b/code/modules/mining/equipment/trophies.dm
@@ -0,0 +1,184 @@
+//trophies
+/obj/item/mob_trophy
+ name = "tail spike"
+ desc = "A strange spike with no usage."
+ icon = 'icons/obj/lavaland/artefacts.dmi'
+ icon_state = "tail_spike"
+
+//legion
+/obj/item/mob_trophy/legion_skull
+ name = "legion skull"
+ desc = "A dead and lifeless legion skull. Could be used in crafting."
+ icon_state = "legion_skull"
+
+/obj/item/mob_trophy/wolf_ear
+ name = "wolf ear"
+ desc = "The battered remains of a wolf's ear. You could attach it to a crusher, or use the fur to craft a trophy."
+ icon = 'icons/obj/lavaland/elite_trophies.dmi'
+ icon_state = "torn_ear"
+
+/obj/item/mob_trophy/fang
+ name = "battle-stained fang"
+ desc = "A wolf fang, displaying the wear and tear associated with a long and colorful life. Could be attached to a kinetic crusher or used to make a trophy."
+ icon = 'icons/obj/lavaland/elite_trophies.dmi'
+ icon_state = "fang"
+
+/*
+//goliath
+/obj/item/mob_trophy/goliath_tentacle
+ name = "goliath tentacle"
+ desc = "A sliced-off goliath tentacle."
+ icon_state = "goliath_tentacle"
+
+//ancient goliath
+/obj/item/mob_trophy/elder_tentacle
+ name = "elder tentacle"
+ desc = "The barbed tip of a tentacle sliced from an incredibly ancient goliath."
+ icon_state = "elder_tentacle"
+ icon = 'icons/obj/lavaland/elite_trophies.dmi'
+
+//crystal goliath
+/obj/item/mob_trophy/goliath_crystal
+ name = "goliath crystal"
+ desc = "A crystal ripped off from a goliath infected by the strange crystals. You can see the original skin of the goliath deeply embeded in it."
+ icon_state = "goliath_crystal"
+
+//watcher
+/obj/item/mob_trophy/watcher_wing
+ name = "watcher wing"
+ desc = "A wing ripped from a watcher."
+ icon_state = "watcher_wing"
+
+//magmawing watcher
+/obj/item/mob_trophy/magma_wing
+ name = "magmatic sinew"
+ desc = "A fuming organ, dropped by beings hotter then lava."
+ icon_state = "magma_wing"
+ gender = NEUTER
+
+//icewing watcher
+/obj/item/mob_trophy/ice_wing
+ name = "frigid sinew"
+ desc = "A carefully-preserved freezing organ, dropped by chilling beings."
+ icon_state = "ice_wing"
+
+//forgotten watcher
+/obj/item/mob_trophy/watcher_wing_forgotten
+ name = "forgotten watcher wing"
+ desc = "A wing with a terminal infection of the strange crystals."
+ icon_state = "watcher_wing_crystal"
+ gender = NEUTER
+
+//dwarf legion
+/obj/item/mob_trophy/dwarf_skull
+ name = "shrunken skull"
+ desc = "Looks like someone hasn't been drinking their milk. Could be used in crafting."
+ icon = 'icons/obj/lavaland/elite_trophies.dmi'
+ icon_state = "shrunk_skull"
+
+//disfigured legion
+/obj/item/mob_trophy/legion_skull_crystal
+ name = "disfigured legion skull"
+ desc = "A dead and lifeless legion skull. The crystals keep it alive, even in agony."
+ icon_state = "legion_skull_crystal"
+
+//blood-drunk hunter
+/obj/item/mob_trophy/miner_eye
+ name = "eye of a blood-drunk hunter"
+ desc = "Its pupil is collapsed and turned to mush."
+ icon_state = "hunter_eye"
+
+//whelp
+/obj/item/mob_trophy/tail_spike
+ desc = "A spike taken from a young dragon's tail. Sharp enough to stab someone with."
+ force = 10
+ throwforce = 15
+ throw_speed = 4
+ sharpness = IS_SHARP
+ attack_verb = list("cut", "sliced", "diced")
+ hitsound = 'sound/weapons/bladeslice.ogg'
+
+//ash drake
+/obj/item/mob_trophy/ash_spike
+ desc = "A molten spike taken from an ash drake's tail. Hot to the touch and extremely sharp."
+ icon = 'icons/obj/lavaland/elite_trophies.dmi'
+ icon_state = "ash_spike"
+ force = 15
+ throwforce = 20
+ throw_speed = 4
+ sharpness = IS_SHARP
+ attack_verb = list("cut", "braised", "singed")
+ hitsound = 'sound/weapons/bladeslice.ogg'
+
+//bubblegum
+/obj/item/mob_trophy/demon_claws
+ name = "demon claws"
+ desc = "A set of blood-drenched claws from a massive demon's hand."
+ icon_state = "demon_claws"
+ gender = PLURAL
+
+//colossus
+/obj/item/mob_trophy/blaster_tubes
+ name = "blaster tubes"
+ desc = "The blaster tubes from a colossus's arm."
+ icon_state = "blaster_tubes"
+ gender = PLURAL
+
+//hierophant
+/obj/item/mob_trophy/vortex_talisman
+ name = "vortex talisman"
+ desc = "A glowing trinket that was originally the Hierophant's beacon."
+ icon_state = "vortex_talisman"
+
+// Broodmother's loot: Broodmother Tongue
+/obj/item/mob_trophy/broodmother_tongue
+ name = "broodmother tongue"
+ desc = "The tongue of a broodmother. If attached a certain way, makes for a suitable crusher trophy."
+ icon = 'icons/obj/lavaland/elite_trophies.dmi'
+ icon_state = "broodmother_tongue"
+
+/obj/item/mob_trophy/shiny
+ name = "shiny nugget"
+ icon = 'icons/obj/lavaland/elite_trophies.dmi'
+ desc = "A glimmering nugget of dull metal. As it turns out, the fools were right- pyrite is a far rarer substance than gold in the space age. You could probably sell this for a fair price."
+ icon_state = "nugget"
+ gender = PLURAL
+
+/obj/item/mob_trophy/lobster_claw
+ name = "lobster claw"
+ icon_state = "lobster_claw"
+ desc = "A lobster claw."
+
+/obj/item/mob_trophy/ice_block_talisman
+ name = "ice block talisman"
+ desc = "A glowing trinket that a demonic miner had on him, it seems he couldn't utilize it for whatever reason."
+ icon_state = "freeze_cube"
+
+/obj/item/mob_trophy/brimdemon_fang
+ name = "brimdemon's fang"
+ icon_state = "brimdemon_fang"
+ desc = "A fang from a brimdemon's corpse."
+
+/obj/item/mob_trophy/ice_crystal
+ name = "frost gem"
+ icon = 'icons/obj/lavaland/elite_trophies.dmi'
+ desc = "The glowing remnant of an ancient ice demon- so cold that it hurts to touch."
+ icon_state = "ice_crystal"
+
+/obj/item/mob_trophy/lobster_claw
+ name = "lobster claw"
+ icon_state = "lobster_claw"
+ desc = "A lobster claw."
+
+/obj/item/mob_trophy/bear_paw
+ name = "polar bear paw"
+ desc = "It's a polar bear paw."
+ icon_state = "bear_paw"
+ icon ='icons/obj/lavaland/elite_trophies.dmi'
+
+/obj/item/mob_trophy/war_paw
+ name = "Armored bear paw"
+ desc = "It's a paw from a true warrior. Still remembers the basics of CQB."
+ icon_state = "armor_paw"
+ icon ='icons/obj/lavaland/elite_trophies.dmi'
+*/
diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm
index 0bade04d3fe8..f9563cc078eb 100644
--- a/code/modules/mining/lavaland/ash_flora.dm
+++ b/code/modules/mining/lavaland/ash_flora.dm
@@ -432,14 +432,6 @@
user.put_in_hands(result)
to_chat(user, "You finish breaking [src]")
-//CRAFTING
-
-/datum/crafting_recipe/mushroom_bowl
- name = "Mushroom Bowl"
- result = /obj/item/reagent_containers/glass/bowl/mushroom_bowl
- reqs = list(/obj/item/reagent_containers/food/snacks/grown/ash_flora/shavings = 5)
- time = 30
- category = CAT_PRIMAL
/obj/item/reagent_containers/food/snacks/customizable/salad/ashsalad
desc = "Very ashy."
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 985c5212299b..e48f4d5af5aa 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -66,8 +66,6 @@
new /obj/item/wisp_lantern(src)
if(20)
new /obj/item/immortality_talisman(src)
- if(21)
- new /obj/item/gun/magic/hook(src)
if(22)
new /obj/item/voodoo(src)
if(23)
@@ -143,8 +141,6 @@
new /obj/item/wisp_lantern(src)
if(20)
new /obj/item/immortality_talisman(src)
- if(21)
- new /obj/item/gun/magic/hook(src)
if(22)
new /obj/item/voodoo(src)
if(23)
@@ -481,91 +477,6 @@
/obj/effect/warp_cube/ex_act(severity, target)
return
-//Meat Hook
-/obj/item/gun/magic/hook
- name = "meat hook"
- desc = "A light hooked blade, attached by the handle to a long chain. Can be used to make quick strikes in hand, or thrown at enemies, magically dragging them to the user. Get over here!"
- ammo_type = /obj/item/ammo_casing/magic/hook
- icon_state = "hook"
- item_state = "hook"
- lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
- fire_sound = 'sound/weapons/batonextend.ogg'
- max_charges = 1
- item_flags = NEEDS_PERMIT
- force = 15
- sharpness = IS_SHARP
- block_chance = 5//A pittance, but might be worth something in a scuffle
- hitsound = 'sound/weapons/chainhit.ogg'
-
-/obj/item/gun/magic/hook/melee_attack_chain(mob/user, atom/target, params)
- ..()
- user.changeNext_move(CLICK_CD_MELEE * 0.5)//quick to swing. 15 force can be quite something with this attack frequency.
-
-/obj/item/gun/magic/hook/Initialize()
- . = ..()
- AddComponent(/datum/component/butchering, 15, 130, 0, hitsound)
-
-/obj/item/ammo_casing/magic/hook
- name = "hook"
- desc = "A hook."
- projectile_type = /obj/projectile/hook
- caliber = "hook"
- icon_state = "arrow"
-
-/obj/projectile/hook
- name = "hook"
- icon_state = "hook"
- icon = 'icons/obj/lavaland/artefacts.dmi'
- pass_flags = PASSTABLE
- damage = 20
- stamina = 20
- armour_penetration = 60
- damage_type = BRUTE
- hitsound = 'sound/effects/splat.ogg'
- var/chain
- var/knockdown_time = (0.5 SECONDS)
-
-/obj/projectile/hook/fire(setAngle)
- if(firer)
- chain = firer.Beam(src, icon_state = "chain", emissive = FALSE)
- ..()
- //TODO: root the firer until the chain returns
-
-/obj/projectile/hook/on_hit(atom/target)
- . = ..()
- if(ismovable(target))
- var/atom/movable/A = target
- if(A.anchored)
- return
- A.visible_message("[A] is snagged by [firer]'s hook!")
- new /datum/forced_movement(A, get_turf(firer), 5, TRUE)
- if (isliving(target))
- var/mob/living/fresh_meat = target
- fresh_meat.Knockdown(knockdown_time)
- return
- //TODO: keep the chain beamed to A
- //TODO: needs a callback to delete the chain
-
-/obj/projectile/hook/Destroy()
- qdel(chain)
- return ..()
-
-//just a nerfed version of the real thing for the bounty hunters.
-/obj/item/gun/magic/hook/bounty
- name = "hook"
- ammo_type = /obj/item/ammo_casing/magic/hook/bounty
-
-/obj/item/gun/magic/hook/bounty/shoot_with_empty_chamber(mob/living/user)
- to_chat(user, "The [src] isn't ready to fire yet!")
-
-/obj/item/ammo_casing/magic/hook/bounty
- projectile_type = /obj/projectile/hook/bounty
-
-/obj/projectile/hook/bounty
- damage = 0
- stamina = 40
-
//Immortality Talisman: Now with state-of-the-art panic button technology
/obj/item/immortality_talisman
name = "\improper Immortality Talisman"
@@ -590,10 +501,6 @@
if(input)
src.warcry = input
-/obj/item/immortality_talisman/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE, TRUE)
-
/datum/action/item_action/hands_free/immortality
name = "Immortality"
@@ -882,6 +789,39 @@
walk(hit_mob, 0) //stops them mid pathing even if they're stunimmune
hit_mob.apply_status_effect(/datum/status_effect/ice_block_talisman, 5 SECONDS)
+/datum/status_effect/ice_block_talisman
+ id = "ice_block_talisman"
+ duration = 40
+ status_type = STATUS_EFFECT_REFRESH
+ alert_type = /atom/movable/screen/alert/status_effect/ice_block_talisman
+ /// Stored icon overlay for the hit mob, removed when effect is removed
+ var/icon/cube
+
+/atom/movable/screen/alert/status_effect/ice_block_talisman
+ name = "Frozen Solid"
+ desc = "You're frozen inside an ice cube, and cannot move!"
+ icon_state = "frozen"
+
+/datum/status_effect/ice_block_talisman/on_apply()
+ RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(owner_moved))
+ if(!owner.stat)
+ to_chat(owner, "You become frozen in a cube!")
+ cube = icon('icons/effects/freeze.dmi', "ice_cube")
+ var/icon/size_check = icon(owner.icon, owner.icon_state)
+ cube.Scale(size_check.Width(), size_check.Height())
+ owner.add_overlay(cube)
+ return ..()
+
+/// Blocks movement from the status effect owner
+/datum/status_effect/ice_block_talisman/proc/owner_moved()
+ return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
+
+/datum/status_effect/ice_block_talisman/on_remove()
+ if(!owner.stat)
+ to_chat(owner, "The cube melts!")
+ owner.cut_overlay(cube)
+ UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE)
+
//earthquake gauntlets
/obj/item/clothing/gloves/gauntlets
name = "concussive gauntlets"
@@ -924,19 +864,19 @@
return COMPONENT_NO_ATTACK_OBJ
//A version of the Cave Story refrence that a deranged scientist got their hands on. Better? Not really. Different? Definitely.
+//TODO: replace with a proper polar star and spur, not to mention a proper sprite
/obj/item/gun/energy/spur
name = "Slowpoke"
desc = "The work of a truly genius gunsmith, altered and \"improved\" by a truly deranged Nanotrasen scientist, using components from a kinetic accelerator and beam rifle. Draw, partner!"
icon = 'icons/obj/guns/energy.dmi'
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
icon_state = "spur"
item_state = "spur"
- fire_delay = 0.5 //BRATATAT! This is a cowboy's six-shooter after all.
selfcharge = 1
charge_delay = 1
slot_flags = ITEM_SLOT_BELT
- fire_delay = 1
+ fire_delay = 0.1 SECONDS
recoil = 1
cell_type = /obj/item/stock_parts/cell/gun
ammo_type = list(/obj/item/ammo_casing/energy/spur)
@@ -1270,17 +1210,9 @@
new /obj/item/lava_staff(src)
if(3)
new /obj/item/book/granter/spell/sacredflame(src)
- new /obj/item/gun/magic/wand/fireball(src)
if(4)
new /obj/item/dragons_blood(src)
-/obj/structure/closet/crate/necropolis/dragon/crusher
- name = "firey dragon chest"
-
-/obj/structure/closet/crate/necropolis/dragon/crusher/PopulateContents()
- ..()
- new /obj/item/crusher_trophy/ash_spike(src)
-
/obj/item/melee/ghost_sword
name = "\improper spectral blade"
desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly."
@@ -1493,21 +1425,12 @@
/obj/structure/closet/crate/necropolis/bubblegum/PopulateContents()
new /obj/item/clothing/suit/space/hostile_environment(src)
new /obj/item/clothing/head/helmet/space/hostile_environment(src)
- var/loot = rand(1,3)
+ var/loot = rand(1,2)
switch(loot)
if(1)
new /obj/item/mayhem(src)
if(2)
new /obj/item/blood_contract(src)
- if(3)
- new /obj/item/gun/magic/staff/spellblade(src)
-
-/obj/structure/closet/crate/necropolis/bubblegum/crusher
- name = "bloody bubblegum chest"
-
-/obj/structure/closet/crate/necropolis/bubblegum/crusher/PopulateContents()
- ..()
- new /obj/item/crusher_trophy/demon_claws(src)
/obj/item/mayhem
name = "mayhem in a bottle"
@@ -1517,8 +1440,8 @@
/obj/item/mayhem/attack_self(mob/user)
for(var/mob/living/carbon/human/H in range(7,user))
- var/obj/effect/mine/pickup/bloodbath/B = new(H)
- INVOKE_ASYNC(B, TYPE_PROC_REF(/obj/effect/mine/pickup/bloodbath, mineEffect), H)
+ var/obj/item/mine/pressure/pickup/bloodbath/B = new(H)
+ INVOKE_ASYNC(B, TYPE_PROC_REF(/obj/item/mine/pressure/pickup/bloodbath, mine_effect), H)
to_chat(user, "You shatter the bottle!")
playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, TRUE)
message_admins("[ADMIN_LOOKUPFLW(user)] has activated a bottle of mayhem!")
@@ -1584,13 +1507,6 @@
new random_crystal(src)
new /obj/item/organ/vocal_cords/colossus(src)
-/obj/structure/closet/crate/necropolis/colossus/crusher
- name = "angelic colossus chest"
-
-/obj/structure/closet/crate/necropolis/colossus/crusher/PopulateContents()
- ..()
- new /obj/item/crusher_trophy/blaster_tubes(src)
-
//Hierophant
/obj/item/hierophant_club
name = "hierophant club"
diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm
index 8a73aff51a69..63b220828f81 100644
--- a/code/modules/mining/lavaland/ruins/gym.dm
+++ b/code/modules/mining/lavaland/ruins/gym.dm
@@ -7,6 +7,47 @@
layer = WALL_OBJ_LAYER
var/list/hit_sounds = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg',\
'sound/weapons/punch1.ogg', 'sound/weapons/punch2.ogg', 'sound/weapons/punch3.ogg', 'sound/weapons/punch4.ogg')
+ var/buildstacktype = /obj/item/stack/sheet/cotton/cloth
+ var/buildstackamount = 5
+
+/obj/structure/punching_bag/deconstruct(disassembled = TRUE)
+ if(!(flags_1 & NODECONSTRUCT_1))
+ if(buildstacktype)
+ new buildstacktype(loc,buildstackamount)
+ return..()
+
+/obj/structure/punching_bag/wrench_act(mob/living/user, obj/item/W)
+ if(..())
+ return TRUE
+ add_fingerprint(user)
+ var/action = anchored ? "unbolts [src] from" : "bolts [src] to"
+ var/uraction = anchored ? "unbolt [src] from" : "bolt [src] to"
+ user.visible_message(span_warning("[user] [action] the floor."), span_notice("You start to [uraction] the floor..."), span_hear("You hear rustling noises."))
+ if(W.use_tool(src, user, 50, volume=100, extra_checks = CALLBACK(src, PROC_REF(check_anchored_state), anchored)))
+ set_anchored(!anchored)
+ to_chat(user, span_notice("You [anchored ? "bolt" : "unbolt"] [src] from the floor."))
+ return TRUE
+
+/obj/structure/punching_bag/wirecutter_act(mob/living/user, obj/item/W)
+ . = ..()
+ if(!anchored)
+ user.visible_message(span_warning("[user] cuts apart [src]."), span_notice("You start to cut apart [src]."), span_hear("You hear cutting."))
+ if(W.use_tool(src, user, 50, volume=100))
+ if(anchored)
+ return TRUE
+ to_chat(user, span_notice("You cut apart [src]."))
+ deconstruct(TRUE)
+ return TRUE
+
+/obj/structure/punching_bag/proc/check_anchored_state(check_anchored)
+ return anchored == check_anchored
+
+/obj/structure/punching_bag/examine(mob/user)
+ . = ..()
+ if(anchored)
+ . += span_notice("[src] is bolted to the floor.")
+ else
+ . += span_notice("[src] is no longer bolted to the floor, and the seams can be cut apart.")
/obj/structure/punching_bag/attack_hand(mob/user as mob)
. = ..()
@@ -25,6 +66,8 @@
icon = 'icons/obj/gym_equipment.dmi'
density = TRUE
anchored = TRUE
+ var/buildstacktype = /obj/item/stack/sheet/metal
+ var/buildstackamount = 5
/obj/structure/weightmachine/proc/AnimateMachine(mob/living/user)
return
@@ -33,6 +76,45 @@
. = ..()
icon_state = (obj_flags & IN_USE) ? "[base_icon_state]-u" : base_icon_state
+/obj/structure/weightmachine/deconstruct(disassembled = TRUE)
+ if(!(flags_1 & NODECONSTRUCT_1))
+ if(buildstacktype)
+ new buildstacktype(loc,buildstackamount)
+ return..()
+
+/obj/structure/weightmachine/wrench_act(mob/living/user, obj/item/W)
+ if(..())
+ return TRUE
+ add_fingerprint(user)
+ var/action = anchored ? "unbolts [src] from" : "bolts [src] to"
+ var/uraction = anchored ? "unbolt [src] from" : "bolt [src] to"
+ user.visible_message(span_warning("[user] [action] the floor."), span_notice("You start to [uraction] the floor..."), span_hear("You hear rustling noises."))
+ if(W.use_tool(src, user, 50, volume=100, extra_checks = CALLBACK(src, PROC_REF(check_anchored_state), anchored)))
+ set_anchored(!anchored)
+ to_chat(user, span_notice("You [anchored ? "bolt" : "unbolt"] [src] from the floor."))
+ return TRUE
+
+/obj/structure/weightmachine/screwdriver_act(mob/living/user, obj/item/W)
+ . = ..()
+ if(!anchored)
+ user.visible_message(span_warning("[user] screws apart [src]."), span_notice("You start to screw apart [src]."), span_hear("You hear screwing."))
+ if(W.use_tool(src, user, 50, volume=100))
+ if(anchored)
+ return TRUE
+ to_chat(user, span_notice("You screw apart [src]."))
+ deconstruct(TRUE)
+ return TRUE
+
+/obj/structure/weightmachine/proc/check_anchored_state(check_anchored)
+ return anchored == check_anchored
+
+/obj/structure/weightmachine/examine(mob/user)
+ . = ..()
+ if(anchored)
+ . += span_notice("[src] is bolted to the floor.")
+ else
+ . += span_notice("[src] is no longer bolted to the floor, and the screws are exposed.")
+
/obj/structure/weightmachine/update_overlays()
. = ..()
@@ -44,7 +126,7 @@
if(.)
return
if(obj_flags & IN_USE)
- to_chat(user, "It's already in use - wait a bit!")
+ to_chat(user, span_warning("It's already in use - wait a bit!"))
return
else
obj_flags |= IN_USE
@@ -100,3 +182,4 @@
sleep(3)
animate(user, pixel_y = 2, time = 3)
sleep(3)
+
diff --git a/code/modules/mining/machine_bluespaceminer.dm b/code/modules/mining/machine_bluespaceminer.dm
index feffb562a7e0..f44775d20c20 100644
--- a/code/modules/mining/machine_bluespaceminer.dm
+++ b/code/modules/mining/machine_bluespaceminer.dm
@@ -7,7 +7,7 @@
circuit = /obj/item/circuitboard/machine/bluespace_miner
layer = BELOW_OBJ_LAYER
use_power = NO_POWER_USE
- idle_power_usage = 50000
+ idle_power_usage = ACTIVE_DRAW_EXTREME * 10
var/powered = FALSE
var/active = FALSE
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index bbc84ec7ee68..0ae29ca8ee54 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -3,6 +3,7 @@
/**********************Mineral processing unit console**************************/
/obj/machinery/mineral
+ idle_power_usage = IDLE_DRAW_MINIMAL
processing_flags = START_PROCESSING_MANUALLY
subsystem_type = /datum/controller/subsystem/processing/fastprocess
/// The current direction of `input_turf`, in relation to the machine.
@@ -142,7 +143,7 @@
/obj/machinery/mineral/processing_unit/Initialize()
. = ..()
proximity_monitor = new(src, 1)
- AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace), INFINITY, TRUE, /obj/item/stack)
+ AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/hellstone, /datum/material/titanium, /datum/material/bluespace), INFINITY, TRUE, /obj/item/stack)
stored_research = new /datum/techweb/specialized/autounlocking/smelter
selected_material = SSmaterials.GetMaterialRef(/datum/material/iron)
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index fd36a4bb4ab1..2b3e379691c9 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -17,7 +17,7 @@
var/points = 0
var/ore_multiplier = 1
var/point_upgrade = 1
- var/list/ore_values = list(/datum/material/iron = 1, /datum/material/glass = 1, /datum/material/plasma = 15, /datum/material/silver = 16, /datum/material/gold = 18, /datum/material/titanium = 30, /datum/material/uranium = 30, /datum/material/diamond = 50, /datum/material/bluespace = 50, /datum/material/bananium = 60)
+ var/list/ore_values = list(/datum/material/iron = 1, /datum/material/glass = 1, /datum/material/plasma = 15, /datum/material/silver = 16, /datum/material/gold = 18, /datum/material/titanium = 30, /datum/material/uranium = 30, /datum/material/diamond = 50, /datum/material/bluespace = 50)
/// Variable that holds a timer which is used for callbacks to `send_console_message()`. Used for preventing multiple calls to this proc while the ORM is eating a stack of ores.
var/console_notify_timer
var/datum/techweb/stored_research
@@ -249,7 +249,7 @@
switch(action)
if("Claim")
var/mob/M = usr
- var/obj/item/card/id/I = M.get_idcard(TRUE)
+ var/obj/item/card/bank/I = M.get_bankcard()
if(points)
if(I)
I.mining_points += points
diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm
index 788d1c102f75..444e72992685 100644
--- a/code/modules/mining/machine_silo.dm
+++ b/code/modules/mining/machine_silo.dm
@@ -22,7 +22,6 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
/datum/material/diamond,
/datum/material/plasma,
/datum/material/uranium,
- /datum/material/bananium,
/datum/material/titanium,
/datum/material/bluespace,
/datum/material/plastic,
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index c84d61ab7cf2..15cde601689e 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -1,7 +1,7 @@
/* Mining Points Equipment Vendor */
/obj/machinery/vending/mining_equipment
name = "frontier equipment vendor"
- desc = "An equipment vendor for miners, prospectors, and all manner of far reach scroungers. Ore Redemption Points can be spent here to purchase rough-and-tumble goods. Sold by EXOCON."
+ desc = "An equipment vendor for miners, prospectors, and all manner of far reach scroungers. Ore Redemption Points can be spent here to purchase rough-and-tumble goods. Sold by EXOCOM."
icon_state = "mining"
icon_deny = "mining-deny"
max_integrity = 500 // A bit more durable than your average snack vendor
diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm
index 707d68a871f7..cc2a9f176c70 100644
--- a/code/modules/mining/minebot.dm
+++ b/code/modules/mining/minebot.dm
@@ -33,7 +33,7 @@
wanted_objects = list(
/obj/item/stack/ore/diamond, /obj/item/stack/ore/gold, /obj/item/stack/ore/silver,
/obj/item/stack/ore/plasma, /obj/item/stack/ore/uranium, /obj/item/stack/ore/iron,
- /obj/item/stack/ore/bananium, /obj/item/stack/ore/titanium)
+ /obj/item/stack/ore/hellstone, /obj/item/stack/ore/titanium)
healable = 0
loot = list(/obj/effect/decal/cleanable/robot_debris)
del_on_death = TRUE
diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm
index 33117d99c518..79c2f0d52208 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -24,11 +24,8 @@
/datum/material/uranium,
/datum/material/titanium,
/datum/material/diamond,
- /datum/material/bananium,
- /datum/material/adamantine,
- /datum/material/mythril,
/datum/material/plastic,
- /datum/material/runite
+ /datum/material/hellstone,
), MINERAL_MATERIAL_AMOUNT * 75, FALSE, /obj/item/stack)
chosen = SSmaterials.GetMaterialRef(chosen)
diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm
index 46011ae8ec7e..2c8ac19a353a 100644
--- a/code/modules/mining/money_bag.dm
+++ b/code/modules/mining/money_bag.dm
@@ -26,4 +26,4 @@
new /obj/item/coin/silver(src)
new /obj/item/coin/gold(src)
new /obj/item/coin/gold(src)
- new /obj/item/coin/adamantine(src)
+ new /obj/item/coin/hellstone(src)
diff --git a/code/modules/mining/ore_veins.dm b/code/modules/mining/ore_veins.dm
index 3e5e20053a77..32b1ffeab8d5 100644
--- a/code/modules/mining/ore_veins.dm
+++ b/code/modules/mining/ore_veins.dm
@@ -40,8 +40,8 @@ GLOBAL_LIST_EMPTY(ore_veins)
var/max_mobs = 6
var/spawn_time = 150 //15 seconds
var/mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 60,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 20,
+ /mob/living/simple_animal/hostile/asteroid/goliath/beast/nest = 60,
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/nest = 20,
/mob/living/simple_animal/hostile/asteroid/brimdemon = 20,
)
var/spawn_text = "emerges from"
@@ -126,11 +126,11 @@ GLOBAL_LIST_EMPTY(ore_veins)
max_mobs = 6
spawn_time = 100
mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 60,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 30,
+ /mob/living/simple_animal/hostile/asteroid/goliath/beast/nest = 60,
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/nest = 30,
/mob/living/simple_animal/hostile/asteroid/brimdemon = 20,
/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient = 5,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf/tendril = 5,
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf/nest = 5,
)
/obj/structure/vein/classthree
@@ -149,18 +149,18 @@ GLOBAL_LIST_EMPTY(ore_veins)
max_mobs = 6 //Best not to go past 6 due to balance and lag reasons
spawn_time = 80
mob_types = list(
- /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril = 60,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril = 30,
+ /mob/living/simple_animal/hostile/asteroid/goliath/beast/nest = 60,
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/nest = 30,
/mob/living/simple_animal/hostile/asteroid/brimdemon = 20,
/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient = 10,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf/tendril = 10,
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf/nest = 10,
)
/obj/structure/vein/ice
mob_types = list(
/mob/living/simple_animal/hostile/asteroid/wolf = 30,
/mob/living/simple_animal/hostile/asteroid/polarbear = 30,
- /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril = 20,
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/nest = 20,
/mob/living/simple_animal/hostile/asteroid/ice_demon = 10,
/mob/living/simple_animal/hostile/asteroid/ice_whelp = 5,
/mob/living/simple_animal/hostile/asteroid/lobstrosity = 20,
@@ -176,6 +176,7 @@ GLOBAL_LIST_EMPTY(ore_veins)
/obj/item/stack/ore/titanium = 2,
/obj/item/stack/ore/gold = 1,
/obj/item/stack/ore/diamond = 1,
+ /obj/item/stack/ore/ice = 7,
)
/obj/structure/vein/ice/classtwo
@@ -190,6 +191,7 @@ GLOBAL_LIST_EMPTY(ore_veins)
/obj/item/stack/ore/diamond = 2,
/obj/item/stack/ore/gold = 3,
/obj/item/stack/ore/bluespace_crystal = 1,
+ /obj/item/stack/ore/ice = 8,
)
max_mobs = 6
spawn_time = 100
@@ -206,6 +208,40 @@ GLOBAL_LIST_EMPTY(ore_veins)
/obj/item/stack/ore/diamond = 4,
/obj/item/stack/ore/gold = 6,
/obj/item/stack/ore/bluespace_crystal = 4,
+ /obj/item/stack/ore/ice = 8,
)
max_mobs = 6
spawn_time = 80
+
+// Asteroid veins are the same as the base planetary ones yield wise, but with the asteroid mobs.
+
+/obj/structure/vein/asteroid
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/goliath = 60,
+ /mob/living/simple_animal/hostile/asteroid/basilisk = 30,
+ /mob/living/simple_animal/hostile/asteroid/hivelord = 30,
+ /mob/living/simple_animal/hostile/asteroid/brimdemon = 20,
+ /mob/living/simple_animal/hostile/carp = 20,
+ )
+
+/obj/structure/vein/classtwo/asteroid
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/goliath = 60,
+ /mob/living/simple_animal/hostile/asteroid/basilisk = 30,
+ /mob/living/simple_animal/hostile/asteroid/hivelord = 30,
+ /mob/living/simple_animal/hostile/asteroid/brimdemon = 20,
+ /mob/living/simple_animal/hostile/carp = 20,
+ /mob/living/simple_animal/hostile/carp/megacarp = 15,
+ /mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient = 5
+ )
+
+/obj/structure/vein/classthree/asteroid
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/goliath = 60,
+ /mob/living/simple_animal/hostile/asteroid/basilisk = 30,
+ /mob/living/simple_animal/hostile/asteroid/hivelord = 30,
+ /mob/living/simple_animal/hostile/asteroid/brimdemon = 20,
+ /mob/living/simple_animal/hostile/carp/megacarp = 20,
+ /mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient = 10
+ )
+
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index ec971ed84bed..55130b0a20d7 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -217,16 +217,6 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
mine_experience = 10
scan_state = "rock_Diamond"
-/obj/item/stack/ore/bananium
- name = "bananium ore"
- icon_state = "Bananium ore"
- item_state = "Bananium ore"
- singular_name = "bananium ore chunk"
- points = 60
- custom_materials = list(/datum/material/bananium=MINERAL_MATERIAL_AMOUNT)
- refined_type = /obj/item/stack/sheet/mineral/bananium
- mine_experience = 15
- scan_state = "rock_Bananium"
/obj/item/stack/ore/titanium
name = "titanium ore"
@@ -240,6 +230,16 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
scan_state = "rock_Titanium"
spreadChance = 5
+/obj/item/stack/ore/hellstone
+ name = "hellstone ore"
+ icon_state = "hellstone-ore"
+ item_state = "hellstone-ore"
+ singular_name = "hellstone ore chunk"
+ resistance_flags = LAVA_PROOF
+ points = 50
+ custom_materials = list(/datum/material/hellstone=MINERAL_MATERIAL_AMOUNT)
+ refined_type = /obj/item/stack/sheet/mineral/hidden/hellstone
+
/obj/item/stack/ore/slag
name = "slag"
desc = "Completely useless."
@@ -247,6 +247,17 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
item_state = "slag"
singular_name = "slag chunk"
+/obj/item/stack/ore/ice
+ name = "ice crystals"
+ desc = "Used in an electrolyzer to produce hydrogen and oxygen."
+ icon_state = "Ice ore"
+ item_state = "Ice ore"
+ singular_name = "ice chunk"
+ scan_state = "rock_Ice"
+ mine_experience = 2
+ grind_results = list(/datum/reagent/consumable/ice = 10)
+ spreadChance = 10
+
/obj/item/gibtonite
name = "gibtonite ore"
desc = "Extremely explosive if struck with mining equipment, Gibtonite is often used by miners to speed up their work by using it as a mining charge. This material is illegal to possess by unauthorized personnel under space law."
@@ -458,20 +469,11 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
/obj/item/coin/titanium
custom_materials = list(/datum/material/titanium = 400)
-/obj/item/coin/bananium
- custom_materials = list(/datum/material/bananium = 400)
-
-/obj/item/coin/adamantine
- custom_materials = list(/datum/material/adamantine = 400)
-
-/obj/item/coin/mythril
- custom_materials = list(/datum/material/mythril = 400)
-
/obj/item/coin/plastic
custom_materials = list(/datum/material/plastic = 400)
-/obj/item/coin/runite
- custom_materials = list(/datum/material/runite = 400)
+/obj/item/coin/hellstone
+ custom_materials = list(/datum/material/hellstone = 400)
/obj/item/coin/twoheaded
desc = "Hey, this coin's the same on both sides!"
diff --git a/code/modules/mob/dead/crew_manifest.dm b/code/modules/mob/dead/crew_manifest.dm
index c7ca52968f86..da742342218c 100644
--- a/code/modules/mob/dead/crew_manifest.dm
+++ b/code/modules/mob/dead/crew_manifest.dm
@@ -4,7 +4,7 @@
return GLOB.always_state
/datum/crew_manifest/ui_status(mob/user, datum/ui_state/state)
- return (isnewplayer(user) || isobserver(user) || isAI(user) || ispAI(user)) ? UI_INTERACTIVE : UI_CLOSE
+ return (ismob(user)) ? UI_INTERACTIVE : UI_CLOSE
/datum/crew_manifest/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index 5a1e5bbf3387..85c60a15b031 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -107,7 +107,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
. = ..()
if(!client)
return
- LAZYADDASSOC(SSmobs.dead_players_by_virtual_z, "[virtual_z()]", src)
+ LAZYADDASSOCLIST(SSmobs.dead_players_by_virtual_z, "[virtual_z()]", src)
/mob/dead/Logout()
. = ..()
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 9baa46f526b5..8fbf9c32a38e 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -249,8 +249,8 @@
observer.client.init_verbs()
observer.update_appearance()
observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
- deadchat_broadcast(" has observed.", "[observer.real_name]", follow_target = observer, turf_target = get_turf(observer), message_type = DEADCHAT_DEATHRATTLE)
QDEL_NULL(mind)
+ deadchat_broadcast(" has observed.", "[observer.real_name]", follow_target = observer, turf_target = get_turf(observer), message_type = DEADCHAT_DEATHRATTLE)
qdel(src)
return TRUE
@@ -319,7 +319,6 @@
spawn_point.join_player_here(character)
var/atom/movable/screen/splash/Spl = new(character.client, TRUE)
Spl.Fade(TRUE)
- character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25)
character.update_parallax_teleport()
@@ -329,14 +328,13 @@
var/mob/living/carbon/human/humanc = character
ship.manifest_inject(humanc, client, job)
GLOB.data_core.manifest_inject(humanc, client)
+ ship.add_mob_to_crew_guestbook(humanc)
AnnounceArrival(humanc, job.name, ship)
AddEmploymentContract(humanc)
SSblackbox.record_feedback("tally", "species_spawned", 1, humanc.dna.species.name)
if(GLOB.summon_guns_triggered)
give_guns(humanc)
- if(GLOB.summon_magic_triggered)
- give_magic(humanc)
if(GLOB.curse_of_madness_triggered)
give_madness(humanc, GLOB.curse_of_madness_triggered)
if(CONFIG_GET(flag/roundstart_traits))
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
index 8b0ec1d6f79d..c01a20a18f64 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
@@ -3,33 +3,62 @@
/datum/sprite_accessory/ears
icon = 'icons/mob/mutant_bodyparts.dmi'
-/datum/sprite_accessory/ears/none
+/datum/sprite_accessory/ears/human/none
name = "None"
icon_state = "none"
-/datum/sprite_accessory/ears/cat
- icon = 'icons/mob/species/misc/cat.dmi'
+/datum/sprite_accessory/ears/human/elf
+ icon = 'icons/mob/species/human/elf.dmi'
+ name = "Elf"
+ icon_state = "elf"
+ secondary_color = FALSE
+ color_src = SKINCOLORS
+
+/datum/sprite_accessory/ears/human/cat
+ icon = 'icons/mob/species/human/cat.dmi'
name = "Cat"
icon_state = "cat"
secondary_color = TRUE
color_src = HAIR
-/datum/sprite_accessory/ears/cat/slime
+/datum/sprite_accessory/ears/human/cat/slime
name = "Slimecat"
icon_state = "cat"
secondary_color = FALSE
color_src = HAIR
image_alpha = 150
-/datum/sprite_accessory/ears/fox
- icon = 'icons/mob/species/misc/fox.dmi'
+/datum/sprite_accessory/ears/human/dog
+ icon = 'icons/mob/species/human/dog.dmi'
+ name = "Dog"
+ icon_state = "dog"
+ secondary_color = FALSE
+ color_src = HAIR
+
+/datum/sprite_accessory/ears/human/fox
+ icon = 'icons/mob/species/human/fox.dmi'
name = "Fox"
icon_state = "fox"
secondary_color = TRUE
color_src = HAIR
-/datum/sprite_accessory/ears/elf
- name = "Elf"
- icon_state = "elf"
- secondary_color = FALSE
- color_src = SKINCOLORS
+/datum/sprite_accessory/ears/human/rabbit
+ icon = 'icons/mob/species/human/rabbit.dmi'
+ name = "Rabbit"
+ icon_state = "bunny"
+ secondary_color = TRUE
+ color_src = HAIR
+
+/datum/sprite_accessory/ears/human/rabbit/bent
+ icon = 'icons/mob/species/human/rabbit.dmi'
+ name = "Bent Rabbit"
+ icon_state = "bunny_bent"
+ secondary_color = TRUE
+ color_src = HAIR
+
+/datum/sprite_accessory/ears/human/rabbit/floppy
+ icon = 'icons/mob/species/human/rabbit.dmi'
+ name = "Floppy Rabbit"
+ icon_state = "bunny_floppy"
+ secondary_color = TRUE
+ color_src = HAIR
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ipc.dm b/code/modules/mob/dead/new_player/sprite_accessories/ipc.dm
index b13b8f96a51e..16f7e269c760 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ipc.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ipc.dm
@@ -301,6 +301,7 @@
var/has_screen = TRUE //do we have a screen to toggle
var/has_overlay = FALSE //does this chasis have a overlay icon?
var/is_digi = FALSE //does this chasis use digitigrade
+ var/has_snout = FALSE
/datum/sprite_accessory/ipc_chassis/mcgreyscale
name = "Morpheus Cyberkinetics (Custom)"
@@ -354,6 +355,7 @@
color_src = MUTCOLORS
has_overlay = TRUE
use_eyes = TRUE
+ has_snout = TRUE
/datum/sprite_accessory/ipc_chassis/pgfmechanicsdigigrade
name = "PGF MECHANICS TYPE-D"
@@ -363,6 +365,7 @@
has_overlay = TRUE
use_eyes = TRUE
is_digi = TRUE
+ has_snout = TRUE
/datum/sprite_accessory/ipc_chassis/inteqsprinter
name = "Inteq Mothership 'Sprinter'"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/kepori.dm b/code/modules/mob/dead/new_player/sprite_accessories/kepori.dm
index 4ed949c63ef8..9fd4579e46f8 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/kepori.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/kepori.dm
@@ -1,10 +1,9 @@
-//Kepori mutant parts
-
-//Start head feathers
+// "Hair" feathers
/datum/sprite_accessory/kepori_feathers
color_src = HAIR
- icon = 'icons/mob/kepori_parts.dmi'
+ body_zone = BODY_ZONE_HEAD
+ icon = 'icons/mob/species/kepori/kepori_parts.dmi'
/datum/sprite_accessory/kepori_feathers/none
name = "None"
@@ -37,10 +36,6 @@
name = "Spikey"
icon_state = "spikey"
-/datum/sprite_accessory/kepori_feathers/soap
- name = "Soap"
- icon_state = "soap"
-
/datum/sprite_accessory/kepori_feathers/crowned
name = "Crowned"
icon_state = "crowned"
@@ -57,40 +52,60 @@
name = "Bun"
icon_state = "bun"
-//Start body feathers
+// Head/Face feathers
+
+/datum/sprite_accessory/kepori_head_feathers
+ color_src = MUTCOLORS_SECONDARY
+ body_zone = BODY_ZONE_HEAD
+ icon = 'icons/mob/species/kepori/kepori_parts.dmi'
+
+/datum/sprite_accessory/kepori_head_feathers/none
+ name = "None"
+
+/datum/sprite_accessory/kepori_head_feathers/full
+ name = "Full"
+ icon_state = "full"
+
+/datum/sprite_accessory/kepori_head_feathers/half
+ name = "Half"
+ icon_state = "half"
+
+// Body feathers
/datum/sprite_accessory/kepori_body_feathers
color_src = MUTCOLORS_SECONDARY
- icon = 'icons/mob/kepori_parts.dmi'
+ body_zone = BODY_ZONE_CHEST
+ icon = 'icons/mob/species/kepori/kepori_parts.dmi'
/datum/sprite_accessory/kepori_body_feathers/none
name = "None"
-/datum/sprite_accessory/kepori_body_feathers/aftik
- name = "Aftik"
- icon_state = "aftik"
-
/datum/sprite_accessory/kepori_body_feathers/belly
name = "Belly"
icon_state = "belly"
-/datum/sprite_accessory/kepori_body_feathers/shirt
- name = "Shirt"
- icon_state = "shirt"
+/datum/sprite_accessory/kepori_body_feathers/belly_wings
+ name = "Belly + Wings"
+ icon_state = "bwings"
/datum/sprite_accessory/kepori_body_feathers/soap
name = "Soap"
icon_state = "soap"
+/datum/sprite_accessory/kepori_body_feathers/soap_wings
+ name = "Soap + Wings"
+ icon_state = "swings"
+
/datum/sprite_accessory/kepori_body_feathers/wings
name = "Wings"
icon_state = "wings"
-//Start tail feathers
+// Tail feathers
/datum/sprite_accessory/kepori_tail_feathers
color_src = MUTCOLORS_SECONDARY
- icon = 'icons/mob/kepori_parts.dmi'
+ body_zone = BODY_ZONE_CHEST
+ icon = 'icons/mob/species/kepori/kepori_parts.dmi'
/datum/sprite_accessory/kepori_tail_feathers/none
name = "None"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
index 5a3d2eb3d62b..9a0da947d3b7 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
@@ -9,13 +9,13 @@
icon_state = "none"
/datum/sprite_accessory/tails/human/cat
- icon = 'icons/mob/species/misc/cat.dmi'
+ icon = 'icons/mob/species/human/cat.dmi'
name = "Cat"
icon_state = "cat"
color_src = HAIR
/datum/sprite_accessory/tails_animated/human/cat
- icon = 'icons/mob/species/misc/cat.dmi'
+ icon = 'icons/mob/species/human/cat.dmi'
name = "Cat"
icon_state = "cat"
color_src = HAIR
@@ -32,26 +32,44 @@
color_src = HAIR
image_alpha = 150
+/datum/sprite_accessory/tails/human/dog
+ icon = 'icons/mob/species/human/dog.dmi'
+ name = "Dog"
+ icon_state = "dog"
+ color_src = HAIR
+
+/datum/sprite_accessory/tails_animated/human/dog
+ icon = 'icons/mob/species/human/dog.dmi'
+ name = "Dog"
+ icon_state = "dog"
+ color_src = HAIR
+
/datum/sprite_accessory/tails/human/fox
- icon = 'icons/mob/species/misc/fox.dmi'
+ icon = 'icons/mob/species/human/fox.dmi'
name = "Fox"
icon_state = "fox"
color_src = HAIR
/datum/sprite_accessory/tails_animated/human/fox
- icon = 'icons/mob/species/misc/fox.dmi'
+ icon = 'icons/mob/species/human/fox.dmi'
name = "Fox"
icon_state = "fox"
color_src = HAIR
/datum/sprite_accessory/tails/human/fox/alt
- icon = 'icons/mob/species/misc/fox.dmi'
+ icon = 'icons/mob/species/human/fox.dmi'
name = "Fox 2"
icon_state = "fox2"
color_src = HAIR
/datum/sprite_accessory/tails_animated/human/fox/alt
- icon = 'icons/mob/species/misc/fox.dmi'
+ icon = 'icons/mob/species/human/fox.dmi'
name = "Fox 2"
icon_state = "fox2"
color_src = HAIR
+
+/datum/sprite_accessory/tails/human/rabbit
+ icon = 'icons/mob/species/human/rabbit.dmi'
+ name = "Rabbit"
+ icon_state = "bunny"
+ color_src = HAIR
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 6fffc48e76a1..4a768fc1c501 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -68,8 +68,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
add_verb(src, list(
/mob/dead/observer/proc/dead_tele,
/mob/dead/observer/proc/open_spawners_menu,
- /mob/dead/observer/proc/tray_view,
- /mob/dead/observer/proc/possess_mouse_verb))
+ /mob/dead/observer/proc/tray_view))
if(icon_state in GLOB.ghost_forms_with_directions_list)
ghostimage_default = image(src.icon,src,src.icon_state + "_nodir")
@@ -496,7 +495,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(isobserver(usr)) //Make sure they're an observer!
-
var/list/dest = list() //List of possible destinations (mobs)
var/target = null //Chosen target.
@@ -962,70 +960,3 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.images += t_ray_images
else
client.images -= stored_t_ray_images
-
-//WS Begin
-/mob/dead/observer/proc/possess_mouse_verb()
- set category = "Ghost"
- set name = "Possess a mouse"
- set desc = "Possess a mouse to haunt the station.... and their food!"
-
- var/list/possessible = list()
-
- for(var/mob/living/simple_animal/mouse/M in GLOB.alive_mob_list)
- if(M.stat != CONSCIOUS)
- continue
- if(M.key)
- continue
- if(M in GLOB.player_list)
- continue
- if(M.mind)
- continue
-
- possessible += M
-
- if(!possessible.len)
- to_chat(src, "There are currently no mice able to be possessed!")
- return FALSE
-
- var/mob/living/simple_animal/mouse/M = pick(possessible)
-
- possess_mouse(M)
-
-
-/mob/dead/observer/proc/possess_mouse(mob/living/simple_animal/mouse/M)
- if(!M)
- return FALSE
-
- if(!SSticker.HasRoundStarted())
- to_chat(usr, "The round hasn't started yet!")
- return FALSE
-
- if(is_banned_from(key, ROLE_SENTIENCE))
- to_chat(src, "You are job banned!")
- return FALSE
-
- if(alert("Are you sure you want to become a mouse? (Warning, you can no longer be cloned!)",,"Yes","No") != "Yes")
- return FALSE
-
- if(M.key || (M.stat != CONSCIOUS) || (M in GLOB.player_list) || M.mind || QDELETED(src) || QDELETED(M))
- to_chat(src, "This mouse is unable to be controlled, please try again!")
- return FALSE
-
- log_game("[key_name(src)] has became a mouse")
-
- M.key = key
- M.faction = list("neutral")
- M.chew_probability = 0 //so they cant pull off a big brain play by ghosting somewhere or idk
- M.layer = BELOW_OPEN_DOOR_LAYER //ENGAGE ADVANCED HIDING BRAIN FUNCTIONS
- M.language_holder = new /datum/language_holder/mouse(M)
- M.pass_flags |= PASSDOORHATCH
- M.sentience_act()
- M.maxHealth = 15
- M.health = M.maxHealth
-
- to_chat(M , "You are now possessing a mouse. \
- You do not remember your previous life. You can eat trash and \
- food on the floor to gain health and help create new mice. Mouse traps will hurt your fragile body \
- and so will any kind of weapons. You can control click food and trash items in order to eat them. Get. That. Cheese.")
- return TRUE
-//WS End
diff --git a/code/modules/mob/dead/observer/orbit.dm b/code/modules/mob/dead/observer/orbit.dm
index 86d54577538c..da3bc7c2dfb5 100644
--- a/code/modules/mob/dead/observer/orbit.dm
+++ b/code/modules/mob/dead/observer/orbit.dm
@@ -57,7 +57,7 @@
var/list/misc = list()
var/list/npcs = list()
- var/list/pois = getpois(skip_mindless = TRUE, specify_dead_role = FALSE)
+ var/list/pois = getpois(skip_mindless = TRUE, specify_dead_role = FALSE, only_realname = TRUE)
for (var/name in pois)
var/list/serialized = list()
serialized["name"] = name
@@ -67,6 +67,8 @@
serialized["ref"] = REF(poi)
var/mob/M = poi
+
+ serialized["fake_name"] = M.name
if (istype(M))
if (isobserver(M))
ghosts += list(serialized)
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index de07b3d4f0fd..0d9dab7a035f 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -275,7 +275,7 @@
*/
/mob/proc/dropItemToGround(obj/item/I, force = FALSE, silent = FALSE)
. = doUnEquip(I, force, drop_location(), FALSE, silent = silent)
- if(. && I) //ensure the item exists and that it was dropped properly.
+ if(. && I && !(I.item_flags & NO_PIXEL_RANDOM_DROP)) //ensure the item exists and that it was dropped properly.
I.pixel_x = rand(-6,6)
I.pixel_y = rand(-6,6)
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index aec75960989d..1910347e4fdd 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -4,19 +4,6 @@
BLOOD SYSTEM
****************************************************/
-/mob/living/carbon/human/proc/suppress_bloodloss(amount)
- if(bleedsuppress)
- return
- else
- bleedsuppress = TRUE
- addtimer(CALLBACK(src, PROC_REF(resume_bleeding)), amount)
-
-/mob/living/carbon/human/proc/resume_bleeding()
- bleedsuppress = 0
- if(stat != DEAD && bleed_rate)
- to_chat(src, "The blood soaks through your bandage.")
-
-
/mob/living/carbon/monkey/handle_blood()
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
@@ -29,7 +16,6 @@
/mob/living/carbon/human/handle_blood()
if(NOBLOOD in dna.species.species_traits)
- bleed_rate = 0
return
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
@@ -83,24 +69,20 @@
if(!HAS_TRAIT(src, TRAIT_NODEATH))
death()
- var/temp_bleed = 0
//Bleeding out
+ var/limb_bleed = 0
for(var/obj/item/bodypart/BP as anything in bodyparts)
- var/brutedamage = BP.brute_dam
-
+ if(BP.GetComponent(/datum/component/bandage))
+ continue
//We want an accurate reading of .len
listclearnulls(BP.embedded_objects)
for(var/obj/item/embeddies in BP.embedded_objects)
if(!embeddies.isEmbedHarmless())
- temp_bleed += 0.5
-
- if(brutedamage >= 20)
- temp_bleed += (brutedamage * 0.013)
-
- bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
+ BP.adjust_bleeding(0.1, BLOOD_LOSS_DAMAGE_MAXIMUM)
+ limb_bleed += BP.bleeding
- if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
- bleed(bleed_rate)
+ if(limb_bleed && !bleedsuppress && !HAS_TRAIT(src, TRAIT_FAKEDEATH))
+ bleed(limb_bleed)
//Makes a blood drop, leaking amt units of blood from the mob
/mob/living/carbon/proc/bleed(amt)
@@ -125,7 +107,8 @@
/mob/living/carbon/human/restore_blood()
blood_volume = BLOOD_VOLUME_NORMAL
- bleed_rate = 0
+ for(var/obj/item/bodypart/BP as anything in get_bleeding_parts())
+ BP.bleeding = 0
/****************************************************
BLOOD TRANSFERS
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index a70520462f39..8629d01650d4 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -113,7 +113,7 @@
return
user.visible_message("[user] starts to pour the contents of [O] onto [src].", "You start to slowly pour the contents of [O] onto [src].")
- if(!do_after(user, 60, TRUE, src))
+ if(!do_after(user, 60, src))
to_chat(user, "You failed to pour [O] onto [src]!")
return
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 23e937acf102..d692e36345cb 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -21,7 +21,6 @@
bubble_icon = "alien"
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
- var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/has_fine_manipulation = FALSE
status_flags = CANUNCONSCIOUS|CANPUSH
@@ -180,3 +179,7 @@
/mob/living/carbon/alien/on_standing_up()
. = ..()
update_icons()
+
+/mob/living/carbon/alien/examine(mob/user)
+ . = ..()
+ . += "It's a strange creature."
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index ec4105fde0ce..ccd6540ffca1 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -291,7 +291,7 @@ Doesn't work on other aliens/AI.*/
/obj/effect/proc_holder/alien/sneak/fire(mob/living/carbon/alien/humanoid/user)
if(!active)
- user.alpha = 25
+ user.alpha = 150
user.sneaking = TRUE
active = TRUE
to_chat(user, "You blend into the shadows...")
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index 5163821a9573..57835578cf84 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -100,8 +100,7 @@
return
else //Maybe uses plasma in the future, although that wouldn't make any sense...
- leaping = 1
- weather_immunities += "lava"
+ leaping = TRUE
update_icons()
throw_at(leap_target, MAX_ALIEN_LEAP_DIST, 2, src, FALSE, TRUE, callback = CALLBACK(src, PROC_REF(leap_end)))
@@ -115,7 +114,6 @@
* the icons of the hunter.
*/
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
- leaping = 0
- LAZYREMOVE(weather_immunities, "lava")
+ leaping = FALSE
update_icons()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index 651ea4c6d0ee..dcb44af19cca 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -63,7 +63,7 @@
if(href_list["pouches"] && usr.canUseTopic(src, BE_CLOSE, NO_DEXTERITY))
visible_message("[usr] tries to empty [src]'s pouches.", \
"[usr] tries to empty your pouches.")
- if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5))
+ if(do_after(usr, POCKET_STRIP_DELAY * 0.5, src))
dropItemToGround(r_store)
dropItemToGround(l_store)
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
index 49ff1e88937b..4e797ede06c0 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
@@ -104,7 +104,8 @@
if(gib_on_success)
new_xeno.visible_message("[new_xeno] bursts out of [owner] in a shower of gore!", "You exit [owner], your previous host.", "You hear organic matter ripping and tearing!")
- owner.gib()
+ owner.adjustBruteLoss(200)
+ owner.cut_overlay(overlay)
else
new_xeno.visible_message("[new_xeno] wriggles out of [owner]!", "You exit [owner], your previous host.")
owner.adjustBruteLoss(40)
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm
index a9caeba37208..c9cdcaf8199c 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm
@@ -47,7 +47,7 @@
/// Whether or not this facehugger can actually impregnate targets
var/sterile = FALSE
/// How long it takes for a facehugger to impregnate a target once attached
- var/pregnation_time = 10 SECONDS
+ var/pregnation_time = 5 SECONDS
/// How long it takes between coupling attempts
var/couple_retry_time = 15 SECONDS
/// The mob's internal mask version, stored within the mob when the facehugger isn't being used as an item.
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 5b316dad9cb6..3ed2b86816ac 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -202,7 +202,7 @@
visible_message("[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].", \
"[usr] tries to [internal ? "close" : "open"] the valve on your [ITEM.name].", null, null, usr)
to_chat(usr, "You try to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name]...")
- if(do_mob(usr, src, POCKET_STRIP_DELAY))
+ if(do_after(usr, POCKET_STRIP_DELAY, src))
if(internal)
internal = null
update_internals_hud_icon(0)
@@ -255,7 +255,7 @@
buckle_cd = O.breakouttime
visible_message("[src] attempts to unbuckle [p_them()]self!", \
"You attempt to unbuckle yourself... (This will take around [round(buckle_cd/600,1)] minute\s, and you need to stay still.)")
- if(do_after(src, buckle_cd, 0, target = src))
+ if(do_after(src, buckle_cd, target = src, timed_action_flags = IGNORE_HELD_ITEM))
if(!buckled)
return
buckled.user_unbuckle_mob(src,src)
@@ -306,7 +306,7 @@
if(!cuff_break)
visible_message("[src] attempts to remove [I]!")
to_chat(src, "You attempt to remove [I]... (This will take around [DisplayTimeText(breakouttime)] and you need to stand still.)")
- if(do_after(src, breakouttime, 0, target = src))
+ if(do_after(src, breakouttime, target = src, timed_action_flags = IGNORE_HELD_ITEM))
. = clear_cuffs(I, cuff_break)
else
to_chat(src, "You fail to remove [I]!")
@@ -315,7 +315,7 @@
breakouttime = 50
visible_message("[src] is trying to break [I]!")
to_chat(src, "You attempt to break [I]... (This will take around 5 seconds and you need to stand still.)")
- if(do_after(src, breakouttime, 0, target = src))
+ if(do_after(src, breakouttime, target = src, timed_action_flags = IGNORE_HELD_ITEM))
. = clear_cuffs(I, cuff_break)
else
to_chat(src, "You fail to break [I]!")
@@ -538,6 +538,7 @@
REMOVE_TRAIT(src, TRAIT_INCAPACITATED, STAMINA)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, STAMINA)
REMOVE_TRAIT(src, TRAIT_FLOORED, STAMINA)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, STAMINA)
else
return
update_health_hud()
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 9b50d1827724..43cefa251e34 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -1,3 +1,25 @@
+/mob/living/carbon/attackby(obj/item/W, mob/user, params)
+ var/obj/item/bodypart/BP = get_bodypart(check_zone(user.zone_selected))
+ var/has_painkillers = reagents.has_reagent(/datum/reagent/medicine/morphine, needs_metabolizing = TRUE)
+ if(W.tool_behaviour == TOOL_WELDER && IS_ROBOTIC_LIMB(BP) && BP.brute_dam) //prioritize healing if we're synthetic
+ return ..()
+ if(user.a_intent != INTENT_HELP || !W.get_temperature() || !BP.can_bandage()) //this will also catch low damage synthetic welding
+ return ..()
+ . = TRUE
+ var/heal_time = 2 SECONDS
+ playsound(user, 'sound/surgery/cautery1.ogg', 20)
+ balloon_alert(user, "cauterizing...")
+ if(src == user && !has_painkillers)
+ heal_time *= 2 //oof ouch owie
+ user.visible_message(span_nicegreen("[user] holds [W] up to [user == src ? "their" : "[src]'s"] [parse_zone(BP.body_zone)], trying to slow [p_their()] bleeding..."), span_nicegreen("You hold [W] up to [user == src ? "your" : "[src]'s"] [parse_zone(BP.body_zone)], trying to slow [user == src ? "your" : p_their()] bleeding..."))
+ if(do_after(user, heal_time, target = src))
+ playsound(user, 'sound/surgery/cautery2.ogg', 20)
+ BP.apply_bandage(0.005, W.get_temperature()/BLOOD_CAUTERIZATION_RATIO, "cauterization") //not particularly fast, this is the "I really would prefer not to be bleeding right now" option
+ BP.receive_damage(burn = W.get_temperature()/BLOOD_CAUTERIZATION_DAMAGE_RATIO) //my body is a MACHINE that turns BLEEDING into BURN DAMAGE
+ user.visible_message(span_nicegreen("[user] cauterizes the bleeding on [user == src ? "their" : "[src]'s"] [parse_zone(BP.body_zone)]!"), span_nicegreen("You cauterize the bleeding on [user == src ? "your" : "[src]'s"] [parse_zone(BP.body_zone)]!"))
+ else
+ to_chat(user, span_warning("You were interrupted!"))
+
/mob/living/carbon/get_eye_protection()
. = ..()
var/obj/item/organ/eyes/E = getorganslot(ORGAN_SLOT_EYES)
@@ -554,14 +576,10 @@
else
to_chat(src, "Your eyes are really starting to hurt. This can't be good for you!")
- if(has_bane(BANE_LIGHT))
- mind.disrupt_spells(-500)
return 1
else if(damage == 0) // just enough protection
if(prob(20))
to_chat(src, "Something bright flashes in the corner of your vision!")
- if(has_bane(BANE_LIGHT))
- mind.disrupt_spells(0)
/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index a7dc41b307c4..8743fe33289e 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -27,6 +27,7 @@
var/obj/item/tank/internal = null
var/obj/item/clothing/head = null
+ var/obj/item/wear_id = null //only used by humans
var/obj/item/clothing/gloves = null ///only used by humans
var/obj/item/clothing/shoes/shoes = null ///only used by humans.
var/obj/item/clothing/glasses/glasses = null ///only used by humans.
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index 2045bfe4aa18..8c023299baed 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -1,6 +1,6 @@
-/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, break_modifier = 1)
+/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, break_modifier = 1, sharpness = FALSE)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!damage || (!forced && hit_percent <= 0))
@@ -21,7 +21,7 @@
switch(damagetype)
if(BRUTE)
if(BP)
- if(BP.receive_damage(damage_amount, 0, break_modifier))
+ if(BP.receive_damage(damage_amount, 0, break_modifier, sharpness = sharpness))
update_damage_overlays()
else //no bodypart, we deal damage with a more general method.
adjustBruteLoss(damage_amount, forced = forced)
@@ -29,7 +29,7 @@
shake_animation(damage_amount)
if(BURN)
if(BP)
- if(BP.receive_damage(0, damage_amount, break_modifier))
+ if(BP.receive_damage(0, damage_amount, break_modifier, sharpness = sharpness))
update_damage_overlays()
else
adjustFireLoss(damage_amount, forced = forced)
@@ -267,3 +267,68 @@
if(update)
update_damage_overlays()
update_stamina()
+
+/// Gets a list of bleeding bodyparts, argument ignore_staunched = are we actively bleeding (no treatment)
+/mob/living/carbon/proc/get_bleeding_parts(ignore_staunched = FALSE)
+ var/list/obj/item/bodypart/parts = list()
+ for(var/obj/item/bodypart/BP as anything in bodyparts)
+ if(BP.bleeding && (!ignore_staunched || !BP.GetComponent(/datum/component/bandage)))
+ parts += BP
+ return parts
+
+/// Gets a list of bandaged parts
+/mob/living/carbon/proc/get_bandaged_parts()
+ var/list/obj/item/bodypart/parts = list()
+ for(var/obj/item/bodypart/BP as anything in bodyparts)
+ if(BP.GetComponent(/datum/component/bandage))
+ parts += BP
+ return parts
+
+/// Apply bleeding to one random bodypart.
+/mob/living/carbon/proc/cause_bleeding(amt)
+ if(amt <= 0)
+ return
+ var/list/obj/item/bodypart/parts = bodyparts.Copy()
+ if(!length(parts))
+ return
+ var/obj/item/bodypart/part_in_question = pick(parts)
+ part_in_question.adjust_bleeding(amt)
+
+/// Heal bleeding from one random bodypart
+/mob/living/carbon/proc/heal_bleeding(amt)
+ if(amt <= 0)
+ return
+ var/list/obj/item/bodypart/parts = get_bleeding_parts()
+ if(!length(parts))
+ return
+ var/obj/item/bodypart/part_in_question = pick(parts)
+ part_in_question.adjust_bleeding(-amt)
+ var/bleed_calc = part_in_question.bleeding
+ return min(bleed_calc - part_in_question.bleeding, 0)
+
+/// Apply bleeding to all bodyparts
+/mob/living/carbon/proc/cause_overall_bleeding(amt)
+ if(amt <= 0)
+ return
+ var/list/obj/item/bodypart/parts = bodyparts.Copy()
+ while(length(parts))
+ var/obj/item/bodypart/part_in_question = pick(parts)
+ if(part_in_question.is_pseudopart)
+ parts -= part_in_question
+ continue
+ var/amount_to_take = min(part_in_question.bleeding, amt / length(parts))
+ part_in_question.adjust_bleeding(amount_to_take)
+ amt -= amount_to_take
+ parts -= part_in_question
+
+/// Heal bleeding from all bodyparts
+/mob/living/carbon/proc/heal_overall_bleeding(amt)
+ if(amt <= 0)
+ return
+ var/list/obj/item/bodypart/parts = get_bleeding_parts()
+ while(length(parts))
+ var/obj/item/bodypart/part_in_question = pick(parts)
+ var/amount_to_take = min(part_in_question.bleeding, amt / length(parts))
+ part_in_question.adjust_bleeding(-amount_to_take)
+ amt -= amount_to_take
+ parts -= part_in_question
diff --git a/code/modules/mob/living/carbon/emote.dm b/code/modules/mob/living/carbon/emote.dm
index 55b01d4200e2..f0d27e801cd2 100644
--- a/code/modules/mob/living/carbon/emote.dm
+++ b/code/modules/mob/living/carbon/emote.dm
@@ -455,7 +455,7 @@
* This fake hit only happens if we can deal damage and if we hit a living thing. Otherwise, we just do normal on hit effects.
*/
/obj/projectile/kiss/proc/harmless_on_hit(mob/living/living_target)
- playsound(get_turf(living_target), hitsound, 100, TRUE)
+ playsound(get_turf(living_target), hitsound, 50, TRUE, -12, ignore_walls = FALSE)
if(!suppressed) // direct
living_target.visible_message(span_danger("[living_target] is hit by \a [src]."), span_userdanger("You're hit by \a [src]!"), vision_distance=COMBAT_MESSAGE_RANGE)
diff --git a/code/modules/mob/living/carbon/human/consistent_human.dm b/code/modules/mob/living/carbon/human/consistent_human.dm
index e63adffeee48..86e6e08c4367 100644
--- a/code/modules/mob/living/carbon/human/consistent_human.dm
+++ b/code/modules/mob/living/carbon/human/consistent_human.dm
@@ -31,6 +31,7 @@
dna.features["spider_spinneret"] = GLOB.spider_spinneret_list[hex2num(copytext(seed, 11, 12)) % length(GLOB.spider_spinneret_list) + 1]
dna.features["kepori_feathers"] = GLOB.kepori_feathers_list[hex2num(copytext(seed, 12, 13)) % length(GLOB.kepori_feathers_list) + 1]
dna.features["kepori_body_feathers"] = GLOB.kepori_body_feathers_list[hex2num(copytext(seed, 13, 14)) % length(GLOB.kepori_body_feathers_list) + 1]
+ dna.features["kepori_head_feathers"] = GLOB.kepori_head_feathers_list[hex2num(copytext(seed, 13, 14)) % length(GLOB.kepori_head_feathers_list) + 1]
dna.features["vox_head_quills"] = GLOB.vox_head_quills_list[hex2num(copytext(seed, 14, 15)) % length(GLOB.vox_head_quills_list) + 1]
dna.features["vox_neck_quills"] = GLOB.vox_neck_quills_list[hex2num(copytext(seed, 15, 16)) % length(GLOB.vox_neck_quills_list) + 1]
dna.features["elzu_horns"] = GLOB.elzu_horns_list[hex2num(copytext(seed, 16, 17)) % length(GLOB.elzu_horns_list) + 1]
diff --git a/code/modules/mob/living/carbon/human/damage_procs.dm b/code/modules/mob/living/carbon/human/damage_procs.dm
index 4883446b7cb1..d7f6834030b3 100644
--- a/code/modules/mob/living/carbon/human/damage_procs.dm
+++ b/code/modules/mob/living/carbon/human/damage_procs.dm
@@ -1,7 +1,7 @@
/// depending on the species, it will run the corresponding apply_damage code there
-/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, break_modifier = 1) //WS Edit - Breakable Bones
- return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage)
+/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, break_modifier = 1, sharpness = FALSE) //WS Edit - Breakable Bones
+ return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage, sharpness = sharpness)
/mob/living/carbon/human/revive(full_heal = 0, admin_revive = 0)
if(..())
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 4e8168fc60d6..da75efa5265a 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -96,7 +96,7 @@
if(islizard(user))
return 'sound/voice/lizard/squeal.ogg' //This is from Bay
-/datum/emote/living/carbon/human/tailthump //lizard
+/datum/emote/living/carbon/human/tailthump //lizard + vox
key = "thump"
key_third_person = "thumps their tail"
message = "thumps their tail!"
@@ -106,7 +106,7 @@
/datum/emote/living/carbon/human/tailthump/get_sound(mob/living/user)
if(!ishuman(user))
return
- if(islizard(user))
+ if(!isnull(user.getorgan(/obj/item/organ/tail)) || (isvox(user)))
return 'sound/voice/lizard/tailthump.ogg' //https://freesound.org/people/TylerAM/sounds/389665/
/datum/emote/living/carbon/human/weh //lizard
@@ -239,7 +239,8 @@
message_param = "beeps at %t."
/datum/emote/living/carbon/human/robot_tongue/beep/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/machines/twobeep.ogg', 50)
/datum/emote/living/carbon/human/robot_tongue/buzz
@@ -249,7 +250,8 @@
message_param = "buzzes at %t."
/datum/emote/living/carbon/human/robot_tongue/buzz/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/machines/buzz-sigh.ogg', 50)
/datum/emote/living/carbon/human/robot_tongue/buzz2
@@ -257,7 +259,8 @@
message = "buzzes twice."
/datum/emote/living/carbon/human/robot_tongue/buzz2/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/machines/buzz-two.ogg', 50)
/datum/emote/living/carbon/human/robot_tongue/chime
@@ -266,7 +269,8 @@
message = "chimes."
/datum/emote/living/carbon/human/robot_tongue/chime/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/machines/chime.ogg', 50)
/datum/emote/living/carbon/human/robot_tongue/no
@@ -275,7 +279,8 @@
message = "emits an negative blip."
/datum/emote/living/carbon/human/robot_tongue/no/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/machines/synth_no.ogg', 50)
/datum/emote/living/carbon/human/robot_tongue/ping
@@ -285,7 +290,8 @@
message_param = "pings at %t."
/datum/emote/living/carbon/human/robot_tongue/ping/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/machines/ping.ogg', 50)
/datum/emote/living/carbon/human/robot_tongue/warn
@@ -294,7 +300,8 @@
message = "blares an alarm!"
/datum/emote/living/carbon/human/robot_tongue/warn/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/machines/warning-buzzer.ogg', 50)
/datum/emote/living/carbon/human/robot_tongue/yes
@@ -303,7 +310,8 @@
message = "emits an affirmative blip."
/datum/emote/living/carbon/human/robot_tongue/yes/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/machines/synth_yes.ogg', 50)
// the following emote were originally clown-locked and synthetic exclusive
@@ -315,5 +323,39 @@
message = "plays a sad trombone..."
/datum/emote/living/carbon/human/robot_tongue/sad/run_emote(mob/user, params)
- if(..())
+ . = ..()
+ if(.)
playsound(user.loc, 'sound/misc/sadtrombone.ogg', 50)
+
+//kepi (plus one vox i guess)
+
+/datum/emote/living/carbon/human/kepiclick
+ key = "click"
+ key_third_person = "clicks"
+ message = "clicks."
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/carbon/human/kepiclick/get_sound(mob/living/user)
+ if(!ishuman(user))
+ return
+ if(iskepori(user) || (isvox(user)))
+ return 'sound/voice/kepori/kepiclick.ogg' //https://freesound.org/people/Ambiabstract/sounds/584212/
+
+/datum/emote/living/carbon/human/kepiwhistle
+ key = "whistle"
+ key_third_person = "whistles"
+ message = "whistles!"
+ emote_type = EMOTE_AUDIBLE
+ vary = TRUE
+
+/datum/emote/living/carbon/human/kepiwhistle/get_sound(mob/living/user)
+ if(!ishuman(user))
+ return
+ if(iskepori(user))
+ return 'sound/voice/kepori/kepiwhistle.ogg' //https://freesound.org/people/Andreas.Mustola/sounds/338277/
+
+/datum/emote/living/carbon/human/kepiwoop // i have yet to find a woop sound that doesnt suck i will do it later
+ key = "woop"
+ key_third_person = "woops"
+ message = "woops!"
+ emote_type = EMOTE_AUDIBLE
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index b024be2f96f7..7bbe9fb1de72 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -8,7 +8,6 @@
var/t_has = p_have()
var/t_is = p_are()
var/obscure_name
-
var/list/obscured = check_obscured_slots()
var/skipface = ((wear_mask?.flags_inv & HIDEFACE) || (head?.flags_inv & HIDEFACE))
@@ -16,10 +15,25 @@
var/mob/living/L = user
if(HAS_TRAIT(L, TRAIT_PROSOPAGNOSIA))
obscure_name = TRUE
- var/apparent_species
- if(dna?.species && !skipface)
- apparent_species = ", \an [dna.species.name]"
- . = list("This is [!obscure_name ? name : "Unknown"][apparent_species]!")
+
+ . = list(span_info("This is [name]!"))
+
+ if(user != src)
+ if(!obscure_name && !skipface)
+ var/face_name = get_face_name("")
+ if(face_name)
+ //if we have no guestbook, we just KNOW okay?
+ var/known_name = user.mind?.guestbook ? user.mind.guestbook.get_known_name(user, src, face_name) : face_name
+ if(known_name)
+ . += "You know them as [known_name]."
+ else
+ . += "You don't recognize [t_him]. You can Ctrl-Shift click [t_him] to memorize their face."
+ else
+ . += "You can't see [t_his] face very well."
+ else
+ . += "You can't see [t_his] face very well."
+ else
+ . += "It's you, [real_name]."
//uniform
if(w_uniform && !(ITEM_SLOT_ICLOTHING in obscured))
@@ -243,9 +257,12 @@
if(blood_volume < BLOOD_VOLUME_SAFE || skin_tone == "albino")
msg += "[t_He] [t_has] pale skin.\n"
- if(bleedsuppress)
- msg += "[t_He] [t_is] bandaged with something.\n"
- else if(bleed_rate)
+
+ if(LAZYLEN(get_bandaged_parts()))
+ msg += "[t_He] [t_has] some dressed bleeding.\n"
+
+ var/list/obj/item/bodypart/bleed_check = get_bleeding_parts(TRUE)
+ if(LAZYLEN(bleed_check))
if(reagents.has_reagent(/datum/reagent/toxin/heparin, needs_metabolizing = TRUE))
msg += "[t_He] [t_is] bleeding uncontrollably!\n"
else
@@ -297,10 +314,6 @@
msg += ""
- if(HAS_TRAIT(user, TRAIT_SPIRITUAL) && mind?.holy_role)
- msg += "[t_He] [t_has] a holy aura about [t_him].\n"
- SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "religious_comfort", /datum/mood_event/religiously_comforted)
-
switch(stat)
if(UNCONSCIOUS, HARD_CRIT)
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seem[p_s()] to be asleep.\n"
@@ -313,7 +326,7 @@
if(!key)
msg += "[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.\n"
else if(!client)
- msg += "[t_He] appears to be suffering from SSD - Space Sleep Disorder. [t_He] may snap out of it at any time! Or maybe never. It's best to leave [t_him] be.\n"
+ msg += "[t_He] [t_has] been suffering from SSD - Space Sleep Disorder - for [trunc(((world.time - lastclienttime) / (1 MINUTES)))] minutes. [t_He] may snap out of it at any time! Or maybe never. It's best to leave [t_him] be.\n"
if (length(msg))
. += "[msg.Join("")]"
@@ -400,20 +413,23 @@
/mob/living/carbon/human/examine_more(mob/user)
. = ..()
+ for(var/obj/item/bodypart/BP as anything in get_bandaged_parts())
+ var/datum/component/bandage/B = BP.GetComponent(/datum/component/bandage)
+ . += span_notice("[p_their(TRUE)] [parse_zone(BP.body_zone)] is dressed with [B.bandage_name]")
+ for(var/obj/item/bodypart/BP as anything in get_bleeding_parts(TRUE))
+ var/bleed_text
+ switch(BP.bleeding)
+ if(0 to 0.5)
+ bleed_text = "lightly."
+ if(0.5 to 1)
+ bleed_text = "moderately."
+ if(1 to 1.5)
+ bleed_text = "heavily!"
+ else
+ bleed_text = "significantly!!"
+ . += span_warning("[p_their(TRUE)] [parse_zone(BP.body_zone)] is bleeding [bleed_text]")
+
if ((wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)))
return
- var/age_text
- switch(age)
- if(-INFINITY to 25)
- age_text = "very young"
- if(26 to 35)
- age_text = "of adult age"
- if(36 to 55)
- age_text = "middle-aged"
- if(56 to 75)
- age_text = "rather old"
- if(76 to 100)
- age_text = "very old"
- if(101 to INFINITY)
- age_text = "withering away"
- . += list(span_notice("[p_they(TRUE)] appear[p_s()] to be [age_text]."))
+ if(get_age())
+ . += list(span_notice("[p_they(TRUE)] appear[p_s()] to be [get_age()]."))
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index f3802e381c55..27fa569de7cd 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -52,8 +52,6 @@
sec_hud_set_ID()
sec_hud_set_implants()
sec_hud_set_security_status()
- //...fan gear
- fan_hud_set_fandom()
//...and display them.
add_to_all_human_data_huds()
@@ -247,7 +245,7 @@
else
return
- if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator)) //placing an item into the pocket is 4 times faster
+ if(do_after(usr, POCKET_STRIP_DELAY/delay_denominator, src, hidden = TRUE)) //placing an item into the pocket is 4 times faster
if(pocket_item)
if(pocket_item == (pocket_id == ITEM_SLOT_RPOCKET ? r_store : l_store)) //item still in the pocket we search
dropItemToGround(pocket_item)
@@ -265,7 +263,7 @@
if(href_list["toggle_uniform"] && usr.canUseTopic(src, BE_CLOSE, NO_DEXTERITY))
var/obj/item/clothing/under/U = get_item_by_slot(ITEM_SLOT_ICLOTHING)
to_chat(src, "[usr.name] is trying to adjust your [U].")
- if(do_mob(usr, src, U.strip_delay/2))
+ if(do_after(usr, U.strip_delay/2, src))
to_chat(src, "[usr.name] successfully adjusted your [U].")
U.toggle_jumpsuit_adjust()
update_inv_w_uniform()
@@ -614,10 +612,13 @@
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/target)
var/panicking = FALSE
+ if(target == src) //Sanity check, in case spacetime crumbles and allows us to perform cpr on ourselves
+ return
+
do
CHECK_DNA_AND_SPECIES(target)
- if (INTERACTING_WITH(src, target))
+ if (DOING_INTERACTION_WITH_TARGET(src,target))
return FALSE
if (target.stat == DEAD || HAS_TRAIT(target, TRAIT_FAKEDEATH))
@@ -643,7 +644,7 @@
visible_message("[src] is trying to perform CPR on [target.name]!", \
"You try to perform CPR on [target.name]... Hold still!")
- if (!do_mob(src, target, time = panicking ? CPR_PANIC_SPEED : (3 SECONDS)))
+ if (!do_after(src, delay = panicking ? CPR_PANIC_SPEED : (3 SECONDS), target = target))
to_chat(src, "You fail to perform CPR on [target]!")
return FALSE
@@ -898,11 +899,6 @@
dna.remove_mutation(HM.name)
..()
-/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
- . = ..()
- if (dna && dna.species)
- . += dna.species.check_species_weakness(weapon, attacker)
-
/mob/living/carbon/human/is_literate()
return TRUE
@@ -1057,6 +1053,12 @@
else if(can_be_firemanned(target))
fireman_carry(target)
+/mob/living/carbon/human/limb_attack_self()
+ var/obj/item/bodypart/arm = hand_bodyparts[active_hand_index]
+ if(arm)
+ arm.attack_self(src)
+ return ..()
+
/mob/living/carbon/human/MouseDrop(mob/over)
. = ..()
if(ishuman(over))
@@ -1064,7 +1066,7 @@
if(!src.is_busy && (src.zone_selected == BODY_ZONE_HEAD || src.zone_selected == BODY_ZONE_PRECISE_GROIN) && get_turf(src) == get_turf(T) && !(T.mobility_flags & MOBILITY_STAND) && src.a_intent != INTENT_HELP) //all the stars align, time to curbstomp
src.is_busy = TRUE
- if (!do_mob(src,T,25) || get_turf(src) != get_turf(T) || (T.mobility_flags & MOBILITY_STAND) || src.a_intent == INTENT_HELP || src == T) //wait 30ds and make sure the stars still align (Body zone check removed after PR #958)
+ if (!do_after(src, 2.5 SECONDS, T) || get_turf(src) != get_turf(T) || (T.mobility_flags & MOBILITY_STAND) || src.a_intent == INTENT_HELP || src == T) //wait 30ds and make sure the stars still align (Body zone check removed after PR #958)
src.is_busy = FALSE
return
@@ -1152,7 +1154,7 @@
//Joe Medic starts quickly/expertly lifting Grey Tider onto their back..
"[carrydelay < 35 ? "Using your gloves' nanochips, you" : "You"] [skills_space] start to lift [target] onto your back[carrydelay == 40 ? ", while assisted by the nanochips in your gloves.." : "..."]")
//(Using your gloves' nanochips, you/You) (/quickly/expertly) start to lift Grey Tider onto your back(, while assisted by the nanochips in your gloves../...)
- if(do_after(src, carrydelay, TRUE, target))
+ if(do_after(src, carrydelay, target))
//Second check to make sure they're still valid to be carried
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE) && !target.buckled)
buckle_mob(target, TRUE, TRUE, 90, 1, 0)
@@ -1175,7 +1177,7 @@
//Joe Medic starts quickly/expertly scooping Grey Tider into their arms..
"[carrydelay < 11 ? "Using your gloves' nanochips, you" : "You"] [skills_space] start to scoop [target] into your arms[carrydelay == 15 ? ", while assisted by the nanochips in your gloves.." : "..."]")
//(Using your gloves' nanochips, you/You) ( /quickly/expertly) start to scoop Grey Tider into your arms(, while assisted by the nanochips in your gloves../...)
- if(do_after(src, carrydelay, TRUE, target))
+ if(do_after(src, carrydelay, target))
//Second check to make sure they're still valid to be carried
if(!incapacitated(FALSE, TRUE) && !target.buckled)
buckle_mob(target, TRUE, TRUE, 90, 1, 0)
@@ -1258,6 +1260,23 @@
return FALSE
return ..()
+/mob/living/carbon/human/CtrlShiftClick(mob/user)
+ . = ..()
+ if(isobserver(user) || !user.mind?.guestbook)
+ return
+ INVOKE_ASYNC(user.mind.guestbook, TYPE_PROC_REF(/datum/guestbook, try_add_guest), user, src, FALSE)
+
+/mob/living/carbon/human/get_screentip_name(client/hovering_client)
+ . = ..()
+ var/mob/hovering_mob = hovering_client?.mob
+ if(!hovering_mob?.mind?.guestbook)
+ return .
+ var/face_name = get_face_name("")
+ var/known_name = hovering_mob.mind.guestbook.get_known_name(hovering_mob, src, face_name)
+ if(known_name)
+ return known_name
+ return .
+
/mob/living/carbon/human/species
var/race = null
@@ -1275,7 +1294,7 @@
race = /datum/species/dullahan
/mob/living/carbon/human/species/ethereal
- race = /datum/species/ethereal
+ race = /datum/species/elzuose
/mob/living/carbon/human/species/fly
race = /datum/species/fly
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 123ecf6d4fba..64dfdfde91ce 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -284,30 +284,30 @@
return TRUE
apply_damage(damage, BRUTE, affecting, armor_block)
- if(M.a_intent == INTENT_DISARM) //Always drop item in hand on first go. If no item exists, try to shove them back. If you share the tile with the target, slam them directly into the ground to stun them and slightly damage them.
- var/obj/item/I = get_active_held_item()
- if(I && dropItemToGround(I))
- playsound(loc, 'sound/weapons/slash.ogg', 25, TRUE, -1)
- visible_message("[M] disarms [src]!", \
- "[M] disarms you!", "You hear aggressive shuffling!", null, M)
- to_chat(M, "You disarm [src]!")
- else if(get_dist(src, M) != 0)
- playsound(loc, 'sound/weapons/pierce.ogg', 25, TRUE, -1)
- var/shovetarget = get_edge_target_turf(M, get_dir(M, get_step_away(src, M)))
- Knockdown(0.3 SECONDS)
- throw_at(shovetarget, 4, 2, M, force = MOVE_FORCE_OVERPOWERING)
- log_combat(M, src, "shoved")
- visible_message("[M] tackles [src] down!", \
- "[M] shoves you with great force!", "You hear aggressive shuffling followed by a loud thud!", null, M)
- to_chat(M, "You shove [src] with great force!")
- else
- Paralyze(3 SECONDS)
- adjustBruteLoss(5)
- playsound(loc, 'sound/weapons/punch3.ogg', 25, TRUE, -1)
- visible_message("[M] slams [src] into the floor!", \
- "[M] slams you into the ground!", "You hear something slam loudly onto the floor!", null, M)
- to_chat(M, "You slam [src] into the floor beneath you!")
- log_combat(M, src, "slammed into the ground")
+ if(M.a_intent == INTENT_DISARM) //Always drop item in hand on first go. If no item exists, try to shove them back. If you share the tile with the target, slam them directly into the ground to stun them and slightly damage them.
+ var/obj/item/I = get_active_held_item()
+ if(I && dropItemToGround(I) && prob(50))
+ playsound(loc, 'sound/weapons/slash.ogg', 25, TRUE, -1)
+ visible_message("[M] disarms [src]!", \
+ "[M] disarms you!", "You hear aggressive shuffling!", null, M)
+ to_chat(M, "You disarm [src]!")
+ else if(get_dist(src, M) != 0)
+ playsound(loc, 'sound/weapons/pierce.ogg', 25, TRUE, -1)
+ var/shovetarget = get_edge_target_turf(M, get_dir(M, get_step_away(src, M)))
+ Knockdown(0.3 SECONDS)
+ throw_at(shovetarget, 4, 2, M, force = MOVE_FORCE_OVERPOWERING)
+ log_combat(M, src, "shoved")
+ visible_message("[M] tackles [src] down!", \
+ "[M] shoves you with great force!", "You hear aggressive shuffling followed by a loud thud!", null, M)
+ to_chat(M, "You shove [src] with great force!")
+ else
+ Paralyze(1 SECONDS)
+ adjustBruteLoss(5)
+ playsound(loc, 'sound/weapons/punch3.ogg', 25, TRUE, -1)
+ visible_message("[M] slams [src] into the floor!", \
+ "[M] slams you into the ground!", "You hear something slam loudly onto the floor!", null, M)
+ to_chat(M, "You slam [src] into the floor beneath you!")
+ log_combat(M, src, "slammed into the ground")
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
@@ -485,6 +485,9 @@
///Calculates the siemens coeff based on clothing and species, can also restart hearts.
/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
+ //If it doesnt have physiology its prob still initializing.
+ if(!physiology)
+ return
//Calculates the siemens coeff based on clothing. Completely ignores the arguments
if(flags & SHOCK_TESLA) //I hate this entire block. This gets the siemens_coeff for tesla shocks
if(gloves && gloves.siemens_coefficient <= 0)
@@ -498,6 +501,10 @@
else if(!(flags & SHOCK_NOGLOVES)) //This gets the siemens_coeff for all non tesla shocks
if(gloves)
siemens_coeff *= gloves.siemens_coefficient
+ //If it doesnt have physiology its prob still initializing.
+ if(!physiology)
+ . = ..()
+ return
siemens_coeff *= physiology.siemens_coeff
siemens_coeff *= dna.species.siemens_coeff
. = ..()
@@ -776,10 +783,10 @@
combined_msg += "\t There is \a [I] embedded in your [LB.name]!"
for(var/t in missing)
- combined_msg += "Your [parse_zone(t)] is missing!"
+ combined_msg += span_boldannounce("Your [parse_zone(t)] is missing!")
- if(bleed_rate)
- combined_msg += "You are bleeding!"
+ for(var/obj/item/bodypart/BP in get_bleeding_parts(TRUE))
+ combined_msg += span_danger("Your [parse_zone(BP.body_zone)] is bleeding!")
if(getStaminaLoss())
if(getStaminaLoss() > 30)
combined_msg += "You're completely exhausted."
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 5b638d330690..567523c11d79 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -54,15 +54,15 @@
var/obj/item/clothing/wear_suit = null
var/obj/item/clothing/w_uniform = null
var/obj/item/belt = null
- var/obj/item/wear_id = null
var/obj/item/r_store = null
var/obj/item/l_store = null
var/obj/item/s_store = null
var/special_voice = "" // For changing our voice. Used by a symptom.
- var/bleed_rate = 0 //how much are we bleeding
- var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
+ /// Adjective used in get_generic_name(), if any
+ var/generic_adjective
+ var/bleedsuppress = 0 //for stopping bloodloss body-wide
var/name_override //For temporary visible name changes
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 2f9814112711..9e2cfe4f1556 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -31,28 +31,19 @@
return pda.owner
return if_no_id
-//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a separate proc as it'll be useful elsewhere
/mob/living/carbon/human/get_visible_name()
- var/face_name = get_face_name("")
- var/id_name = get_id_name("")
if(name_override)
return name_override
- if(face_name)
- if(id_name && (id_name != face_name))
- return "[face_name] (as [id_name])"
- return face_name
- if(id_name)
- return id_name
- return "Unknown"
+ return get_generic_name(TRUE, lowercase = TRUE)
//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when Fluacided or when updating a human's name variable
-/mob/living/carbon/human/proc/get_face_name(if_no_face="Unknown")
- if(wear_mask && (wear_mask.flags_inv&HIDEFACE)) //Wearing a mask which hides our face, use id-name if possible
+/mob/living/carbon/human/proc/get_face_name(if_no_face = get_generic_name(lowercase = TRUE))
+ if(wear_mask && (wear_mask.flags_inv & HIDEFACE)) //Wearing a mask which hides our face, use id-name if possible
return if_no_face
- if(head && (head.flags_inv&HIDEFACE))
- return if_no_face //Likewise for hats
+ if(head && (head.flags_inv & HIDEFACE))
+ return if_no_face //Likewise for hats
var/obj/item/bodypart/O = get_bodypart(BODY_ZONE_HEAD)
- if(!O || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name) //disfigured. use id-name if possible
+ if(!O || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name) //disfigured. use id-name if possible
return if_no_face
return real_name
@@ -110,6 +101,22 @@
if(id_card)
return id_card
+/mob/living/carbon/human/get_bankcard()
+ //Check hands
+ var/list/items_to_check = list()
+ if(get_active_held_item())
+ items_to_check += get_active_held_item()
+ if(get_inactive_held_item())
+ items_to_check += get_inactive_held_item()
+ if(wear_id)
+ items_to_check += wear_id
+ if(belt)
+ items_to_check += belt
+ for(var/obj/item/i in items_to_check)
+ var/obj/item/card/bank/bank_card = i.GetBankCard()
+ if(bank_card)
+ return bank_card
+
/mob/living/carbon/human/get_id_in_hand()
var/obj/item/held_item = get_active_held_item()
if(!held_item)
@@ -146,10 +153,10 @@
to_chat(src, "You can't bring yourself to use a ranged weapon!")
return FALSE
-/mob/living/carbon/human/proc/get_bank_account()
+/mob/living/carbon/proc/get_bank_account()
RETURN_TYPE(/datum/bank_account)
var/datum/bank_account/account
- var/obj/item/card/id/I = get_idcard()
+ var/obj/item/card/bank/I = get_bankcard()
if(I && I.registered_account)
account = I.registered_account
@@ -181,3 +188,61 @@
destination.socks = socks
destination.socks_color = socks_color
destination.jumpsuit_style = jumpsuit_style
+
+/mob/living/carbon/human/proc/get_age()
+ var/obscured = check_obscured_slots()
+ var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
+ if((obscured & ITEM_SLOT_ICLOTHING) && skipface || isipc(src))
+ return FALSE
+ switch(age)
+ if(70 to INFINITY)
+ return "Geriatric"
+ if(60 to 70)
+ return "Elderly"
+ if(50 to 60)
+ return "Old"
+ if(40 to 50)
+ return "Middle-Aged"
+ if(24 to 40)
+ return FALSE //not necessary because this is basically the most common age range
+ if(18 to 24)
+ return "Young"
+ else
+ return "Puzzling"
+
+/mob/living/carbon/human/proc/get_generic_name(prefixed = FALSE, lowercase = FALSE)
+ var/final_string = ""
+ var/obscured = check_obscured_slots()
+ var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
+ var/hide_features = (obscured & ITEM_SLOT_ICLOTHING) && skipface
+
+ if(generic_adjective && !hide_features)
+ final_string += "[generic_adjective] "
+
+ var/visible_age = get_age()
+ if(visible_age)
+ final_string += "[visible_age] "
+
+ final_string += "[dna.species.name] "
+
+ final_string += get_gender()
+
+ if(prefixed)
+ final_string = "\A [final_string]"
+
+ if(lowercase)
+ final_string = lowertext(final_string)
+ return final_string
+
+/mob/living/carbon/human/proc/get_gender()
+ var/visible_gender = p_they()
+ switch(visible_gender)
+ if("he")
+ visible_gender = "Man"
+ if("she")
+ visible_gender = "Woman"
+ if("they")
+ visible_gender = "Person"
+ else
+ visible_gender = "Thing"
+ return visible_gender
diff --git a/code/modules/mob/living/carbon/human/human_say.dm b/code/modules/mob/living/carbon/human/human_say.dm
index 039141bb5fd5..6b0c1ff1c768 100644
--- a/code/modules/mob/living/carbon/human/human_say.dm
+++ b/code/modules/mob/living/carbon/human/human_say.dm
@@ -7,16 +7,14 @@
else
. = ..()
-/mob/living/carbon/human/GetVoice()
+/mob/living/carbon/human/GetVoice(if_no_voice = get_generic_name())
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
- var/obj/item/clothing/mask/chameleon/V = wear_mask
- if(V.voice_change && wear_id)
+ var/obj/item/clothing/mask/chameleon/chameleon_mask = wear_mask
+ if(chameleon_mask.voice_change && wear_id)
var/obj/item/card/id/idcard = wear_id.GetID()
if(istype(idcard))
return idcard.registered_name
- else
- return real_name
- if(istype(wear_mask, /obj/item/clothing/mask/gas/syndicate/voicechanger))
+ else if(istype(wear_mask, /obj/item/clothing/mask/gas/syndicate/voicechanger))
var/obj/item/clothing/mask/gas/syndicate/voicechanger/V = wear_mask
if(V.voice_change && wear_id)
var/obj/item/card/id/idcard = wear_id.GetID()
@@ -26,18 +24,17 @@
return real_name
else
return real_name
- if(istype(wear_mask, /obj/item/clothing/mask/infiltrator))
- var/obj/item/clothing/mask/infiltrator/V = wear_mask
- if(V.voice_unknown)
- return ("Unknown")
- else
- return real_name
+ else if(istype(wear_mask, /obj/item/clothing/mask/infiltrator))
+ var/obj/item/clothing/mask/infiltrator/infiltrator_mask = wear_mask
+ if(infiltrator_mask.voice_unknown)
+ return if_no_voice
if(mind)
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling && changeling.mimicing)
return changeling.mimicing
- if(GetSpecialVoice())
- return GetSpecialVoice()
+ var/special_voice = GetSpecialVoice()
+ if(special_voice)
+ return special_voice
return real_name
/mob/living/carbon/human/IsVocal()
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index eda9c8c3db64..e2a01d29540c 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -688,16 +688,27 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES)
var/mutable_appearance/eye_overlay
var/mutable_appearance/sclera_overlay
+
if(eyes)
if(!HAS_TRAIT(H, TRAIT_EYESCLOSED) && !(H.stat == DEAD))
- eye_overlay = mutable_appearance(species_eye_path || 'icons/mob/human_face.dmi', eyes.eye_icon_state, -BODYPARTS_LAYER)
- sclera_overlay = mutable_appearance('icons/mob/human_face.dmi', eyes.sclera_icon_state, -BODYPARTS_LAYER)
+
+ if(iskepori(H)) // Kepori need sclera but don't fit the normal silhouette, so this needs changing. Make better later.
+ eye_overlay = mutable_appearance('icons/mob/species/kepori/kepori_eyes.dmi', eyes.eye_icon_state, -BODYPARTS_LAYER)
+ sclera_overlay = mutable_appearance('icons/mob/species/kepori/kepori_eyes.dmi', eyes.sclera_icon_state, -BODYPARTS_LAYER)
+
+ else
+ eye_overlay = mutable_appearance(species_eye_path || 'icons/mob/human_face.dmi', eyes.eye_icon_state, -BODYPARTS_LAYER)
+ sclera_overlay = mutable_appearance('icons/mob/human_face.dmi', eyes.sclera_icon_state, -BODYPARTS_LAYER)
+
if((EYECOLOR in species_traits) && eyes)
eye_overlay.color = "#" + H.eye_color
+
if((SCLERA in species_traits) && eyes)
sclera_overlay.color = "#" + H.sclera_color
standing += sclera_overlay
+
standing += eye_overlay
+
if(EMOTE_OVERLAY in species_traits)
// blush
if (HAS_TRAIT(H, TRAIT_BLUSHING)) // Caused by either the *blush emote or the "drunk" mood event
@@ -859,9 +870,9 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(H.dna.species.bodytype & BODYTYPE_DIGITIGRADE)
var/uniform_compatible = FALSE
var/suit_compatible = FALSE
- if(!(H.w_uniform) || (H.w_uniform.supports_variations & DIGITIGRADE_VARIATION) || (H.w_uniform.supports_variations & DIGITIGRADE_VARIATION_NO_NEW_ICON)) //Checks uniform compatibility
+ if(!(H.w_uniform) || (H.w_uniform.supports_variations & DIGITIGRADE_VARIATION) || (H.w_uniform.supports_variations & DIGITIGRADE_VARIATION_NO_NEW_ICON) || (H.w_uniform.supports_variations & DIGITIGRADE_VARIATION_SAME_ICON_FILE)) //Checks uniform compatibility
uniform_compatible = TRUE
- if((!H.wear_suit) || (H.wear_suit.supports_variations & DIGITIGRADE_VARIATION) || !(H.wear_suit.body_parts_covered & LEGS) || (H.wear_suit.supports_variations & DIGITIGRADE_VARIATION_NO_NEW_ICON)) //Checks suit compatability
+ if((!H.wear_suit) || (H.wear_suit.supports_variations & DIGITIGRADE_VARIATION) || !(H.wear_suit.body_parts_covered & LEGS) || (H.wear_suit.supports_variations & DIGITIGRADE_VARIATION_NO_NEW_ICON) || (H.wear_suit.supports_variations & DIGITIGRADE_VARIATION_SAME_ICON_FILE)) //Checks suit compatability
suit_compatible = TRUE
var/show_digitigrade = suit_compatible && (uniform_compatible || H.wear_suit?.flags_inv & HIDEJUMPSUIT) //If the uniform is hidden, it doesnt matter if its compatible
@@ -939,6 +950,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
S = GLOB.spider_spinneret_list[H.dna.features["spider_spinneret"]]
if("kepori_body_feathers")
S = GLOB.kepori_body_feathers_list[H.dna.features["kepori_body_feathers"]]
+ if("kepori_head_feathers")
+ S = GLOB.kepori_head_feathers_list[H.dna.features["kepori_head_feathers"]]
if("kepori_tail_feathers")
S = GLOB.kepori_tail_feathers_list[H.dna.features["kepori_tail_feathers"]]
if("kepori_feathers")
@@ -1166,7 +1179,9 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_ID)
- if(H.wear_id && !swap)
+ if(H.wear_id)
+ if(SEND_SIGNAL(H.wear_id, COMSIG_TRY_STORAGE_CAN_INSERT, I, H, TRUE))
+ return TRUE
return FALSE
var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST)
@@ -1289,9 +1304,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/get_spans()
return list()
-/datum/species/proc/check_species_weakness(obj/item, mob/living/attacker)
- return 0 //This is not a boolean, it's the multiplier for the damage that the user takes from the item.It is added onto the check_weakness value of the mob, and then the force of the item is multiplied by this value
-
/**
* Equip the outfit required for life. Replaces items currently worn.
*/
@@ -1359,9 +1371,9 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
if(hungry >= 70)
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (hungry / 50))
- else if(isethereal(H))
- var/datum/species/ethereal/E = H.dna.species
- if(E.get_charge(H) <= ETHEREAL_CHARGE_NORMAL)
+ else if(iselzuose(H))
+ var/datum/species/elzuose/E = H.dna.species
+ if(E.get_charge(H) <= ELZUOSE_CHARGE_NORMAL)
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (1.5 * (1 - E.get_charge(H) / 100)))
else
H.remove_movespeed_modifier(/datum/movespeed_modifier/hunger)
@@ -1448,7 +1460,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
user.visible_message("[user] starts stealing [target]'s [I.name]!",
"You start stealing [target]'s [I.name]...", null, null, target)
to_chat(target, "[user] starts stealing your [I.name]!")
- if(do_after(user, I.strip_delay, TRUE, target, TRUE))
+ if(do_after(user, I.strip_delay, target))
target.dropItemToGround(I, TRUE)
user.put_in_hands(I)
user.visible_message("[user] stole [target]'s [I.name]!",
@@ -1608,8 +1620,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/armor_block = H.run_armor_check(affecting, "melee", I.armour_penetration, FALSE, "Your armor has protected your [hit_area]!", "Your armor has softened a hit to your [hit_area]!")
armor_block = min(90,armor_block) //cap damage reduction at 90%
- var/weakness = H.check_weakness(I, user)
- apply_damage(I.force * weakness, I.damtype, def_zone, armor_block, H)
+ apply_damage(I.force, I.damtype, def_zone, armor_block, H, sharpness = I.get_sharpness())
H.send_item_attack_message(I, user, hit_area)
@@ -1678,7 +1689,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return TRUE
-/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, break_modifier = 1)
+/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, break_modifier = 1, sharpness = FALSE)
SEND_SIGNAL(H, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
var/hit_percent = (100-(blocked+armor))/100
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
@@ -1701,7 +1712,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.damageoverlaytemp = 20
var/damage_amount = forced ? damage : damage * hit_percent * brutemod * H.physiology.brute_mod
if(BP)
- if(BP.receive_damage(damage_amount, 0, break_modifier = break_modifier))
+ if(BP.receive_damage(damage_amount, 0, break_modifier = break_modifier, sharpness = sharpness))
H.update_damage_overlays()
else//no bodypart, we deal damage with a more general method.
H.adjustBruteLoss(damage_amount)
@@ -1711,7 +1722,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.damageoverlaytemp = 20
var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod
if(BP)
- if(BP.receive_damage(0, damage_amount, break_modifier = break_modifier))
+ if(BP.receive_damage(0, damage_amount, break_modifier = break_modifier, sharpness = sharpness))
H.update_damage_overlays()
else
H.adjustFireLoss(damage_amount)
diff --git a/code/modules/mob/living/carbon/human/species_types/IPC.dm b/code/modules/mob/living/carbon/human/species_types/IPC.dm
index 381708757fd1..9410111c9e4f 100644
--- a/code/modules/mob/living/carbon/human/species_types/IPC.dm
+++ b/code/modules/mob/living/carbon/human/species_types/IPC.dm
@@ -1,5 +1,5 @@
/datum/species/ipc // im fucking lazy mk2 and cant get sprites to normally work
- name = "\improper Integrated Positronic Chassis" //inherited from the real species, for health scanners and things
+ name = "\improper Positronic" //inherited from the real species, for health scanners and things
id = SPECIES_IPC
sexes = FALSE
species_age_min = 0
@@ -133,7 +133,7 @@
icon_state = "wire1"
/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
- if((!istype(target, /obj/machinery/power/apc) && !isethereal(target)) || !ishuman(user) || !proximity_flag)
+ if((!istype(target, /obj/machinery/power/apc) && !iselzuose(target)) || !ishuman(user) || !proximity_flag)
return ..()
user.changeNext_move(CLICK_CD_MELEE)
var/mob/living/carbon/human/H = user
@@ -155,7 +155,7 @@
to_chat(user, "There is not enough charge to draw from that APC.")
return
- if(isethereal(target))
+ if(iselzuose(target))
var/mob/living/carbon/human/target_ethereal = target
var/obj/item/organ/stomach/ethereal/eth_stomach = target_ethereal.getorganslot(ORGAN_SLOT_STOMACH)
if(target_ethereal.nutrition > 0 && eth_stomach)
@@ -207,7 +207,7 @@
if(A.crystal_charge == 0)
to_chat(H, "[A] is completely drained!")
break
- siphon_amt = A.crystal_charge <= (2 * ETHEREAL_CHARGE_SCALING_MULTIPLIER) ? A.crystal_charge : (2 * ETHEREAL_CHARGE_SCALING_MULTIPLIER)
+ siphon_amt = A.crystal_charge <= (2 * ELZUOSE_CHARGE_SCALING_MULTIPLIER) ? A.crystal_charge : (2 * ELZUOSE_CHARGE_SCALING_MULTIPLIER)
A.adjust_charge(-1 * siphon_amt)
H.nutrition += (siphon_amt)
if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
@@ -273,7 +273,11 @@
if(chassis_of_choice.is_digi)
if(istype(BP,/obj/item/bodypart/leg))
- BP.bodytype = BODYTYPE_HUMANOID | BODYTYPE_ROBOTIC | BODYTYPE_DIGITIGRADE //i hate this so much
+ BP.bodytype |= BODYTYPE_DIGITIGRADE //i hate this so much
+
+ if(chassis_of_choice.has_snout)
+ if(istype(BP,/obj/item/bodypart/head))
+ BP.bodytype |= BODYTYPE_SNOUT //hate. hate. (tik tok tts)
if(BP.uses_mutcolor)
BP.should_draw_greyscale = TRUE
diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm
index a2ff92508d61..27362b348cab 100644
--- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm
+++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm
@@ -1,8 +1,12 @@
-#define ETHEREAL_EMAG_COLORS list("#00ffff", "#ffc0cb", "#9400D3", "#4B0082", "#0000FF", "#00FF00", "#FFFF00", "#FF7F00", "#FF0000")
+#define ELZUOSE_EMAG_COLORS list("#00ffff", "#ffc0cb", "#9400D3", "#4B0082", "#0000FF", "#00FF00", "#FFFF00", "#FF7F00", "#FF0000")
+#define GOOD_SOIL list(/turf/open/floor/plating/grass, /turf/open/floor/plating/dirt, /turf/open/floor/ship/dirt, /turf/open/floor/grass/ship, /turf/open/floor/plating/asteroid/whitesands/grass, /turf/open/floor/grass/fairy/beach)
+#define DIG_TIME (7.5 SECONDS)
+#define ROOT_TIME (3 SECONDS)
+#define ROOT_CHARGE_GAIN (5 * ELZUOSE_CHARGE_SCALING_MULTIPLIER)
-/datum/species/ethereal
+/datum/species/elzuose
name = "\improper Elzuose"
- id = SPECIES_ETHEREAL
+ id = SPECIES_ELZUOSE
attack_verb = "burn"
attack_sound = 'sound/weapons/etherealhit.ogg'
miss_sound = 'sound/weapons/etherealmiss.ogg'
@@ -14,6 +18,7 @@
attack_type = BURN //burn bish
exotic_bloodtype = "E"
damage_overlay_type = "" //We are too cool for regular damage overlays
+ species_age_max = 300
species_traits = list(DYNCOLORS, EYECOLOR, HAIR, FACEHAIR)
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
species_language_holder = /datum/language_holder/ethereal
@@ -41,41 +46,121 @@
var/current_color
var/EMPeffect = FALSE
- var/emag_effect = FALSE
var/static/unhealthy_color = rgb(237, 164, 149)
loreblurb = "Elzuosa are an uncommon and unusual species best described as crystalline, electrically-powered plantpeople. They hail from the warm planet Kalixcis, where they evolved alongside the Sarathi. Kalixcian culture places no importance on blood-bonds, and those from it tend to consider their family anyone they are sufficiently close to, and choose their own names."
var/drain_time = 0 //used to keep ethereals from spam draining power sources
var/obj/effect/dummy/lighting_obj/ethereal_light
+ var/datum/action/innate/root/rooting
-/datum/species/ethereal/Destroy(force)
+/datum/species/elzuose/Destroy(force)
if(ethereal_light)
QDEL_NULL(ethereal_light)
return ..()
-/datum/species/ethereal/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
+/datum/species/elzuose/on_species_gain(mob/living/carbon/_carbon, datum/species/old_species, pref_load)
. = ..()
- if(!ishuman(C))
+ if(!ishuman(_carbon))
return
- var/mob/living/carbon/human/ethereal = C
+ var/mob/living/carbon/human/ethereal = _carbon
default_color = "#[ethereal.dna.features["ethcolor"]]"
- RegisterSignal(ethereal, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag_act))
RegisterSignal(ethereal, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act))
ethereal_light = ethereal.mob_light()
spec_updatehealth(ethereal)
+ rooting = new
+ rooting.Grant(_carbon)
+ RegisterSignal(ethereal, COMSIG_DIGOUT, PROC_REF(digout))
+ RegisterSignal(ethereal, COMSIG_MOVABLE_MOVED, PROC_REF(uproot))
//The following code is literally only to make admin-spawned ethereals not be black.
- C.dna.features["mcolor"] = C.dna.features["ethcolor"] //Ethcolor and Mut color are both dogshit and will be replaced
- for(var/obj/item/bodypart/BP as anything in C.bodyparts)
- if(BP.limb_id == SPECIES_ETHEREAL)
+ _carbon.dna.features["mcolor"] = _carbon.dna.features["ethcolor"] //Ethcolor and Mut color are both dogshit and will be replaced
+ for(var/obj/item/bodypart/BP as anything in _carbon.bodyparts)
+ if(BP.limb_id == SPECIES_ELZUOSE)
BP.update_limb(is_creating = TRUE)
-/datum/species/ethereal/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
- UnregisterSignal(C, COMSIG_ATOM_EMAG_ACT)
- UnregisterSignal(C, COMSIG_ATOM_EMP_ACT)
+/datum/species/elzuose/on_species_loss(mob/living/carbon/human/_carbon, datum/species/new_species, pref_load)
+ UnregisterSignal(_carbon, COMSIG_ATOM_EMP_ACT)
+ UnregisterSignal(_carbon, COMSIG_DIGOUT)
+ UnregisterSignal(_carbon, COMSIG_MOVABLE_MOVED)
QDEL_NULL(ethereal_light)
+ if(rooting)
+ rooting.Remove(_carbon)
return ..()
-/datum/species/ethereal/random_name(gender,unique,lastname)
+/datum/action/innate/root
+ name = "Root"
+ desc = "Root into good soil to gain charge."
+ check_flags = AB_CHECK_CONSCIOUS
+ button_icon_state = "plant-22"
+ icon_icon = 'icons/obj/flora/plants.dmi'
+ background_icon_state = "bg_alien"
+
+/datum/action/innate/root/Activate()
+ var/mob/living/carbon/human/_human = owner
+ var/datum/species/elzuose/_elzu = _human.dna.species
+ // this is healthy for elzu, they shouldnt be able to overcharge and get heart attacks from this
+ var/obj/item/organ/stomach/ethereal/stomach = _human.getorganslot(ORGAN_SLOT_STOMACH)
+
+ if(_human.wear_suit && istype(_human.wear_suit, /obj/item/clothing))
+ var/obj/item/clothing/CS = _human.wear_suit
+ if (CS.clothing_flags & THICKMATERIAL)
+ to_chat(_human, span_warning("Your [CS.name] is too thick to root in!"))
+ return
+
+ if(stomach.crystal_charge > ELZUOSE_CHARGE_FULL)
+ to_chat(_human,span_warning("Your charge is full!"))
+ return
+ _elzu.drain_time = world.time + ROOT_TIME
+ _human.visible_message(span_notice("[_human] is digging into the ground"),span_warning("You start to dig yourself into the ground to root. You won't won't be able to move once you start the process."),span_notice("You hear digging."))
+ if(!do_after(_human,DIG_TIME, target = _human))
+ to_chat(_human,span_warning("You were interupted!"))
+ return
+ _human.apply_status_effect(/datum/status_effect/rooted)
+ to_chat(_human, span_notice("You root into the ground and begin to feed."))
+
+ while(do_after(_human, ROOT_TIME, target = _human))
+ if(istype(stomach))
+ to_chat(_human, span_notice("You receive some charge from rooting."))
+ stomach.adjust_charge(ROOT_CHARGE_GAIN)
+ _human.adjustBruteLoss(-3)
+ _human.adjustFireLoss(-3)
+
+ if(stomach.crystal_charge > ELZUOSE_CHARGE_FULL)
+ stomach.crystal_charge = ELZUOSE_CHARGE_FULL
+ to_chat(_human, span_notice("You're full on charge!"))
+ break
+
+ else
+ to_chat(_human,span_warning("You're missing your biological battery and can't recieve charge from rooting!"))
+ break
+
+/datum/species/elzuose/proc/digout(mob/living/carbon/human/_human)
+ if(do_after(_human, DIG_TIME,target = _human))
+ to_chat(_human,span_notice("You finish digging yourself out."))
+ _human.remove_status_effect(/datum/status_effect/rooted)
+ return
+
+/datum/species/elzuose/proc/uproot(mob/living/carbon/human/_human)
+ //You got moved and uprooted, time to suffer the consequences.
+ if(_human.has_status_effect(/datum/status_effect/rooted))
+ _human.visible_message(span_warning("[_human] is forcefully uprooted. That looked like it hurt."),span_warning("You're forcefully unrooted! Ouch!"),span_warning("You hear someone scream in pain."))
+ _human.apply_damage(8,BRUTE,BODY_ZONE_CHEST)
+ _human.apply_damage(8,BRUTE,BODY_ZONE_L_LEG)
+ _human.apply_damage(8,BRUTE,BODY_ZONE_R_LEG)
+ _human.emote("scream")
+ _human.remove_status_effect(/datum/status_effect/rooted)
+ return
+
+/datum/action/innate/root/IsAvailable()
+ if(..())
+ var/mob/living/carbon/human/_human = owner
+ var/turf/terrain = get_turf(_human)
+ if(_human.has_status_effect(/datum/status_effect/rooted))
+ return FALSE
+ if(is_type_in_list(terrain,GOOD_SOIL))
+ return TRUE
+ return FALSE
+
+/datum/species/elzuose/random_name(gender,unique,lastname)
if(unique)
return random_unique_lizard_name(gender)
@@ -86,30 +171,29 @@
return randname
-/datum/species/ethereal/spec_updatehealth(mob/living/carbon/human/H)
+/datum/species/elzuose/spec_updatehealth(mob/living/carbon/human/_human)
. = ..()
if(!ethereal_light)
return
- if(H.stat != DEAD && !EMPeffect)
- if(!emag_effect)
- current_color = health_adjusted_color(H, default_color)
- set_ethereal_light(H, current_color)
+ if(_human.stat != DEAD && !EMPeffect)
+ current_color = health_adjusted_color(_human, default_color)
+ set_ethereal_light(_human, current_color)
ethereal_light.set_light_on(TRUE)
fixed_mut_color = copytext_char(current_color, 2)
else
ethereal_light.set_light_on(FALSE)
fixed_mut_color = rgb(128,128,128)
- for(var/obj/item/bodypart/parts_to_update as anything in H.bodyparts)
+ for(var/obj/item/bodypart/parts_to_update as anything in _human.bodyparts)
parts_to_update.species_color = fixed_mut_color
parts_to_update.update_limb()
- H.update_body()
- H.update_hair()
+ _human.update_body()
+ _human.update_hair()
-/datum/species/ethereal/proc/health_adjusted_color(mob/living/carbon/human/H, default_color)
- var/health_percent = max(H.health, 0) / 100
+/datum/species/elzuose/proc/health_adjusted_color(mob/living/carbon/human/_human, default_color)
+ var/health_percent = max(_human.health, 0) / 100
var/static/unhealthy_color_red_part = GETREDPART(unhealthy_color)
var/static/unhealthy_color_green_part = GETGREENPART(unhealthy_color)
@@ -126,141 +210,87 @@
)
return result
-/datum/species/ethereal/proc/set_ethereal_light(mob/living/carbon/human/H, current_color)
+/datum/species/elzuose/proc/set_ethereal_light(mob/living/carbon/human/_human, current_color)
if(!ethereal_light)
return
- var/health_percent = max(H.health, 0) / 100
+ var/health_percent = max(_human.health, 0) / 100
var/light_range = 1 + (1 * health_percent)
var/light_power = 1 + round(0.5 * health_percent)
ethereal_light.set_light_range_power_color(light_range, light_power, current_color)
-/datum/species/ethereal/proc/on_emp_act(mob/living/carbon/human/H, severity)
+/datum/species/elzuose/proc/on_emp_act(mob/living/carbon/human/_human, severity)
EMPeffect = TRUE
- spec_updatehealth(H)
- to_chat(H, "You feel the light of your body leave you.")
+ spec_updatehealth(_human)
+ to_chat(_human, span_notice("You feel the light of your body leave you."))
switch(severity)
if(EMP_LIGHT)
- addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 10 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 seconds
+ addtimer(CALLBACK(src, PROC_REF(stop_emp), _human), 10 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 seconds
if(EMP_HEAVY)
- addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds
+ addtimer(CALLBACK(src, PROC_REF(stop_emp), _human), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds
-/datum/species/ethereal/proc/on_emag_act(mob/living/carbon/human/H, mob/user)
- if(emag_effect)
- return
- emag_effect = TRUE
- if(user)
- to_chat(user, "You tap [H] on the back with your card.")
- H.visible_message("[H] starts flickering in an array of colors!")
- handle_emag(H)
- addtimer(CALLBACK(src, PROC_REF(stop_emag), H), 30 SECONDS) //Disco mode for 30 seconds! This doesn't affect the ethereal at all besides either annoying some players, or making someone look badass.
-
-/datum/species/ethereal/spec_life(mob/living/carbon/human/H)
+/datum/species/elzuose/spec_life(mob/living/carbon/human/_human)
.=..()
- handle_charge(H)
+ handle_charge(_human)
-/datum/species/ethereal/proc/stop_emp(mob/living/carbon/human/H)
+/datum/species/elzuose/proc/stop_emp(mob/living/carbon/human/_human)
EMPeffect = FALSE
- spec_updatehealth(H)
- to_chat(H, "You feel more energized as your shine comes back.")
-
-/datum/species/ethereal/proc/handle_emag(mob/living/carbon/human/H)
- if(!emag_effect)
- return
- current_color = pick(ETHEREAL_EMAG_COLORS)
- spec_updatehealth(H)
- addtimer(CALLBACK(src, PROC_REF(handle_emag), H), 5) //Call ourselves every 0.5 seconds to change color
-
-/datum/species/ethereal/proc/stop_emag(mob/living/carbon/human/H)
- emag_effect = FALSE
- spec_updatehealth(H)
- H.visible_message("[H] stops flickering and goes back to their normal state!")
+ spec_updatehealth(_human)
+ to_chat(_human, span_notice("You feel more energized as your shine comes back."))
-/datum/species/ethereal/proc/handle_charge(mob/living/carbon/human/H)
+/datum/species/elzuose/proc/handle_charge(mob/living/carbon/human/_human)
brutemod = 1.25
- switch(get_charge(H))
- if(ETHEREAL_CHARGE_NONE to ETHEREAL_CHARGE_LOWPOWER)
- if(get_charge(H) == ETHEREAL_CHARGE_NONE)
- H.throw_alert("ethereal_charge", /atom/movable/screen/alert/etherealcharge, 3)
+ switch(get_charge(_human))
+ if(ELZUOSE_CHARGE_NONE to ELZUOSE_CHARGE_LOWPOWER)
+ if(get_charge(_human) == ELZUOSE_CHARGE_NONE)
+ _human.throw_alert("ELZUOSE_CHARGE", /atom/movable/screen/alert/etherealcharge, 3)
else
- H.throw_alert("ethereal_charge", /atom/movable/screen/alert/etherealcharge, 2)
- if(H.health > 10.5)
- apply_damage(0.2, TOX, null, null, H)
+ _human.throw_alert("ELZUOSE_CHARGE", /atom/movable/screen/alert/etherealcharge, 2)
+ if(_human.health > 10.5)
+ apply_damage(0.2, TOX, null, null, _human)
brutemod = 1.75
- if(ETHEREAL_CHARGE_LOWPOWER to ETHEREAL_CHARGE_NORMAL)
- H.throw_alert("ethereal_charge", /atom/movable/screen/alert/etherealcharge, 1)
+ if(ELZUOSE_CHARGE_LOWPOWER to ELZUOSE_CHARGE_NORMAL)
+ _human.throw_alert("ELZUOSE_CHARGE", /atom/movable/screen/alert/etherealcharge, 1)
brutemod = 1.5
- if(ETHEREAL_CHARGE_FULL to ETHEREAL_CHARGE_OVERLOAD)
- H.throw_alert("ethereal_overcharge", /atom/movable/screen/alert/ethereal_overcharge, 1)
+ if(ELZUOSE_CHARGE_FULL to ELZUOSE_CHARGE_OVERLOAD)
+ _human.throw_alert("ethereal_overcharge", /atom/movable/screen/alert/ethereal_overcharge, 1)
brutemod = 1.5
- if(ETHEREAL_CHARGE_OVERLOAD to ETHEREAL_CHARGE_DANGEROUS)
- H.throw_alert("ethereal_overcharge", /atom/movable/screen/alert/ethereal_overcharge, 2)
+ if(ELZUOSE_CHARGE_OVERLOAD to ELZUOSE_CHARGE_DANGEROUS)
+ _human.throw_alert("ethereal_overcharge", /atom/movable/screen/alert/ethereal_overcharge, 2)
brutemod = 1.75
if(prob(10)) //10% each tick for ethereals to explosively release excess energy if it reaches dangerous levels
- discharge_process(H)
+ discharge_process(_human)
else
- H.clear_alert("ethereal_charge")
- H.clear_alert("ethereal_overcharge")
+ _human.clear_alert("ELZUOSE_CHARGE")
+ _human.clear_alert("ethereal_overcharge")
-/datum/species/ethereal/proc/discharge_process(mob/living/carbon/human/H)
- to_chat(H, "You begin to lose control over your charge!")
- H.visible_message("[H] begins to spark violently!")
+/datum/species/elzuose/proc/discharge_process(mob/living/carbon/human/_human)
+ _human.visible_message(span_danger("[_human] begins to spark violently!"),_human,span_warning("You begin to lose control over your charge!"))
var/static/mutable_appearance/overcharge //shameless copycode from lightning spell
overcharge = overcharge || mutable_appearance('icons/effects/effects.dmi', "electricity", EFFECTS_LAYER)
- H.add_overlay(overcharge)
- if(do_mob(H, H, 50, 1))
- H.flash_lighting_fx(5, 7, current_color)
- var/obj/item/organ/stomach/ethereal/stomach = H.getorganslot(ORGAN_SLOT_STOMACH)
- playsound(H, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
- H.cut_overlay(overcharge)
- tesla_zap(H, 2, (stomach.crystal_charge / ETHEREAL_CHARGE_SCALING_MULTIPLIER) * 50, ZAP_OBJ_DAMAGE | ZAP_ALLOW_DUPLICATES)
+ _human.add_overlay(overcharge)
+ if(do_after(_human, 50, _human, TRUE))
+ _human.flash_lighting_fx(5, 7, current_color)
+ var/obj/item/organ/stomach/ethereal/stomach = _human.getorganslot(ORGAN_SLOT_STOMACH)
+ playsound(_human, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
+ _human.cut_overlay(overcharge)
+ tesla_zap(_human, 2, (stomach.crystal_charge / ELZUOSE_CHARGE_SCALING_MULTIPLIER) * 50, ZAP_OBJ_DAMAGE | ZAP_ALLOW_DUPLICATES)
if(istype(stomach))
- stomach.adjust_charge(ETHEREAL_CHARGE_FULL - stomach.crystal_charge)
- to_chat(H, "You violently discharge energy!")
- H.visible_message("[H] violently discharges energy!")
+ stomach.adjust_charge(ELZUOSE_CHARGE_FULL - stomach.crystal_charge)
+ to_chat(_human,span_warning("You violently discharge energy!"))
+ _human.visible_message(span_danger("[_human] violently discharges energy!"))
if(prob(10)) //chance of developing heart disease to dissuade overcharging oneself
var/datum/disease/D = new /datum/disease/heart_failure
- H.ForceContractDisease(D)
- to_chat(H, "You're pretty sure you just felt your heart stop for a second there..")
- H.playsound_local(H, 'sound/effects/singlebeat.ogg', 100, 0)
- H.Paralyze(100)
+ _human.ForceContractDisease(D)
+ to_chat(_human, span_userdanger("You're pretty sure you just felt your heart stop for a second there."))
+ _human.playsound_local(_human, 'sound/effects/singlebeat.ogg', 100, 0)
+ _human.Paralyze(100)
return
-/datum/species/ethereal/proc/get_charge(mob/living/carbon/H) //this feels like it should be somewhere else. Eh?
- var/obj/item/organ/stomach/ethereal/stomach = H.getorganslot(ORGAN_SLOT_STOMACH)
+/datum/species/elzuose/proc/get_charge(mob/living/carbon/_human) //this feels like it should be somewhere else. Eh?
+ var/obj/item/organ/stomach/ethereal/stomach = _human.getorganslot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
return stomach.crystal_charge
- return ETHEREAL_CHARGE_NONE
-
-/datum/species/ethereal/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
- if(istype(I, /obj/item/multitool))
- if(user.a_intent == INTENT_HARM)
- . = ..() // multitool beatdown
- return
-
- if (emag_effect == TRUE)
- to_chat(user, "The multitool can't get a lock on [H]'s EM frequency")
- return
-
- if(user != H)
- // random color change
- default_color = "#" + GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)]
- current_color = health_adjusted_color(H, default_color)
- spec_updatehealth(H)
- H.visible_message("[H]'s EM frequency is scrambled to a random color.")
- else
- // select new color
- var/new_etherealcolor = input(user, "Choose your Elzuose color:", "Character Preference",default_color) as color|null
- if(new_etherealcolor)
- var/temp_hsv = RGBtoHSV(new_etherealcolor)
- if(ReadHSV(temp_hsv)[3] >= ReadHSV("#505050")[3]) // elzu colors should be bright ok??
- default_color = sanitize_hexcolor(new_etherealcolor, 6, TRUE)
- current_color = health_adjusted_color(H, default_color)
- spec_updatehealth(H)
- H.visible_message("[H] modulates \his EM frequency to [new_etherealcolor].")
- else
- to_chat(user, "Invalid color. Your color is not bright enough.")
- else
- . = ..()
+ return ELZUOSE_CHARGE_NONE
diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
index af19f1316ce2..f5de9f873b3b 100644
--- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
@@ -35,7 +35,3 @@
"You throw up on the floor!")
return ..()
-/datum/species/fly/check_species_weakness(obj/item/weapon, mob/living/attacker)
- if(istype(weapon, /obj/item/melee/flyswatter))
- return 29 //Flyswatters deal 30x damage to flypeople.
- return 0
diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm
index 885be6f5886a..882fffc9ff41 100644
--- a/code/modules/mob/living/carbon/human/species_types/humans.dm
+++ b/code/modules/mob/living/carbon/human/species_types/humans.dm
@@ -13,16 +13,33 @@
loreblurb = "Mostly hairless mammalians. Their home system, Sol, lies in a sort of \"bluespace dead-zone\" that blocks anything from entering or exiting Sol's dead-zone through bluespace without a relay. While it leaves Sol extremely well-defended, it meant that they went unnoticed and uncontacted until they were themselves able to breach it."
/datum/species/human/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
- if(C.dna.features["ears"] == "Cat")
- mutantears = /obj/item/organ/ears/cat
- if(C.dna.features["ears"] == "Fox")
- mutantears = /obj/item/organ/ears/fox
- if(C.dna.features["tail_human"] == "Cat")
- mutant_organs |= /obj/item/organ/tail/cat
- if(C.dna.features["tail_human"] == "Fox")
- mutant_organs |= /obj/item/organ/tail/fox
- if(C.dna.features["ears"] == "Elf")
- mutantears = /obj/item/organ/ears/elf
+ switch(C.dna.features["ears"])
+ if("Elf")
+ mutantears = /obj/item/organ/ears/elf
+ if("Cat")
+ mutantears = /obj/item/organ/ears/cat
+ if("Dog")
+ mutantears = /obj/item/organ/ears/dog
+ if("Fox")
+ mutantears = /obj/item/organ/ears/fox
+ if("Rabbit")
+ mutantears = /obj/item/organ/ears/rabbit
+ if("Bent Rabbit")
+ mutantears = /obj/item/organ/ears/rabbit/bent
+ if("Floppy Rabbit")
+ mutantears = /obj/item/organ/ears/rabbit/floppy
+ switch(C.dna.features["tail_human"])
+ if("Cat")
+ mutant_organs |= /obj/item/organ/tail/cat
+ if("Dog")
+ mutant_organs |= /obj/item/organ/tail/dog
+ if("Fox")
+ mutant_organs |= /obj/item/organ/tail/fox
+ if("Fox 2")
+ mutant_organs |= /obj/item/organ/tail/fox/alt
+ if("Rabbit")
+ mutant_organs |= /obj/item/organ/tail/rabbit
+
return ..()
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index eb78ef131644..14526059354d 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -313,7 +313,7 @@
H.notransform = TRUE
- if(do_after(owner, delay=60, needhand=FALSE, target=owner, progress=TRUE))
+ if(do_after(owner, delay = 60, target = owner, progress = TRUE, timed_action_flags = IGNORE_HELD_ITEM))
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
make_dupe()
else
diff --git a/code/modules/mob/living/carbon/human/species_types/kepori.dm b/code/modules/mob/living/carbon/human/species_types/kepori.dm
index 5693c646cf3f..7e76fff79c1e 100644
--- a/code/modules/mob/living/carbon/human/species_types/kepori.dm
+++ b/code/modules/mob/living/carbon/human/species_types/kepori.dm
@@ -2,20 +2,20 @@
name = "\improper Kepori"
id = SPECIES_KEPORI
default_color = "6060FF"
- species_traits = list(MUTCOLORS, EYECOLOR, MUTCOLORS_SECONDARY)
+ species_traits = list(SCLERA, MUTCOLORS, EYECOLOR, MUTCOLORS_SECONDARY)
inherent_traits = list(TRAIT_SCOOPABLE)
- mutant_bodyparts = list("kepori_body_feathers", "kepori_tail_feathers", "kepori_feathers")
- default_features = list("mcolor" = "0F0", "wings" = "None", "kepori_feathers" = "Plain", "kepori_body_feathers" = "Plain", "kepori_tail_feathers" = "Fan", "body_size" = "Normal")
+ mutant_bodyparts = list("kepori_body_feathers", "kepori_head_feathers", "kepori_tail_feathers", "kepori_feathers")
+ default_features = list("mcolor" = "0F0", "wings" = "None", "kepori_feathers" = "None", "kepori_head_feathers" = "None", "kepori_body_feathers" = "None", "kepori_tail_feathers" = "None")
meat = /obj/item/reagent_containers/food/snacks/meat/slab/chicken
disliked_food = FRIED | GROSS | CLOTH
liked_food = MEAT | GORE
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT
- loreblurb = "Kepori are a species covered in feathers vaguely reminiscent of earth’s extinct troodontidae. They’re small and sometimes seen as weak by other species due to their hollow bones but make up for that in speed and reflexes. Those found in space are commonly known as rollaways. They tend to woop when excited, scared, or for any other reason at all."
+ loreblurb = "Kepori are a species covered in feathers vaguely reminiscent of earth’s extinct troodontidae. They’re small and sometimes seen as weak by other species due to their hollow bones but make up for that in speed and reflexes. They tend to woop when excited, scared, or for any other reason at all."
attack_verb = "slash"
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
species_clothing_path = 'icons/mob/clothing/species/kepori.dmi'
- species_eye_path = 'icons/mob/kepori_parts.dmi'
+ species_eye_path = 'icons/mob/species/kepori/kepori_eyes.dmi'
heatmod = 0.67
coldmod = 1.5
brutemod = 1.5
@@ -57,17 +57,64 @@
species_robotic_l_leg = /obj/item/bodypart/leg/left/robot/surplus/kepori
species_robotic_r_leg = /obj/item/bodypart/leg/right/robot/surplus/kepori
+ robotic_eyes = /obj/item/organ/eyes/robotic/kepori
+
/datum/species/kepori/New()
. = ..()
// This is in new because "[HEAD_LAYER]" etc. is NOT a constant compile-time value. For some reason.
// Why not just use HEAD_LAYER? Well, because HEAD_LAYER is a number, and if you try to use numbers as indexes,
// BYOND will try to make it an ordered list. So, we have to use a string. This is annoying, but it's the only way to do it smoothly.
offset_clothing = list(
- "[HEAD_LAYER]" = list("[NORTH]" = list("x" = 0, "y" = -4), "[EAST]" = list("x" = 4, "y" = -4), "[SOUTH]" = list("x" = 0, "y" = -4), "[WEST]" = list("x" = -4, "y" = -4)),
- "[GLASSES_LAYER]" = list("[NORTH]" = list("x" = 0, "y" = -4), "[EAST]" = list("x" = 4, "y" = -4), "[SOUTH]" = list("x" = 0, "y" = -4), "[WEST]" = list("x" = -4, "y" = -4)),
- "[FACEMASK_LAYER]" = list("[NORTH]" = list("x" = 0, "y" = -5), "[EAST]" = list("x" = 4, "y" = -5), "[SOUTH]" = list("x" = 0, "y" = -5), "[WEST]" = list("x" = -4, "y" = -5)),
+ "[HEAD_LAYER]" = list(
+ "[NORTH]" = list("x" = 8, "y" = -3),
+ "[EAST]" = list("x" = 19, "y" = -3), //ISSUE: The head sprites seem to be cut off when given an offset this large, combined with kepori offset
+ "[SOUTH]" = list("x" = 8, "y" = -3),
+ "[WEST]" = list("x" = -3, "y" = -3)
+ ),
+ "[GLASSES_LAYER]" = list(
+ "[NORTH]" = list("x" = 8, "y" = -3),
+ "[EAST]" = list("x" = 19, "y" = -3),
+ "[SOUTH]" = list("x" = 8, "y" = -3),
+ "[WEST]" = list("x" = -3, "y" = -3)
+ ),
+ "[FACEMASK_LAYER]" = list(
+ "[NORTH]" = list("x" = 8, "y" = -3),
+ "[EAST]" = list("x" = 19, "y" = -3),
+ "[SOUTH]" = list("x" = 8, "y" = -3),
+ "[WEST]" = list("x" = -3, "y" = -3)
+ ),
+ "[BELT_LAYER]" = list(
+ "[NORTH]" = list("x" = 8, "y" = -1),
+ "[EAST]" = list("x" = 8, "y" = -1),
+ "[SOUTH]" = list("x" = 8, "y" = -1),
+ "[WEST]" = list("x" = 9, "y" = -1)
+ ),
+ "[EARS_LAYER]" = list(
+ "[NORTH]" = list("x" = 8, "y" = -3),
+ "[EAST]" = list("x" = 19, "y" = -3),
+ "[SOUTH]" = list("x" = 8, "y" = -3),
+ "[WEST]" = list("x" = -3, "y" = -3)
+ ),
+ "[SUIT_STORE_LAYER]" = list(
+ "[NORTH]" = list("x" = 8, "y" = -1),
+ "[EAST]" = list("x" = 8, "y" = -1),
+ "[SOUTH]" = list("x" = 8, "y" = -1),
+ "[WEST]" = list("x" = -8, "y" = -1)
+ ),
)
+// First list is left hand, second list is right hand. This is used for inhand offsets.
+/datum/species/kepori/get_item_offsets_for_dir(dir, hand)
+ //LEFT/RIGHT
+ if(dir & NORTH)
+ return list(list("x" = 9, "y" = -1), list("x" = 7, "y" = -1))
+ if(dir & SOUTH)
+ return list(list("x" = 7, "y" = -1), list("x" = 9, "y" = -1))
+ if(dir & EAST)
+ return list(list("x" = 18, "y" = -2), list("x" = 21, "y" = -2)) //("x" = 18, "y" = 2), list("x" = 21, "y" = -1))
+ if(dir & WEST)
+ return list(list("x" = -4, "y" = -2), list("x" = -1, "y" = -2)) //("x" = -5, "y" = -1), list("x" = -1, "y" = 2))
+
/datum/species/kepori/random_name(gender,unique,lastname)
if(unique)
return random_unique_kepori_name()
@@ -86,17 +133,27 @@
return equip_delay_self_check(I, H, bypass_equip_delay_self)
/datum/species/kepori/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
- ..()
+ . = ..()
+
+ C.base_pixel_x -= 8
+ C.pixel_x = C.base_pixel_x
+ C.update_hands_on_rotate()
+
if(ishuman(C))
keptackle = new
keptackle.Grant(C)
/datum/species/kepori/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
+ . = ..()
+
+ C.base_pixel_x += 8
+ C.pixel_x = C.base_pixel_x
+ C.stop_updating_hands()
+
if(keptackle)
keptackle.Remove(C)
- qdel(C.GetComponent(/datum/component/tackler))
- ..()
+ qdel(C.GetComponent(/datum/component/tackler))
/datum/action/innate/keptackle
name = "Pounce"
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index 141efed98e12..c34a70b3afde 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -1,8 +1,9 @@
/datum/species/lizard
// Reptilian humanoids with scaled skin and tails.
name = "\improper Sarathi"
- id = SPECIES_LIZARD
+ id = SPECIES_SARATHI
default_color = "00FF00"
+ species_age_max = 175
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,SCLERA,EMOTE_OVERLAY,MUTCOLORS_SECONDARY)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE
mutant_bodyparts = list("tail_lizard", "face_markings", "frills", "horns", "spines", "body_markings", "legs")
@@ -20,7 +21,6 @@
exotic_bloodtype = "L"
disliked_food = GRAIN | DAIRY | CLOTH | GROSS
liked_food = GORE | MEAT
- inert_mutation = FIREBREATH
deathsound = 'sound/voice/lizard/deathsound.ogg'
wings_icons = list("Dragon")
species_language_holder = /datum/language_holder/lizard
@@ -110,7 +110,7 @@ Lizard subspecies: ASHWALKERS
/datum/species/lizard/ashwalker
name = "Ash Walker"
id = SPECIES_ASHWALKER
- examine_limb_id = SPECIES_LIZARD
+ examine_limb_id = SPECIES_SARATHI
species_traits = list(MUTCOLORS,EYECOLOR,LIPS, NO_UNDERWEAR)
inherent_traits = list(TRAIT_CHUNKYFINGERS,TRAIT_NOBREATH)
species_language_holder = /datum/language_holder/lizard/ash
@@ -121,7 +121,7 @@ Lizard subspecies: ASHWALKERS
/datum/species/lizard/ashwalker/kobold
name = "Kobold"
id = SPECIES_KOBOLD
- examine_limb_id = SPECIES_LIZARD
+ examine_limb_id = SPECIES_SARATHI
species_traits = list(MUTCOLORS,EYECOLOR,LIPS, NO_UNDERWEAR)
inherent_traits = list(TRAIT_CHUNKYFINGERS,TRAIT_NOBREATH)
species_language_holder = /datum/language_holder/lizard/ash
diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm
index 02ddf79f6bc4..91169299afba 100644
--- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm
@@ -1,5 +1,5 @@
/datum/species/moth
- name = "\improper Mothman"
+ name = "\improper Mothperson"
id = SPECIES_MOTH
default_color = "00FF00"
species_traits = list(LIPS, NOEYESPRITES, TRAIT_ANTENNAE, HAIR, EMOTE_OVERLAY)
@@ -36,17 +36,6 @@
var/mob/living/carbon/human/H = C
handle_mutant_bodyparts(H)
-/datum/species/moth/random_name(gender,unique,lastname)
- if(unique)
- return random_unique_moth_name()
-
- var/randname = moth_name()
-
- if(lastname)
- randname += " [lastname]"
-
- return randname
-
/datum/species/handle_fire(mob/living/carbon/human/H, no_protection = FALSE)
. = ..()
if(.) //if the mob is immune to fire, don't burn wings off.
@@ -84,11 +73,6 @@
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return ..()
-/datum/species/moth/check_species_weakness(obj/item/weapon, mob/living/attacker)
- if(istype(weapon, /obj/item/melee/flyswatter))
- return 9 //flyswatters deal 10x damage to moths
- return 0
-
/datum/species/space_move(mob/living/carbon/human/H)
. = ..()
if(H.loc && !isspaceturf(H.loc) && H.getorganslot(ORGAN_SLOT_WINGS) && !flying_species) //"flying_species" is exclusive to the potion of flight, which has its flying mechanics. If they want to fly they can use that instead
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index ec9afd777f2c..d3c900c56786 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -1,5 +1,5 @@
/datum/species/plasmaman
- name = "\improper Plasmaman"
+ name = "\improper Phorid"
id = SPECIES_PLASMAMAN
sexes = 0
meat = /obj/item/stack/sheet/mineral/plasma
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 6e4ae1cdb9a3..b613b8a0094e 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -190,7 +190,7 @@
return
if(isliving(AM))
var/mob/living/L = AM
- if(isethereal(AM))
+ if(iselzuose(AM))
AM.emp_act(EMP_LIGHT)
else if(iscyborg(AM))
diff --git a/code/modules/mob/living/carbon/human/species_types/spider.dm b/code/modules/mob/living/carbon/human/species_types/spider.dm
index 847d6ad74f3f..764a7166ff2d 100644
--- a/code/modules/mob/living/carbon/human/species_types/spider.dm
+++ b/code/modules/mob/living/carbon/human/species_types/spider.dm
@@ -97,11 +97,6 @@ GLOBAL_LIST_INIT(spider_last, world.file2list("strings/names/spider_last.txt"))
H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM)
return ..()
-/datum/species/spider/check_species_weakness(obj/item/weapon, mob/living/attacker)
- if(istype(weapon, /obj/item/melee/flyswatter))
- return 9 //flyswatters deal 10x damage to spiders
- return 0
-
/mob/living/carbon/human/species/spider
race = /datum/species/spider
@@ -152,7 +147,7 @@ GLOBAL_LIST_INIT(spider_last, world.file2list("strings/names/spider_last.txt"))
var/nutrition_threshold = NUTRITION_LEVEL_FED
if (H.nutrition >= nutrition_threshold)
to_chat(H, "You begin spinning some web...")
- if(!do_after(H, 10 SECONDS, 1, T))
+ if(!do_after(H, 10 SECONDS, T, hidden = TRUE))
to_chat(H, "Your web spinning was interrupted!")
return
if(prob(75))
@@ -213,7 +208,7 @@ GLOBAL_LIST_INIT(spider_last, world.file2list("strings/names/spider_last.txt"))
to_chat(H, "You cannot wrap this.")
return
H.visible_message("[H] starts to wrap [A] into a cocoon!","You start to wrap [A] into a cocoon.")
- if(!do_after(H, 10 SECONDS, 1, A))
+ if(!do_after(H, 10 SECONDS, A, hidden = TRUE))
to_chat(H, "Your web spinning was interrupted!")
return
H.adjust_nutrition(E.spinner_rate * -3.5)
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index 070894a92bee..5caf871a7f23 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -53,11 +53,6 @@
C.adjust_fire_stacks(6)
C.IgniteMob()
-/datum/species/vampire/check_species_weakness(obj/item/weapon, mob/living/attacker)
- if(istype(weapon, /obj/item/nullrod/whip))
- return 1 //Whips deal 2x damage to vampires. Vampire killer.
- return 0
-
/obj/item/organ/tongue/vampire
name = "vampire tongue"
actions_types = list(/datum/action/item_action/organ_action/vampire)
diff --git a/code/modules/mob/living/carbon/human/species_types/vox.dm b/code/modules/mob/living/carbon/human/species_types/vox.dm
index fd03e184b9ba..b9cc8306762e 100644
--- a/code/modules/mob/living/carbon/human/species_types/vox.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vox.dm
@@ -67,14 +67,29 @@
/datum/species/vox/New()
. = ..()
+ // This is in new because "[HEAD_LAYER]" etc. is NOT a constant compile-time value. For some reason.
+ // Why not just use HEAD_LAYER? Well, because HEAD_LAYER is a number, and if you try to use numbers as indexes,
+ // BYOND will try to make it an ordered list. So, we have to use a string. This is annoying, but it's the only way to do it smoothly.
+ offset_clothing = list(
+ "[SUIT_STORE_LAYER]" = list(
+ "[NORTH]" = list("x" = 8, "y" = 0),
+ "[EAST]" = list("x" = 8, "y" = 0),
+ "[SOUTH]" = list("x" = 8, "y" = 0),
+ "[WEST]" = list("x" = -8, "y" = 0)
+ ),
+ "[EARS_LAYER]" = list(
+ "[NORTH]" = list("x" = 8, "y" = 0),
+ "[EAST]" = list("x" = 8, "y" = 0),
+ "[SOUTH]" = list("x" = 8, "y" = 0),
+ "[WEST]" = list("x" = -8, "y" = 0)
+ ),
+ )
/datum/species/vox/random_name(gender,unique,lastname)
if(unique)
return random_unique_vox_name()
return vox_name()
-
-
/datum/species/vox/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
. = ..()
C.base_pixel_x -= 9
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 702adfb224a2..c90cbd0dbc8f 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -46,7 +46,7 @@
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
. = min(20, amount)
-/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
+/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, sharpness = FALSE)
. = ..()
if(.)
regen_cooldown = world.time + REGENERATION_DELAY
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 09445cef4c4e..0f3ab70e4034 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -1,5 +1,4 @@
#define RESOLVE_ICON_STATE(I) (I.mob_overlay_state || I.icon_state)
-#define CHECK_USE_AUTOGEN (handled_by_bodytype ? null : dna.species) //Is this gross overuse of macros? Yes. Fuck you.
///////////////////////
//UPDATE_ICONS SYSTEM//
@@ -111,9 +110,6 @@ There are several things that need to be remembered:
if(wear_suit && (wear_suit.flags_inv & HIDEJUMPSUIT))
return
- var/target_overlay = U.icon_state
- if(U.adjusted == ALT_STYLE)
- target_overlay = "[target_overlay]_d"
var/t_color = U.item_color
@@ -122,27 +118,50 @@ There are several things that need to be remembered:
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d"
+ ///The final thing we overlay. Set on build_worn_icon.
var/mutable_appearance/uniform_overlay
- var/icon_file
- var/handled_by_bodytype = TRUE
+ ///icon file of the clothing
+ var/icon_file = U.mob_overlay_icon
+ ///The icon state to overlay
+ var/target_overlay = U.icon_state
+ if(U.adjusted == ALT_STYLE)
+ target_overlay = "[target_overlay]_d"
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
+
if(!uniform_overlay)
//Kapu's autistic attempt at digitigrade handling
//Hi Kapu
- if((dna.species.bodytype & BODYTYPE_DIGITIGRADE) && (U.supports_variations & DIGITIGRADE_VARIATION))
+ if((dna.species.bodytype & BODYTYPE_DIGITIGRADE) && ((U.supports_variations & DIGITIGRADE_VARIATION) || (U.supports_variations & DIGITIGRADE_VARIATION_SAME_ICON_FILE)))
icon_file = DIGITIGRADE_PATH
+ if((U.supports_variations & DIGITIGRADE_VARIATION_SAME_ICON_FILE))
+ icon_file = U.mob_overlay_icon
+ target_overlay = "[target_overlay]_digi"
+
+ else if(dna.species.bodytype & BODYTYPE_VOX)
+ if(U.supports_variations & VOX_VARIATION)
+ icon_file = VOX_UNIFORM_PATH
+ if(U.vox_override_icon)
+ icon_file = U.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(U.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_UNIFORM_PATH
+ if(U.kepoi_override_icon)
+ icon_file = U.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
- else if((dna.species.bodytype & BODYTYPE_VOX) && (U.supports_variations & VOX_VARIATION))
- icon_file = VOX_UNIFORM_PATH
-
- else if((dna.species.bodytype & BODYTYPE_KEPORI) && (U.supports_variations & KEPORI_VARIATION))
- icon_file = KEPORI_UNIFORM_PATH
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(U))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = U.mob_overlay_icon || DEFAULT_UNIFORM_PATH
- uniform_overlay = U.build_worn_icon(default_layer = UNIFORM_LAYER, default_icon_file = icon_file, isinhands = FALSE, override_file = icon_file, override_state = target_overlay, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ uniform_overlay = U.build_worn_icon(default_layer = UNIFORM_LAYER, default_icon_file = icon_file, override_file = icon_file, isinhands = FALSE, override_file = icon_file, override_state = target_overlay, mob_species = use_autogen)
if(!uniform_overlay)
return
@@ -169,7 +188,8 @@ There are several things that need to be remembered:
var/handled_by_bodytype
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
- id_overlay = I.build_worn_icon(default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi', mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ id_overlay = I.build_worn_icon(default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi', mob_species = use_autogen)
if(!id_overlay)
return
@@ -199,25 +219,41 @@ There are several things that need to be remembered:
//Bloody hands end
- var/mutable_appearance/gloves_overlay
+
if(gloves)
var/obj/item/I = gloves
update_hud_gloves(I)
- var/handled_by_bodytype = TRUE
- var/icon_file
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/gloves_overlay
- if((dna.species.bodytype & BODYTYPE_VOX) && (I.supports_variations & VOX_VARIATION))
- icon_file = VOX_GLOVES_PATH
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
- if((dna.species.bodytype & BODYTYPE_KEPORI) && (I.supports_variations & KEPORI_VARIATION))
- icon_file = KEPORI_GLOVES_PATH
+ if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_GLOVES_PATH
+ if(I.vox_override_icon)
+ icon_file = I.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(I.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_GLOVES_PATH
+ if(I.kepoi_override_icon)
+ icon_file = I.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = DEFAULT_GLOVES_PATH
- gloves_overlay = I.build_worn_icon(default_layer = GLOVES_LAYER, default_icon_file = icon_file, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ gloves_overlay = I.build_worn_icon(default_layer = GLOVES_LAYER, default_icon_file = icon_file, override_file = icon_file, mob_species = use_autogen)
if(!gloves_overlay)
return
@@ -239,18 +275,37 @@ There are several things that need to be remembered:
var/obj/item/I = glasses
update_hud_glasses(I)
if(!(head?.flags_inv & HIDEEYES) && !(wear_mask?.flags_inv & HIDEEYES))
+ ///The final thing we overlay. Set on build_worn_icon.
var/mutable_appearance/glasses_overlay
- var/handled_by_bodytype = TRUE
- var/icon_file
- if((dna.species.bodytype & BODYTYPE_VOX) && (I.supports_variations & VOX_VARIATION))
- icon_file = VOX_GLASSES_PATH
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
+
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
+
+ if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_GLASSES_PATH
+ if(I.vox_override_icon)
+ icon_file = I.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(I.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_GLASSES_PATH
+ if(I.kepoi_override_icon)
+ icon_file = I.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = DEFAULT_GLASSES_PATH
- glasses_overlay = I.build_worn_icon(default_layer = GLASSES_LAYER, default_icon_file = icon_file, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ glasses_overlay = I.build_worn_icon(default_layer = GLASSES_LAYER, default_icon_file = icon_file, override_file = icon_file, mob_species = use_autogen)
if(!glasses_overlay)
return
@@ -270,20 +325,38 @@ There are several things that need to be remembered:
if(ears)
var/obj/item/I = ears
- var/mutable_appearance/ears_overlay
update_hud_ears(I)
- var/handled_by_bodytype = TRUE
- var/icon_file
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/ears_overlay
+
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
- if((dna.species.bodytype & BODYTYPE_VOX) && (I.supports_variations & VOX_VARIATION))
- icon_file = VOX_EARS_PATH
+ if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_EARS_PATH
+ if(I.vox_override_icon)
+ icon_file = I.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(I.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_EARS_PATH
+ if(I.kepoi_override_icon)
+ icon_file = I.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = DEFAULT_EARS_PATH
- ears_overlay = I.build_worn_icon(default_layer = EARS_LAYER, override_file = icon_file, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ ears_overlay = I.build_worn_icon(default_layer = EARS_LAYER, override_file = icon_file, mob_species = use_autogen)
if(!ears_overlay)
return
@@ -303,27 +376,48 @@ There are several things that need to be remembered:
if(shoes)
var/obj/item/I = shoes
- var/mutable_appearance/shoes_overlay
- var/icon_file
update_hud_shoes(I)
- var/handled_by_bodytype = TRUE
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/shoes_overlay
- if((dna.species.bodytype & BODYTYPE_DIGITIGRADE) && (I.supports_variations & DIGITIGRADE_VARIATION))
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
+ ///The icon state to overlay
+ var/target_overlay = I.icon_state
+
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
+
+ if((dna.species.bodytype & BODYTYPE_DIGITIGRADE) && ((I.supports_variations & DIGITIGRADE_VARIATION) || (I.supports_variations & DIGITIGRADE_VARIATION_SAME_ICON_FILE)))
var/obj/item/bodypart/leg = src.get_bodypart(BODY_ZONE_L_LEG)
if(leg.bodytype & BODYTYPE_DIGITIGRADE && !leg.plantigrade_forced)
icon_file = DIGITIGRADE_SHOES_PATH
+ if((I.supports_variations & DIGITIGRADE_VARIATION_SAME_ICON_FILE))
+ icon_file = I.mob_overlay_icon
+ target_overlay = "[target_overlay]_digi"
+
+ else if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_SHOES_PATH
+ if(I.vox_override_icon)
+ icon_file = I.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
- if((I.supports_variations & VOX_VARIATION) && (dna.species.bodytype & BODYTYPE_VOX))
- icon_file = VOX_SHOES_PATH
-
- if((I.supports_variations & KEPORI_VARIATION) && (dna.species.bodytype & BODYTYPE_KEPORI))
- icon_file = KEPORI_SHOES_PATH
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(I.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_SHOES_PATH
+ if(I.kepoi_override_icon)
+ icon_file = I.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = DEFAULT_SHOES_PATH
- shoes_overlay = I.build_worn_icon(default_layer = SHOES_LAYER, default_icon_file = icon_file, isinhands = FALSE, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ shoes_overlay = I.build_worn_icon(default_layer = SHOES_LAYER, default_icon_file = icon_file, override_file = icon_file, isinhands = FALSE, mob_species = use_autogen, override_state = target_overlay)
if(!shoes_overlay)
return
@@ -341,18 +435,42 @@ There are several things that need to be remembered:
if(s_store)
var/obj/item/I = s_store
- var/mutable_appearance/s_store_overlay
update_hud_s_store(I)
- var/t_state = I.item_state
- if(!t_state)
- t_state = I.icon_state
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/suit_store_overlay
- s_store_overlay = mutable_appearance('icons/mob/clothing/belt_mirror.dmi', t_state, -SUIT_STORE_LAYER)
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
- if(!s_store_overlay)
- return
- overlays_standing[SUIT_STORE_LAYER] = s_store_overlay
- apply_overlay(SUIT_STORE_LAYER)
+ /// Does this clothing need to be generated via greyscale
+ var/handled_by_bodytype = FALSE
+
+ if(!suit_store_overlay)
+ if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_BACK_PATH
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+// if(I.supports_variations & KEPORI_VARIATION)
+// icon_file = KEPORI_BACK_PATH
+// else
+ handled_by_bodytype = TRUE
+
+ if(!icon_exists(icon_file, RESOLVE_ICON_STATE(I)))
+ icon_file = DEFAULT_BACK_PATH
+ handled_by_bodytype = TRUE
+
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ suit_store_overlay = I.build_worn_icon(default_layer = -SUIT_STORE_LAYER, default_icon_file = icon_file, override_file = icon_file, isinhands = FALSE, override_file = icon_file, mob_species = use_autogen)
+
+ if(!suit_store_overlay)
+ return
+ overlays_standing[SUIT_STORE_LAYER] = suit_store_overlay
+
+ if(suit_store_overlay)
+ apply_overlay(SUIT_STORE_LAYER)
/mob/living/carbon/human/update_inv_head()
@@ -360,25 +478,46 @@ There are several things that need to be remembered:
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1])
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1]
inv.update_appearance()
-
if(head)
var/obj/item/I = head
- var/mutable_appearance/head_overlay
update_hud_head(I)
- var/handled_by_bodytype = TRUE
- var/icon_file
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/head_overlay
- if((I.supports_variations & VOX_VARIATION) && (dna.species.bodytype & BODYTYPE_VOX))
- icon_file = VOX_HEAD_PATH
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
+ ///The icon state to overlay
+ var/target_overlay = I.icon_state
- if((I.supports_variations & KEPORI_VARIATION) && (dna.species.bodytype & BODYTYPE_KEPORI))
- icon_file = KEPORI_HEAD_PATH
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
+
+ var/obj/item/bodypart/head_bodypart = src.get_bodypart(BODY_ZONE_HEAD)
+ if((head_bodypart.bodytype & BODYTYPE_SNOUT) && (I.supports_variations & SNOUTED_VARIATION))
+ target_overlay = "[target_overlay]_snouted"
+
+ else if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_HEAD_PATH
+ if(I.vox_override_icon)
+ icon_file = I.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(I.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_HEAD_PATH
+ if(I.kepoi_override_icon)
+ icon_file = I.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = DEFAULT_HEAD_PATH
- head_overlay = I.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = icon_file, isinhands = FALSE, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ head_overlay = I.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = icon_file, override_file = icon_file, isinhands = FALSE, mob_species = use_autogen, override_state = target_overlay)
if(!head_overlay)
return
@@ -396,22 +535,39 @@ There are several things that need to be remembered:
if(belt)
var/obj/item/I = belt
- var/mutable_appearance/belt_overlay
update_hud_belt(I)
- var/handled_by_bodytype
- var/icon_file
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/belt_overlay
+
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
- if((I.supports_variations & VOX_VARIATION) && (dna.species.bodytype & BODYTYPE_VOX))
- icon_file = VOX_BELT_PATH
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
- //if((I.supports_variations & KEPORI_VARIATION) && (dna.species.bodytype & BODYTYPE_KEPORI))
- //icon_file = KEPORI_BELT_PATH
+
+ if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_BELT_PATH
+ if(I.vox_override_icon)
+ icon_file = I.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(I.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_BELT_PATH
+ if(I.kepoi_override_icon)
+ icon_file = I.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = DEFAULT_BELT_PATH
- belt_overlay = I.build_worn_icon(default_layer = BELT_LAYER, default_icon_file = icon_file, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ belt_overlay = I.build_worn_icon(default_layer = BELT_LAYER, default_icon_file = icon_file, override_file = icon_file, mob_species = use_autogen)
if(!belt_overlay)
return
@@ -430,26 +586,46 @@ There are several things that need to be remembered:
if(wear_suit)
var/obj/item/I = wear_suit
- var/mutable_appearance/suit_overlay
update_hud_wear_suit(I)
- var/icon_file
-
- var/handled_by_bodytype = TRUE
- if(dna.species.bodytype & BODYTYPE_DIGITIGRADE)
- if(I.supports_variations & DIGITIGRADE_VARIATION)
- icon_file = DIGITIGRADE_SUIT_PATH
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/suit_overlay
- else if((dna.species.bodytype & BODYTYPE_VOX) && (I.supports_variations & VOX_VARIATION))
- icon_file = VOX_SUIT_PATH
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
+ ///The icon state to overlay
+ var/target_overlay = I.icon_state
+
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
+
+ if((dna.species.bodytype & BODYTYPE_DIGITIGRADE) && ((I.supports_variations & DIGITIGRADE_VARIATION) || (I.supports_variations & DIGITIGRADE_VARIATION_SAME_ICON_FILE)))
+ icon_file = DIGITIGRADE_SUIT_PATH
+ if((I.supports_variations & DIGITIGRADE_VARIATION_SAME_ICON_FILE))
+ icon_file = I.mob_overlay_icon
+ target_overlay = "[target_overlay]_digi"
+
+ else if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_SUIT_PATH
+ if(I.vox_override_icon)
+ icon_file = I.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
- else if((dna.species.bodytype & BODYTYPE_KEPORI) && (I.supports_variations & KEPORI_VARIATION))
- icon_file = KEPORI_SUIT_PATH
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(I.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_SUIT_PATH
+ if(I.kepoi_override_icon)
+ icon_file = I.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = I.mob_overlay_icon
- suit_overlay = wear_suit.build_worn_icon(default_layer = SUIT_LAYER, override_file = icon_file, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ suit_overlay = wear_suit.build_worn_icon(default_layer = SUIT_LAYER, override_file = icon_file, mob_species = use_autogen, override_state = target_overlay)
if(!suit_overlay)
return
@@ -495,22 +671,44 @@ There are several things that need to be remembered:
if(wear_mask)
var/obj/item/I = wear_mask
update_hud_wear_mask(I)
+ ///The final thing we overlay. Set on build_worn_icon.
var/mutable_appearance/mask_overlay
- var/icon_file
- var/handled_by_bodytype = TRUE
- if(!(ITEM_SLOT_MASK in check_obscured_slots()))
- if((dna.species.bodytype & BODYTYPE_VOX) && (I.supports_variations & VOX_VARIATION))
- icon_file = VOX_MASK_PATH
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
+ ///The icon state to overlay
+ var/target_overlay = I.icon_state
- if((dna.species.bodytype & BODYTYPE_KEPORI) && (I.supports_variations & KEPORI_VARIATION))
- icon_file = KEPORI_MASK_PATH
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
+
+ if(!(ITEM_SLOT_MASK in check_obscured_slots()))
+ var/obj/item/bodypart/head_bodypart = src.get_bodypart(BODY_ZONE_HEAD)
+ if((head_bodypart.bodytype & BODYTYPE_SNOUT) && (I.supports_variations & SNOUTED_VARIATION))
+ target_overlay = "[target_overlay]_snouted"
+
+ if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_MASK_PATH
+ if(I.vox_override_icon)
+ icon_file = I.vox_override_icon
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+ if(I.supports_variations & KEPORI_VARIATION)
+ icon_file = KEPORI_MASK_PATH
+ if(I.kepoi_override_icon)
+ icon_file = I.kepoi_override_icon
+ else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
icon_file = DEFAULT_MASK_PATH
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
- mask_overlay = I.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = icon_file, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ mask_overlay = I.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = icon_file, override_file = icon_file, mob_species = use_autogen, override_state = target_overlay)
if(!mask_overlay)
return
@@ -528,17 +726,48 @@ There are several things that need to be remembered:
if(wear_neck)
var/obj/item/I = wear_neck
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/neck_overlay
+
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
+ ///The icon state to overlay
+ var/target_overlay = I.icon_state
+
+ /// Does this clothing need to be generated via greyscale?
+ var/handled_by_bodytype = FALSE
+
+
update_hud_neck(I)
if(!(ITEM_SLOT_NECK in check_obscured_slots()))
- var/icon_file
- var/handled_by_bodytype = TRUE
+
+ if(dna.species.bodytype & BODYTYPE_VOX) // there is neither a vox or kepori neck path, we just tell it to greyscale no matter what
+// if(I.supports_variations & VOX_VARIATION)
+// icon_file = VOX_NECK_PATH
+// if(I.vox_override_icon)
+// icon_file = I.vox_override_icon
+// else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+// if(I.supports_variations & KEPORI_VARIATION)
+// icon_file = KEPORI_NECK_PATH
+// if(I.kepoi_override_icon)
+// icon_file = I.kepoi_override_icon
+// else
+ handled_by_bodytype = TRUE
if(!(icon_exists(icon_file, RESOLVE_ICON_STATE(I))))
- handled_by_bodytype = FALSE
+ handled_by_bodytype = TRUE
icon_file = DEFAULT_NECK_PATH
- overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = icon_file, mob_species = CHECK_USE_AUTOGEN)
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ neck_overlay = I.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = icon_file, override_file = icon_file, isinhands = FALSE, mob_species = use_autogen, override_state = target_overlay)
+ if(!neck_overlay)
+ return
+
+ overlays_standing[NECK_LAYER] = neck_overlay
apply_overlay(NECK_LAYER)
@@ -551,23 +780,42 @@ There are several things that need to be remembered:
if(back)
var/obj/item/I = back
- var/mutable_appearance/back_overlay
update_hud_back(I)
- var/icon_file
- var/handled_by_bodytype = TRUE
- if((dna.species.bodytype & BODYTYPE_VOX) && (I.supports_variations & VOX_VARIATION))
- icon_file = VOX_BACK_PATH
+ ///The final thing we overlay. Set on build_worn_icon.
+ var/mutable_appearance/back_overlay
- if(!icon_exists(icon_file, RESOLVE_ICON_STATE(I)))
- icon_file = DEFAULT_BACK_PATH
- handled_by_bodytype = FALSE
+ ///icon file of the clothing
+ var/icon_file = I.mob_overlay_icon
- back_overlay = I.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = icon_file, isinhands = FALSE, override_file = icon_file, mob_species = CHECK_USE_AUTOGEN)
+ /// Does this clothing need to be generated via greyscale
+ var/handled_by_bodytype = FALSE
if(!back_overlay)
- return
- overlays_standing[BACK_LAYER] = back_overlay
- apply_overlay(BACK_LAYER)
+ if(dna.species.bodytype & BODYTYPE_VOX)
+ if(I.supports_variations & VOX_VARIATION)
+ icon_file = VOX_BACK_PATH
+ else
+ handled_by_bodytype = TRUE
+
+ else if(dna.species.bodytype & BODYTYPE_KEPORI)
+// if(I.supports_variations & KEPORI_VARIATION)
+// icon_file = KEPORI_BACK_PATH
+// else
+ handled_by_bodytype = TRUE
+
+ if(!icon_exists(icon_file, RESOLVE_ICON_STATE(I)))
+ icon_file = DEFAULT_BACK_PATH
+ handled_by_bodytype = TRUE
+
+ var/use_autogen = handled_by_bodytype ? dna.species : null
+ back_overlay = I.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = icon_file, override_file = icon_file, isinhands = FALSE, override_file = icon_file, mob_species = use_autogen)
+
+ if(!back_overlay)
+ return
+ overlays_standing[BACK_LAYER] = back_overlay
+
+ if(back_overlay) //This is faster fuck you
+ apply_overlay(BACK_LAYER)
/mob/living/carbon/human/update_inv_legcuffed()
remove_overlay(LEGCUFF_LAYER)
@@ -708,6 +956,7 @@ in this situation default_icon_file is expected to match either the lefthand_ or
^this female part sucks and will be fully ripped out ideally
*/
+// Note: if handled_by_bodytype is TRUE before calling this, it makes species use greyscale
/obj/item/proc/build_worn_icon(default_layer = 0, default_icon_file = null, isinhands = FALSE, override_state = null, override_file = null, datum/species/mob_species = null, direction = null)
// WS Edit Start - Worn Icon State
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index 7a995dea28da..d5b97a942da2 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -84,6 +84,9 @@
if(ITEM_SLOT_BACKPACK)
if(!back || !SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE))
not_handled = TRUE
+ if(ITEM_SLOT_ID)
+ if(!wear_id || !SEND_SIGNAL(wear_id, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE))
+ not_handled = TRUE
else
not_handled = TRUE
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 0fc21db37d8c..c5145600bbf8 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -25,9 +25,12 @@
if(.) //not dead
handle_blood()
- if(isLivingSSD())//if you're disconnected, you're going to sleep
- if(AmountSleeping() < 20)
- AdjustSleeping(20)//adjust every 10 seconds
+ if(isLivingSSD()) // If you're disconnected, you're going to sleep
+ if(trunc((world.time - lastclienttime) / (3 MINUTES)) > 0) // After a three minute grace period, your character will fall asleep
+ if(AmountSleeping() < 20)
+ AdjustSleeping(20) // Adjust every 10 seconds
+ if(ssd_indicator)
+ cut_overlay(GLOB.ssd_indicator_overlay) // Prevents chronically SSD players from breaking immersion
if(stat != DEAD)
var/bprv = handle_bodyparts()
diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm
index 1f730de799d0..8fd4e89566c7 100644
--- a/code/modules/mob/living/carbon/monkey/combat.dm
+++ b/code/modules/mob/living/carbon/monkey/combat.dm
@@ -296,7 +296,7 @@
return IsStandingStill()
/mob/living/carbon/monkey/proc/pickpocket(mob/M)
- if(do_mob(src, M, MONKEY_ITEM_SNATCH_DELAY) && pickupTarget)
+ if(do_after(src, MONKEY_ITEM_SNATCH_DELAY, M) && pickupTarget)
for(var/obj/item/I in M.held_items)
if(I == pickupTarget)
M.visible_message("[src] snatches [pickupTarget] from [M].", "[src] snatched [pickupTarget]!")
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 6a66c0546f6e..755c674a107d 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -75,8 +75,6 @@
var/amount
if(reagents.has_reagent(/datum/reagent/medicine/morphine))
amount = -1
- if(reagents.has_reagent(/datum/reagent/consumable/nuka_cola))
- amount = -1
if(amount)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_reagent_speedmod, TRUE, amount)
diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm
index cc15c12d836e..5ab2c57be0f4 100644
--- a/code/modules/mob/living/carbon/status_procs.dm
+++ b/code/modules/mob/living/carbon/status_procs.dm
@@ -17,6 +17,7 @@
ADD_TRAIT(src, TRAIT_INCAPACITATED, STAMINA)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, STAMINA)
ADD_TRAIT(src, TRAIT_FLOORED, STAMINA)
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, STAMINA)
if((maxHealth - health + getStaminaLoss()) > 120) // Puts you a little further into the initial stamcrit, makes stamcrit harder to outright counter with chems. //WS Edit - Stamina stacks with health damage
adjustStaminaLoss(30, FALSE)
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index 76daa5ba21d4..430d02f7f1ea 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -11,10 +11,12 @@
* * blocked - armor value applied
* * forced - bypass hit percentage
* * spread_damage - used in overrides
+ * * break_modifier - increases bone breaking chance
+ * * sharpness - used for bleeding
*
* Returns TRUE if damage applied
*/
-/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, break_modifier = 1)//WS Edit - Breakable Bones
+/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, break_modifier = 1, sharpness = FALSE)//WS Edit - Breakable Bones
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!damage || (!forced && hit_percent <= 0) || !(flags_1 & INITIALIZED_1))
diff --git a/code/modules/mob/living/inhand_holder.dm b/code/modules/mob/living/inhand_holder.dm
index e16dcf9e3326..f593a269cbd6 100644
--- a/code/modules/mob/living/inhand_holder.dm
+++ b/code/modules/mob/living/inhand_holder.dm
@@ -7,7 +7,8 @@
icon_state = ""
slot_flags = NONE
moth_edible = FALSE
- w_class = 20 // so that only one can fit in a duffel bag
+ w_class = WEIGHT_CLASS_BULKY
+ w_volume = ITEM_VOLUME_MOB// so that only one can fit in a duffel bag
var/mob/living/held_mob
/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/M, worn_state, head_icon, lh_icon, rh_icon, worn_slot_flags = NONE)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 47fc5bd82ecb..a25025294497 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -38,6 +38,8 @@
if (QDELETED(src)) // diseases can qdel the mob via transformations
return
+ SEND_SIGNAL(src, COMSIG_MOB_LIFE)
+
if(stat != DEAD)
//Random events (vomiting etc)
handle_random_events()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index b240836b55e7..269c74a837bd 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -507,7 +507,7 @@
/mob/living/proc/get_up(instant = FALSE)
set waitfor = FALSE
- if(!instant && !do_mob(src, src, 2 SECONDS, uninterruptible = TRUE, extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback))))
+ if(!instant && !do_after(src, 1 SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback)), interaction_key = DOAFTER_SOURCE_GETTING_UP))
return
if(resting || body_position == STANDING_UP || HAS_TRAIT(src, TRAIT_FLOORED))
return
@@ -820,7 +820,7 @@
TH.transfer_mob_blood_dna(src)
/mob/living/carbon/human/makeTrail(turf/T)
- if((NOBLOOD in dna.species.species_traits) || !bleed_rate || bleedsuppress)
+ if((NOBLOOD in dna.species.species_traits) || bleedsuppress || !LAZYLEN(get_bleeding_parts(TRUE)))
return
..()
@@ -977,7 +977,7 @@
"[src] tries to remove your [what.name].", null, null, src)
to_chat(src, "You try to remove [who]'s [what.name]...")
what.add_fingerprint(src)
- if(do_mob(src, who, what.strip_delay))
+ if(do_after(src, what.strip_delay, who, interaction_key = what))
if(what && Adjacent(who))
if(islist(where))
var/list/L = where
@@ -1024,7 +1024,7 @@
who.visible_message("[src] tries to put [what] on [who].", \
"[src] tries to put [what] on you.", null, null, src)
to_chat(src, "You try to put [what] on [who]...")
- if(do_mob(src, who, what.equip_delay_other))
+ if(do_after(src, what.equip_delay_other, who))
if(what && Adjacent(who) && what.mob_can_equip(who, src, final_where, TRUE, TRUE))
if(temporarilyRemoveItemFromInventory(what))
if(where_list)
@@ -1144,15 +1144,6 @@
devilInfo.remove_soul(mind)
mind.soulOwner = mind
-/mob/living/proc/has_bane(banetype)
- var/datum/antagonist/devil/devilInfo = is_devil(src)
- return devilInfo && banetype == devilInfo.bane
-
-/mob/living/proc/check_weakness(obj/item/weapon, mob/living/attacker)
- if(mind && mind.has_antag_datum(/datum/antagonist/devil))
- return check_devil_bane_multiplier(weapon, attacker)
- return 1 //This is not a boolean, it's the multiplier for the damage the weapon does.
-
/mob/living/proc/check_acedia()
if(mind && mind.has_objective(/datum/objective/sintouched/acedia))
return TRUE
@@ -1419,6 +1410,32 @@
if(player_logged && stat != DEAD)
return TRUE
+// The above code is kept to prevent old SSD behavior from breaking, while the code below is dedicated to the SSD Indicator
+
+GLOBAL_VAR_INIT(ssd_indicator_overlay, mutable_appearance('icons/mob/ssd_indicator.dmi', "default0", RUNECHAT_PLANE))
+
+/mob/living
+ var/ssd_indicator = FALSE
+ var/lastclienttime = 0
+
+/mob/living/proc/set_ssd_indicator(state)
+ if(state == ssd_indicator)
+ return
+ ssd_indicator = state
+ if(ssd_indicator && stat != DEAD)
+ add_overlay(GLOB.ssd_indicator_overlay)
+ else
+ cut_overlay(GLOB.ssd_indicator_overlay)
+
+/mob/living/Login()
+ . = ..()
+ set_ssd_indicator(FALSE)
+
+/mob/living/Logout()
+ . = ..()
+ lastclienttime = world.time
+ set_ssd_indicator(TRUE)
+
/mob/living/vv_get_header()
. = ..()
var/refid = REF(src)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 86c85d27360a..2ed00efe2e4b 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -54,7 +54,7 @@
var/armor = run_armor_check(def_zone, P.flag, P.armour_penetration, silent = TRUE)
var/on_hit_state = P.on_hit(src, armor, piercing_hit)
if(!P.nodamage && on_hit_state != BULLET_ACT_BLOCK && !QDELETED(src)) //QDELETED literally just for the instagib rifle. Yeah.
- apply_damage(P.damage, P.damage_type, def_zone, armor)
+ apply_damage(P.damage, P.damage_type, def_zone, armor, sharpness = TRUE)
recoil_camera(src, clamp((P.damage-armor)/4,0.5,10), clamp((P.damage-armor)/4,0.5,10), P.damage/8, P.Angle)
apply_effects(P.stun, P.knockdown, P.unconscious, P.irradiate, P.slur, P.stutter, P.eyeblur, P.drowsy, armor, P.stamina, P.jitter, P.paralyze, P.immobilize)
if(P.dismemberment)
@@ -101,6 +101,9 @@
return 1
else
playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1) //Item sounds are handled in the item itself
+
+ if(body_position == LYING_DOWN) // physics says it's significantly harder to push someone by constantly chucking random furniture at them if they are down on the floor.
+ hitpush = FALSE
..()
@@ -179,7 +182,7 @@
log_combat(user, src, "attempted to neck grab", addition="neck grab")
if(GRAB_NECK)
log_combat(user, src, "attempted to strangle", addition="kill grab")
- if(!do_mob(user, src, grab_upgrade_time))
+ if(!do_after(user, grab_upgrade_time, src))
return 0
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state)
return 0
@@ -404,15 +407,13 @@
if(client)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, cultoverride = TRUE)
else
- switch(rand(1, 4))
+ switch(rand(1, 3))
if(1)
new /mob/living/simple_animal/hostile/construct/juggernaut/hostile(get_turf(src))
if(2)
new /mob/living/simple_animal/hostile/construct/wraith/hostile(get_turf(src))
if(3)
new /mob/living/simple_animal/hostile/construct/artificer/hostile(get_turf(src))
- if(4)
- new /mob/living/simple_animal/hostile/construct/proteon/hostile(get_turf(src))
spawn_dust()
gib()
return TRUE
diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm
index d59e3f77781e..62098a940937 100644
--- a/code/modules/mob/living/login.dm
+++ b/code/modules/mob/living/login.dm
@@ -18,7 +18,7 @@
var/virtual_z = virtual_z()
- LAZYADDASSOC(SSmobs.players_by_virtual_z, "[virtual_z]", src)
+ LAZYADDASSOCLIST(SSmobs.players_by_virtual_z, "[virtual_z]", src)
SSidlenpcpool.try_wakeup_virtual_z(virtual_z)
//Vents
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index daa987904737..cfd7d9153c8d 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -1063,3 +1063,4 @@
ghostize(1)
QDEL_NULL(src)
+
diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm
index a6d86d1507ba..80c643e0ceef 100644
--- a/code/modules/mob/living/silicon/damage_procs.dm
+++ b/code/modules/mob/living/silicon/damage_procs.dm
@@ -1,5 +1,5 @@
-/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, break_modifier = 1)
+/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, break_modifier = 1, sharpness = FALSE)
var/hit_percent = (100-blocked)/100
if((!damage || (!forced && hit_percent <= 0)))
return 0
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 1f574f08a450..9f3b85fd4a92 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -74,7 +74,7 @@
var/emitterregen = 0.25
var/emittercd = 50
var/emitteroverloadcd = 100
- var/emittersemicd = FALSE
+ var/emittercurrent_cooldown = FALSE
var/overload_ventcrawl = 0
var/overload_bulletblock = 0 //Why is this a good idea?
@@ -125,7 +125,7 @@
. = ..()
- emittersemicd = TRUE
+ emittercurrent_cooldown = TRUE
addtimer(CALLBACK(src, PROC_REF(emittercool)), 600)
if(!holoform)
diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm
index ec49e59ecace..4a3e284addd6 100644
--- a/code/modules/mob/living/silicon/pai/pai_defense.dm
+++ b/code/modules/mob/living/silicon/pai/pai_defense.dm
@@ -50,7 +50,7 @@
user.do_attack_animation(src)
if (user.name == master)
visible_message("Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence.")
- if(do_after(user, 1 SECONDS, TRUE, src))
+ if(do_after(user, 1 SECONDS, src, hidden = TRUE))
fold_in()
if(user.put_in_hands(card))
user.visible_message("[user] promptly scoops up [user.p_their()] pAI's card.")
diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm
index 31a807b319b2..8d50f4a389f4 100644
--- a/code/modules/mob/living/silicon/pai/pai_shell.dm
+++ b/code/modules/mob/living/silicon/pai/pai_shell.dm
@@ -12,11 +12,11 @@
. = fold_in(force)
return
- if(emittersemicd)
+ if(emittercurrent_cooldown)
to_chat(src, "Error: Holochassis emitters recycling. Please try again later.")
return FALSE
- emittersemicd = TRUE
+ emittercurrent_cooldown = TRUE
addtimer(CALLBACK(src, PROC_REF(emittercool)), emittercd)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PAI_FOLDED)
REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, PAI_FOLDED)
@@ -42,10 +42,10 @@
holoform = TRUE
/mob/living/silicon/pai/proc/emittercool()
- emittersemicd = FALSE
+ emittercurrent_cooldown = FALSE
/mob/living/silicon/pai/proc/fold_in(force = FALSE)
- emittersemicd = TRUE
+ emittercurrent_cooldown = TRUE
if(!force)
addtimer(CALLBACK(src, PROC_REF(emittercool)), emittercd)
else
diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm
index d15c20f1aa1d..980f12897e70 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -280,7 +280,7 @@
/mob/living/simple_animal/bot/floorbot/proc/is_hull_breach(turf/t) //Ignore space tiles not considered part of a structure, also ignores shuttle docking areas.
var/area/t_area = get_area(t)
- if(istype(t_area, /area/space) || istype(t_area, /area/solar) || istype(t_area, /area/asteroid))
+ if(istype(t_area, /area/space) || istype(t_area, /area/asteroid))
return FALSE
else
return TRUE
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index 3a07ffc4cb8d..22d68c8a6190 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -488,6 +488,9 @@
return TRUE
/mob/living/simple_animal/bot/medbot/attack_hand(mob/living/carbon/human/H)
+ if(DOING_INTERACTION_WITH_TARGET(H, src))
+ to_chat(H, "You're already interacting with [src].")
+ return
if(H.a_intent == INTENT_DISARM && mode != BOT_TIPPED)
H.visible_message("[H] begins tipping over [src].", "You begin tipping over [src]...")
@@ -574,7 +577,7 @@
C.visible_message("[src] is trying to tend the wounds of [patient]!", \
"[src] is trying to tend your wounds!")
- if(do_mob(src, patient, 20)) //Slightly faster than default tend wounds, but does less HPS
+ if(do_after(src, 2 SECONDS, patient)) //Slightly faster than default tend wounds, but does less HPS
if((get_dist(src, patient) <= 1) && (on) && assess_patient(patient))
var/healies = heal_amount
var/obj/item/storage/firstaid/FA = firstaid
diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm
index aa49c6e52b59..1b8004cbd5b5 100644
--- a/code/modules/mob/living/simple_animal/corpse.dm
+++ b/code/modules/mob/living/simple_animal/corpse.dm
@@ -47,14 +47,14 @@
id = /obj/item/card/id/syndicate
/obj/effect/mob_spawn/human/corpse/syndicateramzi
- name = "Ramzi's Clique Commando"
+ name = "Ramzi Clique Commando"
id_job = "Cutthroat"
hairstyle = "Bald"
facial_hairstyle = "Shaved"
outfit = /datum/outfit/syndicateramzicorpse
/datum/outfit/syndicateramzicorpse
- name = "Ramzi's Clique Commando Corpse"
+ name = "Ramzi Clique Commando Corpse"
uniform = /obj/item/clothing/under/syndicate/gorlex
suit = /obj/item/clothing/suit/space/hardsuit/syndi/ramzi
shoes = /obj/item/clothing/shoes/combat
@@ -125,7 +125,7 @@
/datum/outfit/frontier
name = "Frontiersman Corpse"
- uniform = /obj/item/clothing/under/rank/security/officer/frontier
+ uniform = /obj/item/clothing/under/frontiersmen
shoes = /obj/item/clothing/shoes/jackboots
head = /obj/item/clothing/head/beret/sec/frontier
gloves = /obj/item/clothing/gloves/color/black
@@ -151,11 +151,11 @@
/datum/outfit/frontier/officer
name = "Frontiersman Officer Corpse"
- uniform = /obj/item/clothing/under/rank/security/officer/frontier/officer
+ uniform = /obj/item/clothing/under/frontiersmen/officer
suit = /obj/item/clothing/suit/armor/frontier
shoes = /obj/item/clothing/shoes/combat
ears = /obj/item/radio/headset
- head = /obj/item/clothing/head/caphat/frontier
+ head = /obj/item/clothing/head/frontier/peaked
/obj/effect/mob_spawn/human/corpse/frontier/ranged/trooper/heavy
outfit = /datum/outfit/frontier/trooper/heavy
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
index 8aeb3b64a8cd..16f377cb1b01 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
@@ -17,7 +17,7 @@
if("Cannibalize")
if(D.health < D.maxHealth)
D.visible_message("[D] begins to cannibalize parts from [src].", "You begin to cannibalize parts from [src]...")
- if(do_after(D, 60, 0, target = src))
+ if(do_after(D, 60, src, FALSE))
D.visible_message("[D] repairs itself using [src]'s remains!", "You repair yourself using [src]'s remains.")
D.adjustBruteLoss(-src.maxHealth)
new /obj/effect/decal/cleanable/oil/streak(get_turf(src))
@@ -79,7 +79,7 @@
to_chat(user, "You can't seem to find the [pick(faux_gadgets)]! Without it, [src] [pick(faux_problems)].")
return
user.visible_message("[user] begins to reactivate [src].", "You begin to reactivate [src]...")
- if(do_after(user, 30, 1, target = src))
+ if(do_after(user, 30, target = src))
revive(full_heal = TRUE, admin_revive = FALSE)
user.visible_message("[user] reactivates [src]!", "You reactivate [src].")
alert_drones(DRONE_NET_CONNECT)
diff --git a/code/modules/mob/living/simple_animal/friendly/mothroach.dm b/code/modules/mob/living/simple_animal/friendly/mothroach.dm
index 2002ef3b5d8d..881e64d2a70f 100644
--- a/code/modules/mob/living/simple_animal/friendly/mothroach.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mothroach.dm
@@ -64,8 +64,3 @@
qdel(I) // this sucks
else
return ..()
-
-/mob/living/simple_animal/pet/mothroach/check_weakness(obj/item/weapon, mob/living/attacker)
- if(istype(weapon, /obj/item/melee/flyswatter))
- return 9 // flyswatters deal 10x damage to mothroaches
- return 0
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index cf1b0de8ae70..7b11d05bcf2c 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -145,9 +145,6 @@ GLOBAL_VAR_INIT(mouse_killed, 0)
else
return ..()
-/mob/living/simple_animal/mouse/attack_ghost(mob/dead/observer/user)
- user.possess_mouse(src)
-
/mob/living/simple_animal/mouse/start_pulling(atom/movable/AM, state, force, supress_message)
return FALSE
@@ -165,7 +162,7 @@ GLOBAL_VAR_INIT(mouse_killed, 0)
visible_message(
"[src] starts eating away [A]...",
"You start eating the [A]...")
- if(do_after(src, 30, FALSE, A))
+ if(do_after(src, 30, A, hidden = TRUE))
if(QDELETED(A))
return
visible_message(
diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm
index 1e02c89c81f7..57f1b1892f9d 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/support.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm
@@ -134,7 +134,7 @@
"You start to faintly glow, and you feel strangely weightless!")
do_attack_animation(A)
- if(!do_mob(src, A, 60)) //now start the channel
+ if(!do_after(src, 6 SECONDS, A)) //now start the channel
to_chat(src, "You need to hold still!")
return
diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm
deleted file mode 100644
index 57d6f2fc325f..000000000000
--- a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm
+++ /dev/null
@@ -1,171 +0,0 @@
-//Paper Wizard Boss
-/mob/living/simple_animal/hostile/boss/paper_wizard
- name = "Mjor the Creative"
- desc = "A wizard with a taste for the arts."
- mob_biotypes = MOB_HUMANOID
- boss_abilities = list(/datum/action/boss/wizard_summon_minions, /datum/action/boss/wizard_mimic)
- faction = list("hostile","stickman")
- del_on_death = TRUE
- icon = 'icons/mob/simple_human.dmi'
- icon_state = "paperwizard"
- ranged = 1
- environment_smash = ENVIRONMENT_SMASH_NONE
- minimum_distance = 3
- retreat_distance = 3
- obj_damage = 0
- melee_damage_lower = 10
- melee_damage_upper = 20
- health = 1000
- maxHealth = 1000
- loot = list(/obj/effect/temp_visual/paperwiz_dying)
- projectiletype = /obj/projectile/temp
- projectilesound = 'sound/weapons/emitter.ogg'
- attack_sound = 'sound/hallucinations/growl1.ogg'
- var/list/copies = list()
-
- footstep_type = FOOTSTEP_MOB_SHOE
-
-
-//Summon Ability
-//Lets the wizard summon his art to fight for him
-/datum/action/boss/wizard_summon_minions
- name = "Summon Minions"
- icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
- button_icon_state = "art_summon"
- usage_probability = 40
- boss_cost = 30
- boss_type = /mob/living/simple_animal/hostile/boss/paper_wizard
- needs_target = FALSE
- say_when_triggered = "Rise, my creations! Jump off your pages and into this realm!"
- var/static/summoned_minions = 0
-
-/datum/action/boss/wizard_summon_minions/Trigger()
- if(summoned_minions <= 6 && ..())
- var/list/minions = list(
- /mob/living/simple_animal/hostile/stickman,
- /mob/living/simple_animal/hostile/stickman/ranged,
- /mob/living/simple_animal/hostile/stickman/dog)
- var/list/directions = GLOB.cardinals.Copy()
- for(var/i in 1 to 3)
- var/minions_chosen = pick_n_take(minions)
- new minions_chosen (get_step(boss,pick_n_take(directions)), 1)
- summoned_minions += 3;
-
-
-//Mimic Ability
-//Summons mimics of himself with magical papercraft
-//Hitting a decoy hurts nearby people excluding the wizard himself
-//Hitting the wizard himself destroys all decoys
-/datum/action/boss/wizard_mimic
- name = "Craft Mimicry"
- icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
- button_icon_state = "mimic_summon"
- usage_probability = 30
- boss_cost = 40
- boss_type = /mob/living/simple_animal/hostile/boss/paper_wizard
- say_when_triggered = ""
-
-/datum/action/boss/wizard_mimic/Trigger()
- if(..())
- var/mob/living/target
- if(!boss.client) //AI's target
- target = boss.target
- else //random mob
- var/list/threats = boss.PossibleThreats()
- if(threats.len)
- target = pick(threats)
- if(target)
- var/mob/living/simple_animal/hostile/boss/paper_wizard/wiz = boss
- var/directions = GLOB.cardinals.Copy()
- for(var/i in 1 to 3)
- var/mob/living/simple_animal/hostile/boss/paper_wizard/copy/C = new (get_step(target,pick_n_take(directions)))
- wiz.copies += C
- C.original = wiz
- C.say("My craft defines me, you could even say it IS me!")
- wiz.say("My craft defines me, you could even say it IS me!")
- wiz.forceMove(get_step(target,pick_n_take(directions)))
- wiz.minimum_distance = 1 //so he doesn't run away and ruin everything
- wiz.retreat_distance = 0
- else
- boss.atb.refund(boss_cost)
-
-/mob/living/simple_animal/hostile/boss/paper_wizard/copy
- desc = "'Tis a ruse!"
- health = 1
- maxHealth = 1
- alpha = 200
- boss_abilities = list()
- melee_damage_lower = 1
- melee_damage_upper = 5
- minimum_distance = 0
- retreat_distance = 0
- ranged = 0
- loot = list()
- var/mob/living/simple_animal/hostile/boss/paper_wizard/original
-
-//Hit a fake? eat pain!
-/mob/living/simple_animal/hostile/boss/paper_wizard/copy/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- if(amount > 0) //damage
- if(original)
- original.minimum_distance = 3
- original.retreat_distance = 3
- original.copies -= src
- for(var/c in original.copies)
- qdel(c)
- for(var/mob/living/L in range(5,src))
- if(L == original || istype(L, type))
- continue
- L.adjustBruteLoss(50)
- qdel(src)
- else
- . = ..()
-
-//Hit the real guy? copies go bai-bai
-/mob/living/simple_animal/hostile/boss/paper_wizard/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- . = ..()
- if(. > 0)//damage
- minimum_distance = 3
- retreat_distance = 3
- for(var/copy in copies)
- qdel(copy)
-
-/mob/living/simple_animal/hostile/boss/paper_wizard/copy/examine(mob/user)
- . = ..()
- qdel(src) //I see through your ruse!
-
-//fancy effects
-/obj/effect/temp_visual/paper_scatter
- name = "scattering paper"
- desc = "Pieces of paper scattering to the wind."
- layer = ABOVE_OPEN_TURF_LAYER
- icon = 'icons/effects/effects.dmi'
- icon_state = "paper_scatter"
- anchored = TRUE
- duration = 5
- randomdir = FALSE
-
-/obj/effect/temp_visual/paperwiz_dying
- name = "craft portal"
- desc = "A wormhole sucking the wizard into the void. Neat."
- layer = ABOVE_OPEN_TURF_LAYER
- icon = 'icons/effects/effects.dmi'
- icon_state = "paperwiz_poof"
- anchored = TRUE
- duration = 18
- randomdir = FALSE
-
-/obj/effect/temp_visual/paperwiz_dying/Initialize()
- . = ..()
- visible_message("The wizard cries out in pain as a gate appears behind him, sucking him in!")
- playsound(get_turf(src),'sound/magic/mandswap.ogg', 50, TRUE, TRUE)
- playsound(get_turf(src),'sound/hallucinations/wail.ogg', 50, TRUE, TRUE)
-
-/obj/effect/temp_visual/paperwiz_dying/Destroy()
- for(var/mob/M in range(7,src))
- shake_camera(M, 7, 1)
- var/turf/T = get_turf(src)
- playsound(T,'sound/magic/summon_magic.ogg', 50, TRUE, TRUE)
- new /obj/effect/temp_visual/paper_scatter(T)
- new /obj/item/clothing/suit/wizrobe/paper(T)
- new /obj/item/clothing/head/collectable/paper(T)
- return ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm
deleted file mode 100644
index 5c3e60c8377b..000000000000
--- a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm
+++ /dev/null
@@ -1,41 +0,0 @@
-/mob/living/simple_animal/hostile/dark_wizard
- name = "Dark Wizard"
- desc = "Killing amateurs since the dawn of times."
- icon = 'icons/mob/simple_human.dmi'
- icon_state = "dark_wizard"
- icon_living = "dark_wizard"
- move_to_delay = 10
- projectiletype = /obj/projectile/temp/earth_bolt
- projectilesound = 'sound/magic/ethereal_enter.ogg'
- ranged = TRUE
- ranged_message = "earth bolts"
- ranged_cooldown_time = 20
- maxHealth = 50
- health = 50
- harm_intent_damage = 5
- obj_damage = 20
- melee_damage_lower = 5
- melee_damage_upper = 5
- attack_verb_continuous = "staves"
- a_intent = INTENT_HARM
- speak_emote = list("chants")
- attack_sound = 'sound/weapons/bladeslice.ogg'
- aggro_vision_range = 9
- turns_per_move = 5
- gold_core_spawnable = HOSTILE_SPAWN
- faction = list(ROLE_WIZARD)
- footstep_type = FOOTSTEP_MOB_SHOE
- weather_immunities = list("lava","ash")
- minbodytemp = 0
- maxbodytemp = INFINITY
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- loot = list(/obj/effect/decal/remains/human)
- del_on_death = TRUE
-
-/obj/projectile/temp/earth_bolt
- name = "earth bolt"
- icon_state = "declone"
- damage = 4
- damage_type = BURN
- flag = "energy"
- temperature = -100 // closer to the old temp loss
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 526763e875b7..70ce3f665bab 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -30,7 +30,7 @@
var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time
var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is
var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash
- var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting
+ var/check_friendly_fire = FALSE // Should the ranged mob check for friendlies when shooting
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance
diff --git a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm b/code/modules/mob/living/simple_animal/hostile/human/cat_butcher.dm
similarity index 86%
rename from code/modules/mob/living/simple_animal/hostile/cat_butcher.dm
rename to code/modules/mob/living/simple_animal/hostile/human/cat_butcher.dm
index 8da384aaca4b..0f14f615e5b6 100644
--- a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm
+++ b/code/modules/mob/living/simple_animal/hostile/human/cat_butcher.dm
@@ -1,41 +1,27 @@
-/mob/living/simple_animal/hostile/cat_butcherer
+/mob/living/simple_animal/hostile/human/cat_butcherer
name = "Cat Surgeon"
desc = "Feline genemod physiological modification surgery is outlawed in Nanotrasen-controlled sectors. This doctor doesn't seem to care, and thus, is wanted for several warcrimes."
- icon = 'icons/mob/simple_human.dmi'
icon_state = "cat_butcher"
icon_living = "cat_butcher"
- icon_dead = "syndicate_dead"
- icon_gib = "syndicate_gib"
projectiletype = /obj/projectile/bullet/dart/tranq
projectilesound = 'sound/items/syringeproj.ogg'
- ranged = 1
+ ranged = TRUE
ranged_message = "fires the syringe gun at"
ranged_cooldown_time = 30
speak_chance = 0
- turns_per_move = 5
- speed = 0
stat_attack = HARD_CRIT
- robust_searching = 1
- maxHealth = 100
- health = 100
- harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
attack_verb_continuous = "slashes at"
attack_verb_simple = "slash at"
attack_sound = 'sound/weapons/circsawhit.ogg'
- a_intent = INTENT_HARM
- mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw, /obj/item/gun/syringe)
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
- unsuitable_atmos_damage = 15
faction = list("hostile")
- check_friendly_fire = 1
- status_flags = CANPUSH
- del_on_death = 1
+ check_friendly_fire = TRUE
var/impatience = 0
-/mob/living/simple_animal/hostile/cat_butcherer/CanAttack(atom/the_target)
+/mob/living/simple_animal/hostile/human/cat_butcherer/CanAttack(atom/the_target)
if(iscarbon(target))
var/mob/living/carbon/human/C = target
if(C.getorgan(/obj/item/organ/ears/cat) && C.getorgan(/obj/item/organ/tail/cat) && C.has_trauma_type(/datum/brain_trauma/severe/pacifism))//he wont attack his creations
@@ -45,7 +31,7 @@
return FALSE
return ..()
-/mob/living/simple_animal/hostile/cat_butcherer/AttackingTarget()
+/mob/living/simple_animal/hostile/human/cat_butcherer/AttackingTarget()
if(iscarbon(target))
var/mob/living/carbon/human/L = target
if(!L.getorgan(/obj/item/organ/ears/cat) && L.stat >= UNCONSCIOUS) //target doesnt have cat ears
@@ -82,11 +68,11 @@
L.adjustOxyLoss(-50)// do CPR first
if(L.blood_volume <= 500) //bandage them up and give em some blood if they're bleeding
L.blood_volume += 30
- L.suppress_bloodloss(1800)
+ L.heal_bleeding(10)
if(L.getBruteLoss() >= 50)// first, did we beat them into crit? if so, heal that
var/healing = min(L.getBruteLoss(), 120)
L.adjustBruteLoss(-healing)
- L.suppress_bloodloss(1800)//bandage their ass
+ L.heal_bleeding(10)
return
else if(L.getFireLoss() >= 50) // are they still down from other damage? fix it, but not as fast as the burns
var/healing = min(L.getFireLoss(), 50)
diff --git a/code/modules/mob/living/simple_animal/hostile/frontiersman.dm b/code/modules/mob/living/simple_animal/hostile/human/frontiersman.dm
similarity index 69%
rename from code/modules/mob/living/simple_animal/hostile/frontiersman.dm
rename to code/modules/mob/living/simple_animal/hostile/human/frontiersman.dm
index 213cd8c2b822..4d38e1c5f87f 100644
--- a/code/modules/mob/living/simple_animal/hostile/frontiersman.dm
+++ b/code/modules/mob/living/simple_animal/hostile/human/frontiersman.dm
@@ -1,50 +1,32 @@
-/mob/living/simple_animal/hostile/frontier
+/mob/living/simple_animal/hostile/human/frontier
name = "Frontiersman"
desc = "A frontiersman! A terrorist that would probably kill everyone without mercy."
- icon = 'icons/mob/simple_human.dmi'
icon_state = "frontiersmanmelee"
icon_living = "frontiersmanmelee"
icon_dead = "frontiersmanmelee_dead"
- icon_gib = "syndicate_gib"
- mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 0
- turns_per_move = 5
- speed = 0
- maxHealth = 100
- health = 100
- harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
- attack_verb_continuous = "punches"
- attack_verb_simple = "punch"
- attack_sound = 'sound/weapons/punch1.ogg'
- a_intent = INTENT_HARM
loot = list(/obj/effect/mob_spawn/human/corpse/frontier,
/obj/item/kitchen/knife)
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
- unsuitable_atmos_damage = 15
faction = list(FACTION_ANTAG_FRONTIERSMEN)
- status_flags = CANPUSH
- del_on_death = 1
- footstep_type = FOOTSTEP_MOB_SHOE
-
-
-/mob/living/simple_animal/hostile/frontier/ranged
+/mob/living/simple_animal/hostile/human/frontier/ranged
icon_state = "frontiersmanranged"
icon_living = "frontiersmanranged"
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged,
- /obj/item/gun/ballistic/revolver)
+ /obj/item/gun/ballistic/revolver/syndicate)
ranged = 1
retreat_distance = 5
minimum_distance = 5
projectilesound = 'sound/weapons/gun/revolver/shot.ogg'
casingtype = /obj/item/ammo_casing/a357
-/mob/living/simple_animal/hostile/frontier/ranged/neutered
+/mob/living/simple_animal/hostile/human/frontier/ranged/neutered
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged)
-/mob/living/simple_animal/hostile/frontier/ranged/mosin
+/mob/living/simple_animal/hostile/human/frontier/ranged/mosin
icon_state = "frontiersmanrangedrifle"
icon_living = "frontiersmanrangedrifle"
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged,
@@ -52,10 +34,10 @@
casingtype = /obj/item/ammo_casing/a8_50r
projectilesound = 'sound/weapons/gun/rifle/mosin.ogg'
-/mob/living/simple_animal/hostile/frontier/ranged/mosin/neutered
+/mob/living/simple_animal/hostile/human/frontier/ranged/mosin/neutered
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged)
-/mob/living/simple_animal/hostile/frontier/ranged/trooper
+/mob/living/simple_animal/hostile/human/frontier/ranged/trooper
icon_state = "frontiersmanrangedelite"
icon_living = "frontiersmanrangedelite"
maxHealth = 170
@@ -65,10 +47,10 @@
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/trooper,
/obj/item/gun/ballistic/shotgun/brimstone)
-/mob/living/simple_animal/hostile/frontier/ranged/trooper/neutered
+/mob/living/simple_animal/hostile/human/frontier/ranged/trooper/neutered
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/trooper)
-/mob/living/simple_animal/hostile/frontier/ranged/trooper/skm
+/mob/living/simple_animal/hostile/human/frontier/ranged/trooper/skm
icon_state = "frontiersmanrangedak47"
icon_living = "frontiersmanrangedak47"
projectilesound = 'sound/weapons/gun/rifle/skm.ogg'
@@ -78,10 +60,10 @@
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/trooper,
/obj/item/gun/ballistic/automatic/assault/skm)
-/mob/living/simple_animal/hostile/frontier/ranged/trooper/skm/neutured
+/mob/living/simple_animal/hostile/human/frontier/ranged/trooper/skm/neutured
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/trooper)
-/mob/living/simple_animal/hostile/frontier/ranged/trooper/rifle
+/mob/living/simple_animal/hostile/human/frontier/ranged/trooper/rifle
icon_state = "frontiersmanrangedmosin"
icon_living = "frontiersmanrangedmosin"
@@ -90,10 +72,10 @@
casingtype = /obj/item/ammo_casing/a8_50r
projectilesound = 'sound/weapons/gun/rifle/mosin.ogg'
-/mob/living/simple_animal/hostile/frontier/ranged/trooper/rifle/neutered
+/mob/living/simple_animal/hostile/human/frontier/ranged/trooper/rifle/neutered
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/trooper)
-/mob/living/simple_animal/hostile/frontier/ranged/trooper/heavy
+/mob/living/simple_animal/hostile/human/frontier/ranged/trooper/heavy
icon_state = "frontiersmanrangedminigun"
icon_living = "frontiersmanrangedminigun"
projectilesound = 'sound/weapons/laser4.ogg'
@@ -105,10 +87,10 @@
projectiletype = /obj/projectile/beam/weak/penetrator
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/trooper/heavy)
-/mob/living/simple_animal/hostile/frontier/ranged/trooper/heavy/neutered
+/mob/living/simple_animal/hostile/human/frontier/ranged/trooper/heavy/neutered
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/trooper/heavy/gunless)
-/mob/living/simple_animal/hostile/frontier/ranged/officer
+/mob/living/simple_animal/hostile/human/frontier/ranged/officer
name = "Frontiersman Officer"
icon_state = "frontiersmanofficer"
icon_living = "frontiersmanofficer"
@@ -119,10 +101,10 @@
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/officer,
/obj/item/gun/ballistic/automatic/pistol/APS)
-/mob/living/simple_animal/hostile/frontier/ranged/officer/neutured
+/mob/living/simple_animal/hostile/human/frontier/ranged/officer/neutured
loot = list(/obj/effect/mob_spawn/human/corpse/frontier/ranged/officer)
-/mob/living/simple_animal/hostile/frontier/ranged/officer/Aggro()
+/mob/living/simple_animal/hostile/human/frontier/ranged/officer/Aggro()
..()
summon_backup(15)
say(pick("Help!!", "They're right here!!", "Don't let me die!!"))
diff --git a/code/modules/mob/living/simple_animal/hostile/human/human.dm b/code/modules/mob/living/simple_animal/hostile/human/human.dm
new file mode 100644
index 000000000000..633bd40090e8
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/human/human.dm
@@ -0,0 +1,41 @@
+/mob/living/simple_animal/hostile/human
+ name = "crazed human"
+ desc = "A crazed human, they cannot be reasoned with"
+ icon = 'icons/mob/simple_human.dmi'
+ icon_state = "survivor_base"
+ icon_living = "survivor_base"
+ icon_dead = null
+ icon_gib = "syndicate_gib"
+ mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
+
+ speak_chance = 20
+ speak_emote = list("groans")
+
+ turns_per_move = 5
+ speed = 0
+ maxHealth = 100
+ health = 100
+
+ robust_searching = TRUE
+ harm_intent_damage = 5
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ attack_verb_continuous = "punches"
+ attack_verb_simple = "punch"
+ attack_sound = 'sound/weapons/punch1.ogg'
+ a_intent = INTENT_HARM
+ response_help_continuous = "pushes"
+ response_help_simple = "push"
+
+ loot = list(/obj/effect/mob_spawn/human/corpse/damaged)
+ del_on_death = TRUE
+
+ atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
+ unsuitable_atmos_damage = 15
+ minbodytemp = 180
+ status_flags = CANPUSH
+ del_on_death = TRUE
+
+ footstep_type = FOOTSTEP_MOB_SHOE
+
+ faction = list("hermit")
diff --git a/code/modules/mob/living/simple_animal/hostile/human/nanotrasen.dm b/code/modules/mob/living/simple_animal/hostile/human/nanotrasen.dm
new file mode 100644
index 000000000000..6c1676d202ab
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/human/nanotrasen.dm
@@ -0,0 +1,80 @@
+/mob/living/simple_animal/hostile/human/nanotrasen
+ name = "\improper Nanotrasen Private Security Officer"
+ desc = "An officer part of Nanotrasen's private security force, he seems rather unpleased to meet you."
+ icon_state = "nanotrasen"
+ icon_living = "nanotrasen"
+ speak_chance = 0
+ stat_attack = HARD_CRIT
+ melee_damage_upper = 15
+ loot = list(/obj/effect/mob_spawn/human/corpse/nanotrasensoldier)
+ atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
+ faction = list(ROLE_DEATHSQUAD)
+ check_friendly_fire = TRUE
+ dodging = TRUE
+
+/mob/living/simple_animal/hostile/human/nanotrasen/screaming
+ icon_state = "nanotrasen"
+ icon_living = "nanotrasen"
+
+/mob/living/simple_animal/hostile/human/nanotrasen/screaming/Aggro()
+ ..()
+ summon_backup(15)
+ say("411 in progress, requesting backup!")
+
+
+/mob/living/simple_animal/hostile/human/nanotrasen/ranged
+ icon_state = "nanotrasenranged"
+ icon_living = "nanotrasenranged"
+ ranged = 1
+ retreat_distance = 3
+ minimum_distance = 5
+ casingtype = /obj/item/ammo_casing/c45
+ projectilesound = 'sound/weapons/gun/pistol/shot_alt.ogg'
+
+
+/mob/living/simple_animal/hostile/human/nanotrasen/ranged/smg
+ icon_state = "nanotrasenrangedsmg"
+ icon_living = "nanotrasenrangedsmg"
+ rapid = 3
+ casingtype = /obj/item/ammo_casing/c46x30mm
+ projectilesound = 'sound/weapons/gun/smg/shot.ogg'
+
+/mob/living/simple_animal/hostile/human/nanotrasen/ranged/assault
+ name = "Nanotrasen Assault Officer"
+ desc = "A Nanotrasen Assault Officer. Prepare to die, if you've been found near Syndicate property."
+ icon_state = "nanotrasenrangedassault"
+ icon_living = "nanotrasenrangedassault"
+ icon_dead = null
+ icon_gib = "syndicate_gib"
+ ranged = TRUE
+ rapid = 4
+ rapid_fire_delay = 1
+ rapid_melee = 1
+ retreat_distance = 2
+ minimum_distance = 4
+ casingtype = /obj/item/ammo_casing/c46x30mm
+ projectilesound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
+ loot = list(/obj/effect/mob_spawn/human/corpse/nanotrasenassaultsoldier)
+
+/mob/living/simple_animal/hostile/human/nanotrasen/elite
+ name = "Nanotrasen Elite Assault Officer"
+ desc = "Pray for your life, syndicate. Run while you can."
+ icon = 'icons/mob/simple_human.dmi'
+ icon_state = "nanotrasen_ert"
+ icon_living = "nanotrasen_ert"
+ maxHealth = 150
+ health = 150
+ melee_damage_lower = 13
+ melee_damage_upper = 18
+ ranged = TRUE
+ rapid = 3
+ rapid_fire_delay = 5
+ rapid_melee = 3
+ retreat_distance = 0
+ minimum_distance = 1
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
+ projectiletype = /obj/projectile/beam/laser
+ projectilesound = 'sound/weapons/laser.ogg'
+ loot = list(/obj/effect/gibspawner/human)
+ faction = list(ROLE_DEATHSQUAD)
diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/human/pirate.dm
similarity index 67%
rename from code/modules/mob/living/simple_animal/hostile/pirate.dm
rename to code/modules/mob/living/simple_animal/hostile/human/pirate.dm
index b0bc7941fd69..df10cfa6a2b4 100644
--- a/code/modules/mob/living/simple_animal/hostile/pirate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/human/pirate.dm
@@ -1,35 +1,17 @@
-/mob/living/simple_animal/hostile/pirate
+/mob/living/simple_animal/hostile/human/pirate
name = "Pirate"
desc = "Does what he wants cause a pirate is free."
- icon = 'icons/mob/simple_human.dmi'
icon_state = "piratemelee"
icon_living = "piratemelee"
icon_dead = "pirate_dead"
- mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 0
- turns_per_move = 5
- response_help_continuous = "pushes"
- response_help_simple = "push"
- speed = 0
- maxHealth = 100
- health = 100
- harm_intent_damage = 5
- melee_damage_lower = 10
- melee_damage_upper = 10
- attack_verb_continuous = "punches"
- attack_verb_simple = "punch"
- attack_sound = 'sound/weapons/punch1.ogg'
- a_intent = INTENT_HARM
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
- unsuitable_atmos_damage = 15
speak_emote = list("yarrs")
loot = list(/obj/effect/mob_spawn/human/corpse/pirate,
/obj/item/melee/transforming/energy/sword/saber/pirate)
- del_on_death = 1
faction = list("pirate")
-
-/mob/living/simple_animal/hostile/pirate/melee
+/mob/living/simple_animal/hostile/human/pirate/melee
name = "Pirate Swashbuckler"
icon_state = "piratemelee"
icon_living = "piratemelee"
@@ -44,7 +26,7 @@
footstep_type = FOOTSTEP_MOB_SHOE
-/mob/living/simple_animal/hostile/pirate/melee/space
+/mob/living/simple_animal/hostile/human/pirate/melee/space
name = "Space Pirate Swashbuckler"
icon_state = "piratespace"
icon_living = "piratespace"
@@ -53,23 +35,23 @@
minbodytemp = 0
speed = 1
-/mob/living/simple_animal/hostile/pirate/melee/space/Initialize()
+/mob/living/simple_animal/hostile/human/pirate/melee/space/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
-/mob/living/simple_animal/hostile/pirate/melee/Initialize()
+/mob/living/simple_animal/hostile/human/pirate/melee/Initialize()
. = ..()
sord = new(src)
-/mob/living/simple_animal/hostile/pirate/melee/Destroy()
+/mob/living/simple_animal/hostile/human/pirate/melee/Destroy()
QDEL_NULL(sord)
return ..()
-/mob/living/simple_animal/hostile/pirate/melee/Initialize()
+/mob/living/simple_animal/hostile/human/pirate/melee/Initialize()
. = ..()
set_light(2)
-/mob/living/simple_animal/hostile/pirate/ranged
+/mob/living/simple_animal/hostile/human/pirate/ranged
name = "Pirate Gunner"
icon_state = "pirateranged"
icon_living = "pirateranged"
@@ -84,7 +66,7 @@
loot = list(/obj/effect/mob_spawn/human/corpse/pirate/ranged,
/obj/item/gun/energy/laser)
-/mob/living/simple_animal/hostile/pirate/ranged/space
+/mob/living/simple_animal/hostile/human/pirate/ranged/space
name = "Space Pirate Gunner"
icon_state = "piratespaceranged"
icon_living = "piratespaceranged"
@@ -93,6 +75,6 @@
minbodytemp = 0
speed = 1
-/mob/living/simple_animal/hostile/pirate/ranged/space/Initialize()
+/mob/living/simple_animal/hostile/human/pirate/ranged/space/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/human/skeleton.dm
similarity index 74%
rename from code/modules/mob/living/simple_animal/hostile/skeleton.dm
rename to code/modules/mob/living/simple_animal/hostile/human/skeleton.dm
index 477233566f35..b251dda91e48 100644
--- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm
+++ b/code/modules/mob/living/simple_animal/hostile/human/skeleton.dm
@@ -1,20 +1,16 @@
-/mob/living/simple_animal/hostile/skeleton
+/mob/living/simple_animal/hostile/human/skeleton
name = "reanimated skeleton"
desc = "A real bonefied skeleton, doesn't seem like it wants to socialize."
- icon = 'icons/mob/simple_human.dmi'
icon_state = "skeleton"
icon_living = "skeleton"
icon_dead = "skeleton"
gender = NEUTER
mob_biotypes = MOB_UNDEAD|MOB_HUMANOID
- turns_per_move = 5
speak_emote = list("rattles")
emote_see = list("rattles")
- a_intent = INTENT_HARM
maxHealth = 40
health = 40
speed = 1
- harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
minbodytemp = 0
@@ -25,36 +21,15 @@
attack_sound = 'sound/hallucinations/growl1.ogg'
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 10
- robust_searching = 1
stat_attack = HARD_CRIT
faction = list("skeleton")
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
deathmessage = "collapses into a pile of bones!"
- del_on_death = 1
loot = list(/obj/effect/decal/remains/human)
-
footstep_type = FOOTSTEP_MOB_SHOE
-/mob/living/simple_animal/hostile/skeleton/eskimo
- name = "undead eskimo"
- desc = "The reanimated remains of some poor traveler."
- icon_state = "eskimo"
- icon_living = "eskimo"
- icon_dead = "eskimo_dead"
- maxHealth = 55
- health = 55
- weather_immunities = list("snow")
- melee_damage_lower = 17
- melee_damage_upper = 20
- deathmessage = "collapses into a pile of bones, its gear falling to the floor!"
- loot = list(/obj/effect/decal/remains/human,
- /obj/item/spear,
- /obj/item/clothing/shoes/winterboots,
- /obj/item/clothing/suit/hooded/wintercoat)
-
-
-/mob/living/simple_animal/hostile/skeleton/templar
+/mob/living/simple_animal/hostile/human/skeleton/templar
name = "undead templar"
desc = "The reanimated remains of a holy templar knight."
icon_state = "templar"
@@ -72,11 +47,11 @@
melee_damage_upper = 30
deathmessage = "collapses into a pile of bones, its gear clanging as it hits the ground!"
loot = list(/obj/effect/decal/remains/human,
- /obj/item/clothing/suit/armor/riot/chaplain,
- /obj/item/clothing/head/helmet/chaplain,
+ /obj/item/clothing/suit/armor/witchhunter,
+ /obj/item/clothing/head/witchunter,
/obj/item/claymore/weak{name = "holy sword"})
-/mob/living/simple_animal/hostile/skeleton/ice
+/mob/living/simple_animal/hostile/human/skeleton/ice
name = "ice skeleton"
desc = "A reanimated skeleton protected by a thick sheet of natural ice armor. Looks slow, though."
speed = 5
@@ -86,7 +61,7 @@
color = rgb(114,228,250)
loot = list(/obj/effect/decal/remains/human{color = rgb(114,228,250)})
-/mob/living/simple_animal/hostile/skeleton/plasmaminer
+/mob/living/simple_animal/hostile/human/skeleton/plasmaminer
name = "shambling miner"
desc = "A plasma-soaked miner, their exposed limbs turned into a grossly incandescent bone seemingly made of plasma."
icon_state = "plasma_miner"
@@ -104,7 +79,7 @@
deathmessage = "collapses into a pile of bones, their suit dissolving among the plasma!"
loot = list(/obj/effect/decal/remains/plasma)
-/mob/living/simple_animal/hostile/skeleton/plasmaminer/jackhammer
+/mob/living/simple_animal/hostile/human/skeleton/plasmaminer/jackhammer
desc = "A plasma-soaked miner, their exposed limbs turned into a grossly incandescent bone seemingly made of plasma. They seem to still have their mining tool in their hand, gripping tightly."
icon_state = "plasma_miner_tool"
icon_living = "plasma_miner_tool"
@@ -119,6 +94,6 @@
attack_sound = 'sound/weapons/sonic_jackhammer.ogg'
loot = list(/obj/effect/decal/remains/plasma, /obj/item/pickaxe/drill/jackhammer)
-/mob/living/simple_animal/hostile/skeleton/plasmaminer/Initialize()
+/mob/living/simple_animal/hostile/human/skeleton/plasmaminer/Initialize()
. = ..()
set_light(2)
diff --git a/code/modules/mob/living/simple_animal/hostile/survivors.dm b/code/modules/mob/living/simple_animal/hostile/human/survivors.dm
similarity index 52%
rename from code/modules/mob/living/simple_animal/hostile/survivors.dm
rename to code/modules/mob/living/simple_animal/hostile/human/survivors.dm
index bc7573552bc5..f7abea96b222 100644
--- a/code/modules/mob/living/simple_animal/hostile/survivors.dm
+++ b/code/modules/mob/living/simple_animal/hostile/human/survivors.dm
@@ -1,59 +1,41 @@
-/mob/living/simple_animal/hostile/asteroid/whitesands
+/mob/living/simple_animal/hostile/human/hermit
name = "Whitesands Inhabitant"
desc = "If you can read this, yell at a coder!"
- icon = 'icons/mob/simple_human.dmi'
icon_state = "survivor_base"
icon_living = "survivor_base"
- icon_dead = null
- icon_gib = "syndicate_gib"
- mob_biotypes = MOB_ORGANIC
- minbodytemp = 180
- unsuitable_atmos_damage = 15
atmos_requirements = list("min_oxy" = 1, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 999, "min_n2" = 0, "max_n2" = 0)
- speak_chance = 20
- turns_per_move = 5
- response_help_continuous = "pushes"
- response_help_simple = "push"
- speed = 0
- maxHealth = 100
- health = 100
- harm_intent_damage = 5
- melee_damage_lower = 10
- melee_damage_upper = 10
- attack_verb_continuous = "punches"
- attack_verb_simple = "punch"
- attack_sound = 'sound/weapons/punch1.ogg'
- a_intent = INTENT_HARM
- unsuitable_atmos_damage = 15
- speak_emote = list("groans")
loot = list(
/obj/effect/mob_spawn/human/corpse/damaged/whitesands
)
- del_on_death = 1
- faction = list("hermit")
-/mob/living/simple_animal/hostile/asteroid/whitesands/survivor/death(gibbed)
+/mob/living/simple_animal/hostile/human/hermit/survivor/death(gibbed)
move_force = MOVE_FORCE_DEFAULT
move_resist = MOVE_RESIST_DEFAULT
pull_force = PULL_FORCE_DEFAULT
+ ..()
+ /*
if(prob(15))
- new /obj/item/crusher_trophy/shiny(loc)
+ new /obj/item/mob_trophy/shiny(loc)
visible_message("You notice a glimmering nugget of shiny metal.")
- ..()
+ */
-/mob/living/simple_animal/hostile/asteroid/whitesands/survivor
+/mob/living/simple_animal/hostile/human/hermit/survivor
name = "Hermit Wanderer"
desc =" A wild-eyed figure, wearing tattered mining equipment and boasting a malformed body, twisted by the heavy metals and high background radiation of the sandworlds."
+ loot = list(
+ /obj/effect/mob_spawn/human/corpse/damaged/whitesands/survivor
+ )
-/mob/living/simple_animal/hostile/asteroid/whitesands/survivor/random/Initialize()
+/mob/living/simple_animal/hostile/human/hermit/survivor/random/Initialize()
. = ..()
if(prob(35))
- new /mob/living/simple_animal/hostile/asteroid/whitesands/ranged/hunter(loc)
+ new /mob/living/simple_animal/hostile/human/hermit/ranged/hunter(loc)
+ return INITIALIZE_HINT_QDEL
if(prob(10))
- new /mob/living/simple_animal/hostile/asteroid/whitesands/ranged/gunslinger(loc)
+ new /mob/living/simple_animal/hostile/human/hermit/ranged/gunslinger(loc)
return INITIALIZE_HINT_QDEL
-/mob/living/simple_animal/hostile/asteroid/whitesands/ranged
+/mob/living/simple_animal/hostile/human/hermit/ranged
icon_state = "survivor_hunter"
icon_living = "survivor_hunter"
projectiletype = null
@@ -64,14 +46,14 @@
retreat_distance = 5
minimum_distance = 5
-/mob/living/simple_animal/hostile/asteroid/whitesands/ranged/hunter
+/mob/living/simple_animal/hostile/human/hermit/ranged/hunter
name = "Hermit Hunter"
desc ="A wild-eyed figure. Watch out- he has a gun, and he remembers just enough of his old life to use it!"
loot = list(
/obj/effect/mob_spawn/human/corpse/damaged/whitesands/hunter,
)
-/mob/living/simple_animal/hostile/asteroid/whitesands/ranged/gunslinger
+/mob/living/simple_animal/hostile/human/hermit/ranged/gunslinger
name = "Hermit Soldier"
desc = "The miner's rebellion, though mostly underground, recieved a few good weapon shipments from an off-sector source. You should probably start running."
icon_state = "survivor_gunslinger"
@@ -88,102 +70,25 @@
//survivor corpses
/obj/effect/mob_spawn/human/corpse/damaged/whitesands
+ uniform = /obj/item/clothing/under/color/random
+ belt = /obj/item/storage/belt/fannypack
+ shoes = /obj/item/clothing/shoes/workboots/mining
+ suit = /obj/item/clothing/suit/hooded/survivor
+ l_pocket = /obj/item/radio
+ r_pocket = /obj/item/tank/internals/emergency_oxygen/engi
var/survivor_type //room for alternatives inside the fuckoff grade init.
/obj/effect/mob_spawn/human/corpse/damaged/whitesands/Initialize() //everything here should equal out to 100 for the sake of my sanity.
-
mob_species = pickweight(list(
/datum/species/human = 50,
- /datum/species/lizard = 25,
- /datum/species/ethereal = 10,
- /datum/species/moth = 10,
- /datum/species/spider = 3,
- /datum/species/fly = 2
- )
+ /datum/species/lizard = 20,
+ /datum/species/ipc = 10,
+ /datum/species/elzuose = 10,
+ /datum/species/moth = 5,
+ /datum/species/spider = 5
)
+ )
//to-do: learn how to make mobsprites for other survivors
- //uniforms are random to show varied backgrounds, but similar goal
- if(survivor_type == "survivor")
- uniform = pickweight(list(
- /obj/item/clothing/under/color/random = 65,
- /obj/item/clothing/under/rank/cargo/miner/lavaland = 10,
- /obj/item/clothing/under/rank/prisoner = 10,
- /obj/item/clothing/under/rank/cargo/miner/lavaland/old = 5,
- /obj/item/clothing/under/color/khaki/buster = 5,
- /obj/item/clothing/under/rank/cargo/miner = 5
- )
- )
- else if (survivor_type == "hunter")
- uniform = pickweight(list(
- /obj/item/clothing/under/color/random = 50,
- /obj/item/clothing/under/rank/cargo/miner/lavaland = 25,
- /obj/item/clothing/under/rank/cargo/miner/lavaland/old = 15,
- /obj/item/clothing/under/rank/security/officer/camo = 5,
- /obj/item/clothing/under/utility = 5
- )
- )
- else if (survivor_type == "gunslinger")
- uniform = pickweight(list(
- /obj/item/clothing/under/rank/cargo/miner/lavaland = 35,
- /obj/item/clothing/under/color/random = 25,
- /obj/item/clothing/under/rank/cargo/miner/lavaland/old = 15,
- /obj/item/clothing/under/rank/security/officer/camo = 10,
- /obj/item/clothing/under/syndicate/camo = 10,
- /obj/item/clothing/under/syndicate/combat = 5
- )
- )
- else
- uniform = /obj/item/clothing/under/color/random
-
- //storage is semi-randomized, giving some variety
- if(survivor_type == "survivor")
- belt = pickweight(list(
- /obj/item/storage/belt/fannypack = 40,
- /obj/item/storage/belt/mining = 20,
- /obj/item/storage/belt/mining/alt = 15,
- /obj/item/storage/belt/utility = 10,
- /obj/item/storage/belt/bandolier = 9,
- /obj/item/storage/belt/utility/full = 5,
- /obj/item/storage/belt/chameleon= 1,
- )
- )
- else if(survivor_type == "hunter")
- belt = pickweight(list(
- /obj/item/storage/belt/mining = 30,
- /obj/item/storage/belt/fannypack = 20,
- /obj/item/storage/belt/mining/alt = 15,
- /obj/item/storage/belt/mining/primitive = 15,
- /obj/item/storage/belt/bandolier = 10,
- /obj/item/storage/belt/military = 7,
- /obj/item/storage/belt/mining/vendor = 3,
- )
- )
- else if(survivor_type == "gunslinger")
- belt = pickweight(list(
- /obj/item/storage/belt/mining = 30,
- /obj/item/storage/belt/bandolier = 30,
- /obj/item/storage/belt/military = 20,
- /obj/item/storage/belt/fannypack = 15,
- /obj/item/storage/belt/mining/alt = 5,
- /obj/item/storage/belt/mining/primitive = 5
- )
- )
- else
- belt = /obj/item/storage/belt/fannypack
-
- //everyone wears the same suit
- suit = /obj/item/clothing/suit/hooded/survivor
-
- if (survivor_type == "gunslinger")
- if(prob(30))
- shoes = /obj/item/clothing/shoes/combat //but sometimes there are nicer shoes
- else
- shoes = /obj/item/clothing/shoes/workboots/mining
- else
- shoes = /obj/item/clothing/shoes/workboots/mining
-
-
-
//gloves are a tossup
gloves = pickweight(list(
@@ -260,35 +165,6 @@
if(prob(30)) //some pens maybe?
backpack_contents += /obj/item/reagent_containers/hypospray/medipen/survival
- //pockets
- if(survivor_type == "survivor") //could also use fleshing out
- if(prob(30))
- l_pocket = /obj/item/reagent_containers/food/snacks/meat/steak/goliath
- else
- l_pocket = /obj/item/tank/internals/emergency_oxygen/engi
- if (prob(20))
- r_pocket = /obj/item/spacecash/bundle/mediumrand
- else
- r_pocket = null
-
- if(survivor_type == "hunter")
- l_pocket = /obj/item/tank/internals/emergency_oxygen/engi
- if (prob(20))
- r_pocket = /obj/item/reagent_containers/food/snacks/meat/steak/goliath
- else if (prob(60))
- r_pocket = /obj/item/ammo_box/aac_300blk_stripper
- else
- r_pocket = null
-
- if(survivor_type == "gunslinger")
- if(prob(50))
- l_pocket = /obj/item/ammo_box/magazine/skm_545_39
- r_pocket = /obj/item/tank/internals/emergency_oxygen/engi
-
- else
- r_pocket = /obj/item/tank/internals/emergency_oxygen/engi
- l_pocket = /obj/item/radio
-
//masks
mask = pickweight(list(
/obj/item/clothing/mask/gas = 40,
@@ -298,7 +174,7 @@
)
)
- //the eyes are the window into the soul. I don't think these things have souls but whatever.
+ //the eyes are the window into the soul.
if(prob(70))
glasses = pickweight(list(
/obj/item/clothing/glasses/heat = 20,
@@ -307,8 +183,6 @@
/obj/item/clothing/glasses = 20
)
)
- else
- glasses = null
//and of course, ears.
if(prob(1)) //oh my god they can't hear the sandstorm coming they've got airpods in
@@ -319,21 +193,91 @@
/obj/item/radio/headset/alt = 50
)
)
+ //now for the fun stuff
+ switch(survivor_type)
+ if("survivor")
+ //uniforms are random to show varied backgrounds, but similar goal
+ uniform = pickweight(list(
+ /obj/item/clothing/under/color/random = 65,
+ /obj/item/clothing/under/rank/cargo/miner/lavaland = 10,
+ /obj/item/clothing/under/rank/prisoner = 10,
+ /obj/item/clothing/under/rank/cargo/miner/lavaland/old = 5,
+ /obj/item/clothing/under/color/khaki/buster = 5,
+ /obj/item/clothing/under/rank/cargo/miner = 5
+ )
+ )
+ //storage is semi-randomized, giving some variety
+ belt = pickweight(list(
+ /obj/item/storage/belt/fannypack = 40,
+ /obj/item/storage/belt/mining = 20,
+ /obj/item/storage/belt/mining/alt = 15,
+ /obj/item/storage/belt/utility = 10,
+ /obj/item/storage/belt/bandolier = 9,
+ /obj/item/storage/belt/utility/full = 5,
+ /obj/item/storage/belt/chameleon= 1,
+ )
+ )
+ if(prob(30))
+ l_pocket = /obj/item/reagent_containers/food/snacks/meat/steak/goliath
+ if(prob(20))
+ r_pocket = /obj/item/spacecash/bundle/smallrand
+
+ if("hunter")
+ uniform = pickweight(list(
+ /obj/item/clothing/under/color/random = 50,
+ /obj/item/clothing/under/rank/cargo/miner/lavaland = 25,
+ /obj/item/clothing/under/rank/cargo/miner/lavaland/old = 15,
+ /obj/item/clothing/under/rank/security/officer/camo = 5,
+ /obj/item/clothing/under/utility = 5
+ )
+ )
+ belt = pickweight(list(
+ /obj/item/storage/belt/mining = 30,
+ /obj/item/storage/belt/fannypack = 20,
+ /obj/item/storage/belt/mining/alt = 15,
+ /obj/item/storage/belt/mining/primitive = 15,
+ /obj/item/storage/belt/bandolier = 10,
+ /obj/item/storage/belt/military = 7,
+ /obj/item/storage/belt/mining/vendor = 3,
+ )
+ )
+ if(prob(20))
+ l_pocket = /obj/item/reagent_containers/food/snacks/meat/steak/goliath
+ else if(prob(60))
+ l_pocket = /obj/item/ammo_box/aac_300blk_stripper
+ if(prob(20))
+ new /obj/item/gun/ballistic/rifle/polymer(loc)
+ else
+ visible_message(span_warning("The hunter's weapon shatters as they impact the ground!"))
+
+ if("gunslinger")
+ uniform = pickweight(list(
+ /obj/item/clothing/under/rank/cargo/miner/lavaland = 35,
+ /obj/item/clothing/under/color/random = 25,
+ /obj/item/clothing/under/rank/cargo/miner/lavaland/old = 15,
+ /obj/item/clothing/under/rank/security/officer/camo = 10,
+ /obj/item/clothing/under/syndicate/camo = 10,
+ /obj/item/clothing/under/syndicate/combat = 5
+ )
+ )
+ belt = pickweight(list(
+ /obj/item/storage/belt/mining = 30,
+ /obj/item/storage/belt/bandolier = 30,
+ /obj/item/storage/belt/military = 20,
+ /obj/item/storage/belt/fannypack = 15,
+ /obj/item/storage/belt/mining/alt = 5,
+ /obj/item/storage/belt/mining/primitive = 5
+ )
+ )
+ if(prob(30))
+ shoes = /obj/item/clothing/shoes/combat //sometimes there are nicer shoes
+ if(prob(50))
+ l_pocket = /obj/item/ammo_box/magazine/skm_545_39
+ if(prob(20))
+ new /obj/item/gun/ballistic/automatic/smg/skm_carbine(loc)
+ else
+ visible_message(span_warning("The gunslinger's weapon shatters as they impact the ground!"))
- //exosuit bits
- suit_store = null
- if (survivor_type == "hunter")
- if(prob(20))
- new /obj/item/gun/ballistic/rifle/polymer(loc)
- else
- visible_message("The hunter's weapon shatters as they impact the ground!")
- suit_store = null
- if(survivor_type == "gunslinger")
- if(prob(20))
- new /obj/item/gun/ballistic/automatic/smg/skm_carbine(loc)
- else
- visible_message("The gunslinger's weapon shatters as they impact the ground!")
- suit_store = null
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/human/syndicate.dm
similarity index 61%
rename from code/modules/mob/living/simple_animal/hostile/syndicate.dm
rename to code/modules/mob/living/simple_animal/hostile/human/syndicate.dm
index b98d14128e12..a88a79610b60 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/human/syndicate.dm
@@ -1,12 +1,3 @@
-/*
- CONTENTS
- LINE 10 - BASE MOB
- LINE 52 - SWORD AND SHIELD
- LINE 164 - GUNS
- LINE 267 - MISC
-*/
-
-
///////////////Base mob////////////
/obj/effect/light_emitter/red_energy_sword //used so there's a combination of both their head light and light coming off the energy sword
set_luminosity = 2
@@ -14,65 +5,48 @@
light_color = COLOR_SOFT_RED
-/mob/living/simple_animal/hostile/syndicate
- name = "Syndicate Operative"
- desc = "Death to Nanotrasen."
- icon = 'icons/mob/simple_human.dmi'
+/mob/living/simple_animal/hostile/human/syndicate
+ name = "Ramzi Clique Operative"
+ desc = "An ex-Syndicate pirate of the Ramzi Clique."
icon_state = "syndicate"
icon_living = "syndicate"
- icon_dead = "syndicate_dead"
- icon_gib = "syndicate_gib"
- mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 0
- turns_per_move = 5
- speed = 0
stat_attack = HARD_CRIT
- robust_searching = 1
- maxHealth = 100
- health = 100
- harm_intent_damage = 5
- melee_damage_lower = 10
- melee_damage_upper = 10
- attack_verb_continuous = "punches"
- attack_verb_simple = "punch"
- attack_sound = 'sound/weapons/punch1.ogg'
- a_intent = INTENT_HARM
loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier)
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
+ maxbodytemp = 400
unsuitable_atmos_damage = 15
faction = list(FACTION_ANTAG_SYNDICATE)
- check_friendly_fire = 1
- status_flags = CANPUSH
- del_on_death = 1
+ check_friendly_fire = TRUE
dodging = TRUE
rapid_melee = 2
- footstep_type = FOOTSTEP_MOB_SHOE
///////////////Melee////////////
-/mob/living/simple_animal/hostile/syndicate/space
+/mob/living/simple_animal/hostile/human/syndicate/space
icon_state = "syndicate_space"
icon_living = "syndicate_space"
- name = "Syndicate Commando"
+ name = "Ramzi Clique Commando"
maxHealth = 170
health = 170
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
+ maxbodytemp = 1000
speed = 1
-/mob/living/simple_animal/hostile/syndicate/space/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/space/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
set_light(4)
-/mob/living/simple_animal/hostile/syndicate/space/stormtrooper
+/mob/living/simple_animal/hostile/human/syndicate/space/stormtrooper
icon_state = "syndicate_stormtrooper"
icon_living = "syndicate_stormtrooper"
- name = "Syndicate Stormtrooper"
+ name = "Ramzi Clique Assault Trooper"
maxHealth = 250
health = 250
-/mob/living/simple_animal/hostile/syndicate/melee //dude with a knife and no shields
+/mob/living/simple_animal/hostile/human/syndicate/melee //dude with a knife and no shields
melee_damage_lower = 15
melee_damage_upper = 15
icon_state = "syndicate_knife"
@@ -84,31 +58,32 @@
status_flags = 0
var/projectile_deflect_chance = 0
-/mob/living/simple_animal/hostile/syndicate/melee/space
+/mob/living/simple_animal/hostile/human/syndicate/melee/space
icon_state = "syndicate_space_knife"
icon_living = "syndicate_space_knife"
- name = "Syndicate Commando"
+ name = "Ramzi Clique Commando"
maxHealth = 170
health = 170
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
+ maxbodytemp = 1000
speed = 1
projectile_deflect_chance = 50
-/mob/living/simple_animal/hostile/syndicate/melee/space/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/melee/space/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
set_light(4)
-/mob/living/simple_animal/hostile/syndicate/melee/space/stormtrooper
+/mob/living/simple_animal/hostile/human/syndicate/melee/space/stormtrooper
icon_state = "syndicate_stormtrooper_knife"
icon_living = "syndicate_stormtrooper_knife"
- name = "Syndicate Stormtrooper"
+ name = "Ramzi Clique Stormtrooper"
maxHealth = 250
health = 250
projectile_deflect_chance = 50
-/mob/living/simple_animal/hostile/syndicate/melee/sword
+/mob/living/simple_animal/hostile/human/syndicate/melee/sword
melee_damage_lower = 30
melee_damage_upper = 30
icon_state = "syndicate_sword"
@@ -122,52 +97,53 @@
var/obj/effect/light_emitter/red_energy_sword/sord
projectile_deflect_chance = 50
-/mob/living/simple_animal/hostile/syndicate/melee/sword/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/melee/sword/Initialize()
. = ..()
set_light(2)
-/mob/living/simple_animal/hostile/syndicate/melee/sword/Destroy()
+/mob/living/simple_animal/hostile/human/syndicate/melee/sword/Destroy()
QDEL_NULL(sord)
return ..()
-/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(obj/projectile/Proj)
+/mob/living/simple_animal/hostile/human/syndicate/melee/bullet_act(obj/projectile/Proj)
if(prob(projectile_deflect_chance))
visible_message("[src] blocks [Proj] with its shield!")
return BULLET_ACT_BLOCK
return ..()
-/mob/living/simple_animal/hostile/syndicate/melee/sword/space
+/mob/living/simple_animal/hostile/human/syndicate/melee/sword/space
icon_state = "syndicate_space_sword"
icon_living = "syndicate_space_sword"
- name = "Syndicate Commando"
+ name = "Ramzi Clique Commando"
maxHealth = 170
health = 170
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
+ maxbodytemp = 1000
speed = 1
projectile_deflect_chance = 50
-/mob/living/simple_animal/hostile/syndicate/melee/sword/space/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/melee/sword/space/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
sord = new(src)
set_light(4)
-/mob/living/simple_animal/hostile/syndicate/melee/sword/space/Destroy()
+/mob/living/simple_animal/hostile/human/syndicate/melee/sword/space/Destroy()
QDEL_NULL(sord)
return ..()
-/mob/living/simple_animal/hostile/syndicate/melee/sword/space/stormtrooper
+/mob/living/simple_animal/hostile/human/syndicate/melee/sword/space/stormtrooper
icon_state = "syndicate_stormtrooper_sword"
icon_living = "syndicate_stormtrooper_sword"
- name = "Syndicate Stormtrooper"
+ name = "Ramzi Clique Stormtrooper"
maxHealth = 250
health = 250
projectile_deflect_chance = 50
///////////////Guns////////////
-/mob/living/simple_animal/hostile/syndicate/ranged
+/mob/living/simple_animal/hostile/human/syndicate/ranged
ranged = 1
retreat_distance = 5
minimum_distance = 5
@@ -179,104 +155,103 @@
dodging = FALSE
rapid_melee = 1
-/mob/living/simple_animal/hostile/syndicate/ranged/infiltrator //shuttle loan event
+/mob/living/simple_animal/hostile/human/syndicate/ranged/infiltrator //shuttle loan event
projectilesound = 'sound/weapons/gun/smg/shot_suppressed.ogg'
loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier)
-/mob/living/simple_animal/hostile/syndicate/ranged/space
+/mob/living/simple_animal/hostile/human/syndicate/ranged/space
icon_state = "syndicate_space_pistol"
icon_living = "syndicate_space_pistol"
- name = "Syndicate Commando"
+ name = "Ramzi Clique Commando"
maxHealth = 170
health = 170
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
+ maxbodytemp = 1000
speed = 1
-/mob/living/simple_animal/hostile/syndicate/ranged/space/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/ranged/space/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
set_light(4)
-/mob/living/simple_animal/hostile/syndicate/ranged/space/stormtrooper
+/mob/living/simple_animal/hostile/human/syndicate/ranged/space/stormtrooper
icon_state = "syndicate_stormtrooper_pistol"
icon_living = "syndicate_stormtrooper_pistol"
- name = "Syndicate Stormtrooper"
+ name = "Ramzi Clique Stormtrooper"
maxHealth = 250
health = 250
-/mob/living/simple_animal/hostile/syndicate/ranged/smg
+/mob/living/simple_animal/hostile/human/syndicate/ranged/smg
rapid = 2
icon_state = "syndicate_smg"
icon_living = "syndicate_smg"
casingtype = /obj/item/ammo_casing/c45
projectilesound = 'sound/weapons/gun/smg/shot.ogg'
-/mob/living/simple_animal/hostile/syndicate/ranged/smg/pilot //caravan ambush ruin
- name = "Syndicate Salvage Pilot"
- loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier)
-
-/mob/living/simple_animal/hostile/syndicate/ranged/smg/space
+/mob/living/simple_animal/hostile/human/syndicate/ranged/smg/space
icon_state = "syndicate_space_smg"
icon_living = "syndicate_space_smg"
- name = "Syndicate Commando"
+ name = "Ramzi Clique Commando"
maxHealth = 170
health = 170
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
+ maxbodytemp = 1000
speed = 1
-/mob/living/simple_animal/hostile/syndicate/ranged/smg/space/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/ranged/smg/space/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
set_light(4)
-/mob/living/simple_animal/hostile/syndicate/ranged/smg/space/stormtrooper
+/mob/living/simple_animal/hostile/human/syndicate/ranged/smg/space/stormtrooper
icon_state = "syndicate_stormtrooper_smg"
icon_living = "syndicate_stormtrooper_smg"
- name = "Syndicate Stormtrooper"
+ name = "Ramzi Clique Stormtrooper"
maxHealth = 250
health = 250
-/mob/living/simple_animal/hostile/syndicate/ranged/shotgun
+/mob/living/simple_animal/hostile/human/syndicate/ranged/shotgun
rapid = 2
rapid_fire_delay = 6
minimum_distance = 3
icon_state = "syndicate_shotgun"
icon_living = "syndicate_shotgun"
- casingtype = /obj/item/ammo_casing/shotgun/buckshot //buckshot (up to 72.5 brute) fired in a two-round burst
+ casingtype = /obj/item/ammo_casing/shotgun/buckshot //buckshot fired in a two-round burst. This will two-tap unarmored players.
-/mob/living/simple_animal/hostile/syndicate/ranged/shotgun/space
+/mob/living/simple_animal/hostile/human/syndicate/ranged/shotgun/space
icon_state = "syndicate_space_shotgun"
icon_living = "syndicate_space_shotgun"
- name = "Syndicate Commando"
+ name = "Ramzi Clique Commando"
maxHealth = 170
health = 170
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
+ maxbodytemp = 1000
speed = 1
-/mob/living/simple_animal/hostile/syndicate/ranged/shotgun/space/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/ranged/shotgun/space/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
set_light(4)
-/mob/living/simple_animal/hostile/syndicate/ranged/shotgun/space/stormtrooper
+/mob/living/simple_animal/hostile/human/syndicate/ranged/shotgun/space/stormtrooper
icon_state = "syndicate_stormtrooper_shotgun"
icon_living = "syndicate_stormtrooper_shotgun"
- name = "Syndicate Stormtrooper"
+ name = "Ramzi Clique Stormtrooper"
maxHealth = 250
health = 250
///////////////Misc////////////
-/mob/living/simple_animal/hostile/syndicate/civilian
+/mob/living/simple_animal/hostile/human/syndicate/civilian
minimum_distance = 10
retreat_distance = 10
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
-/mob/living/simple_animal/hostile/syndicate/civilian/Aggro()
+/mob/living/simple_animal/hostile/human/syndicate/civilian/Aggro()
..()
summon_backup(15)
say("GUARDS!!")
@@ -302,6 +277,7 @@
faction = list(ROLE_SYNDICATE)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
+ maxbodytemp = 1000
mob_size = MOB_SIZE_TINY
movement_type = FLYING
limb_destroyer = 1
@@ -314,32 +290,3 @@
/mob/living/simple_animal/hostile/viscerator/Initialize()
. = ..()
AddComponent(/datum/component/swarming)
-
-/mob/living/simple_animal/hostile/syndicate/melee/sword/space/oldcode
- melee_damage_lower = 20
- melee_damage_upper = 20
- icon = 'icons/mob/simple_human.dmi'
- icon_state = "oldcode_syndicate_csaber"
- icon_living = "oldcode_syndicate_csaber"
- name = "Syndicate Spaceman"
- desc = "Death to IS-Nanotrasen."
- maxHealth = 170
- health = 170
- armour_penetration = 20
- light_color = LIGHT_COLOR_BLUE
- sord = /obj/effect/light_emitter/blue_energy_sword
- projectile_deflect_chance = 10
-
-/mob/living/simple_animal/hostile/syndicate/ranged/space/oldcode
- icon = 'icons/mob/simple_human.dmi'
- icon_state = "oldcode_syndicate_gun"
- icon_living = "oldcode_syndicate_gun"
- name = "Syndicate Spaceman"
- desc = "Death to IS-Nanotrasen."
- maxHealth = 170
- health = 170
-
-/obj/effect/light_emitter/blue_energy_sword
- set_luminosity = 2
- set_cap = 2.5
- light_color = LIGHT_COLOR_BLUE
diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/human/zombie.dm
similarity index 83%
rename from code/modules/mob/living/simple_animal/hostile/zombie.dm
rename to code/modules/mob/living/simple_animal/hostile/human/zombie.dm
index 6f1db7aaf996..7a12465b98bb 100644
--- a/code/modules/mob/living/simple_animal/hostile/zombie.dm
+++ b/code/modules/mob/living/simple_animal/hostile/human/zombie.dm
@@ -1,4 +1,4 @@
-/mob/living/simple_animal/hostile/zombie
+/mob/living/simple_animal/hostile/human/zombie
name = "Shambling Corpse"
desc = "When there is no more room in hell, the dead will walk in outer space."
icon = 'icons/mob/simple_human.dmi'
@@ -19,16 +19,17 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
status_flags = CANPUSH
+ loot = list()
del_on_death = 1
var/zombiejob = "Medical Doctor"
var/infection_chance = 0
var/obj/effect/mob_spawn/human/corpse/delayed/corpse
-/mob/living/simple_animal/hostile/zombie/Initialize(mapload)
+/mob/living/simple_animal/hostile/human/zombie/Initialize(mapload)
. = ..()
INVOKE_ASYNC(src, PROC_REF(setup_visuals))
-/mob/living/simple_animal/hostile/zombie/proc/setup_visuals()
+/mob/living/simple_animal/hostile/human/zombie/proc/setup_visuals()
var/datum/preferences/dummy_prefs = new
dummy_prefs.pref_species = new /datum/species/zombie
dummy_prefs.randomise[RANDOM_BODY] = TRUE
@@ -48,17 +49,17 @@
corpse.mob_species = /datum/species/zombie
corpse.mob_name = name
-/mob/living/simple_animal/hostile/zombie/AttackingTarget()
+/mob/living/simple_animal/hostile/human/zombie/AttackingTarget()
. = ..()
if(. && ishuman(target) && prob(infection_chance))
try_to_zombie_infect(target)
-/mob/living/simple_animal/hostile/zombie/drop_loot()
+/mob/living/simple_animal/hostile/human/zombie/drop_loot()
. = ..()
corpse.forceMove(drop_location())
corpse.create()
-/mob/living/simple_animal/hostile/zombie/kudzu
+/mob/living/simple_animal/hostile/human/zombie/kudzu
name = "shambling bramble"
desc = "A shambling mass of vibrant vines and rotting flesh. "
melee_damage_lower = 15
diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
index cf8a32af157c..2a60b3c52fc2 100644
--- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm
@@ -18,7 +18,7 @@ Featuring:
*/
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot
name = "Syndicate Mecha Pilot"
desc = "Death to Nanotrasen. This variant comes in MECHA DEATH flavour."
wanted_objects = list()
@@ -36,15 +36,15 @@ Featuring:
var/smoke_chance = 20 //Chance to deploy smoke for crowd control
var/retreat_chance = 40 //Chance to run away
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/no_mech
spawn_mecha_type = null
search_objects = 2
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/no_mech/Initialize()
. = ..()
wanted_objects = typecacheof(/obj/mecha/combat, TRUE)
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/nanotrasen //nanotrasen are syndies! no it's just a weird path.
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/nanotrasen //nanotrasen are syndies! no it's just a weird path.
name = "\improper Nanotrasen Mecha Pilot"
desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour."
icon_living = "nanotrasen"
@@ -52,7 +52,7 @@ Featuring:
faction = list("nanotrasen")
spawn_mecha_type = /obj/mecha/combat/marauder/loaded
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/nanotrasen
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/no_mech/nanotrasen
name = "\improper Nanotrasen Mecha Pilot"
desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour."
icon_living = "nanotrasen"
@@ -60,7 +60,7 @@ Featuring:
faction = list("nanotrasen")
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/Initialize()
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/Initialize()
. = ..()
if(spawn_mecha_type)
var/obj/mecha/M = new spawn_mecha_type (get_turf(src))
@@ -68,7 +68,7 @@ Featuring:
INVOKE_ASYNC(src, PROC_REF(enter_mecha), M)
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/mecha/M)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/proc/enter_mecha(obj/mecha/M)
if(!M)
return 0
LoseTarget() //Target was our mecha, so null it out
@@ -93,7 +93,7 @@ Featuring:
mecha.lights_action.Activate()
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/exit_mecha(obj/mecha/M)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/proc/exit_mecha(obj/mecha/M)
if(!M)
return 0
@@ -116,7 +116,7 @@ Featuring:
walk(M,0)//end any lingering movement loops, to prevent the haunted mecha bug
//Checks if a mecha is valid for theft
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/is_valid_mecha(obj/mecha/M)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/proc/is_valid_mecha(obj/mecha/M)
if(!M)
return 0
if(M.occupant)
@@ -128,7 +128,7 @@ Featuring:
return 1
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/mecha_face_target(atom/A)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/proc/mecha_face_target(atom/A)
if(mecha)
var/dirto = get_dir(mecha,A)
if(mecha.dir != dirto) //checking, because otherwise the mecha makes too many turn noises
@@ -136,7 +136,7 @@ Featuring:
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/mecha_reload()
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/proc/mecha_reload()
if(mecha)
for(var/equip in mecha.equipment)
var/obj/item/mecha_parts/mecha_equipment/ME = equip
@@ -144,7 +144,7 @@ Featuring:
ME.rearm()
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/get_mecha_equip_by_flag(flag = MECHA_RANGED)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/proc/get_mecha_equip_by_flag(flag = MECHA_RANGED)
. = list()
if(mecha)
for(var/equip in mecha.equipment)
@@ -156,7 +156,7 @@ Featuring:
//Pick a ranged weapon/tool
//Fire it
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/OpenFire(atom/A)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/OpenFire(atom/A)
if(mecha)
mecha_reload()
mecha_face_target(A)
@@ -171,7 +171,7 @@ Featuring:
..()
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/AttackingTarget()
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/AttackingTarget()
if(mecha)
var/list/possible_weapons = get_mecha_equip_by_flag(MECHA_MELEE)
if(possible_weapons.len)
@@ -198,7 +198,7 @@ Featuring:
return target.attack_animal(src)
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/handle_automated_action()
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/handle_automated_action()
if(..())
if(!mecha)
for(var/obj/mecha/combat/C in range(src,vision_range))
@@ -245,12 +245,12 @@ Featuring:
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/death(gibbed)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/death(gibbed)
if(mecha)
mecha.aimob_exit_mech(src)
..()
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/gib()
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/gib()
if(mecha)
mecha.aimob_exit_mech(src)
..()
@@ -258,7 +258,7 @@ Featuring:
//Yes they actually try and pull this shit
//~simple animals~
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/CanAttack(atom/the_target)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/CanAttack(atom/the_target)
if(ismecha(the_target))
var/obj/mecha/M = the_target
if(mecha)
@@ -275,19 +275,19 @@ Featuring:
. = ..()
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/EscapeConfinement()
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/EscapeConfinement()
if(mecha && loc == mecha)
return 0
..()
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/Move(NewLoc,Dir=0,step_x=0,step_y=0)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/Move(NewLoc,Dir=0,step_x=0,step_y=0)
if(mecha && loc == mecha)
return mecha.relaymove(src, Dir)
return ..()
-/mob/living/simple_animal/hostile/syndicate/mecha_pilot/Goto(target, delay, minimum_distance)
+/mob/living/simple_animal/hostile/human/syndicate/mecha_pilot/Goto(target, delay, minimum_distance)
if(mecha)
walk_to(mecha, target, minimum_distance, mecha.step_in)
else
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index 5bdc5c882214..63519d29c7cd 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -41,7 +41,7 @@ Difficulty: Medium
ranged_cooldown_time = 16
pixel_x = -16
base_pixel_x = -16
- crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator, /obj/item/crusher_trophy/miner_eye)
+ //mob_trophy = /obj/item/mob_trophy/miner_eye
loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
wander = FALSE
del_on_death = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index d62d695e1be7..1a0bbc10fac4 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -56,7 +56,7 @@ Difficulty: Hard
pixel_x = -32
base_pixel_x = -32
del_on_death = TRUE
- crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher)
+ //mob_trophy = /obj/item/mob_trophy/demon_claws
loot = list(/obj/structure/closet/crate/necropolis/bubblegum)
blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME
var/charging = FALSE
@@ -504,7 +504,7 @@ Difficulty: Hard
health = 1
maxHealth = 1
alpha = 127.5
- crusher_loot = null
+ mob_trophy = null
loot = null
achievement_type = null
crusher_achievement_type = null
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/codename_claw.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/codename_claw.dm
index cca8a649353f..a762a9298279 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/codename_claw.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/codename_claw.dm
@@ -21,7 +21,6 @@
ranged = TRUE
speed = 4
move_to_delay = 4
- crusher_loot = list(/obj/item/card/id/ert/deathsquad, /obj/item/documents/nanotrasen)
loot = list(/obj/item/card/id/ert/deathsquad, /obj/item/documents/nanotrasen)
wander = FALSE
blood_volume = BLOOD_VOLUME_NORMAL
@@ -59,8 +58,8 @@
speed = 5
move_to_delay = 5
speak_emote = list("verbalizes")
- crusher_loot = list(/obj/effect/spawner/clawloot)
- loot = list(/obj/effect/spawner/clawloot/crusher)
+ mob_trophy = /obj/item/nullrod/armblade/tentacle
+ loot = list(/obj/effect/spawner/clawloot)
health = 2250
maxHealth = 2250
shouldnt_move = TRUE //we want to show the transforming animation
@@ -76,9 +75,6 @@
new /obj/item/gun/energy/pulse/pistol(get_turf(src))
qdel(src)
-/obj/effect/spawner/clawloot/crusher/spawn_loot()
- new /obj/item/nullrod/armblade/tentacle(get_turf(src)) //idk what to put here, memed is the loot person
- return ..()
///LOOT END
//PHASE ONE
@@ -236,7 +232,6 @@
projectiletype = /obj/projectile/tentacle
projectilesound = 'sound/effects/splat.ogg'
Shoot(target)
-
/////TENTACLE END
/////STING ATTACK
@@ -319,3 +314,102 @@
empulse(src, 5, 8)
new /obj/effect/gibspawner/human(get_turf(src))
qdel(src)
+
+/obj/projectile/tentacle
+ name = "tentacle"
+ icon_state = "tentacle_end"
+ pass_flags = PASSTABLE
+ damage = 0
+ damage_type = BRUTE
+ range = 8
+ hitsound = 'sound/weapons/thudswoosh.ogg'
+ var/chain
+
+/obj/projectile/tentacle/fire(setAngle)
+ if(firer)
+ chain = firer.Beam(src, icon_state = "tentacle", emissive = FALSE)
+ ..()
+
+/obj/projectile/tentacle/proc/reset_throw(mob/living/carbon/human/H)
+ if(H.throw_mode)
+ H.throw_mode_off() //Don't annoy the changeling if he doesn't catch the item
+
+/obj/projectile/tentacle/proc/tentacle_grab(mob/living/carbon/human/H, mob/living/carbon/C)
+ if(H.Adjacent(C))
+ if(H.get_active_held_item() && !H.get_inactive_held_item())
+ H.swap_hand()
+ if(H.get_active_held_item())
+ return
+ C.grabbedby(H)
+ C.grippedby(H, instant = TRUE) //instant aggro grab
+
+/obj/projectile/tentacle/proc/tentacle_stab(mob/living/carbon/human/H, mob/living/carbon/C)
+ if(H.Adjacent(C))
+ for(var/obj/item/I in H.held_items)
+ if(I.get_sharpness())
+ C.visible_message("[H] impales [C] with [H.p_their()] [I.name]!", "[H] impales you with [H.p_their()] [I.name]!")
+ C.apply_damage(I.force, BRUTE, BODY_ZONE_CHEST)
+ H.do_item_attack_animation(C, used_item = I)
+ H.add_mob_blood(C)
+ playsound(get_turf(H),I.hitsound,75,TRUE)
+ return
+
+/obj/projectile/tentacle/on_hit(atom/target, blocked = FALSE)
+ var/mob/living/carbon/human/H = firer
+ if(blocked >= 100)
+ return BULLET_ACT_BLOCK
+ if(isitem(target))
+ var/obj/item/I = target
+ if(!I.anchored)
+ to_chat(firer, "You pull [I] towards yourself.")
+ H.throw_mode_on()
+ I.throw_at(H, 10, 2)
+ . = BULLET_ACT_HIT
+
+ else if(isliving(target))
+ var/mob/living/L = target
+ if(!L.anchored && !L.throwing)//avoid double hits
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ var/firer_intent = INTENT_HARM
+ var/mob/M = firer
+ if(istype(M))
+ firer_intent = M.a_intent
+ switch(firer_intent)
+ if(INTENT_HELP)
+ C.visible_message("[L] is pulled by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
+ C.throw_at(get_step_towards(H,C), 8, 2)
+ return BULLET_ACT_HIT
+
+ if(INTENT_DISARM)
+ var/obj/item/I = C.get_active_held_item()
+ if(I)
+ if(C.dropItemToGround(I))
+ C.visible_message("[I] is yanked off [C]'s hand by [src]!","A tentacle pulls [I] away from you!")
+ on_hit(I) //grab the item as if you had hit it directly with the tentacle
+ return BULLET_ACT_HIT
+ else
+ to_chat(firer, "You can't seem to pry [I] off [C]'s hands!")
+ return BULLET_ACT_BLOCK
+ else
+ to_chat(firer, "[C] has nothing in hand to disarm!")
+ return BULLET_ACT_HIT
+
+ if(INTENT_GRAB)
+ C.visible_message("[L] is grabbed by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
+ C.throw_at(get_step_towards(H,C), 8, 2, H, TRUE, TRUE, callback=CALLBACK(src, PROC_REF(tentacle_grab), H, C))
+ return BULLET_ACT_HIT
+
+ if(INTENT_HARM)
+ C.visible_message("[L] is thrown towards [H] by a tentacle!","A tentacle grabs you and throws you towards [H]!")
+ C.throw_at(get_step_towards(H,C), 8, 2, H, TRUE, TRUE, callback=CALLBACK(src, PROC_REF(tentacle_stab), H, C))
+ return BULLET_ACT_HIT
+ else
+ L.visible_message("[L] is pulled by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!")
+ L.throw_at(get_step_towards(H,L), 8, 2)
+ . = BULLET_ACT_HIT
+
+/obj/projectile/tentacle/Destroy()
+ qdel(chain)
+ return ..()
+
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index bd09f06f3521..863abf56dad1 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -50,7 +50,7 @@ Difficulty: Very Hard
achievement_type = /datum/award/achievement/boss/colossus_kill
crusher_achievement_type = /datum/award/achievement/boss/colossus_crusher
score_achievement_type = /datum/award/score/colussus_score
- crusher_loot = list(/obj/structure/closet/crate/necropolis/colossus/crusher)
+ //mob_trophy = /obj/item/mob_trophy/blaster_tubes
loot = list(/obj/structure/closet/crate/necropolis/colossus)
deathmessage = "disintegrates, leaving a glowing core in its wake."
deathsound = 'sound/magic/demon_dies.ogg'
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/cult_templar.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/cult_templar.dm
index 96fbc8b5c4ec..08ef1a7b21cb 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/cult_templar.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/cult_templar.dm
@@ -24,7 +24,7 @@
vision_range = 10
damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 0.5, CLONE = 0.5, STAMINA = 0, OXY = 0.5)
loot = list(/obj/item/claymore/cursed, /obj/item/clothing/suit/space/hardsuit/cult/enchanted)
- crusher_loot = list(/obj/item/claymore/cursed, /obj/item/clothing/suit/space/hardsuit/cult/enchanted, /obj/item/upgradescroll)
+ mob_trophy = list(/obj/item/claymore/cursed, /obj/item/clothing/suit/space/hardsuit/cult/enchanted, /obj/item/upgradescroll)
wander = FALSE
del_on_death = TRUE
blood_volume = BLOOD_VOLUME_NORMAL
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
index 550c78532cd6..03faa787d155 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
@@ -28,7 +28,7 @@ Difficulty: Extremely Hard
speed = 20
move_to_delay = 20
ranged = TRUE
- crusher_loot = list(/obj/effect/decal/remains/plasma, /obj/item/crusher_trophy/ice_block_talisman)
+ //mob_trophy = /obj/item/mob_trophy/ice_block_talisman
loot = list(/obj/effect/decal/remains/plasma)
wander = FALSE
del_on_death = TRUE
@@ -322,48 +322,3 @@ Difficulty: Extremely Hard
var/turf/T = get_turf(target)
mineral_scan_pulse(T, world.view + 1)
. = ..()
-
-/obj/item/crusher_trophy/ice_block_talisman
- name = "ice block talisman"
- desc = "A glowing trinket that a demonic miner had on him, it seems he couldn't utilize it for whatever reason."
- icon_state = "freeze_cube"
- denied_type = /obj/item/crusher_trophy/ice_block_talisman
-
-/obj/item/crusher_trophy/ice_block_talisman/effect_desc()
- return "waveform collapse to freeze a creature in a block of ice for a period, preventing them from moving"
-
-/obj/item/crusher_trophy/ice_block_talisman/on_mark_detonation(mob/living/target, mob/living/user)
- target.apply_status_effect(/datum/status_effect/ice_block_talisman)
-
-/datum/status_effect/ice_block_talisman
- id = "ice_block_talisman"
- duration = 40
- status_type = STATUS_EFFECT_REFRESH
- alert_type = /atom/movable/screen/alert/status_effect/ice_block_talisman
- /// Stored icon overlay for the hit mob, removed when effect is removed
- var/icon/cube
-
-/atom/movable/screen/alert/status_effect/ice_block_talisman
- name = "Frozen Solid"
- desc = "You're frozen inside an ice cube, and cannot move!"
- icon_state = "frozen"
-
-/datum/status_effect/ice_block_talisman/on_apply()
- RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(owner_moved))
- if(!owner.stat)
- to_chat(owner, "You become frozen in a cube!")
- cube = icon('icons/effects/freeze.dmi', "ice_cube")
- var/icon/size_check = icon(owner.icon, owner.icon_state)
- cube.Scale(size_check.Width(), size_check.Height())
- owner.add_overlay(cube)
- return ..()
-
-/// Blocks movement from the status effect owner
-/datum/status_effect/ice_block_talisman/proc/owner_moved()
- return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
-
-/datum/status_effect/ice_block_talisman/on_remove()
- if(!owner.stat)
- to_chat(owner, "The cube melts!")
- owner.cut_overlay(cube)
- UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
index 6fcf5ada7f4a..b7a2f0912653 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
@@ -54,10 +54,10 @@ Difficulty: Medium
ranged = TRUE
pixel_x = -32
base_pixel_x = -32
- crusher_loot = list(/obj/structure/closet/crate/necropolis/dragon/crusher)
+ //mob_trophy = /obj/item/mob_trophy/ash_spike
loot = list(/obj/structure/closet/crate/necropolis/dragon)
butcher_results = list(/obj/item/gem/amber = 1, /obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30)
- guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/crusher_trophy/ash_spike = 1)
+ guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/ashdrake = 10)
var/swooping = NONE
var/player_cooldown = 0
var/dungeon = FALSE //if true, on death will spawn a ghost role at a lank mark and open blast doors with a certain id
@@ -583,7 +583,7 @@ Difficulty: Medium
mouse_opacity = MOUSE_OPACITY_ICON
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
loot = list()
- crusher_loot = list()
+ mob_trophy = list()
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30)
attack_action_types = list()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index 4df97bac4a6f..ba112bbf5e72 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -59,7 +59,7 @@ Difficulty: Hard
ranged_cooldown_time = 40
aggro_vision_range = 21 //so it can see to one side of the arena to the other
loot = list(/obj/item/hierophant_club)
- crusher_loot = list(/obj/item/hierophant_club, /obj/item/crusher_trophy/vortex_talisman)
+ //mob_trophy = /obj/item/mob_trophy/vortex_talisman
wander = FALSE
gps_name = "Zealous Signal"
achievement_type = /datum/award/achievement/boss/hierophant_kill
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index 120b850cf428..37934c0367e5 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -28,7 +28,7 @@
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
- var/list/crusher_loot
+ var/mob_trophy
var/achievement_type
var/crusher_achievement_type
var/score_achievement_type
@@ -71,10 +71,10 @@
if(health > 0)
return
else
- var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
+ spawn_mob_trophy()
+ var/datum/status_effect/crusher_damage/crusher = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/crusher_kill = FALSE
- if(C && crusher_loot && C.total_damage >= maxHealth * 0.6)
- spawn_crusher_loot()
+ if(crusher && mob_trophy && crusher.total_damage >= maxHealth * 0.6)
crusher_kill = TRUE
if(true_spawn && !(flags_1 & ADMIN_SPAWNED_1))
var/tab = "megafauna_kills"
@@ -85,8 +85,8 @@
SSblackbox.record_feedback("tally", tab, 1, "[initial(name)]")
..()
-/mob/living/simple_animal/hostile/megafauna/proc/spawn_crusher_loot()
- loot = crusher_loot
+/mob/living/simple_animal/hostile/megafauna/proc/spawn_mob_trophy()
+ loot += mob_trophy
/mob/living/simple_animal/hostile/megafauna/gib()
if(health > 0)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
index a2cceb5a3aaa..04723d80ba5a 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
@@ -39,7 +39,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
for(var/t in swarmerTypes)
. += GLOB.AISwarmerCapsByType[t]
-
+//this should. not be a simple mob i think
/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon
name = "swarmer beacon"
desc = "That name is a bit of a mouthful, but stop paying attention to your mouth they're eating everything!"
@@ -49,9 +49,6 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
maxHealth = 750 //""""low-ish"""" HP because it's a passive boss, and the swarm itself is the real foe
mob_biotypes = MOB_ROBOTIC
gps_name = "Hungry Signal"
- achievement_type = /datum/award/achievement/boss/swarmer_beacon_kill
- crusher_achievement_type = /datum/award/achievement/boss/swarmer_beacon_crusher
- score_achievement_type = /datum/award/score/swarmer_beacon_score
faction = list("mining", "boss", "swarmer")
weather_immunities = list("lava","ash")
stop_automated_movement = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm
index 59a58bd48d16..095ad0f8fca2 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm
@@ -32,7 +32,7 @@ Difficulty: Hard
loot = list()
butcher_results = list()
guaranteed_butcher_results = list(/obj/item/wendigo_blood = 1)
- crusher_loot = list(/obj/item/crusher_trophy/demon_claws)
+ //mob_trophy = /obj/item/mob_trophy/demon_claws
wander = FALSE
del_on_death = FALSE
blood_volume = BLOOD_VOLUME_NORMAL
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index ca595d4d682f..0568533c1e0c 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -205,7 +205,6 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
/mob/living/simple_animal/hostile/mimic/copy/ranged
var/obj/item/gun/TrueGun = null
- var/obj/item/gun/magic/Zapstick
var/obj/item/gun/ballistic/Pewgun
var/obj/item/gun/energy/Zapgun
@@ -223,10 +222,6 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
move_to_delay = 2 * G.w_class + 1
projectilesound = G.fire_sound
TrueGun = G
- if(istype(G, /obj/item/gun/magic))
- Zapstick = G
- var/obj/item/ammo_casing/magic/M = Zapstick.ammo_type
- projectiletype = initial(M.projectile_type)
if(istype(G, /obj/item/gun/ballistic))
Pewgun = G
var/obj/item/ammo_box/magazine/M = Pewgun.mag_type
@@ -245,11 +240,6 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
Zapgun.cell.use(shot.e_cost)
Zapgun.update_appearance()
..()
- else if(Zapstick)
- if(Zapstick.charges)
- Zapstick.charges--
- Zapstick.update_appearance()
- ..()
else if(Pewgun)
if(Pewgun.chambered)
if(Pewgun.chambered.BB)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
index eb8302536e50..b03363e956f1 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
@@ -1,4 +1,3 @@
-#define LEGIONVIRUS_TYPE /datum/disease/transformation/legionvirus
#define BULLET_SHELL_DAMAGE 1
//A beast that fire freezing blasts.
@@ -204,7 +203,6 @@
projectiletype = /obj/projectile/temp/basilisk/heated
#undef BULLET_SHELL_DAMAGE
-#undef LEGIONVIRUS_TYPE
//Watcher
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher
@@ -230,7 +228,7 @@
movement_type = FLYING
robust_searching = 1
attack_same = TRUE // So we'll fight basilisks
- crusher_loot = /obj/item/crusher_trophy/watcher_wing
+ //mob_trophy = /obj/item/mob_trophy/watcher_wing
gold_core_spawnable = NO_SPAWN
loot = list()
butcher_results = list(/obj/item/stack/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
@@ -294,8 +292,8 @@
light_power = 2.5
light_color = LIGHT_COLOR_LAVA
projectiletype = /obj/projectile/temp/basilisk/magmawing
- crusher_loot = /obj/item/crusher_trophy/magma_wing
- crusher_drop_mod = 75
+ //mob_trophy = /obj/item/mob_trophy/magma_wing
+ trophy_drop_mod = 75
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing
name = "icewing watcher"
@@ -309,8 +307,8 @@
ranged_cooldown_time = 20
projectiletype = /obj/projectile/temp/basilisk/icewing
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/bone = 1) //No sinew; the wings are too fragile to be usable
- crusher_loot = /obj/item/crusher_trophy/ice_wing
- crusher_drop_mod = 75
+ //mob_trophy = /obj/item/mob_trophy/ice_wing
+ trophy_drop_mod = 75
/obj/projectile/temp/basilisk/magmawing
name = "scorching blast"
@@ -340,8 +338,8 @@
if(istype(L))
L.apply_status_effect(/datum/status_effect/freon/watcher)
-/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril
- fromtendril = TRUE
+/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/nest
+ from_nest = TRUE
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/forgotten
name = "forgotten watcher"
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/brimdemon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/brimdemon.dm
index 1d9f6e174660..769f6ce3d5fa 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/brimdemon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/brimdemon.dm
@@ -14,7 +14,7 @@
emote_hear = list("cackles","screeches")
stat_attack = CONSCIOUS
ranged_cooldown_time = 5 SECONDS
- vision_range = 9
+ vision_range = 6
retreat_distance = 2
speed = 3
move_to_delay = 5
@@ -37,7 +37,7 @@
light_color = LIGHT_COLOR_BLOOD_MAGIC
light_power = 5
light_range = 1.4
- crusher_loot = /obj/item/crusher_trophy/brimdemon_fang
+ //mob_trophy = /obj/item/mob_trophy/brimdemon_fang
/// Are we charging/firing? If yes stops our movement.
var/firing = FALSE
/// A list of all the beam parts.
@@ -98,7 +98,7 @@
visible_message(span_danger("[src] starts charging!"))
balloon_alert(src, "charging...")
to_chat(src, "You begin to charge up...")
- addtimer(CALLBACK(src, PROC_REF(fire_laser)), 1 SECONDS)
+ fire_laser()
COOLDOWN_START(src, ranged_cooldown, ranged_cooldown_time)
/mob/living/simple_animal/hostile/asteroid/brimdemon/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE)
@@ -115,10 +115,6 @@
/mob/living/simple_animal/hostile/asteroid/brimdemon/proc/fire_laser()
if(stat == DEAD)
return
- visible_message(span_danger("[src] fires a brimbeam!"))
- balloon_alert(src, "brimbeam fired")
- playsound(src, 'sound/creatures/brimdemon.ogg', 150, FALSE, 0, 3)
- cut_overlay("brimdemon_telegraph_dir")
var/turf/target_turf = get_ranged_target_turf(src, dir, BRIMBEAM_RANGE)
var/turf/origin_turf = get_turf(src)
var/list/affected_turfs = get_line(origin_turf, target_turf) - origin_turf
@@ -135,15 +131,30 @@
var/atom/new_brimbeam = new /obj/effect/brimbeam(affected_turf)
new_brimbeam.dir = dir
beamparts += new_brimbeam
- for(var/mob/living/hit_mob in affected_turf.contents)
- hit_mob.adjustFireLoss(35)
- to_chat(hit_mob, span_userdanger("You're hit by [src]'s brimbeam!"))
+ animate(new_brimbeam, 1 SECONDS, alpha = 255)
if(length(beamparts))
var/atom/last_brimbeam = beamparts[length(beamparts)]
last_brimbeam.icon_state = "brimbeam_end"
var/atom/first_brimbeam = beamparts[1]
first_brimbeam.icon_state = "brimbeam_start"
- addtimer(CALLBACK(src, PROC_REF(end_laser)), 2 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(kill_people)), 1 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(end_laser)), 3 SECONDS)
+
+/// Tells the lasers to start murdering people
+/mob/living/simple_animal/hostile/asteroid/brimdemon/proc/kill_people()
+ if(stat == DEAD)
+ end_laser()
+ return
+ playsound(src, 'sound/creatures/brimdemon.ogg', 150, FALSE, 0, 3)
+ visible_message(span_danger("[src] fires a brimbeam!"))
+ balloon_alert(src, "brimbeam fired")
+ cut_overlay("brimdemon_telegraph_dir")
+ for(var/obj/effect/brimbeam/beam in beamparts)
+ var/turf/affected_turf = get_turf(beam)
+ START_PROCESSING(SSfastprocess, beam)
+ for(var/mob/living/hit_mob in affected_turf.contents)
+ hit_mob.adjustFireLoss(35)
+ to_chat(hit_mob, span_userdanger("You're hit by [src]'s brimbeam!"))
/// Deletes all the brimbeam parts and sets variables back to their initial ones.
/mob/living/simple_animal/hostile/asteroid/brimdemon/proc/end_laser()
@@ -163,15 +174,12 @@
icon_state = "brimbeam_mid"
layer = ABOVE_MOB_LAYER
plane = -2
+ alpha = 150
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
light_color = LIGHT_COLOR_BLOOD_MAGIC
light_power = 3
light_range = 2
-/obj/effect/brimbeam/Initialize()
- . = ..()
- START_PROCESSING(SSfastprocess, src)
-
/obj/effect/brimbeam/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
@@ -184,22 +192,6 @@
hit_mob.adjustFireLoss(5)
to_chat(hit_mob, span_danger("You're damaged by [src]!"))
-/obj/item/crusher_trophy/brimdemon_fang
- name = "brimdemon's fang"
- icon_state = "brimdemon_fang"
- desc = "A fang from a brimdemon's corpse."
- denied_type = /obj/item/crusher_trophy/brimdemon_fang
- var/static/list/comic_phrases = list("BOOM", "BANG", "KABLOW", "KAPOW", "OUCH", "BAM", "KAPOW", "WHAM", "POW", "KABOOM")
- var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
-
-/obj/item/crusher_trophy/brimdemon_fang/effect_desc()
- return "mark detonation creates audiosensory effects on the target and slightly heals the wielder"
-
-/obj/item/crusher_trophy/brimdemon_fang/on_mark_detonation(mob/living/target, mob/living/user)
- target.balloon_alert_to_viewers("[pick(comic_phrases)]!")
- playsound(target, 'sound/creatures/brimdemon_crush.ogg', 100)
- user.heal_ordered_damage(bonus_value * 0.4, damage_heal_order)
-
/obj/effect/decal/cleanable/brimdust
name = "brimdust"
desc = "Dust from a brimdemon. It is considered valuable for botanical and heating purposes."
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm
index 7e2b1c3d990c..94dd221945b9 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm
@@ -43,7 +43,7 @@
mob_biotypes = MOB_ORGANIC|MOB_BEAST
mouse_opacity = MOUSE_OPACITY_ICON
deathmessage = "explodes into gore!"
- loot_drop = /obj/item/crusher_trophy/broodmother_tongue
+ //loot_drop = /obj/item/mob_trophy/broodmother_tongue
attack_action_types = list(/datum/action/innate/elite_attack/tentacle_patch,
/datum/action/innate/elite_attack/spawn_children,
@@ -185,7 +185,6 @@
move_to_delay = 5
mob_biotypes = MOB_ORGANIC|MOB_BEAST
mouse_opacity = MOUSE_OPACITY_ICON
- butcher_results = list()
guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide = 1)
deathmessage = "falls to the ground."
status_flags = CANPUSH
@@ -246,22 +245,6 @@
T = get_step(T, i)
new /obj/effect/temp_visual/goliath_tentacle/broodmother(T, spawner)
-// Broodmother's loot: Broodmother Tongue
-/obj/item/crusher_trophy/broodmother_tongue
- name = "broodmother tongue"
- desc = "The tongue of a broodmother. If attached a certain way, makes for a suitable crusher trophy."
- icon = 'icons/obj/lavaland/elite_trophies.dmi'
- icon_state = "broodmother_tongue"
- denied_type = /obj/item/crusher_trophy/broodmother_tongue
- bonus_value = 35
-
-/obj/item/crusher_trophy/broodmother_tongue/effect_desc()
- return "waveform collapse to have a [bonus_value]% chance to summon a patch of goliath tentacles at the target's location"
-
-/obj/item/crusher_trophy/broodmother_tongue/on_mark_detonation(mob/living/target, mob/living/user)
- if(rand(1, 100) <= bonus_value && target.stat != DEAD)
- new /obj/effect/temp_visual/goliath_tentacle/broodmother/patch(get_turf(target), user)
-
/mob/living/simple_animal/hostile/asteroid/elite/broodmother_child/rockplanet
name = "baby gruboid"
desc = "A young gruboid recently born. As a defense mechanism, they violently explode if killed."
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm
index f0b6dc3e8d54..e6ea404aca09 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/legionnaire.dm
@@ -38,7 +38,7 @@
mouse_opacity = MOUSE_OPACITY_ICON
deathsound = 'sound/magic/curse.ogg'
deathmessage = "'s arms reach out before it falls apart onto the floor, lifeless."
- loot_drop = /obj/item/crusher_trophy/legionnaire_spine
+ loot_drop = /obj/item/mob_trophy/legionnaire_spine
attack_action_types = list(/datum/action/innate/elite_attack/legionnaire_charge,
/datum/action/innate/elite_attack/head_detach,
@@ -278,23 +278,8 @@
transform *= 0.33
// Legionnaire's loot: Legionnaire Spine
-
-/obj/item/crusher_trophy/legionnaire_spine
+/obj/item/mob_trophy/legionnaire_spine
name = "legionnaire spine"
desc = "The spine of a legionnaire. It almost feels like it's moving..."
icon = 'icons/obj/lavaland/elite_trophies.dmi'
icon_state = "legionnaire_spine"
- denied_type = /obj/item/crusher_trophy/legionnaire_spine
- bonus_value = 50//These skulls are a joke, so this bonus value had to be put on steroidal emergency treatment
-
-/obj/item/crusher_trophy/legionnaire_spine/effect_desc()
- return "waveform collapse to have a [bonus_value]% chance to summon a loyal legion skull"
-
-/obj/item/crusher_trophy/legionnaire_spine/on_mark_detonation(mob/living/target, mob/living/user)
- if(!rand(1, 100) <= bonus_value || target.stat == DEAD)
- return
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(user.loc)
- A.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
- A.GiveTarget(target)
- A.friends = user
- A.faction = user.faction.Copy()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
index ce3850d22f01..e4478b705f45 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
@@ -147,7 +147,7 @@
icon_dead = "goliath_dead"
throw_message = "does nothing to the tough hide of the"
pre_attack_icon = "goliath_preattack"
- crusher_loot = /obj/item/crusher_trophy/goliath_tentacle
+ //mob_trophy = /obj/item/mob_trophy/goliath_tentacle
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/goliath = 2, /obj/item/stack/sheet/bone = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/ore/silver = 10)
guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide = 2)
loot = list()
@@ -213,7 +213,7 @@
/mob/living/simple_animal/hostile/asteroid/goliath/beast/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/saddle) && !saddled)
- if(tame && do_after(user,55,target=src))
+ if(tame && do_after(user, 55, target=src))
user.visible_message("You manage to put [O] on [src], you can now ride [p_them()].")
qdel(O)
saddled = TRUE
@@ -249,11 +249,8 @@
maxHealth = 180
health = 180
speed = 4
- crusher_loot = /obj/item/crusher_trophy/elder_tentacle
- pre_attack_icon = "ancient_goliath_preattack"
- throw_message = "does nothing to the rocky hide of the"
+ //mob_trophy = /obj/item/mob_trophy/elder_tentacle
guaranteed_butcher_results = list()
- crusher_drop_mod = 75
wander = FALSE
bonus_tame_chance = 10
var/list/cached_tentacle_turfs
@@ -280,9 +277,9 @@
else
cached_tentacle_turfs -= t
-/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril
+/mob/living/simple_animal/hostile/asteroid/goliath/beast/nest
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/goliath = 2, /obj/item/stack/sheet/bone = 2, /obj/item/stack/sheet/sinew = 2)
- fromtendril = TRUE
+ from_nest = TRUE
//tentacles
/obj/effect/temp_visual/goliath_tentacle
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
index b602e948af98..b5d539086ac7 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
@@ -50,8 +50,8 @@
OpenFire()
return TRUE
-/mob/living/simple_animal/hostile/asteroid/hivelord/spawn_crusher_loot()
- loot += crusher_loot //we don't butcher
+/mob/living/simple_animal/hostile/asteroid/hivelord/spawn_mob_trophy()
+ loot += mob_trophy //we don't butcher
/mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed)
mouse_opacity = MOUSE_OPACITY_ICON
@@ -119,7 +119,7 @@
throw_message = "bounces harmlessly off of"
loot = list(/obj/item/organ/regenerative_core/legion)
brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion
- crusher_loot = /obj/item/crusher_trophy/legion_skull
+ mob_trophy = /obj/item/mob_trophy/legion_skull
del_on_death = 1
stat_attack = HARD_CRIT
robust_searching = 1
@@ -131,7 +131,7 @@
move_resist = MOVE_RESIST_DEFAULT
pull_force = PULL_FORCE_DEFAULT
if(prob(15))
- new /obj/item/crusher_trophy/legion_skull(loc)
+ new /obj/item/mob_trophy/legion_skull(loc)
visible_message("One of the [src]'s skulls looks intact.")
..()
@@ -150,7 +150,7 @@
icon_living = "dwarf_legion"
icon_aggro = "dwarf_legion"
icon_dead = "dwarf_legion"
- crusher_loot = /obj/item/crusher_trophy/dwarf_skull
+ //mob_trophy = /obj/item/mob_trophy/dwarf_skull
maxHealth = 150
health = 150
move_to_delay = 2
@@ -164,7 +164,7 @@
if(stored_mob)
stored_mob.forceMove(get_turf(src))
stored_mob = null
- else if(fromtendril)
+ else if(from_nest)
new /obj/effect/mob_spawn/human/corpse/charredskeleton(T)
else if(dwarf_mob)
new /obj/effect/mob_spawn/human/corpse/damaged/legioninfested/dwarf(T)
@@ -172,19 +172,16 @@
new /obj/effect/mob_spawn/human/corpse/damaged/legioninfested(T)
..(gibbed)
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril
- fromtendril = TRUE
+/mob/living/simple_animal/hostile/asteroid/hivelord/legion/nest
+ from_nest = TRUE
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf/tendril
- fromtendril = TRUE
+/mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf/nest
+ from_nest = TRUE
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/dwarf/death(gibbed)
move_force = MOVE_FORCE_DEFAULT
move_resist = MOVE_RESIST_DEFAULT
pull_force = PULL_FORCE_DEFAULT
- if(prob(75))
- new /obj/item/crusher_trophy/dwarf_skull(loc)
- visible_message("One of the [src]'s skulls looks like it survived.")
..()
//Legion skull
@@ -316,19 +313,14 @@
move_resist = MOVE_RESIST_DEFAULT
pull_force = PULL_FORCE_DEFAULT
visible_message("[src] falls over with a mighty crash, the remaining legions within it falling apart!")
- new /obj/item/crusher_trophy/legion_skull(loc)
- new /obj/item/crusher_trophy/legion_skull(loc)
- new /obj/item/crusher_trophy/legion_skull(loc)
new /mob/living/simple_animal/hostile/asteroid/hivelord/legion(loc)
new /mob/living/simple_animal/hostile/asteroid/hivelord/legion(loc)
new /mob/living/simple_animal/hostile/asteroid/hivelord/legion(loc)
- if(prob(45))
- new /obj/item/reagent_containers/glass/bottle/necropolis_seed(loc)
..(gibbed)
/mob/living/simple_animal/hostile/big_legion/Initialize()
.=..()
- AddComponent(/datum/component/spawner, list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril), 200, faction, "peels itself off from", 3)
+ AddComponent(/datum/component/spawner, list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/nest), 200, faction, "peels itself off from", 3)
// Snow Legion
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow
@@ -339,7 +331,7 @@
icon_living = "snowlegion"
icon_aggro = "snowlegion_alive"
icon_dead = "snowlegion"
- crusher_loot = /obj/item/crusher_trophy/legion_skull
+ mob_trophy = /obj/item/mob_trophy/legion_skull
loot = list(/obj/item/organ/regenerative_core/legion)
brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow
@@ -353,8 +345,8 @@
icon_aggro = "snowlegion_head"
icon_dead = "snowlegion_head"
-/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril
- fromtendril = TRUE
+/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/nest
+ from_nest = TRUE
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/crystal
name = "disfigured legion"
@@ -363,7 +355,6 @@
icon_living = "disfigured_legion"
icon_aggro = "disfigured_legion"
icon_dead = "disfigured_legion"
- difficulty = 2
brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/crystal
loot = list(/obj/item/organ/regenerative_core/legion/crystal)
@@ -385,7 +376,7 @@
P.fire(i*(360/5))
return ..()
-//Tendril-spawned Legion remains, the charred skeletons of those whose bodies sank into lava or fell into chasms.
+//nest-spawned Legion remains, the charred skeletons of those whose bodies sank into lava or fell into chasms.
/obj/effect/mob_spawn/human/corpse/charredskeleton
name = "charred skeletal remains"
burn_damage = 1000
@@ -403,521 +394,35 @@
/obj/effect/mob_spawn/human/corpse/damaged/legioninfested/Initialize() //in an ideal world, these would generate, the legion would overlay over the corpse, and we'd get cool sprites
mob_species = pickweight(list(
- /datum/species/human = 31,
- /datum/species/lizard = 26,
- /datum/species/ethereal = 24,
- /datum/species/spider = 7,
- /datum/species/ipc = 7,
- /datum/species/jelly = 4,
- /datum/species/fly = 1
+ /datum/species/human = 50,
+ /datum/species/lizard = 20,
+ /datum/species/ipc = 10,
+ /datum/species/elzuose = 10,
+ /datum/species/moth = 5,
+ /datum/species/spider = 5
)
)
var/type = pickweight(list(
- "Miner" = 44,
- "Waldo" = 3,
- "Ashwalker" = 7,
- "Soldier" = 5,
- "Oldminer" = 8,
- "Kobold" = 5,
- "SRM" = 6,
- "Operative" = 5,
- pick("Shadow", "YeOlde") = 4
+ "Miner" = 40,
+ "Assistant" = 10,
+ "Engineer" = 5,
+ "Doctor" = 5,
+ "Scientist" = 5,
+ "Cargo" = 5,
+ "Security" = 5
)
)
- switch(type)
- if("Miner")
- if(prob(2))
- mob_species = /datum/species/plasmaman
- uniform = /obj/item/clothing/under/plasmaman
- head = /obj/item/clothing/head/helmet/space/plasmaman
- belt = /obj/item/tank/internals/plasmaman/belt
- else
- uniform = /obj/item/clothing/under/rank/cargo/miner/lavaland
- if (prob(4))
- belt = pickweight(list(
- /obj/item/storage/belt/mining = 2,
- /obj/item/storage/belt/mining/alt = 2
- )
- )
- else if(prob(10))
- belt = pickweight(list(
- /obj/item/pickaxe = 8,
- /obj/item/pickaxe/mini = 4,
- /obj/item/pickaxe/silver = 2,
- /obj/item/pickaxe/diamond = 1,
- /obj/item/gun/energy/kinetic_accelerator = 1
- )
- )
- else
- belt = /obj/item/tank/internals/emergency_oxygen/engi
- if(mob_species != /datum/species/lizard)
- shoes = /obj/item/clothing/shoes/workboots/mining
- gloves = /obj/item/clothing/gloves/color/black
- mask = /obj/item/clothing/mask/gas/explorer
- if(prob(45))
- glasses = /obj/item/clothing/glasses/meson
- if(prob(20))
- suit = pickweight(list(
- /obj/item/clothing/suit/hooded/explorer = 18,
- /obj/item/clothing/suit/hooded/cloak/goliath = 2
- )
- )
- if(prob(30))
- r_pocket = pickweight(list(
- /obj/item/stack/marker_beacon = 20,
- /obj/item/spacecash/bundle/mediumrand = 7,
- /obj/item/reagent_containers/hypospray/medipen/survival = 2,
- /obj/item/borg/upgrade/modkit/damage = 1
- )
- )
- if(prob(10))
- l_pocket = pickweight(list(
- /obj/item/spacecash/bundle/mediumrand = 7,
- /obj/item/reagent_containers/hypospray/medipen/survival = 2,
- /obj/item/borg/upgrade/modkit/cooldown = 1
- )
- )
- if(prob(95))
- back = /obj/item/storage/backpack/explorer
- backpack_contents = list(/obj/item/radio)
- if(prob(70))
- backpack_contents += pickweight(list(
- /obj/item/borg/upgrade/modkit/damage = 1,
- /obj/item/borg/upgrade/modkit/trigger_guard = 1,
- /obj/item/soap/nanotrasen = 1,
- /obj/item/wormhole_jaunter = 1,
- /obj/item/fulton_core = 1,
- /obj/item/extraction_pack = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 3,
- /obj/item/hivelordstabilizer = 2,
- /obj/item/stack/marker_beacon/ten = 2,
- /obj/item/mining_scanner = 2,
- /obj/item/extinguisher/mini = 2,
- /obj/item/kitchen/knife/combat/survival = 3,
- /obj/item/flashlight/seclite=3,
- /obj/item/stack/sheet/sinew = 3,
- /obj/item/stack/sheet/bone = 3
- )
- )
- if(prob(70))
- backpack_contents += pickweight(list(
- /obj/item/borg/upgrade/modkit/damage = 1,
- /obj/item/borg/upgrade/modkit/trigger_guard = 1,
- /obj/item/soap/nanotrasen = 1,
- /obj/item/wormhole_jaunter = 1,
- /obj/item/fulton_core = 1,
- /obj/item/extraction_pack = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 3,
- /obj/item/hivelordstabilizer = 2,
- /obj/item/stack/marker_beacon/ten = 2,
- /obj/item/mining_scanner = 2,
- /obj/item/extinguisher/mini = 2,
- /obj/item/kitchen/knife/combat/survival = 3,
- /obj/item/flashlight/seclite = 3,
- /obj/item/stack/sheet/sinew = 3,
- /obj/item/stack/sheet/bone = 3
- )
- )
- if(prob(70))
- backpack_contents += pickweight(list(
- /obj/item/borg/upgrade/modkit/damage = 1,
- /obj/item/borg/upgrade/modkit/trigger_guard = 1,
- /obj/item/soap/nanotrasen = 1,
- /obj/item/wormhole_jaunter = 1,
- /obj/item/fulton_core = 1,
- /obj/item/extraction_pack = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 3,
- /obj/item/hivelordstabilizer = 2,
- /obj/item/stack/marker_beacon/ten = 2,
- /obj/item/mining_scanner = 2,
- /obj/item/extinguisher/mini = 2,
- /obj/item/kitchen/knife/combat/survival = 3,
- /obj/item/flashlight/seclite = 3,
- /obj/item/stack/sheet/sinew = 3,
- /obj/item/stack/sheet/bone = 3
- )
- )
- if(prob(30))
- backpack_contents += list(
- /obj/item/reagent_containers/hypospray/medipen/survival = pickweight(list(
- 1 = 3,
- 2 = 2,
- 3 = 1
- )
- )
- )
- else
- back = /obj/item/kinetic_crusher
- if("Oldminer")
- suit = /obj/item/clothing/suit/hooded/explorer/old
- mask = /obj/item/clothing/mask/gas/explorer/old
- if(prob(95))
- glasses = /obj/item/clothing/glasses/meson
- else
- glasses = /obj/item/clothing/glasses/meson/night
- suit_store = /obj/item/tank/internals/oxygen
- gloves = /obj/item/clothing/gloves/explorer/old
- uniform = /obj/item/clothing/under/rank/cargo/miner/lavaland/old
- if(prob(85))
- back = /obj/item/storage/backpack/explorer //someone could totally make these backpacks a subtype and just have them be there. It'd cut down this file size a bit.
- backpack_contents = list()
- if(prob(70))
- backpack_contents += pickweight(list(
- /obj/item/borg/upgrade/modkit/damage = 1,
- /obj/item/borg/upgrade/modkit/trigger_guard = 1,
- /obj/item/soap/nanotrasen = 1,
- /obj/item/wormhole_jaunter = 1,
- /obj/item/fulton_core = 1,
- /obj/item/extraction_pack = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 3,
- /obj/item/hivelordstabilizer = 2,
- /obj/item/stack/marker_beacon/ten = 2,
- /obj/item/mining_scanner = 2,
- /obj/item/extinguisher/mini = 2,
- /obj/item/kitchen/knife/combat/survival = 3,
- /obj/item/flashlight/seclite=3,
- /obj/item/stack/sheet/sinew = 3,
- /obj/item/stack/sheet/bone = 3
- )
- )
- if(prob(70))
- backpack_contents += pickweight(list(
- /obj/item/borg/upgrade/modkit/damage = 1,
- /obj/item/borg/upgrade/modkit/trigger_guard = 1,
- /obj/item/soap/nanotrasen = 1,
- /obj/item/wormhole_jaunter = 1,
- /obj/item/fulton_core = 1,
- /obj/item/extraction_pack = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 3,
- /obj/item/hivelordstabilizer = 2,
- /obj/item/stack/marker_beacon/ten = 2,
- /obj/item/mining_scanner = 2,
- /obj/item/extinguisher/mini = 2,
- /obj/item/kitchen/knife/combat/survival = 3,
- /obj/item/flashlight/seclite=3,
- /obj/item/stack/sheet/sinew = 3,
- /obj/item/stack/sheet/bone = 3
- )
- )
- if(prob(70))
- backpack_contents += pickweight(list(
- /obj/item/borg/upgrade/modkit/damage = 1,
- /obj/item/borg/upgrade/modkit/trigger_guard = 1,
- /obj/item/soap/nanotrasen = 1,
- /obj/item/wormhole_jaunter = 1,
- /obj/item/fulton_core = 1,
- /obj/item/extraction_pack = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 3,
- /obj/item/hivelordstabilizer = 2,
- /obj/item/stack/marker_beacon/ten = 2,
- /obj/item/mining_scanner = 2,
- /obj/item/extinguisher/mini = 2,
- /obj/item/kitchen/knife/combat/survival = 3,
- /obj/item/flashlight/seclite=3,
- /obj/item/stack/sheet/sinew = 3,
- /obj/item/stack/sheet/bone = 3
- )
- )
- if(prob(30))
- backpack_contents += list(
- /obj/item/reagent_containers/hypospray/medipen/survival = pickweight(list(
- 1 = 3,
- 2 = 2,
- 3 = 1
- )
- )
- )
- else
- back = /obj/item/kinetic_crusher/old
- if(prob(30))
- belt = /obj/item/gun/energy/kinetic_accelerator/old
- if(prob(30))
- r_pocket = pickweight(list(
- /obj/item/stack/marker_beacon = 20,
- /obj/item/spacecash/bundle/mediumrand = 7,
- /obj/item/reagent_containers/hypospray/medipen/survival = 2,
- /obj/item/borg/upgrade/modkit/damage = 1
- )
- )
- if(prob(30))
- l_pocket = pickweight(list(
- /obj/item/spacecash/bundle/mediumrand = 5,
- /obj/item/reagent_containers/hypospray/medipen/survival = 2,
- /obj/item/borg/upgrade/modkit/cooldown = 1
- )
- )
- if("Ashwalker")
- mob_species = /datum/species/lizard/ashwalker
- uniform = /obj/item/clothing/under/costume/gladiator/ash_walker
- if(prob(95))
- head = /obj/item/clothing/head/helmet/gladiator
- else
- head = /obj/item/clothing/head/helmet/skull
- suit = /obj/item/clothing/suit/armor/bone
- gloves = /obj/item/clothing/gloves/bracer
- if(prob(45))
- back = pickweight(list(
- /obj/item/spear/bonespear = 3,
- /obj/item/fireaxe/boneaxe = 2
- )
- )
- if(prob(10))
- belt = /obj/item/storage/belt/mining/primitive
- if(prob(30))
- r_pocket = /obj/item/restraints/legcuffs/bola/watcher
- if(prob(30))
- l_pocket = /obj/item/kitchen/knife/combat/bone
- if("Soldier")
- mob_species = /datum/species/human
- if(prob(90))
- uniform = /obj/item/clothing/under/solgov
- suit = /obj/item/clothing/suit/armor/vest/bulletproof/solgov
- shoes = /obj/item/clothing/shoes/jackboots
- gloves = /obj/item/clothing/gloves/color/black
- mask = /obj/item/clothing/mask/gas/sechailer
- head = /obj/item/clothing/head/solgov/sonnensoldner
- id = /obj/item/card/id/solgov
- else
- uniform = /obj/item/clothing/under/solgov
- suit = /obj/item/clothing/suit/space/hardsuit/solgov
- shoes = /obj/item/clothing/shoes/combat
- gloves = /obj/item/clothing/gloves/combat
- mask = /obj/item/clothing/mask/gas/sechailer/swat
- id = /obj/item/card/id/solgov
- if(prob(85))
- back = /obj/item/storage/backpack
- backpack_contents = list()
- if(prob(75))
- backpack_contents += pickweight(list(
- /obj/item/reagent_containers/hypospray/medipen/stimpack/traitor = 1,
- /obj/item/storage/firstaid/tactical = 1,
- /obj/item/gun/ballistic/automatic/pistol/solgov = 1,
- /obj/item/gps = 1,
- /obj/item/stock_parts/cell/gun/upgraded = 2,
- /obj/item/ammo_box/magazine/pistol556mm = 3,
- /obj/item/desk_flag/solgov = 3,
- /obj/item/stack/marker_beacon/ten = 3,
- /obj/item/detective_scanner = 2,
- /obj/item/extinguisher/mini = 3,
- /obj/item/kitchen/knife/combat = 3,
- /obj/item/flashlight/seclite=3,
- /obj/item/ammo_casing/shotgun = 3,
- /obj/item/binoculars = 3,
- /obj/item/clipboard = 3
- )
- )
- if(prob(75))
- backpack_contents += pickweight(list(
- /obj/item/reagent_containers/hypospray/medipen/stimpack/traitor = 1,
- /obj/item/storage/firstaid/tactical = 1,
- /obj/item/gun/ballistic/automatic/pistol/solgov = 1,
- /obj/item/gps = 1,
- /obj/item/stock_parts/cell/gun/upgraded = 2,
- /obj/item/ammo_box/magazine/pistol556mm = 3,
- /obj/item/desk_flag/solgov = 3,
- /obj/item/stack/marker_beacon/ten = 3,
- /obj/item/detective_scanner = 2,
- /obj/item/extinguisher/mini = 3,
- /obj/item/kitchen/knife/combat = 3,
- /obj/item/flashlight/seclite=3,
- /obj/item/ammo_casing/shotgun = 3,
- /obj/item/binoculars = 3,
- /obj/item/clipboard = 3
- )
- )
- if(prob(75))
- backpack_contents += pickweight(list(
- /obj/item/reagent_containers/hypospray/medipen/stimpack/traitor = 1,
- /obj/item/storage/firstaid/tactical = 1,
- /obj/item/gun/ballistic/automatic/pistol/solgov = 1,
- /obj/item/gps = 1,
- /obj/item/stock_parts/cell/gun/upgraded = 2,
- /obj/item/ammo_box/magazine/pistol556mm = 3,
- /obj/item/desk_flag/solgov = 3,
- /obj/item/stack/marker_beacon/ten = 3,
- /obj/item/detective_scanner = 2,
- /obj/item/extinguisher/mini = 3,
- /obj/item/kitchen/knife/combat = 3,
- /obj/item/flashlight/seclite=3,
- /obj/item/ammo_casing/shotgun = 3,
- /obj/item/binoculars = 3,
- /obj/item/clipboard = 3
- )
- )
- else
- back = pickweight(list(
- /obj/item/energyhalberd = 5,
- /obj/item/gun/ballistic/rocketlauncher/unrestricted = 5
- )
- )
- if(prob(25))
- belt = /obj/item/storage/belt/military
- if(prob(50))
- r_pocket = pickweight(list(
- /obj/item/reagent_containers/hypospray/medipen/stimpack = 1,
- /obj/item/kitchen/knife/letter_opener = 3,
- /obj/item/radio/off = 3,
- /obj/item/grenade/syndieminibomb/concussion = 1,
- /obj/item/melee/transforming/energy/ctf/solgov = 1
- )
- )
- if(prob(50))
- l_pocket = pickweight(list(
- /obj/item/reagent_containers/hypospray/medipen/stimpack = 1,
- /obj/item/kitchen/knife/letter_opener = 3,
- /obj/item/radio/off = 3,
- /obj/item/grenade/syndieminibomb/concussion = 1,
- /obj/item/melee/transforming/energy/ctf/solgov = 1
- )
- )
- if(prob(70))
- glasses = pickweight(list(
- /obj/item/clothing/glasses/sunglasses = 3,
- /obj/item/clothing/glasses/hud/health = 3,
- /obj/item/clothing/glasses/hud/health/night = 1,
- /obj/item/clothing/glasses/night = 2
- )
- )
- if("Kobold")
- mob_species = /datum/species/lizard/ashwalker/kobold
- uniform = /obj/item/clothing/under/costume/gladiator/ash_walker
- if(prob(95))
- head = /obj/item/clothing/head/helmet/gladiator
- else
- head = /obj/item/clothing/head/helmet/skull
- suit = /obj/item/clothing/suit/armor/bone
- gloves = /obj/item/clothing/gloves/bracer
- if(prob(5))
- back = pickweight(list(
- /obj/item/spear/bonespear = 3,
- /obj/item/fireaxe/boneaxe = 2
- )
- )
- if(prob(10))
- belt = /obj/item/storage/belt/mining/primitive
- if(prob(30))
- r_pocket = /obj/item/kitchen/knife/combat/bone
- if(prob(30))
- l_pocket = /obj/item/kitchen/knife/combat/bone
- if("YeOlde")
- mob_gender = FEMALE
- uniform = /obj/item/clothing/under/costume/maid
- gloves = /obj/item/clothing/gloves/color/white
- shoes = /obj/item/clothing/shoes/laceup
- head = /obj/item/clothing/head/helmet/knight
- suit = /obj/item/clothing/suit/armor/riot/knight
- back = /obj/item/shield/riot/buckler
- belt = /obj/item/nullrod/claymore
- r_pocket = /obj/item/tank/internals/emergency_oxygen
- mask = /obj/item/clothing/mask/breath
- if("Operative")
- id_job = "Operative"
- if(prob(40))
- outfit = /datum/outfit/syndicatecommandocorpse
- else if(prob(5))
- outfit = /datum/outfit/syndicatestormtroopercorpse
- else
- outfit = /datum/outfit/syndicateramzicorpse
- if("Waldo")//WE FINALLY FOUND HIM
- name = "Waldo"
- uniform = /obj/item/clothing/under/pants/jeans
- suit = /obj/item/clothing/suit/striped_sweater
- head = /obj/item/clothing/head/beanie/waldo
- shoes = /obj/item/clothing/shoes/sneakers/brown
- ears = /obj/item/radio/headset
- glasses = /obj/item/clothing/glasses/regular/circle
- back = /obj/item/storage/backpack/satchel/leather
- backpack_contents = list()
- if(prob(50))
- backpack_contents += pickweight(list(
- /obj/item/book/granter/spell/knock = 1,
- /obj/item/book/granter/spell/blind = 1,
- /obj/item/shadowcloak = 1,
- /obj/item/book/granter/spell/smoke = 2,
- /obj/item/reagent_containers/syringe/mulligan = 2,
- /obj/item/dice/d20 = 3,
- /obj/item/dice/d20/fate/stealth/one_use = 1,
- /obj/item/clothing/head/chameleon/broken = 3,
- /obj/item/stack/marker_beacon/ten = 3,
- /obj/item/grenade/smokebomb = 3,
- /obj/item/grenade/flashbang = 3
- )
- )
- if(prob(50))
- backpack_contents += pickweight(list(
- /obj/item/book/granter/spell/knock = 1,
- /obj/item/book/granter/spell/blind = 1,
- /obj/item/shadowcloak = 1,
- /obj/item/book/granter/spell/smoke = 2,
- /obj/item/reagent_containers/syringe/mulligan = 2,
- /obj/item/dice/d20/fate/stealth/one_use = 1,
- /obj/item/dice/d20 = 3,
- /obj/item/clothing/head/chameleon/broken = 3,
- /obj/item/stack/marker_beacon/ten = 3,
- /obj/item/grenade/smokebomb = 3,
- /obj/item/grenade/flashbang = 3
- )
- )
- if(prob(50))
- backpack_contents += pickweight(list(
- /obj/item/book/granter/spell/knock = 1,
- /obj/item/book/granter/spell/blind = 1,
- /obj/item/shadowcloak = 1,
- /obj/item/book/granter/spell/smoke = 2,
- /obj/item/reagent_containers/syringe/mulligan = 2,
- /obj/item/dice/d20/fate/stealth/one_use = 1,
- /obj/item/clothing/head/chameleon/broken = 3,
- /obj/item/stack/marker_beacon/ten = 3,
- /obj/item/grenade/smokebomb = 3,
- /obj/item/grenade/flashbang = 3
- )
- )
- if(prob(25))
- r_pocket = pickweight(list(
- /obj/item/chameleon,
- /obj/item/dnainjector/chameleonmut = 1,
- /obj/item/flashlight/flashdark = 1
- )
- )
- if(prob(25))
- l_pocket = pickweight(list(
- /obj/item/chameleon,
- /obj/item/dnainjector/chameleonmut = 1,
- /obj/item/flashlight/flashdark = 1
- )
- )
- if("Shadow")
- mob_species = /datum/species/shadow
- neck = /obj/item/clothing/accessory/medal/plasma/nobel_science
- uniform = /obj/item/clothing/under/color/black
- shoes = /obj/item/clothing/shoes/sneakers/black
- suit = /obj/item/clothing/suit/toggle/labcoat
- glasses = /obj/item/clothing/glasses/blindfold
- back = /obj/item/tank/internals/oxygen
- mask = /obj/item/clothing/mask/breath
- if("SRM")
- uniform = /obj/item/clothing/under/suit/roumain
- shoes = /obj/item/clothing/shoes/workboots/mining
- if(prob(50))
- suit = /obj/item/clothing/suit/armor/roumain/shadow
- head = /obj/item/clothing/head/cowboy/sec/roumain/shadow
- else
- suit = /obj/item/clothing/suit/armor/roumain
- head = /obj/item/clothing/head/cowboy/sec/roumain
- if(prob(25))
- suit_store = /obj/item/gun/ballistic/shotgun/flamingarrow
- r_pocket = /obj/item/book/manual/trickwines_4_brewers
- belt = pick(list(/obj/item/kitchen/knife/hunting = 1, /obj/item/gun/ballistic/derringer = 1))
- back = /obj/item/storage/backpack/cultpack
- backpack_contents = list()
- if(prob(75))
- backpack_contents += list(/obj/item/ammo_box/c38_box = 1)
- if(prob(75))
- backpack_contents += list(pick(
- /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/ashwine,
- /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/icewine,
- /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/shockwine,
- /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/hearthwine,
- /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/forcewine,
- /obj/item/reagent_containers/food/drinks/breakawayflask/vintage/prismwine,) = 2)
+
+ var/outfit_map = list(
+ "Miner" = /datum/outfit/generic/miner,
+ "Assistant" = /datum/outfit/generic,
+ "Engineer" = /datum/outfit/generic/engineer,
+ "Doctor" = /datum/outfit/generic/doctor,
+ "Scientist" = /datum/outfit/generic/science,
+ "Cargo" = /datum/outfit/generic/cargo,
+ "Security" = /datum/outfit/generic/security
+ )
+
+ outfit = outfit_map[type] // Access outfit directly
+
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord_outfits.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord_outfits.dm
new file mode 100644
index 000000000000..09d85a664e86
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord_outfits.dm
@@ -0,0 +1,479 @@
+/datum/outfit/generic/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
+ . = ..()
+ uniform = pickweight(list(
+ /obj/item/clothing/under/utility = 5,
+ /obj/item/clothing/under/utility/skirt = 5,
+ /obj/item/clothing/under/color/black = 1,
+ /obj/item/clothing/under/color/white = 1,
+ /obj/item/clothing/under/color/random = 1,
+ /obj/item/clothing/under/suit/white = 1,
+ /obj/item/clothing/under/suit/tan = 1,
+ /obj/item/clothing/under/suit/black_really = 1,
+ /obj/item/clothing/under/suit/navy = 1,
+ /obj/item/clothing/under/suit/burgundy = 1,
+ /obj/item/clothing/under/suit/charcoal = 1,
+ /obj/item/clothing/under/rank/civilian/lawyer/galaxy = 1,
+ /obj/item/clothing/under/suit/black/skirt = 1,
+ /obj/item/clothing/under/suit/black = 1,
+ /obj/item/clothing/under/dress/sailor = 1,
+ /obj/item/clothing/under/dress/striped = 1,
+ /obj/item/clothing/under/dress/skirt/blue = 1,
+ /obj/item/clothing/under/syndicate/tacticool = 1,
+ )
+ )
+ suit = pickweight(list(
+ /obj/item/clothing/suit/hooded/wintercoat = 1,
+ /obj/item/clothing/suit/jacket = 1,
+ /obj/item/clothing/suit/jacket/leather = 1,
+ /obj/item/clothing/suit/jacket/leather/overcoat = 1,
+ /obj/item/clothing/suit/jacket/leather/duster = 1,
+ /obj/item/clothing/suit/jacket/miljacket = 1,
+ /obj/item/clothing/suit/jacket/puffer = 1,
+ /obj/item/clothing/suit/gothcoat = 1,
+ /obj/item/clothing/suit/toggle/industrial = 1,
+ /obj/item/clothing/suit/toggle/hazard = 1,
+ )
+ )
+ back = pickweight(list(
+ /obj/item/storage/backpack = 1,
+ /obj/item/storage/backpack/satchel = 1,
+ /obj/item/storage/backpack/duffelbag = 1,
+ /obj/item/storage/backpack/messenger = 1,
+ /obj/item/storage/backpack/satchel/leather = 1
+ )
+ )
+ if (prob(10))
+ belt = pickweight(list(
+ /obj/item/gun/ballistic/automatic/pistol/candor = 2,
+ /obj/item/gun/ballistic/automatic/pistol/commander = 1,
+ /obj/item/gun/ballistic/automatic/pistol/syndicate = 1,
+ /obj/item/gun/ballistic/revolver/syndicate = 1,
+ /obj/item/gun/ballistic/revolver/firebrand = 1,
+ )
+ )
+ if(prob(50))
+ gloves = pickweight(list(
+ /obj/item/clothing/gloves/color/black = 1,
+ /obj/item/clothing/gloves/fingerless = 1,
+ /obj/item/clothing/gloves/color/white = 1,
+ )
+ )
+ shoes = pickweight(list(
+ /obj/item/clothing/shoes/laceup = 1,
+ /obj/item/clothing/shoes/sandal = 1,
+ /obj/item/clothing/shoes/winterboots = 1,
+ /obj/item/clothing/shoes/workboots/mining = 1,
+ /obj/item/clothing/shoes/workboots = 1,
+ /obj/item/clothing/shoes/sneakers/black = 1,
+ /obj/item/clothing/shoes/sneakers/brown = 1,
+ /obj/item/clothing/shoes/sneakers/white = 1
+ )
+ )
+ if(prob(50))
+ head = pickweight(list(
+ /obj/item/clothing/head/beret = 3,
+ /obj/item/clothing/head/beret/grey = 3,
+ /obj/item/clothing/head/flatcap = 3,
+ /obj/item/clothing/head/beanie = 3,
+ /obj/item/clothing/head/cowboy = 3,
+ /obj/item/clothing/head/trapper = 2,
+ /obj/item/clothing/head/hardhat = 2,
+ /obj/item/clothing/head/hardhat/orange = 2,
+ /obj/item/clothing/head/hardhat/dblue = 2,
+ /obj/item/clothing/head/pirate = 1,
+ /obj/item/clothing/head/foilhat = 1
+ )
+ )
+ if(prob(50))
+ mask = pickweight(list(
+ /obj/item/clothing/mask/balaclava = 1,
+ /obj/item/clothing/mask/bandana/red = 1,
+ /obj/item/clothing/mask/gas = 3,
+ /obj/item/clothing/mask/breath = 3,
+ )
+ )
+ if(prob(25))
+ neck = pickweight(list(
+ /obj/item/clothing/neck/scarf/red = 1,
+ /obj/item/clothing/neck/scarf/green = 1,
+ /obj/item/clothing/neck/scarf/darkblue = 1,
+ /obj/item/clothing/neck/shemagh = 1,
+ /obj/item/clothing/neck/stripedredscarf = 1,
+ /obj/item/clothing/neck/stripedgreenscarf = 1,
+ /obj/item/clothing/neck/stripedbluescarf = 1
+ )
+ )
+ ears = pick(/obj/item/radio/headset, /obj/item/radio/headset/alt)
+ if(prob(50))
+ glasses = pickweight(list(
+ /obj/item/clothing/glasses/regular = 1,
+ /obj/item/clothing/glasses/regular/circle = 1,
+ /obj/item/clothing/glasses/regular/jamjar = 1,
+ /obj/item/clothing/glasses/eyepatch = 1,
+ /obj/item/clothing/glasses/cheapsuns = 1,
+ /obj/item/clothing/glasses/regular/hipster = 1,
+ /obj/item/clothing/glasses/cold = 1,
+ /obj/item/clothing/glasses/heat = 1,
+ /obj/item/clothing/glasses/orange = 1,
+ )
+ )
+ if(prob(75))
+ r_pocket = /obj/item/tank/internals/emergency_oxygen
+ if(prob(75))
+ l_pocket = pick(/obj/item/radio, /obj/item/flashlight)
+ id = /obj/item/card/id
+ backpack_contents = list()
+ backpack_contents += pickweight(list(
+ /obj/item/dice/d20 = 1,
+ /obj/item/lipstick = 1,
+ /obj/item/clothing/mask/vape = 1,
+ /obj/item/clothing/mask/vape/cigar = 1,
+ /obj/item/reagent_containers/food/drinks/flask = 1,
+ /obj/item/lighter = 1,
+ /obj/item/toy/cards/deck = 1,
+ /obj/item/toy/eightball = 1,
+ /obj/item/storage/wallet = 1,
+ /obj/item/paicard = 1,
+ /obj/item/pen/fourcolor = 1,
+ /obj/item/paper_bin = 1,
+ /obj/item/cane = 1,
+ /obj/item/radio = 1,
+ /obj/item/dyespray = 1,
+ /obj/item/table_bell/brass = 1,
+ /obj/item/flashlight = 1,
+ /obj/item/crowbar/red = 1
+ )
+ )
+
+/datum/outfit/generic
+ name = "Generic (Legion)"
+ box = /obj/item/storage/box/survival
+ random = TRUE
+
+/datum/outfit/generic/miner/pre_equip(mob/living/carbon/human/H, visualsOnly)
+ . = ..()
+ if(prob(75))
+ uniform = pickweight(list(
+ /obj/item/clothing/under/rank/cargo/miner/lavaland = 5,
+ /obj/item/clothing/under/rank/cargo/miner = 4,
+ /obj/item/clothing/under/rank/cargo/miner/lavaland/old = 1,
+ )
+ )
+ if(prob(25))
+ suit = pickweight(list(
+ /obj/item/clothing/suit/hooded/explorer = 18,
+ /obj/item/clothing/suit/hooded/explorer/old = 1,
+ /obj/item/clothing/suit/hooded/cloak/goliath = 1
+ )
+ )
+ if(prob(75))
+ back = /obj/item/storage/backpack/explorer
+ if(prob(75))
+ belt = pickweight(list(
+ /obj/item/storage/belt/mining = 2,
+ /obj/item/storage/belt/mining/alt = 2
+ )
+ )
+ else if(prob(75))
+ belt = pickweight(list(
+ /obj/item/pickaxe = 16,
+ /obj/item/pickaxe/mini = 8,
+ /obj/item/pickaxe/silver = 4,
+ /obj/item/pickaxe/diamond = 2,
+ /obj/item/gun/energy/kinetic_accelerator = 2,
+ /obj/item/kinetic_crusher/old = 1
+ )
+ )
+ if(prob(75))
+ gloves = pickweight(list(
+ /obj/item/clothing/gloves/color/black = 9,
+ /obj/item/clothing/gloves/explorer/old = 1
+ )
+ )
+ if(prob(75))
+ shoes = /obj/item/clothing/shoes/workboots/mining
+ if(prob(75))
+ mask = pickweight(list(
+ /obj/item/clothing/mask/gas/explorer = 9,
+ /obj/item/clothing/mask/gas/explorer/old = 1
+ )
+ )
+ if(prob(50))
+ glasses = /obj/item/clothing/glasses/meson
+ if(prob(50))
+ r_pocket = pickweight(list(
+ /obj/item/stack/marker_beacon = 20,
+ /obj/item/spacecash/bundle/mediumrand = 7,
+ /obj/item/reagent_containers/hypospray/medipen/survival = 2,
+ /obj/item/borg/upgrade/modkit/damage = 1
+ )
+ )
+ if(prob(25))
+ l_pocket = pickweight(list(
+ /obj/item/spacecash/bundle/mediumrand = 5,
+ /obj/item/reagent_containers/hypospray/medipen/survival = 2,
+ /obj/item/borg/upgrade/modkit/cooldown = 1
+ )
+ )
+ if(prob(75))
+ for(var/count in 1 to 3)
+ if(prob(70))
+ backpack_contents += pickweight(list(
+ /obj/item/borg/upgrade/modkit/damage = 1,
+ /obj/item/borg/upgrade/modkit/trigger_guard = 1,
+ /obj/item/soap/nanotrasen = 1,
+ /obj/item/wormhole_jaunter = 1,
+ /obj/item/fulton_core = 1,
+ /obj/item/extraction_pack = 2,
+ /obj/item/stack/sheet/animalhide/goliath_hide = 3,
+ /obj/item/hivelordstabilizer = 2,
+ /obj/item/stack/marker_beacon/ten = 2,
+ /obj/item/mining_scanner = 2,
+ /obj/item/extinguisher/mini = 2,
+ /obj/item/kitchen/knife/combat/survival = 3,
+ /obj/item/flashlight/seclite = 3,
+ /obj/item/stack/sheet/sinew = 3,
+ /obj/item/stack/sheet/bone = 3
+ )
+ )
+ if(prob(30))
+ backpack_contents += list(
+ /obj/item/reagent_containers/hypospray/medipen/survival = pickweight(list(
+ 1 = 3,
+ 2 = 2,
+ 3 = 1
+ )
+ )
+ )
+ else if (prob(75))
+ backpack_contents = list()
+ back = pickweight(list(
+ /obj/item/kinetic_crusher = 9,
+ /obj/item/kinetic_crusher/old = 1
+ )
+ )
+
+/datum/outfit/generic/miner
+ name = "Miner (Legion)"
+
+/datum/outfit/generic/engineer/pre_equip(mob/living/carbon/human/H, visualsOnly)
+ . = ..()
+ if(prob(75))
+ uniform = pick(/obj/item/clothing/under/rank/engineering/engineer, /obj/item/clothing/under/rank/engineering/engineer/hazard, /obj/item/clothing/under/rank/security/officer/military/eng)
+ if(prob(75))
+ suit = pick(/obj/item/clothing/suit/toggle/hazard, /obj/item/clothing/suit/hazardvest, /obj/item/clothing/suit/hooded/wintercoat/engineering)
+ if(prob(75))
+ gloves = pick(/obj/item/clothing/gloves/color/yellow, /obj/item/clothing/gloves/color/fyellow, /obj/item/clothing/gloves/color/fyellow/old)
+ if(prob(75))
+ belt = pick(/obj/item/storage/belt/utility/full, /obj/item/storage/belt/utility)
+ if(prob(50))
+ head = /obj/item/clothing/head/welding
+ if(prob(75))
+ ears = /obj/item/radio/headset/headset_eng
+ else if(prob(50))
+ glasses = /obj/item/clothing/glasses/welding
+ if(prob(75))
+ back = pick(/obj/item/storage/backpack/industrial, /obj/item/storage/backpack/satchel/eng, /obj/item/storage/backpack/duffelbag/engineering, /obj/item/storage/backpack/messenger/engi)
+ if(prob(10))
+ back = /obj/item/fireaxe
+ for(var/i = 1 to 3)
+ if(prob(75))
+ backpack_contents += pickweight(list(
+ /obj/item/stack/tape/industrial/electrical = 1,
+ /obj/item/electronics/apc = 1,
+ /obj/item/multitool = 1,
+ /obj/item/pipe_dispenser = 1,
+ /obj/item/tank/internals/emergency_oxygen/engi = 1,
+ /obj/item/holosign_creator/engineering = 1,
+ /obj/item/extinguisher/advanced = 1,
+ /obj/item/stack/sheet/metal/twenty = 1
+ )
+ )
+ if(prob(75))
+ accessory = /obj/item/clothing/accessory/armband/engine
+
+/datum/outfit/generic/engineer
+ name = "Mechanic (Legion)"
+ box = /obj/item/storage/box/survival/engineer
+
+/datum/outfit/generic/doctor/pre_equip(mob/living/carbon/human/H, visualsOnly)
+ . = ..()
+ if(prob(75))
+ uniform = pick(/obj/item/clothing/under/rank/medical/doctor, /obj/item/clothing/under/rank/medical/doctor/blue)
+ if(prob(75))
+ suit = pick(/obj/item/clothing/suit/toggle/labcoat, /obj/item/clothing/suit/apron/surgical ,/obj/item/clothing/suit/hooded/wintercoat/medical)
+ if(prob(75))
+ back = pick(/obj/item/storage/backpack/medic, /obj/item/storage/backpack/satchel/med, /obj/item/storage/backpack/duffelbag/med, /obj/item/storage/backpack/messenger/med)
+ else if (prob(75))
+ back = /obj/item/defibrillator/loaded
+ if(prob(75))
+ belt = pickweight(list(/obj/item/storage/belt/medical = 5, /obj/item/defibrillator/compact/loaded = 1))
+ if(prob(75))
+ gloves = pick(/obj/item/clothing/gloves/color/white, /obj/item/clothing/gloves/color/latex/nitrile)
+ if(prob(75))
+ mask = /obj/item/clothing/mask/surgical
+ if(prob(75))
+ shoes = /obj/item/clothing/shoes/sneakers/white
+ if(prob(75))
+ head = /obj/item/clothing/head/beret/med
+ if(prob(75))
+ ears = /obj/item/radio/headset/headset_med
+ if(prob(75))
+ glasses = pick(/obj/item/clothing/glasses/hud/health, /obj/item/clothing/glasses/hud/health/prescription)
+ for(var/i = 1 to 3)
+ if(prob(75))
+ backpack_contents += pickweight(list(
+ /obj/item/reagent_containers/pill/patch/styptic = 5,
+ /obj/item/reagent_containers/pill/patch/silver_sulf = 5,
+ /obj/item/storage/firstaid/medical = 3,
+ /obj/item/reagent_containers/syringe = 3,
+ /obj/item/reagent_containers/glass/beaker = 2,
+ /obj/item/reagent_containers/dropper = 2,
+ /obj/item/reagent_containers/pill/charcoal = 2,
+ /obj/item/reagent_containers/medigel/styptic = 2,
+ /obj/item/reagent_containers/medigel/silver_sulf = 2,
+ /obj/item/reagent_containers/medigel/sterilizine = 1,
+ /obj/item/flashlight/pen = 1,
+ /obj/item/hypospray/mkii = 1,
+ /obj/item/healthanalyzer = 1,
+ )
+ )
+ if(prob(75))
+ accessory = /obj/item/clothing/accessory/armband/medblue
+
+/datum/outfit/generic/doctor
+ name = "Medical Doctor (Legion)"
+ box = /obj/item/storage/box/survival/medical
+
+/datum/outfit/generic/science/pre_equip(mob/living/carbon/human/H)
+ ..()
+ if(prob(75))
+ uniform = pick(/obj/item/clothing/under/rank/rnd/scientist, /obj/item/clothing/under/rank/rnd/roboticist)
+ if(prob(75))
+ suit = pick(/obj/item/clothing/suit/toggle/labcoat/science, /obj/item/clothing/suit/hooded/wintercoat/science)
+ if(prob(75))
+ back = pick(/obj/item/storage/backpack/science, /obj/item/storage/backpack/satchel/tox, /obj/item/storage/backpack/messenger/tox)
+ if(prob(75))
+ shoes = /obj/item/clothing/shoes/sneakers/white
+ if(prob(75))
+ gloves = /obj/item/clothing/gloves/color/white
+ if(prob(75))
+ head = /obj/item/clothing/head/beret/sci
+ if(prob(75))
+ ears = /obj/item/radio/headset/headset_sci
+ if(prob(75))
+ glasses = pick(/obj/item/clothing/glasses/hud/diagnostic, /obj/item/clothing/glasses/science)
+ if(prob(1))
+ neck = /obj/item/clothing/neck/tie/horrible
+ for(var/i = 1 to 3)
+ if(prob(75))
+ backpack_contents += pickweight(list(
+ /obj/item/research_notes/loot/tiny = 3,
+ /obj/item/research_notes/loot/small = 3,
+ /obj/item/reagent_scanner = 3,
+ /obj/item/assembly/flash/handheld = 3,
+ /obj/item/stock_parts/capacitor/adv = 2,
+ /obj/item/stock_parts/scanning_module/adv = 2,
+ /obj/item/stock_parts/manipulator/nano = 2,
+ /obj/item/stock_parts/micro_laser/high = 2,
+ /obj/item/stock_parts/matter_bin/adv = 2,
+ /obj/item/survey_handheld = 1,
+ /obj/item/weldingtool/experimental = 1,
+ /obj/item/mmi/posibrain = 1,
+ /obj/item/reagent_containers/glass/beaker/plastic = 1,
+ /obj/item/organ/eyes/robotic/shield = 1,
+ /obj/item/organ/eyes/robotic/glow = 1,
+ )
+ )
+ if(prob(75))
+ accessory = /obj/item/clothing/accessory/armband/science
+
+
+/datum/outfit/generic/science
+ name = "Scientist (Legion)"
+
+/datum/outfit/generic/cargo/pre_equip(mob/living/carbon/human/H, visualsOnly)
+ . = ..()
+ if(prob(75))
+ uniform = pick(/obj/item/clothing/under/rank/cargo/tech, /obj/item/clothing/under/shorts/grey)
+ if(prob(75))
+ suit = pick(/obj/item/clothing/suit/hazardvest, /obj/item/clothing/suit/hooded/wintercoat/cargo)
+ if(prob(25))
+ belt = /obj/item/gun/ballistic/automatic/zip_pistol
+ if(prob(75))
+ gloves = /obj/item/clothing/gloves/fingerless
+ if(prob(75))
+ shoes = /obj/item/clothing/shoes/sneakers/black
+ if(prob(75))
+ head = /obj/item/clothing/head/soft
+ if(prob(75))
+ ears = /obj/item/radio/headset/headset_cargo
+ for(var/i = 1 to 3)
+ if(prob(75))
+ backpack_contents += pickweight(list(
+ /obj/item/spacecash/bundle/mediumrand = 5,
+ /obj/item/ammo_box/magazine/illestren_a850r = 5,
+ /obj/item/ammo_box/magazine/zip_ammo_9mm = 5,
+ /obj/item/modular_computer/tablet/preset/cargo = 3,
+ /obj/item/stack/tape = 3,
+ /obj/item/stack/tape/industrial = 3,
+ /obj/item/stack/sheet/plastic/five = 3,
+ /obj/item/grenade/frag = 1
+ )
+ )
+ if(prob(75))
+ accessory = /obj/item/clothing/accessory/armband/cargo
+ if(prob(25))
+ suit = /obj/item/clothing/suit/armor/vest/scrap_armor
+ suit_store = /obj/item/gun/ballistic/rifle/illestren
+
+/datum/outfit/generic/cargo
+ name = "Cargo Technician (Legion)"
+
+/datum/outfit/generic/security/pre_equip(mob/living/carbon/human/H, visualsOnly)
+ . = ..()
+ if(prob(75))
+ uniform = /obj/item/clothing/under/rank/security/officer
+ if(prob(75))
+ suit = pick(/obj/item/clothing/suit/armor/vest, /obj/item/clothing/suit/armor/vest/security/officer, /obj/item/clothing/suit/armor/vest/bulletproof, /obj/item/clothing/suit/armor/vest/blueshirt)
+ if(prob(75))
+ back = pick(/obj/item/storage/backpack/security, /obj/item/storage/backpack/satchel/sec, /obj/item/storage/backpack/duffelbag/sec, /obj/item/storage/backpack/messenger/sec)
+ if(prob(75))
+ belt = pick(/obj/item/storage/belt/security, /obj/item/storage/belt/security/webbing)
+ if(prob(75))
+ gloves = pick(/obj/item/clothing/gloves/color/black, /obj/item/clothing/gloves/tackler)
+ if(prob(75))
+ shoes = /obj/item/clothing/shoes/jackboots
+ if(prob(75))
+ head = pick(/obj/item/clothing/head/helmet/sec, /obj/item/clothing/head/helmet/blueshirt, /obj/item/clothing/head/helmet/bulletproof)
+ if(prob(75))
+ mask = /obj/item/clothing/mask/gas/sechailer
+ if(prob(75))
+ ears = /obj/item/radio/headset/headset_sec
+ if(prob(75))
+ glasses = pick(/obj/item/clothing/glasses/hud/security, /obj/item/clothing/glasses/sunglasses)
+ if(prob(75))
+ r_pocket = pick(/obj/item/flashlight/seclite, /obj/item/assembly/flash/handheld, /obj/item/restraints/handcuffs)
+ if(prob(50))
+ suit_store = pick(/obj/item/gun/energy/e_gun, /obj/item/gun/energy/e_gun/smg, /obj/item/gun/energy/e_gun/iot)
+ for(var/i = 1 to 3)
+ if(prob(75))
+ backpack_contents += pickweight(list(
+ /obj/item/restraints/handcuffs = 8,
+ /obj/item/assembly/flash/handheld = 5,
+ /obj/item/storage/box/evidence = 6,
+ /obj/item/flashlight/seclite = 4,
+ /obj/item/ammo_box/c9mm/rubbershot = 3,
+ /obj/item/ammo_box/c9mm = 1,
+ /obj/item/stock_parts/cell/gun = 3,
+ /obj/item/coin/antagtoken = 1,
+ /obj/item/grenade/stingbang = 1
+ )
+ )
+ if(prob(75))
+ accessory = /obj/item/clothing/accessory/armband/deputy
+
+/datum/outfit/generic/security
+ name = "Security Officer (Legion)"
+ box = /obj/item/storage/box/survival/security
+
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice demon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm
similarity index 72%
rename from code/modules/mob/living/simple_animal/hostile/mining_mobs/ice demon.dm
rename to code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm
index 2315f6e61a4f..786cdaa80966 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice demon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm
@@ -74,8 +74,6 @@
new /obj/item/assembly/signaler/anomaly/bluespace(loc)
if(prob(5))
new /obj/item/gem/fdiamond(loc)
- if(prob(10))
- new /obj/item/crusher_trophy/ice_wing(loc)
return ..()
/mob/living/simple_animal/hostile/asteroid/old_demon
@@ -122,7 +120,7 @@
footstep_type = FOOTSTEP_MOB_CLAW
/// Distance the demon will teleport from the target
var/teleport_distance = 3
- crusher_drop_mod = 75
+ trophy_drop_mod = 75
/obj/projectile/temp/basilisk/ice
name = "ice blast"
@@ -157,8 +155,6 @@
new /obj/item/assembly/signaler/anomaly/bluespace(loc)
if(prob(20))
new /obj/item/gem/fdiamond(loc)
- if(prob(50))
- new /obj/item/crusher_trophy/ice_crystal(loc)
return ..()
/mob/living/simple_animal/hostile/asteroid/ice_demon/random/Initialize()
@@ -166,49 +162,3 @@
if(prob(15))
new /mob/living/simple_animal/hostile/asteroid/old_demon(loc)
return INITIALIZE_HINT_QDEL
-
-/obj/item/crusher_trophy/ice_crystal
- name = "frost gem"
- icon = 'icons/obj/lavaland/elite_trophies.dmi'
- desc = "The glowing remnant of an ancient ice demon- so cold that it hurts to touch."
- icon_state = "ice_crystal"
- denied_type = /obj/item/crusher_trophy/ice_crystal
-
-/obj/item/crusher_trophy/ice_crystal/effect_desc()
- return "waveform collapse to freeze a creature in a block of ice for a period, preventing them from moving"
-
-/obj/item/crusher_trophy/ice_crystal/on_mark_detonation(mob/living/target, mob/living/user)
- target.apply_status_effect(/datum/status_effect/ice_crystal)
-
-/datum/status_effect/ice_crystal
- id = "ice_crystal"
- duration = 20
- status_type = STATUS_EFFECT_REFRESH
- alert_type = /atom/movable/screen/alert/status_effect/ice_crystal
- /// Stored icon overlay for the hit mob, removed when effect is removed
- var/icon/cube
-
-/atom/movable/screen/alert/status_effect/ice_crystal
- name = "Frozen Solid"
- desc = "You're frozen inside an ice cube, and cannot move!"
- icon_state = "frozen"
-
-/datum/status_effect/ice_crystal/on_apply()
- RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(owner_moved))
- if(!owner.stat)
- to_chat(owner, "You become frozen in a cube!")
- cube = icon('icons/effects/freeze.dmi', "ice_cube")
- var/icon/size_check = icon(owner.icon, owner.icon_state)
- cube.Scale(size_check.Width(), size_check.Height())
- owner.add_overlay(cube)
- return ..()
-
-/// Blocks movement from the status effect owner
-/datum/status_effect/ice_crystal/proc/owner_moved()
- return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
-
-/datum/status_effect/ice_crystal/on_remove()
- if(!owner.stat)
- to_chat(owner, "The cube melts!")
- owner.cut_overlay(cube)
- UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice whelp.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm
similarity index 97%
rename from code/modules/mob/living/simple_animal/hostile/mining_mobs/ice whelp.dm
rename to code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm
index ceef301b2349..7a4d8cb234c2 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice whelp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm
@@ -28,7 +28,7 @@
move_resist = MOVE_FORCE_VERY_STRONG
butcher_results = list(/obj/item/stack/ore/diamond = 3, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 10, /obj/item/stack/sheet/animalhide/ashdrake = 1)
loot = list()
- crusher_loot = /obj/item/crusher_trophy/tail_spike
+ //mob_trophy = /obj/item/mob_trophy/tail_spike
deathmessage = "collapses on its side."
deathsound = 'sound/magic/demon_dies.ogg'
stat_attack = HARD_CRIT
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/lobstrosity.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/lobstrosity.dm
index d95c21ec9bbb..074bda5cf91a 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/lobstrosity.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/lobstrosity.dm
@@ -33,7 +33,7 @@
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/rawcrab = 2, /obj/item/stack/sheet/bone = 2)
robust_searching = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
- crusher_loot = /obj/item/crusher_trophy/lobster_claw
+ //mob_trophy = /obj/item/mob_trophy/lobster_claw
/mob/living/simple_animal/hostile/asteroid/lobstrosity/beach
name = "tropical lobstrosity"
@@ -42,15 +42,3 @@
icon_living = "lobstrosity"
icon_dead = "lobstrosity_dead"
-/obj/item/crusher_trophy/lobster_claw
- name = "lobster claw"
- icon_state = "lobster_claw"
- desc = "A lobster claw."
- denied_type = /obj/item/crusher_trophy/lobster_claw
- bonus_value = 1
-
-/obj/item/crusher_trophy/lobster_claw/effect_desc()
- return "mark detonation to briefly stagger the target for [bonus_value] seconds"
-
-/obj/item/crusher_trophy/lobster_claw/on_mark_detonation(mob/living/target, mob/living/user)
- target.apply_status_effect(/datum/status_effect/stagger, bonus_value SECONDS)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm
index b66c71fd58b2..6beb2f23b9e6 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm
@@ -12,15 +12,15 @@
response_harm_simple = "strike"
status_flags = 0
a_intent = INTENT_HARM
- var/crusher_loot
+ var/mob_trophy
var/throw_message = "bounces off of"
var/throw_deflection = 20 //WS edit - Whitesands
- var/fromtendril = FALSE
+ var/from_nest = FALSE
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
mob_size = MOB_SIZE_LARGE
var/icon_aggro = null
- var/crusher_drop_mod = 25
+ var/trophy_drop_mod = 25
var/datum/armor/armor //WS edit - Whitesands
/mob/living/simple_animal/hostile/asteroid/Initialize(mapload)
@@ -70,13 +70,13 @@
/mob/living/simple_animal/hostile/asteroid/death(gibbed)
SSblackbox.record_feedback("tally", "mobs_killed_mining", 1, type)
- var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
- if(C && crusher_loot && prob((C.total_damage/maxHealth) * crusher_drop_mod)) //on average, you'll need to kill 4 creatures before getting the item
- spawn_crusher_loot()
+ if(prob(trophy_drop_mod)) //on average, you'll need to kill 5 creatures before getting the item
+ spawn_mob_trophy()
..(gibbed)
-/mob/living/simple_animal/hostile/asteroid/proc/spawn_crusher_loot()
- butcher_results[crusher_loot] = 1
+/mob/living/simple_animal/hostile/asteroid/proc/spawn_mob_trophy()
+ if(mob_trophy)
+ butcher_results[mob_trophy] = 1
/mob/living/simple_animal/hostile/asteroid/handle_temperature_damage()
if(bodytemperature < minbodytemp)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm
index f9d15892f75d..2bcb3fe06f9a 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/polarbear.dm
@@ -27,7 +27,7 @@
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 3, /obj/item/stack/sheet/bone = 2)
guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 1)
loot = list()
- crusher_loot = /obj/item/crusher_trophy/bear_paw
+ //mob_trophy = /obj/item/mob_trophy/bear_paw
stat_attack = HARD_CRIT
robust_searching = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
@@ -57,24 +57,6 @@
desc = "It seems sentient somehow."
faction = list("neutral")
-/obj/item/crusher_trophy/bear_paw
- name = "polar bear paw"
- desc = "It's a polar bear paw."
- icon_state = "bear_paw"
- icon ='icons/obj/lavaland/elite_trophies.dmi'
- denied_type = /obj/item/crusher_trophy/bear_paw
-
-/obj/item/crusher_trophy/bear_paw/effect_desc()
- return "doubled strikes when below 50% health"
-
-/obj/item/crusher_trophy/bear_paw/on_mark_detonation(mob/living/target, mob/living/user)
- if(user.health / user.maxHealth > 0.5)
- return
- var/obj/item/I = user.get_active_held_item()
- if(!I)
- return
- I.melee_attack_chain(user, target, null)
-
//elite bear
/mob/living/simple_animal/hostile/asteroid/polarbear/warrior
name = "polar warbear"
@@ -91,29 +73,11 @@
icon_state = "warbear"
icon_living = "warbear"
icon_dead = "warbear_dead"
- crusher_loot = /obj/item/crusher_trophy/war_paw
- crusher_drop_mod = 75
+ //mob_trophy = /obj/item/mob_trophy/war_paw
+ trophy_drop_mod = 75
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 3, /obj/item/stack/sheet/bone = 2, /obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 3)
guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 3, /obj/item/bear_armor = 1)
-/obj/item/crusher_trophy/war_paw
- name = "Armored bear paw"
- desc = "It's a paw from a true warrior. Still remembers the basics of CQB."
- icon_state = "armor_paw"
- icon ='icons/obj/lavaland/elite_trophies.dmi'
- denied_type = /obj/item/crusher_trophy/war_paw
-
-/obj/item/crusher_trophy/war_paw/effect_desc()
- return "doubled strikes when below 70% health"
-
-/obj/item/crusher_trophy/war_paw/on_mark_detonation(mob/living/target, mob/living/user)
- if(user.health / user.maxHealth > 0.7)
- return
- var/obj/item/I = user.get_active_held_item()
- if(!I)
- return
- I.melee_attack_chain(user, target, null)
-
/mob/living/simple_animal/hostile/asteroid/polarbear/random/Initialize()
. = ..()
if(prob(15))
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm
index 7df8c04f0cf4..336616dfe110 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/wolf.dm
@@ -30,9 +30,9 @@
move_force = MOVE_FORCE_WEAK
move_resist = MOVE_FORCE_WEAK
pull_force = MOVE_FORCE_WEAK
- butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/stack/sheet/sinew/wolf = 2, /obj/item/stack/sheet/bone = 2, /obj/item/crusher_trophy/wolf_ear = 0.5)
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/stack/sheet/sinew/wolf = 2, /obj/item/stack/sheet/bone = 2, /obj/item/mob_trophy/wolf_ear = 0.5)
loot = list()
- crusher_loot = /obj/item/crusher_trophy/wolf_ear
+ mob_trophy = /obj/item/mob_trophy/wolf_ear
stat_attack = HARD_CRIT
knockdown_time = 1 SECONDS
robust_searching = TRUE
@@ -108,23 +108,10 @@
move_resist = MOVE_RESIST_DEFAULT
pull_force = PULL_FORCE_DEFAULT
if(prob(15))
- new /obj/item/crusher_trophy/wolf_ear(loc)
+ new /obj/item/mob_trophy/wolf_ear(loc)
visible_message("You notice a damaged ear that might be salvagable.")
..()
-/obj/item/crusher_trophy/wolf_ear
- name = "wolf ear"
- desc = "The battered remains of a wolf's ear. You could attach it to a crusher, or use the fur to craft a trophy."
- icon = 'icons/obj/lavaland/elite_trophies.dmi'
- icon_state = "torn_ear"
- denied_type = /obj/item/crusher_trophy/wolf_ear
-
-/obj/item/crusher_trophy/wolf_ear/effect_desc()
- return "waveform collapse to give the user a slight speed boost"
-
-/obj/item/crusher_trophy/wolf_ear/on_mark_detonation(mob/living/target, mob/living/user)
- user.apply_status_effect(/datum/status_effect/speed_boost, 3 SECONDS)
-
//alpha wolf- smaller chance to spawn, practically a miniboss. Has the ability to do a short, untelegraphed lunge with a stun. Be careful!
/mob/living/simple_animal/hostile/asteroid/wolf/alpha
name = "alpha wolf"
@@ -149,35 +136,12 @@
charge_frequency = 20 SECONDS
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/stack/sheet/sinew/wolf = 4, /obj/item/stack/sheet/sinew/wolf = 4, /obj/item/stack/sheet/bone = 5)
loot = list()
- crusher_loot = /obj/item/crusher_trophy/fang
+ mob_trophy = /obj/item/mob_trophy/fang
/mob/living/simple_animal/hostile/asteroid/wolf/alpha/gib()
move_force = MOVE_FORCE_DEFAULT
move_resist = MOVE_RESIST_DEFAULT
pull_force = PULL_FORCE_DEFAULT
- if(prob(75))
- new /obj/item/crusher_trophy/fang(loc)
- visible_message("You find an intact fang that looks salvagable.")
- ..()
-
-/obj/item/crusher_trophy/fang
- name = "battle-stained fang"
- desc = "A wolf fang, displaying the wear and tear associated with a long and colorful life. Could be attached to a kinetic crusher or used to make a trophy."
- icon = 'icons/obj/lavaland/elite_trophies.dmi'
- icon_state = "fang"
- denied_type = /obj/item/crusher_trophy/fang
- var/bleed_stacks_per_hit = 5
-
-/obj/item/crusher_trophy/fang/effect_desc()
- return "waveform collapse to build up a small stack of bleeding, causing a burst of damage if applied repeatedly."
-
-/obj/item/crusher_trophy/fang/on_mark_detonation(mob/living/M, mob/living/user)
- if(istype(M) && (M.mob_biotypes & MOB_ORGANIC))
- var/datum/status_effect/stacking/saw_bleed/bloodletting/B = M.has_status_effect(/datum/status_effect/stacking/saw_bleed/bloodletting)
- if(!B)
- M.apply_status_effect(/datum/status_effect/stacking/saw_bleed/bloodletting, bleed_stacks_per_hit)
- else
- B.add_stacks(bleed_stacks_per_hit)
/mob/living/simple_animal/hostile/asteroid/wolf/random/Initialize()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm
deleted file mode 100644
index 4417e68e2ec1..000000000000
--- a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm
+++ /dev/null
@@ -1,59 +0,0 @@
-/mob/living/simple_animal/hostile/nanotrasen
- name = "\improper Nanotrasen Private Security Officer"
- desc = "An officer part of Nanotrasen's private security force, he seems rather unpleased to meet you."
- icon = 'icons/mob/simple_human.dmi'
- icon_state = "nanotrasen"
- icon_living = "nanotrasen"
- icon_dead = null
- icon_gib = "syndicate_gib"
- mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
- speak_chance = 0
- turns_per_move = 5
- speed = 0
- stat_attack = HARD_CRIT
- robust_searching = 1
- maxHealth = 100
- health = 100
- harm_intent_damage = 5
- melee_damage_lower = 10
- melee_damage_upper = 15
- attack_verb_continuous = "punches"
- attack_verb_simple = "punch"
- attack_sound = 'sound/weapons/punch1.ogg'
- a_intent = INTENT_HARM
- loot = list(/obj/effect/mob_spawn/human/corpse/nanotrasensoldier)
- atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
- unsuitable_atmos_damage = 15
- faction = list(ROLE_DEATHSQUAD)
- check_friendly_fire = TRUE
- status_flags = CANPUSH
- del_on_death = TRUE
- dodging = TRUE
- footstep_type = FOOTSTEP_MOB_SHOE
-
-/mob/living/simple_animal/hostile/nanotrasen/screaming
- icon_state = "nanotrasen"
- icon_living = "nanotrasen"
-
-/mob/living/simple_animal/hostile/nanotrasen/screaming/Aggro()
- ..()
- summon_backup(15)
- say("411 in progress, requesting backup!")
-
-
-/mob/living/simple_animal/hostile/nanotrasen/ranged
- icon_state = "nanotrasenranged"
- icon_living = "nanotrasenranged"
- ranged = 1
- retreat_distance = 3
- minimum_distance = 5
- casingtype = /obj/item/ammo_casing/c45
- projectilesound = 'sound/weapons/gun/pistol/shot_alt.ogg'
-
-
-/mob/living/simple_animal/hostile/nanotrasen/ranged/smg
- icon_state = "nanotrasenrangedsmg"
- icon_living = "nanotrasenrangedsmg"
- rapid = 3
- casingtype = /obj/item/ammo_casing/c46x30mm
- projectilesound = 'sound/weapons/gun/smg/shot.ogg'
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
index 55d873cf036a..25827781b4b8 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -167,48 +167,3 @@
attack_verb_simple = "punch"
deathmessage = "falls apart into a fine dust."
phaser = FALSE
-
-/obj/structure/spawner/nether
- name = "netherworld link"
- desc = null //see examine()
- icon_state = "nether"
- max_integrity = 50
- spawn_time = 600 //1 minute
- max_mobs = 15
- spawn_text = "crawls through"
- mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody)
- faction = list("nether")
-
-/obj/structure/spawner/nether/Initialize()
- .=..()
- START_PROCESSING(SSprocessing, src)
-
-/obj/structure/spawner/nether/examine(mob/user)
- . = ..()
- if(isskeleton(user) || iszombie(user))
- . += "A direct link to another dimension full of creatures very happy to see you. You can see your house from here!"
- else
- . += "A direct link to another dimension full of creatures not very happy to see you. Entering the link would be a very bad idea."
-
-/obj/structure/spawner/nether/attack_hand(mob/user)
- . = ..()
- if(isskeleton(user) || iszombie(user))
- to_chat(user, "You don't feel like going home yet...")
- else
- user.visible_message("[user] is violently pulled into the link!", \
- "Touching the portal, you are quickly pulled through into a world of unimaginable horror!")
- contents.Add(user)
-
-/obj/structure/spawner/nether/process()
- for(var/mob/living/M in contents)
- if(M)
- playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE)
- M.adjustBruteLoss(60)
- new /obj/effect/gibspawner/generic(get_turf(M), M)
- if(M.stat == DEAD)
- var/mob/living/simple_animal/hostile/netherworld/blankbody/blank
- blank = new(loc)
- blank.name = "[M]"
- blank.desc = "It's [M], but [M.p_their()] flesh has an ashy texture, and [M.p_their()] face is featureless save an eerie smile."
- src.visible_message("[M] reemerges from the link!")
- qdel(M)
diff --git a/code/modules/mob/living/simple_animal/hostile/stickman.dm b/code/modules/mob/living/simple_animal/hostile/stickman.dm
deleted file mode 100644
index 1eb03b07650c..000000000000
--- a/code/modules/mob/living/simple_animal/hostile/stickman.dm
+++ /dev/null
@@ -1,61 +0,0 @@
-/mob/living/simple_animal/hostile/stickman
- name = "Angry Stick Man"
- desc = "A being from a realm with only 2 dimensions. At least it's trying to stay faced towards you."
- icon_state = "stickman"
- icon_living = "stickman"
- icon_dead = "stickman_dead"
- icon_gib = "syndicate_gib"
- mob_biotypes = MOB_HUMANOID
- gender = MALE
- speak_chance = 0
- turns_per_move = 5
- speed = 0
- stat_attack = HARD_CRIT
- robust_searching = 1
- environment_smash = ENVIRONMENT_SMASH_NONE
- maxHealth = 100
- health = 100
- harm_intent_damage = 5
- obj_damage = 0
- melee_damage_lower = 10
- melee_damage_upper = 10
- attack_verb_continuous = "punches"
- attack_verb_simple = "punch"
- attack_sound = 'sound/weapons/punch1.ogg'
- a_intent = INTENT_HARM
- atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
- unsuitable_atmos_damage = 15
- faction = list("hostile","stickman")
- check_friendly_fire = 1
- status_flags = CANPUSH
- var/datum/action/boss/wizard_summon_minions/changesummons = /datum/action/boss/wizard_summon_minions
- var/summoned_by_wizard = 0
-
-/mob/living/simple_animal/hostile/stickman/ranged
- ranged = 1
- retreat_distance = 5
- minimum_distance = 5
- icon_state = "stickmanranged"
- icon_living = "stickmanranged"
- casingtype = /obj/item/ammo_casing/c45
- projectilesound = 'sound/misc/bang.ogg'
- loot = list(/obj/item/gun/ballistic/automatic/pistol/stickman)
-
-
-/mob/living/simple_animal/hostile/stickman/dog
- name = "Angry Stick Dog"
- desc = "Stickman's best friend, if he could see him at least."
- icon_state = "stickdog"
- icon_living = "stickdog"
- icon_dead = "stickdog_dead"
- mob_biotypes = MOB_BEAST
-
-/mob/living/simple_animal/hostile/stickman/Initialize(mapload, wizard_summoned)
- . = ..()
- new /obj/effect/temp_visual/paper_scatter(src)
- summoned_by_wizard = wizard_summoned
-
-/mob/living/simple_animal/hostile/stickman/death()
- ..()
- if(summoned_by_wizard == 1)
- changesummons.summoned_minions --
diff --git a/code/modules/mob/living/simple_animal/hostile/wizard.dm b/code/modules/mob/living/simple_animal/hostile/wizard.dm
deleted file mode 100644
index 0d97a1f18869..000000000000
--- a/code/modules/mob/living/simple_animal/hostile/wizard.dm
+++ /dev/null
@@ -1,82 +0,0 @@
-/mob/living/simple_animal/hostile/wizard
- name = "Space Wizard"
- desc = "EI NATH?"
- icon = 'icons/mob/simple_human.dmi'
- icon_state = "wizard"
- icon_living = "wizard"
- icon_dead = "wizard_dead"
- mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
- speak_chance = 0
- turns_per_move = 3
- speed = 0
- maxHealth = 100
- health = 100
- harm_intent_damage = 5
- melee_damage_lower = 5
- melee_damage_upper = 5
- attack_verb_continuous = "punches"
- attack_verb_simple = "punch"
- attack_sound = 'sound/weapons/punch1.ogg'
- a_intent = INTENT_HARM
- atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
- unsuitable_atmos_damage = 15
- faction = list(ROLE_WIZARD)
- status_flags = CANPUSH
-
- retreat_distance = 3 //out of fireball range
- minimum_distance = 3
- del_on_death = 1
- loot = list(/obj/effect/mob_spawn/human/corpse/wizard,
- /obj/item/staff)
-
- var/obj/effect/proc_holder/spell/aimed/fireball/fireball = null
- var/obj/effect/proc_holder/spell/targeted/turf_teleport/blink/blink = null
- var/obj/effect/proc_holder/spell/targeted/projectile/magic_missile/mm = null
-
- var/next_cast = 0
-
- footstep_type = FOOTSTEP_MOB_SHOE
-
-/mob/living/simple_animal/hostile/wizard/Initialize()
- . = ..()
- fireball = new /obj/effect/proc_holder/spell/aimed/fireball
- fireball.clothes_req = 0
- fireball.human_req = 0
- fireball.player_lock = 0
- AddSpell(fireball)
- implants += new /obj/item/implant/exile(src)
-
- mm = new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile
- mm.clothes_req = 0
- mm.human_req = 0
- mm.player_lock = 0
- AddSpell(mm)
-
- blink = new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink
- blink.clothes_req = 0
- blink.human_req = 0
- blink.player_lock = 0
- blink.outer_tele_radius = 3
- AddSpell(blink)
-
-/mob/living/simple_animal/hostile/wizard/handle_automated_action()
- . = ..()
- if(target && next_cast < world.time)
- if((get_dir(src,target) in list(SOUTH,EAST,WEST,NORTH)) && fireball.cast_check(0,src)) //Lined up for fireball
- src.setDir(get_dir(src,target))
- fireball.perform(list(target), user = src)
- next_cast = world.time + 10 //One spell per second
- return .
- if(mm.cast_check(0,src))
- mm.choose_targets(src)
- next_cast = world.time + 10
- return .
- if(blink.cast_check(0,src)) //Spam Blink when you can
- blink.choose_targets(src)
- next_cast = world.time + 10
- return .
-
-/mob/living/simple_animal/hostile/wizard/planet
- weather_immunities = list("lava","ash")
- minbodytemp = 0
- maxbodytemp = INFINITY
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index e4ead25880f9..3670e14a6405 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -636,7 +636,7 @@
switch(togglestatus)
if(AI_Z_OFF)
- LAZYADDASSOC(SSidlenpcpool.idle_mobs_by_virtual_level, virt_z, src)
+ LAZYADDASSOCLIST(SSidlenpcpool.idle_mobs_by_virtual_level, virt_z, src)
else
LAZYREMOVEASSOC(SSidlenpcpool.idle_mobs_by_virtual_level, virt_z, src)
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 8eb5bc620722..d60755693489 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -478,11 +478,11 @@
for(var/listed_type in slowdown_type)
if(ispath(listed_type))
listed_type = "[listed_type]" //Path2String
- LAZYADDASSOC(movespeed_mod_immunities, listed_type, source)
+ LAZYADDASSOCLIST(movespeed_mod_immunities, listed_type, source)
else
if(ispath(slowdown_type))
slowdown_type = "[slowdown_type]" //Path2String
- LAZYADDASSOC(movespeed_mod_immunities, slowdown_type, source)
+ LAZYADDASSOCLIST(movespeed_mod_immunities, slowdown_type, source)
if(update)
update_movespeed()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index d475891fc28f..06c7a9af52d8 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -204,27 +204,34 @@
if(self_message)
hearers -= src
- var/raw_msg = message
- if(visible_message_flags & EMOTE_MESSAGE)
- message = "[src][separation][message]"
-
for(var/mob/M in hearers)
if(!M.client)
continue
- //This entire if/else chain could be in two lines but isn't for readibilties sake.
var/msg = message
+
+ //This entire if/else chain could be in two lines but isn't for readibilties sake.
if(M.see_invisible < invisibility)//if src is invisible to M
msg = blind_message
else if(T != loc && T != src) //if src is inside something and not a turf.
msg = blind_message
else if(T.lighting_object && T.lighting_object.invisibility <= M.see_invisible && T.is_softly_lit()) //if it is too dark.
msg = blind_message
+ else if(visible_message_flags & EMOTE_MESSAGE)
+ var/shown_name = name
+ if(M.mind?.guestbook && ishuman(src))
+ var/mob/living/carbon/human/human_source = src
+ var/known_name = M.mind.guestbook.get_known_name(M, src, human_source.get_face_name())
+ if(known_name)
+ shown_name = known_name
+
+ msg = "[shown_name][separation][message]"
+
if(!msg)
continue
if(visible_message_flags & EMOTE_MESSAGE && runechat_prefs_check(M, visible_message_flags))
- M.create_chat_message(src, raw_message = raw_msg, runechat_flags = visible_message_flags)
+ M.create_chat_message(src, raw_message = message, runechat_flags = visible_message_flags)
M.show_message(msg, MSG_VISUAL, blind_message, MSG_AUDIBLE)
@@ -250,12 +257,24 @@
if(self_message)
hearers -= src
var/raw_msg = message
- if(audible_message_flags & EMOTE_MESSAGE)
- message = "[src][separation][message]"
for(var/mob/M in hearers)
- if(audible_message_flags & EMOTE_MESSAGE && runechat_prefs_check(M, audible_message_flags))
- M.create_chat_message(src, raw_message = raw_msg, runechat_flags = audible_message_flags)
- M.show_message(message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
+ var/msg = raw_msg
+
+ //emote handling
+ if(audible_message_flags & EMOTE_MESSAGE)
+ var/shown_name = name
+ if(M.mind?.guestbook && ishuman(src))
+ var/mob/living/carbon/human/human_source = src
+ var/known_name = M.mind.guestbook.get_known_name(M, src, human_source.GetVoice())
+ if(known_name)
+ shown_name = known_name
+
+ msg = "[shown_name][separation][message]"
+
+ if(runechat_prefs_check(M, audible_message_flags) && M.can_hear())
+ M.create_chat_message(src, raw_message = raw_msg, runechat_flags = audible_message_flags)
+
+ M.show_message(msg, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
/**
* Show a message to all mobs in earshot of this one
@@ -503,7 +522,7 @@
to_chat(src, "You don't have a free hand to examine this!")
return FALSE
//can only queue up one examine on something at a time
- if(examined_thing in do_afters)
+ if(DOING_INTERACTION_WITH_TARGET(src, examined_thing))
return FALSE
to_chat(src, "You start feeling around for something...")
@@ -565,6 +584,15 @@
var/msg = "[src] makes eye contact with you."
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), examined_mob, msg), 3)
+/**
+ * Called by using Activate Held Object with an empty hand/limb
+ *
+ * Does nothing by default. The intended use is to allow limbs to call their
+ * own attack_self procs. It is up to the individual mob to override this
+ * parent and actually use it.
+ */
+/mob/proc/limb_attack_self()
+ return
///Can this mob resist (default FALSE)
/mob/proc/can_resist()
@@ -622,6 +650,8 @@
if(I)
I.attack_self(src)
update_inv_hands()
+ return
+ limb_attack_self()
/mob/verb/do_unique_action()
set name = "Do Unique Action"
@@ -670,6 +700,24 @@
else
to_chat(src, "You don't have a mind datum for some reason, so you can't add a note to it.")
+///Shows guestbook tgui window
+/mob/verb/guestbook()
+ set name = "Guestbook"
+ set category = "IC"
+ set desc = "View your character's Guestbook."
+ // the reason why there are two observer checks in here is because the mind datum sometimes carries over to ghosts.
+ // this is something i should probably fix instead of adding a fallback check, but...
+ if(isobserver(src))
+ to_chat(src, span_warning("You have to be in the current round to do that!"))
+ return
+ if(!mind)
+ var/fail_message = "You have no mind!"
+ if(isobserver(src))
+ fail_message += " You have to be in the current round at some point to have one."
+ to_chat(src, span_warning(fail_message))
+ return
+ mind.guestbook.ui_interact(usr)
+
/**
* Allows you to respawn, abandoning your current mob
*
@@ -773,8 +821,10 @@
src << browse(null, t1)
if(href_list["flavor_more"])
- usr << browse(text("[][]", name, replacetext(flavor_text, "\n", " ")), text("window=[];size=500x200", name))
- onclose(usr, "[name]")
+ var/datum/browser/popup = new(usr, "[name]'s flavor text", "[name]'s Flavor Text (expanded)", 500, 200)
+ popup.set_content(text("[][]", "[name]'s flavor text (expanded)", replacetext(flavor_text, "\n", " ")))
+ popup.open()
+ return
if(user != src)
if(href_list["item"] && user.canUseTopic(src, BE_CLOSE, NO_DEXTERITY))
@@ -1152,6 +1202,7 @@
var/list/searching = GetAllContents()
var/search_id = 1
var/search_pda = 1
+ var/search_bankcard = 1
for(var/A in searching)
if(search_id && istype(A, /obj/item/card/id))
@@ -1159,18 +1210,24 @@
if(ID.registered_name == oldname)
ID.registered_name = newname
ID.update_label()
- if(ID.registered_account?.account_holder == oldname)
- ID.registered_account.account_holder = newname
- if(!search_pda)
+ if(!search_pda || !search_bankcard)
break
search_id = 0
+ if(search_bankcard && istype(A, /obj/item/card/bank))
+ var/obj/item/card/bank/bank_card = A
+ if(bank_card.registered_account?.account_holder == oldname)
+ bank_card.registered_account.account_holder = newname
+ if(!search_id || !search_pda)
+ break
+ search_bankcard = 0
+
else if(search_pda && istype(A, /obj/item/pda))
var/obj/item/pda/PDA = A
if(PDA.owner == oldname)
PDA.owner = newname
PDA.update_label()
- if(!search_id)
+ if(!search_id || !search_bankcard)
break
search_pda = 0
@@ -1253,6 +1310,9 @@
/mob/proc/get_idcard(hand_first)
return
+/mob/proc/get_bankcard()
+ return
+
/mob/proc/get_id_in_hand()
return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 6873ee602dac..def2bde930e0 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -191,7 +191,7 @@
///List of progress bars this mob is currently seeing for actions
var/list/progressbars = null //for stacking do_after bars
- ///For storing what do_after's someone has, in case we want to restrict them to only one of a certain do_after at a time
+ ///For storing what do_after's someone has, key = string, value = amount of interactions of that type happening.
var/list/do_afters
///Allows a datum to intercept all click calls this mob is the source of
diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm
index d2e6a4f0dda2..01e3a4d33b1a 100644
--- a/code/modules/mob/say_vr.dm
+++ b/code/modules/mob/say_vr.dm
@@ -11,7 +11,7 @@
if(usr != src)
to_chat(usr, span_warning("You can't set someone else's flavour text!"))
- var/msg = sanitize(input(usr,"Set the flavor text in your 'examine' verb. Can also be used for OOC notes about your character.","Flavor Text",html_decode(flavor_text)) as message|null)
+ var/msg = input(usr, "A snippet of text shown when others examine you, describing what you may look like. This can also be used for OOC notes.", "Flavor Text", html_decode("flavor_text")) as message|null
if(msg)
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
@@ -22,10 +22,10 @@
/mob/proc/print_flavor_text()
if(flavor_text && flavor_text != "")
var/msg = replacetext(flavor_text, "\n", " ")
- if(length(msg) <= 100)
+ if(length(msg) <= MAX_SHORTFLAVOR_LEN)
return "[msg]"
else
- return "[copytext(msg, 1, 97)]... More..."
+ return "[copytext(msg, 1, MAX_SHORTFLAVOR_LEN)]... More..."
/mob/proc/get_top_level_mob()
if(istype(src.loc,/mob)&&src.loc!=src)
diff --git a/code/modules/mob_spawner/burrow.dm b/code/modules/mob_spawner/burrow.dm
new file mode 100644
index 000000000000..f8d4c31bc87f
--- /dev/null
+++ b/code/modules/mob_spawner/burrow.dm
@@ -0,0 +1,109 @@
+GLOBAL_LIST_INIT(ore_probability, list(
+ /obj/item/stack/ore/plasma = 75,
+ /obj/item/stack/ore/iron = 75,
+ /obj/item/stack/ore/titanium = 50,
+ /obj/item/stack/ore/silver = 50,
+ /obj/item/stack/ore/gold = 50,
+ /obj/item/stack/ore/uranium = 50,
+ /obj/item/stack/ore/diamond = 25,
+ /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25,
+ /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25,
+ /obj/effect/mob_spawn/human/corpse/damaged/legioninfested = 25
+ ))
+
+/obj/structure/spawner/burrow
+ name = "burrow entrance"
+ desc = "A hole in the ground, filled with fauna ready to defend it."
+ max_integrity = 250
+ faction = list("mining")
+ max_mobs = 3
+
+/obj/structure/spawner/burrow/Initialize()
+ . = ..()
+ clear_rock()
+
+/**
+ * Clears rocks around the spawner when it is created
+ *
+ */
+/obj/structure/spawner/burrow/proc/clear_rock()
+ for(var/turf/F in RANGE_TURFS(2, src))
+ if(abs(src.x - F.x) + abs(src.y - F.y) > 3)
+ continue
+ if(ismineralturf(F))
+ var/turf/closed/mineral/M = F
+ M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
+
+/obj/structure/spawner/burrow/deconstruct(disassembled)
+ destroy_effect()
+ drop_loot()
+ return ..()
+
+/**
+ * Effects and messages created when the spawner is destroyed
+ *
+ */
+/obj/structure/spawner/burrow/proc/destroy_effect()
+ playsound(loc,'sound/effects/explosionfar.ogg', 200, TRUE)
+ visible_message("[src] collapses, sealing everything inside!\nOres fall out of the burrow as it is destroyed!")
+
+/**
+ * Drops items after the spawner is destroyed
+ *
+ */
+/obj/structure/spawner/burrow/proc/drop_loot()
+ for(var/type in GLOB.ore_probability)
+ var/chance = GLOB.ore_probability[type]
+ if(!prob(chance))
+ continue
+ new type(loc, rand(5, 10))
+
+/obj/structure/spawner/burrow/lava_planet
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/goliath/beast/nest = 27,
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/nest = 26,
+ /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/nest = 26,
+ /mob/living/simple_animal/hostile/asteroid/brimdemon = 20,
+ /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing = 1
+ )
+
+/obj/structure/spawner/burrow/sand_planet
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/nest = 40,
+ /mob/living/simple_animal/hostile/asteroid/basilisk/whitesands = 40,
+ /mob/living/simple_animal/hostile/asteroid/goliath/beast/nest = 20
+ )
+
+/obj/structure/spawner/burrow/ice_planet
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/wolf,
+ /mob/living/simple_animal/hostile/asteroid/polarbear
+ )
+
+/obj/structure/spawner/burrow/ice_planet/hard
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/brimdemon = 35,
+ /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/nest = 35,
+ /mob/living/simple_animal/hostile/asteroid/ice_whelp = 15,
+ /mob/living/simple_animal/hostile/asteroid/ice_demon = 15
+ )
+
+/obj/structure/spawner/burrow/jungle_planet
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/wolf/random,
+ /mob/living/simple_animal/hostile/retaliate/bat,
+ /mob/living/simple_animal/hostile/retaliate/poison/snake
+ )
+
+/obj/structure/spawner/burrow/rock_plant
+ mob_types = list(
+ /mob/living/simple_animal/hostile/asteroid/goliath/beast/rockplanet,
+ /mob/living/simple_animal/hostile/asteroid/elite/broodmother_child/rockplanet
+ )
+
+/obj/structure/spawner/burrow/asteroid
+ mob_types = list (
+ /mob/living/simple_animal/hostile/asteroid/goliath,
+ /mob/living/simple_animal/hostile/asteroid/hivelord,
+ /mob/living/simple_animal/hostile/carp
+ )
diff --git a/code/modules/mob_spawner/hivebot.dm b/code/modules/mob_spawner/hivebot.dm
new file mode 100644
index 000000000000..630ed6f6f3c7
--- /dev/null
+++ b/code/modules/mob_spawner/hivebot.dm
@@ -0,0 +1,50 @@
+/obj/structure/spawner/hivebot
+ name = "hivebot fabricator"
+ desc = "An active fabricator, creating hivebots out of resources from below the surface."
+
+ icon = 'icons/obj/machines/bsm.dmi'
+ icon_state = "bsm_on"
+
+ faction = list("mining")
+ max_integrity = 250
+ mob_types = list(
+ /mob/living/simple_animal/hostile/hivebot/wasteplanet = 40,
+ /mob/living/simple_animal/hostile/hivebot/wasteplanet/ranged = 40,
+ /mob/living/simple_animal/hostile/hivebot/wasteplanet/ranged/rapid = 10,
+ /mob/living/simple_animal/hostile/hivebot/wasteplanet/strong = 5,
+ /mob/living/simple_animal/hostile/hivebot/mechanic = 5
+ )
+ spawn_text = "crawls out of"
+ spawn_sound = list('sound/effects/suitstep2.ogg')
+ resistance_flags = FIRE_PROOF | LAVA_PROOF
+ var/obj/effect/light_emitter/hivespawner/emitted_light
+
+/obj/structure/spawner/hivebot/Initialize()
+ . = ..()
+ emitted_light = new(loc)
+
+/obj/structure/spawner/hivebot/deconstruct(disassembled)
+ destroy_effect()
+ drop_loot()
+ return ..()
+
+/obj/structure/spawner/hivebot/Destroy()
+ QDEL_NULL(emitted_light)
+ return ..()
+
+/obj/structure/spawner/hivebot/proc/destroy_effect()
+ playsound(loc,'sound/effects/explosionfar.ogg', 200, TRUE)
+ visible_message("[src] begins to rattle and shake, sparks flying off of it!")
+
+
+/obj/structure/spawner/hivebot/proc/drop_loot()
+ var/datum/effect_system/smoke_spread/smoke = new
+ smoke.set_up(2, loc)
+ smoke.start()
+ new /obj/effect/particle_effect/sparks(loc)
+ new /obj/effect/spawner/lootdrop/waste/hivebot/beacon(loc)
+
+/obj/effect/light_emitter/hivespawner
+ set_luminosity = 4
+ set_cap = 2.5
+ light_color = COLOR_RED_LIGHT
diff --git a/code/modules/mob_spawner/spawner.dm b/code/modules/mob_spawner/spawner.dm
new file mode 100644
index 000000000000..f5cfdadd0e96
--- /dev/null
+++ b/code/modules/mob_spawner/spawner.dm
@@ -0,0 +1,40 @@
+/obj/structure/spawner
+ name = "monster nest"
+ icon = 'icons/mob/nest.dmi'
+ icon_state = "hole"
+ max_integrity = 100
+
+ move_resist = INFINITY
+ anchored = TRUE
+ density = TRUE
+
+ var/max_mobs = 5
+ var/spawn_time = 300 //30 seconds default
+ var/mob_types = list(/mob/living/simple_animal/hostile/carp)
+ var/spawn_text = "emerges from"
+ var/faction = list("hostile")
+ var/spawn_sound = list('sound/effects/break_stone.ogg')
+ var/spawner_type = /datum/component/spawner
+ var/spawn_distance_min = 1
+ var/spawn_distance_max = 1
+
+/obj/structure/spawner/Initialize()
+ . = ..()
+ AddComponent(spawner_type, mob_types, spawn_time, faction, spawn_text, max_mobs, spawn_sound, spawn_distance_min, spawn_distance_max)
+
+/obj/structure/spawner/attack_animal(mob/living/simple_animal/M)
+ if(faction_check(faction, M.faction, FALSE)&&!M.client)
+ return
+ ..()
+
+/obj/structure/spawner/carp
+ name = "carp spawn" //the non game spawn meaning
+ desc = "A puddle, which appears to be full of carp"
+ icon_state = "puddle"
+ icon = 'icons/obj/watercloset.dmi'
+ max_integrity = 150
+ max_mobs = 5
+ spawn_time = 1200
+ mob_types = list(/mob/living/simple_animal/hostile/carp)
+ spawn_text = "swims out of"
+ faction = list("carp")
diff --git a/code/datums/components/spawner.dm b/code/modules/mob_spawner/spawner_componet.dm
similarity index 99%
rename from code/datums/components/spawner.dm
rename to code/modules/mob_spawner/spawner_componet.dm
index aab5bb6ea08a..8a904a5504c4 100644
--- a/code/datums/components/spawner.dm
+++ b/code/modules/mob_spawner/spawner_componet.dm
@@ -14,7 +14,6 @@
var/wave_timer
var/current_timerid
-
/datum/component/spawner/Initialize(_mob_types, _spawn_time, _faction, _spawn_text, _max_mobs, _spawn_sound, _spawn_distance_min, _spawn_distance_max, _wave_length, _wave_downtime)
if(_spawn_time)
spawn_time=_spawn_time
diff --git a/code/modules/modular_computers/computers/machinery/modular_console.dm b/code/modules/modular_computers/computers/machinery/modular_console.dm
index 6213cba441a6..a1af42ca3169 100644
--- a/code/modules/modular_computers/computers/machinery/modular_console.dm
+++ b/code/modules/modular_computers/computers/machinery/modular_console.dm
@@ -9,8 +9,8 @@
screen_icon_state_menu = "menu"
hardware_flag = PROGRAM_CONSOLE
density = TRUE
- base_idle_power_usage = 100
- base_active_power_usage = 500
+ base_idle_power_usage = IDLE_DRAW_MINIMAL
+ base_active_power_usage = ACTIVE_DRAW_LOW
max_hardware_size = 4
steel_sheet_cost = 10
light_strength = 2
diff --git a/code/modules/modular_computers/file_system/programs/bounty_board.dm b/code/modules/modular_computers/file_system/programs/bounty_board.dm
index 496011cfdddd..b3b9051e5b8f 100644
--- a/code/modules/modular_computers/file_system/programs/bounty_board.dm
+++ b/code/modules/modular_computers/file_system/programs/bounty_board.dm
@@ -25,8 +25,8 @@
if(!networked)
GLOB.allbountyboards += computer
networked = TRUE
- if(card_slot && card_slot.stored_card && card_slot.stored_card.registered_account)
- current_user = card_slot.stored_card.registered_account
+ if(card_slot && card_slot.bank_card && card_slot.bank_card.registered_account)
+ current_user = card_slot.bank_card.registered_account
for(var/i in GLOB.request_list)
if(!i)
continue
diff --git a/code/modules/modular_computers/file_system/programs/cargoship.dm b/code/modules/modular_computers/file_system/programs/cargoship.dm
index 1bfe53b215f2..2aa9b68565ca 100644
--- a/code/modules/modular_computers/file_system/programs/cargoship.dm
+++ b/code/modules/modular_computers/file_system/programs/cargoship.dm
@@ -35,21 +35,21 @@
// Get components
var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
var/obj/item/computer_hardware/printer/printer = computer.all_components[MC_PRINT]
- var/obj/item/card/id/id_card = card_slot ? card_slot.stored_card : null
+ var/obj/item/card/bank/bank_card = card_slot ? card_slot.stored_card : null
if(!card_slot || !printer) //We need both to successfully use this app.
return
switch(action)
if("ejectid")
- if(id_card)
+ if(bank_card)
card_slot.try_eject(TRUE, usr)
if("selectid")
- if(!id_card)
+ if(!bank_card)
return
- if(!id_card.registered_account)
+ if(!bank_card.registered_account)
playsound(get_turf(ui_host()), 'sound/machines/buzz-sigh.ogg', 50, TRUE, -1)
return
- payments_acc = id_card.registered_account
+ payments_acc = bank_card.registered_account
playsound(get_turf(ui_host()), 'sound/machines/ping.ogg', 50, TRUE, -1)
if("resetid")
payments_acc = null
diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm
index 1acdb72f400e..1ef62b7617f3 100644
--- a/code/modules/modular_computers/hardware/card_slot.dm
+++ b/code/modules/modular_computers/hardware/card_slot.dm
@@ -8,6 +8,7 @@
var/obj/item/card/id/stored_card
var/obj/item/card/id/stored_card2
+ var/obj/item/card/bank/bank_card
/obj/item/computer_hardware/card_slot/Exited(atom/ejected, atom/newloc)
if(!(ejected == stored_card || ejected == stored_card2))
diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm
index eb363de15792..b1ec3d3edc16 100644
--- a/code/modules/modular_computers/laptop_vendor.dm
+++ b/code/modules/modular_computers/laptop_vendor.dm
@@ -248,10 +248,10 @@
visible_message("[user] inserts a [HC.credits] cr holocredit chip into [src].")
qdel(HC)
return
- else if(istype(I, /obj/item/card/id))
+ else if(istype(I, /obj/item/card/bank))
if(state != 2)
return
- var/obj/item/card/id/ID = I
+ var/obj/item/card/bank/ID = I
var/datum/bank_account/account = ID.registered_account
var/target_credits = total_price - credits
if(!account.adjust_money(-target_credits, "laptop_vendor"))
diff --git a/code/modules/movespeed/modifiers/items.dm b/code/modules/movespeed/modifiers/items.dm
index b10e25c84e7a..c858582af6a3 100644
--- a/code/modules/movespeed/modifiers/items.dm
+++ b/code/modules/movespeed/modifiers/items.dm
@@ -17,3 +17,4 @@
/datum/movespeed_modifier/berserk
multiplicative_slowdown = -0.2
+
diff --git a/code/modules/movespeed/modifiers/reagent.dm b/code/modules/movespeed/modifiers/reagent.dm
index d6b0703ccb59..ecf91d0760fa 100644
--- a/code/modules/movespeed/modifiers/reagent.dm
+++ b/code/modules/movespeed/modifiers/reagent.dm
@@ -13,7 +13,7 @@
/datum/movespeed_modifier/reagent/badstims
multiplicative_slowdown = -0.45
-/datum/movespeed_modifier/reagent/monkey_energy
+/datum/movespeed_modifier/reagent/xeno_energy
multiplicative_slowdown = -0.35
/datum/movespeed_modifier/reagent/changelinghaste
diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm
index 2e3dac4fddbe..f45c231c7098 100644
--- a/code/modules/ninja/suit/ninjaDrainAct.dm
+++ b/code/modules/ninja/suit/ninjaDrainAct.dm
@@ -41,7 +41,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
drain = S.cell.maxcharge - S.cell.charge
maxcapacity = 1//Reached maximum battery capacity.
- if (do_after(H,10, target = src))
+ if (do_after(H,10, target = src, hidden = TRUE))
spark_system.start()
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
cell.use(drain)
@@ -85,7 +85,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
drain = S.cell.maxcharge - S.cell.charge
maxcapacity = 1
- if (do_after(H,10, target = src))
+ if (do_after(H, 10, target = src, hidden = TRUE))
spark_system.start()
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
charge -= drain
@@ -104,7 +104,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
. = 0
if(charge)
- if(G.candrain && do_after(H,30, target = src))
+ if(G.candrain && do_after(H,30, target = src, hidden = TRUE))
. = charge
if(S.cell.charge + charge > S.cell.maxcharge)
S.cell.charge = S.cell.maxcharge
@@ -131,7 +131,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
if(stored_research)
to_chat(H, "Copying files...")
- if(do_after(H, S.s_delay, target = src) && G.candrain && src)
+ if(do_after(H, S.s_delay, target = src, hidden = TRUE) && G.candrain && src)
stored_research.copy_research_to(S.stored_research)
to_chat(H, "Data analyzed. Process finished.")
@@ -148,7 +148,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
if(stored_research)
to_chat(H, "Copying files...")
- if(do_after(H, S.s_delay, target = src) && G.candrain && src)
+ if(do_after(H, S.s_delay, target = src, hidden = TRUE) && G.candrain && src)
stored_research.copy_research_to(S.stored_research)
to_chat(H, "Data analyzed. Process finished.")
@@ -167,7 +167,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
while(G.candrain && !maxcapacity && src)
drain = (round((rand(G.mindrain, G.maxdrain))/2))
var/drained = 0
- if(PN && do_after(H,10, target = src))
+ if(PN && do_after(H,10, target = src, hidden = TRUE))
drained = min(drain, delayed_surplus())
add_delayedload(drained)
if(drained < drain)//if no power on net, drain apcs
@@ -207,7 +207,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
if(S.cell.charge + drain > S.cell.maxcharge)
drain = S.cell.maxcharge - S.cell.charge
maxcapacity = 1
- if (do_after(H,10, target = src))
+ if (do_after(H,10, target = src, hidden = TRUE))
spark_system.start()
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
cell.use(drain)
@@ -235,7 +235,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
if(S.cell.charge+drain > S.cell.maxcharge)
drain = S.cell.maxcharge - S.cell.charge
maxcapacity = 1
- if (do_after(H,10))
+ if (do_after(H, 10, hidden = TRUE))
spark_system.start()
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
cell.use(drain)
diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm
index f9641a7a63ff..b700e22156fa 100644
--- a/code/modules/ninja/suit/suit_attackby.dm
+++ b/code/modules/ninja/suit/suit_attackby.dm
@@ -21,7 +21,7 @@
var/obj/item/stock_parts/cell/CELL = I
if(CELL.maxcharge > cell.maxcharge && n_gloves && n_gloves.candrain)
to_chat(U, "Higher maximum capacity detected.\nUpgrading...")
- if (n_gloves && n_gloves.candrain && do_after(U,s_delay, target = src))
+ if (n_gloves && n_gloves.candrain && do_after(U, s_delay, target = src))
U.transferItemToLoc(CELL, src)
CELL.charge = min(CELL.charge+cell.charge, CELL.maxcharge)
var/obj/item/stock_parts/cell/old_cell = cell
diff --git a/code/modules/overmap/helm.dm b/code/modules/overmap/helm.dm
index 59fdee827907..5b1f27fa2cb9 100644
--- a/code/modules/overmap/helm.dm
+++ b/code/modules/overmap/helm.dm
@@ -388,11 +388,11 @@
return
to_chat(user, "You begin to manually override the local database...")
- if(!do_after_mob(user, list(src), 2 SECONDS))
+ if(!do_after(user, 2 SECONDS, list(src)))
return COMPONENT_BLOCK_TOOL_ATTACK
priority_announce("Illegal access to local ship database detected.", sender_override="[src.name]", zlevel=virtual_z())
- if(!do_after_mob(user, list(src), 10 SECONDS))
+ if(!do_after(user, 10 SECONDS, list(src)))
return COMPONENT_BLOCK_TOOL_ATTACK
say("Warning, database corruption present, resetting local database state.")
diff --git a/code/modules/overmap/missions/acquire_mission.dm b/code/modules/overmap/missions/acquire_mission.dm
index de60174081db..1c9b9974ed1b 100644
--- a/code/modules/overmap/missions/acquire_mission.dm
+++ b/code/modules/overmap/missions/acquire_mission.dm
@@ -211,6 +211,21 @@ Acquire: Anomaly
weight = 1
objective_type = /mob/living/simple_animal/bot/firebot/rockplanet
+/*
+ Acquire: Landmines
+*/
+
+/datum/mission/acquire/landmine
+ name = "Defuse landmines"
+ desc = "CLIP and Gezena have assigned us to offer a bounty to turn in disarmed ordnance for future ventures. We'll pay you well, but we're not responsible for any accidents."
+ weight = 6
+ value = 1500
+ duration = 80 MINUTES
+ dur_mod_range = 0.4
+ container_type = /obj/item/storage/toolbox/bounty
+ objective_type = /obj/item/mine/pressure/explosive
+ num_wanted = 2
+
/*
Acquire: Fishing
*/
diff --git a/code/modules/overmap/missions/research_mission.dm b/code/modules/overmap/missions/research_mission.dm
index a84b07b6529a..9481556d33be 100644
--- a/code/modules/overmap/missions/research_mission.dm
+++ b/code/modules/overmap/missions/research_mission.dm
@@ -106,7 +106,7 @@
density = FALSE
anchored = FALSE
use_power = NO_POWER_USE
- idle_power_usage = 400
+ idle_power_usage = IDLE_DRAW_MEDIUM
processing_flags = START_PROCESSING_MANUALLY
/obj/machinery/mission_scanner/wrench_act(mob/living/user, obj/item/I)
@@ -122,7 +122,7 @@
if(anchorvalue)
set_is_operational(TRUE)
START_PROCESSING(SSmachines, src)
- use_power = IDLE_POWER_USE
+ set_idle_power()
else
set_is_operational(FALSE)
STOP_PROCESSING(SSmachines, src)
diff --git a/code/modules/overmap/objects/dynamic_datum.dm b/code/modules/overmap/objects/dynamic_datum.dm
index 69591c71dc8e..dcc62aad7424 100644
--- a/code/modules/overmap/objects/dynamic_datum.dm
+++ b/code/modules/overmap/objects/dynamic_datum.dm
@@ -35,6 +35,9 @@
/// The turf used as the backup baseturf for any reservations created by this datum. Should not be null.
var/turf/default_baseturf = /turf/open/space
+ ///The default gravity the virtual z will have
+ var/gravity = 0
+
///The weather the virtual z will have. If null, the planet will have no weather.
var/datum/weather_controller/weather_controller_type
@@ -139,6 +142,7 @@
token.color = planet.color
ruin_type = planet.ruin_type
default_baseturf = planet.default_baseturf
+ gravity = planet.gravity
mapgen = planet.mapgen
weather_controller_type = planet.weather_controller_type
landing_sound = planet.landing_sound
diff --git a/code/modules/overmap/objects/outpost/outpost.dm b/code/modules/overmap/objects/outpost/outpost.dm
index 774057b68a08..01a100022cbf 100644
--- a/code/modules/overmap/objects/outpost/outpost.dm
+++ b/code/modules/overmap/objects/outpost/outpost.dm
@@ -24,10 +24,12 @@
// NOTE: "planetary" outposts should use baseturf specification and possibly different ztrait sun type, for both hangars and main level.
var/list/main_level_ztraits = list(
ZTRAIT_STATION = TRUE,
- ZTRAIT_SUN_TYPE = AZIMUTH
+ ZTRAIT_SUN_TYPE = AZIMUTH,
+ ZTRAIT_GRAVITY = STANDARD_GRAVITY
)
var/list/hangar_ztraits = list(
- ZTRAIT_SUN_TYPE = STATIC_EXPOSED
+ ZTRAIT_SUN_TYPE = STATIC_EXPOSED,
+ ZTRAIT_GRAVITY = STANDARD_GRAVITY
)
/// The mapzone used by the outpost level and hangars. Using a single mapzone means networked radio messages.
@@ -119,16 +121,14 @@
// fun fact: "Hutton" is in last_names
person_name = pick(GLOB.last_names)
else
- switch(rand(1, 5))
+ switch(rand(1, 4))
if(1)
- person_name = pick(GLOB.moth_last)
- if(2)
person_name = pick(prob(50) ? GLOB.lizard_names_male : GLOB.lizard_names_female)
- if(3)
+ if(2)
person_name = pick(GLOB.spider_last)
- if(4)
+ if(3)
person_name = kepori_name()
- if(5)
+ if(4)
person_name = vox_name()
return "[person_name] [pick(GLOB.station_suffixes)]"
diff --git a/code/modules/overmap/planets/planet_types.dm b/code/modules/overmap/planets/planet_types.dm
index 2152d4efe5ef..74ea0165b357 100644
--- a/code/modules/overmap/planets/planet_types.dm
+++ b/code/modules/overmap/planets/planet_types.dm
@@ -5,6 +5,7 @@
var/ruin_type = null
var/mapgen = null
var/default_baseturf = null
+ var/gravity = 0
var/weather_controller_type = null
var/icon_state = "globe"
var/color = "#ffffff"
@@ -20,6 +21,7 @@
color = COLOR_ORANGE
mapgen = /datum/map_generator/planet_generator/lava
default_baseturf = /turf/open/floor/plating/asteroid/basalt/lava
+ gravity = STANDARD_GRAVITY
weather_controller_type = /datum/weather_controller/lavaland
ruin_type = RUINTYPE_LAVA
landing_sound = 'sound/effects/planet_landing_2.ogg'
@@ -33,6 +35,7 @@
color = COLOR_BLUE_LIGHT
mapgen = /datum/map_generator/planet_generator/snow
default_baseturf = /turf/open/floor/plating/asteroid/snow/icemoon
+ gravity = STANDARD_GRAVITY
weather_controller_type = /datum/weather_controller/snow_planet
ruin_type = RUINTYPE_ICE
landing_sound = 'sound/effects/planet_landing_2.ogg'
@@ -45,6 +48,7 @@
color = COLOR_LIME
mapgen = /datum/map_generator/planet_generator/jungle
default_baseturf = /turf/open/floor/plating/dirt/jungle
+ gravity = STANDARD_GRAVITY
weather_controller_type = /datum/weather_controller/lush
ruin_type = RUINTYPE_JUNGLE
landing_sound = 'sound/effects/planet_landing_1.ogg'
@@ -57,6 +61,7 @@
color = "#bd1313"
mapgen = /datum/map_generator/planet_generator/rock
default_baseturf = /turf/open/floor/plating/asteroid
+ gravity = STANDARD_GRAVITY
weather_controller_type = /datum/weather_controller/rockplanet
ruin_type = RUINTYPE_ROCK
landing_sound = 'sound/effects/planet_landing_2.ogg'
@@ -69,6 +74,7 @@
color = COLOR_GRAY
mapgen = /datum/map_generator/planet_generator/sand
default_baseturf = /turf/open/floor/plating/asteroid/whitesands
+ gravity = STANDARD_GRAVITY
weather_controller_type = /datum/weather_controller/desert
ruin_type = RUINTYPE_SAND
landing_sound = 'sound/effects/planet_landing_2.ogg'
@@ -81,6 +87,7 @@
color = "#c6b597"
mapgen = /datum/map_generator/planet_generator/beach
default_baseturf = /turf/open/floor/plating/asteroid/sand/lit
+ gravity = STANDARD_GRAVITY
weather_controller_type = /datum/weather_controller/lush
ruin_type = RUINTYPE_BEACH
landing_sound = 'sound/effects/planet_landing_1.ogg'
@@ -92,6 +99,7 @@
icon_state = "wormhole"
color = COLOR_YELLOW
mapgen = /datum/map_generator/single_biome/reebe
+ gravity = STANDARD_GRAVITY
default_baseturf = /turf/open/chasm/reebe_void
weather_controller_type = null
weight = 0
@@ -131,6 +139,7 @@
color = "#a9883e"
mapgen = /datum/map_generator/planet_generator/waste
default_baseturf = /turf/open/floor/plating/asteroid/wasteplanet
+ gravity = STANDARD_GRAVITY
weather_controller_type = /datum/weather_controller/chlorine
ruin_type = RUINTYPE_WASTE
landing_sound = 'sound/effects/planet_landing_2.ogg'
@@ -142,6 +151,7 @@
icon_state = "globe"
color = COLOR_DARK_MODERATE_ORANGE
mapgen = /datum/map_generator/single_biome/gas_giant
+ gravity = GAS_GIANT_GRAVITY
default_baseturf = /turf/open/chasm/gas_giant
weather_controller_type = null
ruin_type = null //it's a Gas Giant. Not Cloud fuckin City
@@ -155,6 +165,7 @@
planet = DYNAMIC_WORLD_PLASMA_GIANT
color = COLOR_PURPLE
mapgen = /datum/map_generator/single_biome/plasma_giant
+ gravity = GAS_GIANT_GRAVITY
default_baseturf = /turf/open/chasm/gas_giant/plasma
weight = 0
icon_state = "globe"
diff --git a/code/modules/overmap/ships/controlled_ship_datum.dm b/code/modules/overmap/ships/controlled_ship_datum.dm
index 8174a3e365f4..ec4b78629027 100644
--- a/code/modules/overmap/ships/controlled_ship_datum.dm
+++ b/code/modules/overmap/ships/controlled_ship_datum.dm
@@ -307,6 +307,25 @@
job_holder_refs[human_job] = list()
job_holder_refs[human_job] += WEAKREF(H)
+/**
+ * adds a mob's real name to a crew's guestbooks
+ *
+ * * H - human mob to add to the crew's guestbooks
+ */
+/datum/overmap/ship/controlled/proc/add_mob_to_crew_guestbook(mob/living/carbon/human/H)
+ // iterate over the human list to find crewmembers
+ for(var/mob/living/carbon/human/crewmember as anything in GLOB.human_list)
+ if(crewmember == H)
+ continue
+ if(!(crewmember.real_name in manifest))
+ continue
+ if(!crewmember.mind?.guestbook)
+ continue
+
+ // add the mob to the crewmember's guestbook and viceversa
+ crewmember.mind.guestbook.add_guest(crewmember, H, H.real_name, H.real_name, TRUE)
+ H.mind.guestbook.add_guest(H, crewmember, crewmember.real_name, crewmember.real_name, TRUE)
+
/datum/overmap/ship/controlled/proc/set_owner_mob(mob/new_owner)
if(owner_mob)
// we (hopefully) don't have to hook qdeletion,
@@ -417,6 +436,9 @@
SStgui.close_uis(helm)
helm.say(helm_locked ? "Helm console is now locked." : "Helm console has been unlocked.")
+/datum/overmap/ship/controlled/proc/get_faction()
+ return source_template.faction_name
+
/obj/item/key/ship
name = "ship key"
desc = "A key for locking and unlocking the helm of a ship, comes with a ball chain so it can be worn around the neck. Comes with a cute little shuttle-shaped keychain."
diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm
index cb5a025da475..bce7a3f322c5 100644
--- a/code/modules/paperwork/fax.dm
+++ b/code/modules/paperwork/fax.dm
@@ -308,27 +308,34 @@
update_icon()
return TRUE
if("send_special")
- var/obj/item/paper/fax_paper = loaded_item_ref?.resolve()
- if(!fax_paper)
+ var/obj/item/loaded = loaded_item_ref?.resolve()
+ var/obj/thing_to_send
+ if(!loaded)
return
- if(!istype(fax_paper))
+ if(istype(loaded, /obj/item/paper))
+ var/obj/item/paper/fax_paper = loaded
+ fax_paper.request_state = TRUE
+ thing_to_send = fax_paper
+ else if(istype(loaded, /obj/item/photo))
+ thing_to_send = loaded
+ else
to_chat(usr, icon2html(src.icon, usr) + "ERROR: Failed to send fax.")
return
- fax_paper.request_state = TRUE
- fax_paper.loc = null
-
- INVOKE_ASYNC(src, PROC_REF(animate_object_travel), fax_paper, "fax_receive", find_overlay_state(fax_paper, "send"))
+ if(!thing_to_send)
+ return
+ thing_to_send.loc = null
+ INVOKE_ASYNC(src, PROC_REF(animate_object_travel), thing_to_send, "fax_receive", find_overlay_state(thing_to_send, "send"))
history_add("Send", params["name"])
- GLOB.requests.fax_request(usr.client, "sent a fax message from [fax_name]/[fax_id] to [params["name"]]", fax_paper)
- to_chat(GLOB.admins, "[icon2html(src.icon, GLOB.admins)]FAX REQUEST: [ADMIN_FULLMONTY(usr)]:sent a fax message from [fax_name]/[fax_id][ADMIN_FLW(src)] to [html_encode(params["name"])] [ADMIN_SHOW_PAPER(fax_paper)]")
- log_fax(fax_paper, params["id"], params["name"])
+ GLOB.requests.fax_request(usr.client, "sent a fax message from [fax_name]/[fax_id] to [params["name"]]", thing_to_send)
+ to_chat(GLOB.admins, "[icon2html(src.icon, GLOB.admins)]FAX REQUEST: [ADMIN_FULLMONTY(usr)]:sent a fax message from [fax_name]/[fax_id][ADMIN_FLW(src)] to [html_encode(params["name"])] [istype(thing_to_send, /obj/item/paper) ? ADMIN_SHOW_PAPER(thing_to_send) : ADMIN_SHOW_PHOTO(thing_to_send)]")
+ log_fax(thing_to_send, params["id"], params["name"])
loaded_item_ref = null
for(var/obj/machinery/fax/fax as anything in GLOB.fax_machines)
if(fax.admin_fax_id == params["id"])
- fax.receive(fax_paper, fax_name)
+ fax.receive(thing_to_send, fax_name)
break
update_appearance()
@@ -360,7 +367,7 @@
* * loaded - The object to be sent.
* * id - The network ID of the fax machine you want to send the item to.
*/
-/obj/machinery/fax/proc/send(obj/item/loaded, id)
+/obj/machinery/fax/proc/send(atom/movable/loaded, id)
for(var/obj/machinery/fax/fax as anything in GLOB.fax_machines)
if(fax.fax_id != id)
continue
@@ -385,7 +392,7 @@
* * loaded - The object to be printed.
* * sender_name - The sender's name, which will be displayed in the message and recorded in the history of operations.
*/
-/obj/machinery/fax/proc/receive(obj/item/loaded, sender_name, important = FALSE)
+/obj/machinery/fax/proc/receive(atom/movable/loaded, sender_name, important = FALSE)
playsound(src, 'sound/items/poster_being_created.ogg', 20, FALSE)
INVOKE_ASYNC(src, PROC_REF(animate_object_travel), loaded, "fax_receive", find_overlay_state(loaded, "receive"))
say("Received correspondence from [sender_name].")
@@ -442,7 +449,7 @@
* Arguments:
* * vend - Item to vend from the fax machine.
*/
-/obj/machinery/fax/proc/vend_item(obj/item/vend)
+/obj/machinery/fax/proc/vend_item(atom/movable/vend)
vend.forceMove(drop_location())
if(hurl_contents)
vend.throw_at(get_edge_target_turf(drop_location(), pick(GLOB.alldirs)), rand(1, 4), EMBED_THROWSPEED_THRESHOLD)
diff --git a/code/modules/paperwork/folders_premade.dm b/code/modules/paperwork/folders_premade.dm
index a919dce944ce..3c9dbb89feae 100644
--- a/code/modules/paperwork/folders_premade.dm
+++ b/code/modules/paperwork/folders_premade.dm
@@ -61,3 +61,10 @@
document = /obj/item/documents/terragov
desc = "A green folder with a Terran Regency seal."
icon_state = "folder_terragovred"
+
+/obj/item/folder/suns
+ desc = "A purple folder with a SUNS seal."
+ icon_state = "folder_suns"
+
+/obj/item/folder/suns/red
+ icon_state = "folder_sunsred" // i'm not sure why SUNS would need secret documents
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index b289c32e85e0..cd913c57fb0a 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -80,13 +80,6 @@
custom_materials = null
grind_results = list(/datum/reagent/ash = 5, /datum/reagent/cellulose = 10)
-/datum/crafting_recipe/charcoal_stylus
- name = "Charcoal Stylus"
- result = /obj/item/pen/charcoal
- reqs = list(/obj/item/stack/sheet/mineral/wood = 1, /datum/reagent/ash = 30)
- time = 30
- category = CAT_PRIMAL
-
/obj/item/pen/fountain/captain
name = "captain's fountain pen"
desc = "It's an expensive Oak fountain pen. The nib is quite sharp."
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index f85bd0bc77f9..40b0771981e4 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -24,8 +24,8 @@
anchored = TRUE
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 30
- active_power_usage = 200
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_LOW
power_channel = AREA_USAGE_EQUIP
max_integrity = 300
integrity_failure = 0.33
diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm
index 3bfc292108b5..45893f8d5fc5 100644
--- a/code/modules/paperwork/stamps.dm
+++ b/code/modules/paperwork/stamps.dm
@@ -140,5 +140,10 @@
icon_state = "stamp-bard"
dye_color = DYE_FO
+/obj/item/stamp/suns
+ name = "SUNS rubber stamp"
+ icon_state = "stamp-suns"
+ dye_color = DYE_PURPLE
+
/obj/item/stamp/attack_paw(mob/user)
return attack_hand(user)
diff --git a/code/modules/plumbing/plumbers/_plumb_machinery.dm b/code/modules/plumbing/plumbers/_plumb_machinery.dm
index 87096bad7e56..f4448c4a53ac 100644
--- a/code/modules/plumbing/plumbers/_plumb_machinery.dm
+++ b/code/modules/plumbing/plumbers/_plumb_machinery.dm
@@ -8,7 +8,7 @@
icon = 'icons/obj/plumbing/plumbers.dmi'
icon_state = "pump"
density = TRUE
- active_power_usage = 30
+ active_power_usage = ACTIVE_DRAW_MINIMAL
use_power = ACTIVE_POWER_USE
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
///Plumbing machinery is always gonna need reagents, so we might aswell put it here
diff --git a/code/modules/plumbing/plumbers/pumps.dm b/code/modules/plumbing/plumbers/pumps.dm
index 331e3fc24d89..294b50eff748 100644
--- a/code/modules/plumbing/plumbers/pumps.dm
+++ b/code/modules/plumbing/plumbers/pumps.dm
@@ -7,8 +7,8 @@
base_icon_state = "pump"
anchored = FALSE
density = TRUE
- idle_power_usage = 10
- active_power_usage = 1000
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
rcd_cost = 30
rcd_delay = 40
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 03bb1651fd70..f21f95692234 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -52,7 +52,7 @@
/// How long it takes an elzu to drain or charge APCs. Also used as a spam limiter.
#define APC_DRAIN_TIME (7.5 SECONDS)
/// How much power elzu gain/drain from APCs.
-#define APC_POWER_GAIN (10 * ETHEREAL_CHARGE_SCALING_MULTIPLIER)
+#define APC_POWER_GAIN (10 * ELZUOSE_CHARGE_SCALING_MULTIPLIER)
// Wires & EMPs:
/// The wire value used to reset the APCs wires after one's EMPed.
@@ -217,8 +217,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/power/apc/auto_name, 25)
// this allows the APC to be embedded in a wall, yet still inside an area
if (building)
setDir(ndir)
- tdir = dir // to fix Vars bug
-//!!!!!!!!!!!!!! FUCK YOU SINGLE LINE OF CODE!! FUCK YOU YOU PIECE OF SHIT!!!!! setDir(SOUTH)
+ tdir = dir// to fix Vars bug
+
switch(tdir)
if(NORTH)
if((pixel_y != initial(pixel_y)) && (pixel_y != 23))
@@ -834,10 +834,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/power/apc/auto_name, 25)
return
//[REDACTED] Begin -- Ethereal Charge Scaling //Let the hubris remain but the name be forgotten
- if(isethereal(user))
+ if(iselzuose(user))
var/mob/living/carbon/human/H = user
- var/datum/species/ethereal/E = H.dna.species
- var/charge_limit = ETHEREAL_CHARGE_DANGEROUS - APC_POWER_GAIN
+ var/datum/species/elzuose/E = H.dna.species
+ var/charge_limit = ELZUOSE_CHARGE_DANGEROUS - APC_POWER_GAIN
if((H.a_intent == INTENT_HARM) && (E.drain_time < world.time))
if(cell.charge <= (cell.maxcharge / 20)) // ethereals can't drain APCs under half charge, this is so that they are forced to look to alternative power sources if the station is running low
to_chat(H, "The APC's syphon safeties prevent you from draining power!")
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 3f85acdddfe6..283d41524f79 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -542,7 +542,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list(new/datum/stack_recipe("cable restrain
if(affecting && (!IS_ORGANIC_LIMB(affecting)))
if(user == H)
user.visible_message("[user] starts to fix some of the wires in [H]'s [parse_zone(affecting.body_zone)].", "You start fixing some of the wires in [H == user ? "your" : "[H]'s"] [parse_zone(affecting.body_zone)].")
- if(!do_mob(user, H, 50))
+ if(!do_after(user, 0.5 SECONDS, H))
return
if(item_heal_robotic(H, user, 0, 15))
use(1)
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 0f84b5571382..1a2f87c70dd9 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -1,6 +1,6 @@
#define CELL_DRAIN_TIME 35
-#define CELL_POWER_GAIN (3 * ETHEREAL_CHARGE_SCALING_MULTIPLIER)
-#define CELL_POWER_DRAIN (37.5 * ETHEREAL_CHARGE_SCALING_MULTIPLIER)
+#define CELL_POWER_GAIN (3 * ELZUOSE_CHARGE_SCALING_MULTIPLIER)
+#define CELL_POWER_DRAIN (37.5 * ELZUOSE_CHARGE_SCALING_MULTIPLIER)
/obj/item/stock_parts/cell
name = "power cell"
@@ -150,10 +150,10 @@
//WS Begin -- Ethereal Charge Scaling
/obj/item/stock_parts/cell/attack_self(mob/user)
- if(isethereal(user))
+ if(iselzuose(user))
var/mob/living/carbon/human/H = user
- var/datum/species/ethereal/E = H.dna.species
- var/charge_limit = ETHEREAL_CHARGE_DANGEROUS - CELL_POWER_GAIN
+ var/datum/species/elzuose/E = H.dna.species
+ var/charge_limit = ELZUOSE_CHARGE_DANGEROUS - CELL_POWER_GAIN
if(E.drain_time > world.time)
return
if(charge < CELL_POWER_DRAIN)
diff --git a/code/modules/power/floodlight.dm b/code/modules/power/floodlight.dm
index e112b38f2fd7..0fe0b51c6193 100644
--- a/code/modules/power/floodlight.dm
+++ b/code/modules/power/floodlight.dm
@@ -61,8 +61,8 @@
density = TRUE
max_integrity = 100
integrity_failure = 0.8
- idle_power_usage = 100
- active_power_usage = 1000
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
anchored = FALSE
light_power = 1.75
var/list/light_setting_list = list(0, 5, 10, 15)
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index 1e4660c48953..3ed7e262a53d 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -1,4 +1,3 @@
-
//
// Gravity Generator
//
@@ -116,7 +115,7 @@
/obj/machinery/gravity_generator/main
icon_state = "on_8"
idle_power_usage = 0
- active_power_usage = 3000
+ active_power_usage = ACTIVE_DRAW_EXTREME
power_channel = AREA_USAGE_ENVIRON
sprite_number = 8
use_power = IDLE_POWER_USE
@@ -287,7 +286,10 @@
/obj/machinery/gravity_generator/main/proc/set_state(new_state)
charging_state = POWER_IDLE
on = new_state
- use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE
+ if(on)
+ set_active_power()
+ else
+ set_idle_power()
// Sound the alert if gravity was just enabled or disabled.
var/alert = FALSE
if(SSticker.IsRoundInProgress())
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 24b106f0241f..e92efb779d67 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -13,7 +13,7 @@
#define BROKEN_SPARKS_MAX (9 MINUTES)
#define LIGHT_DRAIN_TIME 25 //WS Edit -- Ethereal Charge Scaling
-#define LIGHT_POWER_GAIN (1.75 * ETHEREAL_CHARGE_SCALING_MULTIPLIER) //WS Edit -- Ethereal Charge Scaling
+#define LIGHT_POWER_GAIN (1.75 * ELZUOSE_CHARGE_SCALING_MULTIPLIER) //WS Edit -- Ethereal Charge Scaling
/obj/item/wallframe/light_fixture
name = "light fixture frame"
@@ -217,9 +217,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/light_construct/small, 28)
desc = "A lighting fixture."
layer = WALL_OBJ_LAYER
max_integrity = 100
- use_power = ACTIVE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 20
+ use_power = IDLE_POWER_USE
+ idle_power_usage = 0
+ active_power_usage = 0
power_channel = AREA_USAGE_LIGHT //Lights are calc'd via area so they dont need to be in the machine list
var/on = FALSE // 1 if on, 0 if off
var/on_gs = FALSE
@@ -360,6 +360,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/small/built, 28)
addtimer(CALLBACK(src, PROC_REF(update), 0), 1)
/obj/machinery/light/Destroy()
+ if(on)
+ removeStaticPower(static_power_used, AREA_USAGE_STATIC_LIGHT)
var/area/A = get_area(src)
if(A)
on = FALSE
@@ -420,22 +422,18 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/small/built, 28)
if(trigger)
burn_out()
else
- use_power = ACTIVE_POWER_USE
set_light(BR, PO, CO)
else if(has_emergency_power(LIGHT_EMERGENCY_POWER_USE) && !turned_off())
- use_power = IDLE_POWER_USE
emergency_mode = TRUE
START_PROCESSING(SSmachines, src)
else
- use_power = IDLE_POWER_USE
set_light(0)
update_appearance()
- active_power_usage = (brightness * 10)
if(on != on_gs)
on_gs = on
if(on)
- static_power_used = brightness * 20 //20W per unit luminosity
+ static_power_used = brightness * LIGHT_DRAW //defined in power defines
addStaticPower(static_power_used, AREA_USAGE_STATIC_LIGHT)
else
removeStaticPower(static_power_used, AREA_USAGE_STATIC_LIGHT)
@@ -690,9 +688,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/small/built, 28)
var/mob/living/carbon/human/H = user
if(istype(H))
- var/datum/species/ethereal/eth_species = H.dna?.species
+ var/datum/species/elzuose/eth_species = H.dna?.species
if(istype(eth_species))
- var/datum/species/ethereal/E = H.dna.species
+ var/datum/species/elzuose/E = H.dna.species
if(E.drain_time > world.time)
return
to_chat(H, "You start channeling some power through the [fitting] into your body.")
@@ -859,8 +857,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/small/built, 28)
if(!..()) //not caught by a mob
shatter()
-// update the icon state and description of the light
+/obj/item/light/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
+ shatter()
+ ..()
+// update the icon state and description of the light
/obj/item/light/proc/update()
switch(status)
if(LIGHT_OK)
diff --git a/code/modules/power/monitor.dm b/code/modules/power/monitor.dm
index b1c2a95a938f..debdba4946bf 100644
--- a/code/modules/power/monitor.dm
+++ b/code/modules/power/monitor.dm
@@ -7,8 +7,8 @@
icon_keyboard = "power_key"
light_color = LIGHT_COLOR_YELLOW
use_power = ACTIVE_POWER_USE
- idle_power_usage = 20
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
circuit = /obj/item/circuitboard/computer/powermonitor
tgui_id = "PowerMonitor"
@@ -49,10 +49,12 @@
/obj/machinery/computer/monitor/process()
if(!get_powernet())
- use_power = IDLE_POWER_USE
+ if(use_static_power != IDLE_POWER_USE)
+ set_idle_power()
search()
else
- use_power = ACTIVE_POWER_USE
+ if(use_static_power != ACTIVE_POWER_USE)
+ set_active_power()
record()
/obj/machinery/computer/monitor/proc/search() //keep in sync with /datum/computer_file/program/power_monitor's version
diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm
index e235e9328549..e63cd1298616 100644
--- a/code/modules/power/port_gen.dm
+++ b/code/modules/power/port_gen.dm
@@ -291,7 +291,6 @@
circuit = /obj/item/circuitboard/machine/pacman/super
sheet_path = /obj/item/stack/sheet/mineral/uranium
power_gen = 15000
- time_per_sheet = 85
/obj/machinery/power/port_gen/pacman/super/overheat()
. =..()
@@ -304,7 +303,6 @@
circuit = /obj/item/circuitboard/machine/pacman/mrs
sheet_path = /obj/item/stack/sheet/mineral/diamond
power_gen = 40000
- time_per_sheet = 80
/obj/machinery/power/port_gen/pacman/mrs/overheat()
. =..()
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index 3cf5f5766097..a386a739622d 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -19,6 +19,7 @@
/obj/machinery/power/Destroy()
disconnect_from_network()
+ set_no_power()
return ..()
///////////////////////////////
@@ -96,14 +97,47 @@
chan = power_channel
A.use_power(amount, chan)
-/obj/machinery/proc/addStaticPower(value, powerchannel)
- var/area/A = get_area(src)
+/obj/machinery/proc/addStaticPower(value, powerchannel, area/A)
if(!A)
- return
+ if(get_area(src))
+ A = get_area(src)
+ else
+ return
A.addStaticPower(value, powerchannel)
-/obj/machinery/proc/removeStaticPower(value, powerchannel)
- addStaticPower(-value, powerchannel)
+/obj/machinery/proc/removeStaticPower(value, powerchannel, area/A)
+ addStaticPower(-value, powerchannel, A)
+
+/obj/machinery/proc/set_idle_power(area/A)
+ set_no_power(A)
+ if(use_power == NO_POWER_USE)
+ return
+ use_static_power = IDLE_POWER_USE
+ addStaticPower(idle_power_usage, power_channel + 3, A)
+
+/obj/machinery/proc/set_active_power(area/A)
+ set_no_power(A)
+ if(use_power == NO_POWER_USE)
+ return
+ use_static_power = ACTIVE_POWER_USE
+ addStaticPower(active_power_usage, power_channel + 3, A)
+
+/obj/machinery/proc/set_no_power(area/A)
+ switch(use_static_power)
+ if(IDLE_POWER_USE)
+ removeStaticPower(idle_power_usage, power_channel + 3, A)
+ if(ACTIVE_POWER_USE)
+ removeStaticPower(active_power_usage, power_channel + 3, A)
+ use_static_power = NO_POWER_USE
+
+/obj/machinery/proc/set_static_power(area/A)//used to set the actual draw to the value of use_static_power
+ switch(use_power)
+ if(NO_POWER_USE)
+ set_no_power(A)
+ if(IDLE_POWER_USE)
+ set_idle_power(A)
+ if(ACTIVE_POWER_USE)
+ set_active_power(A)
/**
* Called whenever the power settings of the containing area change
@@ -112,13 +146,15 @@
*
* Returns TRUE if the NOPOWER flag was toggled
*/
-/obj/machinery/proc/power_change()
+/obj/machinery/proc/power_change(area/A)
SIGNAL_HANDLER
SHOULD_CALL_PARENT(1)
+ set_no_power(A)
if(machine_stat & BROKEN)
return
if(powered(power_channel))
+ set_static_power(A)
if(machine_stat & NOPOWER)
SEND_SIGNAL(src, COMSIG_MACHINERY_POWER_RESTORED)
. = TRUE
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 8850c4e68981..d1c14fe67917 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -1,7 +1,7 @@
// stored_energy += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
-#define RAD_COLLECTOR_EFFICIENCY 80 // radiation needs to be over this amount to get power
-#define RAD_COLLECTOR_COEFFICIENT 10
-#define RAD_COLLECTOR_STORED_OUT 0.001 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
+#define RAD_COLLECTOR_EFFICIENCY 300 // radiation needs to be over this amount to get power
+#define RAD_COLLECTOR_COEFFICIENT 100
+#define RAD_COLLECTOR_STORED_OUT 0.04 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
#define RAD_COLLECTOR_MINING_CONVERSION_RATE 0.00001 //This is gonna need a lot of tweaking to get right. This is the number used to calculate the conversion of watts to research points per process()
#define RAD_COLLECTOR_OUTPUT min(stored_energy, (stored_energy*RAD_COLLECTOR_STORED_OUT)+1000) //Produces at least 1000 watts if it has more than that stored
#define PUBLIC_TECHWEB_GAIN 0.6 //how many research points go directly into the main pool
@@ -70,7 +70,6 @@
loaded_tank.air_contents.adjust_moles(GAS_O2, -gasdrained)
loaded_tank.air_contents.adjust_moles(GAS_CO2, gasdrained*2)
var/bitcoins_mined = RAD_COLLECTOR_OUTPUT
- new /obj/item/spacecash(get_dumping_location(), bitcoins_mined * RAD_COLLECTOR_MINING_CONVERSION_RATE)
stored_research += bitcoins_mined*RAD_COLLECTOR_MINING_CONVERSION_RATE*PRIVATE_TECHWEB_GAIN
linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, bitcoins_mined*RAD_COLLECTOR_MINING_CONVERSION_RATE*PUBLIC_TECHWEB_GAIN)
stored_energy-=bitcoins_mined
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index d17e12264706..2dcaa224a71e 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -11,8 +11,8 @@
circuit = /obj/item/circuitboard/machine/emitter
use_power = NO_POWER_USE
- idle_power_usage = 10
- active_power_usage = 300
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_LOW
var/icon_state_on = "emitter_+a"
var/icon_state_underpowered = "emitter_+u"
@@ -67,7 +67,7 @@
var/max_firedelay = 120
var/firedelay = 120
var/min_firedelay = 24
- var/power_usage = 350
+ var/power_usage = ACTIVE_DRAW_LOW
for(var/obj/item/stock_parts/micro_laser/L in component_parts)
max_firedelay -= 20 * L.rating
min_firedelay -= 4 * L.rating
diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm
index 7bc3fa552ad3..ddcaf026a40e 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_control.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm
@@ -6,8 +6,8 @@
anchored = FALSE
density = TRUE
use_power = NO_POWER_USE
- idle_power_usage = 500
- active_power_usage = 10000
+ idle_power_usage = IDLE_DRAW_MEDIUM
+ active_power_usage = ACTIVE_DRAW_EXTREME * 2
dir = NORTH
mouse_opacity = MOUSE_OPACITY_OPAQUE
var/strength_upper_limit = 2
@@ -53,7 +53,7 @@
connected_parts.Cut()
return
if(!part_scan())
- use_power = IDLE_POWER_USE
+ set_idle_power()
active = FALSE
connected_parts.Cut()
@@ -106,7 +106,7 @@
active = FALSE
use_power = NO_POWER_USE
else if(!machine_stat && construction_state == PA_CONSTRUCTION_COMPLETE)
- use_power = IDLE_POWER_USE
+ set_idle_power()
/obj/machinery/particle_accelerator/control_box/process()
if(active)
@@ -175,14 +175,14 @@
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? ADMIN_LOOKUPFLW(usr) : "outside forces"] in [ADMIN_VERBOSEJMP(src)]")
log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] at [AREACOORD(src)]")
if(active)
- use_power = ACTIVE_POWER_USE
+ set_active_power()
for(var/CP in connected_parts)
var/obj/structure/particle_accelerator/part = CP
part.strength = strength
part.powered = TRUE
part.update_appearance()
else
- use_power = IDLE_POWER_USE
+ set_idle_power()
for(var/CP in connected_parts)
var/obj/structure/particle_accelerator/part = CP
part.strength = null
diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm
index 8ca409051d6c..d25fc732abe7 100644
--- a/code/modules/power/solar.dm
+++ b/code/modules/power/solar.dm
@@ -324,7 +324,7 @@
icon_state = "computer"
density = TRUE
use_power = IDLE_POWER_USE
- idle_power_usage = 250
+ idle_power_usage = IDLE_DRAW_LOW
max_integrity = 200
integrity_failure = 0.5
var/icon_screen = "solar"
diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm
index ccbb774f0224..7f6ca0f5d360 100644
--- a/code/modules/power/tesla/coil.dm
+++ b/code/modules/power/tesla/coil.dm
@@ -96,7 +96,6 @@
var/power_produced = powernet ? power / power_loss : power
add_avail(power_produced*input_power_multiplier)
flick("coilhit", src)
- new /obj/item/spacecash(get_dumping_location(), power_produced)
if(istype(linked_techweb) && (zap_flags & ZAP_GIVES_RESEARCH) && can_generate_research)
linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 3)) // x4 coils = 12 points a shock for RND, if they even bothered to link the server.
addtimer(CALLBACK(src, PROC_REF(reset_shocked)), 10)
@@ -133,7 +132,6 @@
var/power_produced = powernet ? power / power_loss : power
add_avail(power_produced*input_power_multiplier)
flick("rpcoilhit", src)
- new /obj/item/spacecash(get_dumping_location(), min(power_produced, 12))
if(istype(linked_techweb) && (zap_flags & ZAP_GIVES_RESEARCH))
linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 25)) // x4 coils = 100 points per shock, which is a good reward for building a research tesla or electrical storm harvest ship
addtimer(CALLBACK(src, PROC_REF(reset_shocked)), 10)
diff --git a/code/modules/projectiles/ammunition/_ammunition.dm b/code/modules/projectiles/ammunition/_ammunition.dm
index 5b7317972175..b216296cfe8d 100644
--- a/code/modules/projectiles/ammunition/_ammunition.dm
+++ b/code/modules/projectiles/ammunition/_ammunition.dm
@@ -32,12 +32,14 @@
var/pellets = 1 //Pellets for spreadshot
var/variance = 0 //Variance for inaccuracy fundamental to the casing
- var/randomspread = 0 //Randomspread for automatics
+ var/randomspread = FALSE //Randomspread for automatics
var/delay = 0 //Delay for energy weapons
var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown.
var/list/bounce_sfx_override // if true, overrides the bouncing sfx from the turf to this one
+ var/bullet_per_box
+
/obj/item/ammo_casing/spent
name = "spent bullet casing"
@@ -49,6 +51,7 @@
BB = new projectile_type(src)
pixel_x = base_pixel_x + rand(-10, 10)
pixel_y = base_pixel_y + rand(-10, 10)
+ item_flags |= NO_PIXEL_RANDOM_DROP
if(auto_rotate)
transform = transform.Turn(pick(0, 90, 180, 270))
update_appearance()
@@ -100,9 +103,14 @@
bounce_away(FALSE, NONE)
. = ..()
-/obj/item/ammo_casing/proc/on_eject()
+/obj/item/ammo_casing/proc/on_eject(atom/shooter)
forceMove(drop_location()) //Eject casing onto ground.
- bounce_away(TRUE)
+ pixel_x = rand(-4, 4)
+ pixel_y = rand(-4, 4)
+ pixel_z = 8 //bounce time
+ var/angle_of_movement = !isnull(shooter) ? (rand(-3000, 3000) / 100) + dir2angle(turn(shooter.dir, 180)) : rand(-3000, 3000) / 100
+ AddComponent(/datum/component/movable_physics, _horizontal_velocity = rand(400, 450) / 100, _vertical_velocity = rand(400, 450) / 100, _horizontal_friction = rand(20, 24) / 100, _z_gravity = PHYSICS_GRAV_STANDARD, _z_floor = 0, _angle_of_movement = angle_of_movement, _bounce_sound = bounce_sfx_override)
+
/obj/item/ammo_casing/proc/bounce_away(still_warm = FALSE, bounce_delay = 3)
if(!heavy_metal)
diff --git a/code/modules/projectiles/ammunition/_firing.dm b/code/modules/projectiles/ammunition/_firing.dm
index ee155db4e719..93fa4208d571 100644
--- a/code/modules/projectiles/ammunition/_firing.dm
+++ b/code/modules/projectiles/ammunition/_firing.dm
@@ -18,8 +18,6 @@
if(click_cooldown_override)
user.changeNext_move(click_cooldown_override)
- else
- user.changeNext_move(CLICK_CD_RANGE)
user.newtonian_move(get_dir(target, user))
update_appearance()
diff --git a/code/modules/projectiles/ammunition/ballistic/lmg.dm b/code/modules/projectiles/ammunition/ballistic/lmg.dm
index 90030e7b0944..d46001951ba4 100644
--- a/code/modules/projectiles/ammunition/ballistic/lmg.dm
+++ b/code/modules/projectiles/ammunition/ballistic/lmg.dm
@@ -6,6 +6,7 @@
icon_state = "rifle-steel"
caliber = "7.12x82mm"
projectile_type = /obj/projectile/bullet/mm712x82
+ bullet_per_box = 100
/obj/item/ammo_casing/mm712x82/ap
name = "7.12x82mm armor-piercing bullet casing"
diff --git a/code/modules/projectiles/ammunition/ballistic/pistol.dm b/code/modules/projectiles/ammunition/ballistic/pistol.dm
index a105ae6602ee..0f37b5426d2d 100644
--- a/code/modules/projectiles/ammunition/ballistic/pistol.dm
+++ b/code/modules/projectiles/ammunition/ballistic/pistol.dm
@@ -6,6 +6,7 @@
icon_state = "pistol-steel"
caliber = "10mm"
projectile_type = /obj/projectile/bullet/c10mm
+ bullet_per_box = 50
/obj/item/ammo_casing/c10mm/surplus
name = "10mm surplus bullet casing"
@@ -45,6 +46,7 @@
icon_state = "pistol-brass"
caliber = "9mm"
projectile_type = /obj/projectile/bullet/c9mm
+ bullet_per_box = 50
/obj/item/ammo_casing/c9mm/surplus
name = "9mm surplus bullet casing"
@@ -84,6 +86,7 @@
icon_state = "pistol-steel"
caliber = ".45"
projectile_type = /obj/projectile/bullet/c45
+ bullet_per_box = 50
/obj/item/ammo_casing/c45/surplus
name = ".45 surplus bullet casing"
@@ -122,6 +125,7 @@
desc = "A .50 AE bullet casing."
caliber = ".50 AE"
projectile_type = /obj/projectile/bullet/a50AE
+ bullet_per_box = 20
/obj/item/ammo_casing/a50AE/hp
name = ".50 AE hollow point bullet casing"
@@ -134,4 +138,5 @@
desc = "A .22 LR bullet casing."
projectile_type = /obj/projectile/bullet/c22lr
caliber = "22lr"
+ bullet_per_box = 75
diff --git a/code/modules/projectiles/ammunition/ballistic/revolver.dm b/code/modules/projectiles/ammunition/ballistic/revolver.dm
index d5684e834e3d..e235e00b98f6 100644
--- a/code/modules/projectiles/ammunition/ballistic/revolver.dm
+++ b/code/modules/projectiles/ammunition/ballistic/revolver.dm
@@ -6,6 +6,7 @@
caliber = ".357"
icon_state = "magnum-brass"
projectile_type = /obj/projectile/bullet/a357
+ bullet_per_box = 50
/obj/item/ammo_casing/a357/match
name = ".357 match bullet casing"
@@ -28,6 +29,7 @@
caliber = ".45-70"
icon_state = "magnum-brass"
projectile_type = /obj/projectile/bullet/a4570
+ bullet_per_box = 12
/obj/item/ammo_casing/a4570/match
name = ".45-70 match bullet casing"
@@ -53,6 +55,7 @@
desc = "A .38 Special bullet casing."
caliber = ".38"
projectile_type = /obj/projectile/bullet/c38
+ bullet_per_box = 50
/obj/item/ammo_casing/c38/surplus
name = ".38 surplus bullet casing"
@@ -95,3 +98,24 @@
desc = "A .38 iceblox bullet casing."
bullet_skin = "surplus"
projectile_type = /obj/projectile/bullet/c38/iceblox
+
+//44 Roumain (Montagne & Shadow)
+
+/obj/item/ammo_casing/a44roum
+ name = ".44 roumain bullet casing"
+ desc = "A .44 roumain bullet casing."
+ caliber = ".44 Roumain"
+ icon_state = "pistol-steel"
+ projectile_type = /obj/projectile/bullet/a44roum
+
+/obj/item/ammo_casing/a44roum/rubber
+ name = ".44 roumain rubber bullet casing"
+ desc = "A .44 roumain rubber bullet casing."
+ bullet_skin = "rubber"
+ projectile_type = /obj/projectile/bullet/a44roum/rubber
+
+/obj/item/ammo_casing/a44roum/hp
+ name = ".44 roumain hollow point bullet casing"
+ desc = "A .44 roumain holow point bullet casing."
+ bullet_skin = "hollow"
+ projectile_type = /obj/projectile/bullet/a44roum/hp
diff --git a/code/modules/projectiles/ammunition/ballistic/rifle.dm b/code/modules/projectiles/ammunition/ballistic/rifle.dm
index 5b93bfaa2463..b3875292fba2 100644
--- a/code/modules/projectiles/ammunition/ballistic/rifle.dm
+++ b/code/modules/projectiles/ammunition/ballistic/rifle.dm
@@ -6,6 +6,7 @@
icon_state = "rifle-brass"
caliber = "8x50mmR"
projectile_type = /obj/projectile/bullet/a8_50r
+ bullet_per_box = 20
/obj/item/ammo_casing/a8_50rhp
name = "8x50mmR hollow point bullet casing"
@@ -23,6 +24,7 @@
icon_state = "caseless"
caliber = "a858"
projectile_type = /obj/projectile/bullet/a858
+ bullet_per_box = 20
// .300 Magnum (Smile Rifle)
@@ -32,6 +34,7 @@
icon_state = "rifle-steel"
caliber = "a300"
projectile_type = /obj/projectile/bullet/a300
+ bullet_per_box = 20
// 5.56x39mm (M-90gl Carbine & P-16)
@@ -41,6 +44,7 @@
icon_state = "rifle-brass"
caliber = "5.56x45mm"
projectile_type = /obj/projectile/bullet/a556_45
+ bullet_per_box = 80
// 5.45x39mm (SKM-24v)
@@ -51,6 +55,7 @@
caliber = "5.45x39mm"
randomspread = TRUE
projectile_type = /obj/projectile/bullet/a545_39
+ bullet_per_box = 80
/obj/item/ammo_casing/a545_39/recycled
name = "recycled 5.45x39mm bullet casing"
@@ -67,6 +72,7 @@
icon_state = "rifle-brass"
caliber = "7.62x40mm"
projectile_type = /obj/projectile/bullet/a762_40
+ bullet_per_box = 80
// .300 Blackout (Polymer Survivor Rifle)
@@ -76,6 +82,7 @@
icon_state = "rifle-steel"
caliber = ".300 BLK"
projectile_type = /obj/projectile/bullet/aac_300blk
+ bullet_per_box = 20
/obj/item/ammo_casing/aac_300blk/recycled
name = "recycled .300 BLK bullet casing"
@@ -91,6 +98,7 @@
icon_state = "rifle-brass"
caliber = ".308"
projectile_type = /obj/projectile/bullet/a308
+ bullet_per_box = 20
/obj/item/ammo_casing/caseless/c299
name = ".229 Eoehoma caseless bullet casing"
@@ -98,3 +106,4 @@
icon_state = "caseless"
caliber = ".299 caseless"
projectile_type = /obj/projectile/bullet/c299
+ bullet_per_box = 100
diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm
index b297ee30e776..9f6a8c169ecd 100644
--- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm
+++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm
@@ -8,6 +8,7 @@
caliber = "12ga"
custom_materials = list(/datum/material/iron=4000)
projectile_type = /obj/projectile/bullet/slug
+ bullet_per_box = 25
bounce_sfx_override = 'sound/weapons/gun/general/bulletcasing_shotgun_bounce.ogg'
@@ -110,8 +111,8 @@
desc = "A shotgun shell which fires a spread of incendiary pellets."
icon_state = "dragonsbreath"
projectile_type = /obj/projectile/bullet/incendiary/shotgun/dragonsbreath
- pellets = 4
- variance = 35
+ pellets = 8
+ variance = 45
/obj/item/ammo_casing/shotgun/meteorslug
name = "meteorslug shell"
@@ -127,20 +128,20 @@
/obj/item/ammo_casing/shotgun/ion
name = "ion shell"
- desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \
- The unique properties of the crystal split the pulse into a spread of individually weaker bolts."
+ desc = "An advanced shotgun shell which uses a micro laser to focus the effects of an EMP reaction to produce an effect similar to a standard ion rifle. \
+ The more uncontrolled nature of the reaction causes the pulse to spread into multiple individually weaker bolts."
icon_state = "ion"
projectile_type = /obj/projectile/ion/weak
- pellets = 4
- variance = 35
+ pellets = 8
+ variance = 25
/obj/item/ammo_casing/shotgun/laserscatter
name = "scatter laser shell"
desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a scatter laser weapon in a ballistic package."
icon_state = "laser"
projectile_type = /obj/projectile/beam/weak
- pellets = 4 //WS edit: makes scatter lasers based again
- variance = 35
+ pellets = 8
+ variance = 25
/obj/item/ammo_casing/shotgun/pulseslug
name = "pulse slug"
diff --git a/code/modules/projectiles/ammunition/ballistic/smg.dm b/code/modules/projectiles/ammunition/ballistic/smg.dm
index d947736d5f25..74bb35b1ec2e 100644
--- a/code/modules/projectiles/ammunition/ballistic/smg.dm
+++ b/code/modules/projectiles/ammunition/ballistic/smg.dm
@@ -6,6 +6,7 @@
icon_state = "rifle-brass"
caliber = "4.6x30mm"
projectile_type = /obj/projectile/bullet/c46x30mm
+ bullet_per_box = 50
/obj/item/ammo_casing/c46x30mm/ap
name = "4.6x30mm armor-piercing bullet casing"
@@ -18,6 +19,7 @@
desc = "A 4.6x30mm incendiary bullet casing."
bullet_skin = "incen"
projectile_type = /obj/projectile/bullet/incendiary/c46x30mm
+ bullet_per_box = 50
// 4.73x33mm caseless (Solar)
@@ -27,6 +29,7 @@
icon_state = "caseless"
caliber = "4.73x33mm caseless"
projectile_type = /obj/projectile/bullet/c47x33mm
+ bullet_per_box = 50
// 5.56mm HITP caseless (Pistole C)
diff --git a/code/modules/projectiles/ammunition/ballistic/sniper.dm b/code/modules/projectiles/ammunition/ballistic/sniper.dm
index af7369204e6d..e4b668c2228f 100644
--- a/code/modules/projectiles/ammunition/ballistic/sniper.dm
+++ b/code/modules/projectiles/ammunition/ballistic/sniper.dm
@@ -6,6 +6,7 @@
icon_state = "big-steel"
caliber = ".50 BMG"
projectile_type = /obj/projectile/bullet/p50
+ bullet_per_box = 20
/obj/item/ammo_casing/p50/soporific
name = ".50 BMG soporific bullet casing"
diff --git a/code/modules/projectiles/ammunition/caseless/_caseless.dm b/code/modules/projectiles/ammunition/caseless/_caseless.dm
index 2fe0ecf808eb..9e9dafb8d806 100644
--- a/code/modules/projectiles/ammunition/caseless/_caseless.dm
+++ b/code/modules/projectiles/ammunition/caseless/_caseless.dm
@@ -3,8 +3,10 @@
firing_effect_type = null
heavy_metal = FALSE
-/obj/item/ammo_casing/caseless/on_eject()
- qdel(src)
+/obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from)
+ . = ..()
+ if(.)
+ qdel(src)
// Overridden; caseless ammo does not distinguish between "live" and "empty"/"spent" icon states (because it has no casing).
/obj/item/ammo_casing/caseless/update_icon_state()
diff --git a/code/modules/projectiles/ammunition/caseless/foam.dm b/code/modules/projectiles/ammunition/caseless/foam.dm
index 3c71d31eb5ed..0051680fd1e8 100644
--- a/code/modules/projectiles/ammunition/caseless/foam.dm
+++ b/code/modules/projectiles/ammunition/caseless/foam.dm
@@ -9,6 +9,7 @@
custom_materials = list(/datum/material/iron = 11.25)
harmful = FALSE
var/modified = FALSE
+ bullet_per_box = 40
/obj/item/ammo_casing/caseless/foam_dart/update_icon_state()
. = ..()
diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm
index 6320cb24b0c6..d0334e8d8acc 100644
--- a/code/modules/projectiles/ammunition/energy/laser.dm
+++ b/code/modules/projectiles/ammunition/energy/laser.dm
@@ -31,7 +31,7 @@
projectile_type = /obj/projectile/beam/laser/weak/negative_ap
e_cost = 799 //12 shots with a normal power cell, 25 with an upgraded
select_name = "kill"
- delay = 0.1 SECONDS
+ delay = 0.13 SECONDS
/obj/item/ammo_casing/energy/lasergun/old
projectile_type = /obj/projectile/beam/laser
diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm
index 917e1c8c8189..1f74196eb83b 100644
--- a/code/modules/projectiles/ammunition/energy/stun.dm
+++ b/code/modules/projectiles/ammunition/energy/stun.dm
@@ -46,4 +46,4 @@
/obj/item/ammo_casing/energy/disabler/smg
projectile_type = /obj/projectile/beam/disabler/weak/negative_ap
e_cost = 330
- delay = 0.1 SECONDS
+ delay = 0.13 SECONDS
diff --git a/code/modules/projectiles/ammunition/special/magic.dm b/code/modules/projectiles/ammunition/special/magic.dm
index e38df896bed1..046ae7dbc078 100644
--- a/code/modules/projectiles/ammunition/special/magic.dm
+++ b/code/modules/projectiles/ammunition/special/magic.dm
@@ -4,68 +4,3 @@
projectile_type = /obj/projectile/magic
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/magic
heavy_metal = FALSE
-
-/obj/item/ammo_casing/magic/change
- projectile_type = /obj/projectile/magic/change
-
-/obj/item/ammo_casing/magic/animate
- projectile_type = /obj/projectile/magic/animate
-
-/obj/item/ammo_casing/magic/heal
- projectile_type = /obj/projectile/magic/resurrection
- harmful = FALSE
-
-/obj/item/ammo_casing/magic/death
- projectile_type = /obj/projectile/magic/death
-
-/obj/item/ammo_casing/magic/teleport
- projectile_type = /obj/projectile/magic/teleport
- harmful = FALSE
-
-/obj/item/ammo_casing/magic/safety
- projectile_type = /obj/projectile/magic/safety
- harmful = FALSE
-
-/obj/item/ammo_casing/magic/door
- projectile_type = /obj/projectile/magic/door
- harmful = FALSE
-
-/obj/item/ammo_casing/magic/fireball
- projectile_type = /obj/projectile/magic/aoe/fireball
-
-/obj/item/ammo_casing/magic/chaos
- projectile_type = /obj/projectile/magic
-
-/obj/item/ammo_casing/magic/spellblade
- projectile_type = /obj/projectile/magic/spellblade
-
-/obj/item/ammo_casing/magic/arcane_barrage
- projectile_type = /obj/projectile/magic/arcane_barrage
-
-/obj/item/ammo_casing/magic/honk
- projectile_type = /obj/projectile/bullet/honker
-
-/obj/item/ammo_casing/magic/locker
- projectile_type = /obj/projectile/magic/locker
-
-/obj/item/ammo_casing/magic/flying
- projectile_type = /obj/projectile/magic/flying
-
-/obj/item/ammo_casing/magic/bounty
- projectile_type = /obj/projectile/magic/bounty
-
-/obj/item/ammo_casing/magic/antimagic
- projectile_type = /obj/projectile/magic/antimagic
-
-/obj/item/ammo_casing/magic/sapping
- projectile_type = /obj/projectile/magic/sapping
-
-/obj/item/ammo_casing/magic/necropotence
- projectile_type = /obj/projectile/magic/necropotence
-
-/obj/item/ammo_casing/magic/wipe
- projectile_type = /obj/projectile/magic/wipe
-
-/obj/item/ammo_casing/magic/nothing
- projectile_type = /obj/projectile/magic/nothing
- harmful = FALSE
diff --git a/code/modules/projectiles/boxes_magazines/_box_magazine.dm b/code/modules/projectiles/boxes_magazines/_box_magazine.dm
index 87f47b99d36d..3b1bdbc6eb1c 100644
--- a/code/modules/projectiles/boxes_magazines/_box_magazine.dm
+++ b/code/modules/projectiles/boxes_magazines/_box_magazine.dm
@@ -51,7 +51,7 @@
if(!start_empty)
for(var/i = 1, i <= max_ammo, i++)
stored_ammo += new ammo_type(src)
- update_appearance()
+ update_ammo_count()
///gets a round from the magazine, if keep is TRUE the round will stay in the gun
/obj/item/ammo_box/proc/get_round(keep = FALSE)
@@ -98,7 +98,7 @@
if(istype(attacking_obj, /obj/item/ammo_box))
var/obj/item/ammo_box/attacking_box = attacking_obj
for(var/obj/item/ammo_casing/casing_to_insert in attacking_box.stored_ammo)
- if(!((instant_load && attacking_box.instant_load) || (stored_ammo.len >= max_ammo) || do_after_mob(user, list(attacking_box), 1 SECONDS)))
+ if(!((instant_load && attacking_box.instant_load) || (stored_ammo.len >= max_ammo) || do_after(user, 1 SECONDS, attacking_box)))
break
var/did_load = give_round(casing_to_insert, replace_spent)
if(!did_load)
@@ -107,8 +107,8 @@
if(!silent)
playsound(get_turf(attacking_box), 'sound/weapons/gun/general/mag_bullet_insert.ogg', 60, TRUE) //src is nullspaced, which means internal magazines won't properly play sound, thus we use attacking_box
num_loaded++
- attacking_obj.update_appearance()
- update_appearance()
+ attacking_box.update_ammo_count()
+ update_ammo_count()
if(istype(attacking_obj, /obj/item/ammo_casing))
var/obj/item/ammo_casing/casing_to_insert = attacking_obj
@@ -117,7 +117,7 @@
if(!silent)
playsound(casing_to_insert, 'sound/weapons/gun/general/mag_bullet_insert.ogg', 60, TRUE)
num_loaded++
- update_appearance()
+ update_ammo_count()
if(num_loaded)
diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
index fa7b0a133bae..955856704ac6 100644
--- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
+++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm
@@ -13,6 +13,9 @@
w_class = WEIGHT_CLASS_TINY
instant_load = TRUE
+/obj/item/ammo_box/a357/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/a357/match
name = "speed loader (.357 match)"
desc = "A 7-round speed loader for quickly reloading .357 revolvers. These match rounds travel faster, perform better against armor, and can ricochet off targets."
@@ -23,6 +26,28 @@
desc = "A 7-round speed loader for quickly reloading .357 revolvers. These hollow point rounds do incredible damage against soft targets, but are nearly ineffective against armored ones."
ammo_type = /obj/item/ammo_casing/a357/hp
+/obj/item/ammo_box/a357_box
+ name = "ammo box (.357)"
+ desc = "A box of standard .357 ammo."
+ icon_state = "357box"
+ ammo_type = /obj/item/ammo_casing/a357
+ max_ammo = 50
+
+/obj/item/ammo_box/a357_box/match
+ name = "ammo box (.357)"
+ desc = "A box of match .357 ammo."
+ icon_state = "357box-match"
+ ammo_type = /obj/item/ammo_casing/a357/match
+ max_ammo = 50
+
+/obj/item/ammo_box/a357_box/hp
+ name = "ammo box (.357)"
+ desc = "A box of hollow point .357 ammo."
+ icon_state = "357box-hp"
+ ammo_type = /obj/item/ammo_casing/a357/hp
+ max_ammo = 50
+
+
// .45-70 Ammo Holders (Hunting Revolver)
/obj/item/ammo_box/a4570
@@ -97,6 +122,9 @@
desc = "A 6-round speed loader for quickly reloading .38 special revolvers. These iceblox bullets contain a cryogenic payload that chills targets."
ammo_type = /obj/item/ammo_casing/c38/iceblox
+/obj/item/ammo_box/c38/empty
+ start_empty = TRUE
+
// 8x58mm Stripper Clip (SSG-669C)
/obj/item/ammo_box/a858
@@ -134,6 +162,8 @@
w_class = WEIGHT_CLASS_TINY
instant_load = TRUE
+/obj/item/ammo_box/a300/empty
+ start_empty = TRUE
// .300 Blackout Stripper Clip (Polymer Survivor Rifle)
/obj/item/ammo_box/aac_300blk_stripper
@@ -389,19 +419,22 @@
ammo_type = /obj/item/ammo_casing/c22lr
max_ammo = 75
-/obj/item/ammo_box/c45_speedloader
- name = "speed loader (.45)"
+/obj/item/ammo_box/a44roum_speedloader
+ name = "speed loader (.44)"
desc = "Designed to quickly reload revolvers."
icon_state = "speedloader_38-6"
base_icon_state = "speedloader_38"
- ammo_type = /obj/item/ammo_casing/c45
- caliber = ".45"
+ ammo_type = /obj/item/ammo_casing/a44roum
+ caliber = ".44 Roumain"
max_ammo = 6
multiple_sprites = AMMO_BOX_PER_BULLET
custom_materials = list(/datum/material/iron = 15000)
w_class = WEIGHT_CLASS_TINY
instant_load = TRUE
+/obj/item/ammo_box/a44roum_speedloader/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/c46x30mm_box
name = "ammo box (4.6x30mm)"
desc = "A box of standard 4.6x30mm ammo."
@@ -443,3 +476,31 @@
icon_state = "8x50mmbox-hp"
ammo_type = /obj/item/ammo_casing/a8_50rhp
max_ammo = 20
+
+/obj/item/ammo_box/a300_box
+ name = "ammo box (.300 Magnum)"
+ desc = "A box of standard .300 Magnum ammo."
+ icon_state = "300box"
+ ammo_type = /obj/item/ammo_casing/a300
+ max_ammo = 20
+
+/obj/item/ammo_box/a44roum
+ name = "ammo box (.44 roumain)"
+ desc = "A box of standard .44 roumain ammo."
+ icon_state = "a44roum"
+ ammo_type = /obj/item/ammo_casing/a44roum
+ max_ammo = 50
+
+/obj/item/ammo_box/a44roum/rubber
+ name = "ammo box (.44 roumain rubber)"
+ desc = "A box of .44 roumain rubbershot ammo, designed to disable targets without causing serious damage."
+ icon_state = "a44roum-rubber"
+ ammo_type = /obj/item/ammo_casing/a44roum/rubber
+ max_ammo = 50
+
+/obj/item/ammo_box/a44roum/hp
+ name = "ammo box (.44 roumain hollow point)"
+ desc = "A box of .44 roumain hollow point ammo, designed to cause massive damage at the cost of armor penetration."
+ icon_state = "a44roum-hp"
+ ammo_type = /obj/item/ammo_casing/a44roum/hp
+ max_ammo = 50
diff --git a/code/modules/projectiles/boxes_magazines/external/gauss.dm b/code/modules/projectiles/boxes_magazines/external/gauss.dm
index fa3797707ce6..d2edfc4aac94 100644
--- a/code/modules/projectiles/boxes_magazines/external/gauss.dm
+++ b/code/modules/projectiles/boxes_magazines/external/gauss.dm
@@ -16,6 +16,9 @@
max_ammo = 10
multiple_sprites = AMMO_BOX_FULL_EMPTY
+/obj/item/ammo_box/magazine/modelh/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/magazine/gar
name = "GAR tube magazine (ferromagnetic lances)"
desc = "A 32-round magazined for the GAR assault rifle. Ferromagnetic lances do good damage with significant armor penetration."
diff --git a/code/modules/projectiles/boxes_magazines/external/pistol.dm b/code/modules/projectiles/boxes_magazines/external/pistol.dm
index 66b9238a5c90..8a1792485715 100644
--- a/code/modules/projectiles/boxes_magazines/external/pistol.dm
+++ b/code/modules/projectiles/boxes_magazines/external/pistol.dm
@@ -8,6 +8,9 @@
max_ammo = 8
multiple_sprites = AMMO_BOX_FULL_EMPTY
+/obj/item/ammo_box/magazine/m10mm/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/magazine/m10mm/inc
name = "pistol magazine (10mm incendiary)"
desc = "An 8-round single-stack magazine for the stechkin pistol. These incendiary rounds deal mediocre damage, but leave flaming trails which set targets ablaze."
@@ -37,6 +40,9 @@
caliber = ".45"
max_ammo = 8
+/obj/item/ammo_box/magazine/m45/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/magazine/m45/inc
name = "pistol magazine (.45 incendiary)"
desc = "An 8-round single-stack magazine for the Candor pistol. These incendiary rounds deal mediocre damage, but leave flaming trails which set targets ablaze."
@@ -71,6 +77,9 @@
max_ammo = 10
multiple_sprites = AMMO_BOX_PER_BULLET
+/obj/item/ammo_box/magazine/co9mm/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/magazine/pistol556mm
name = "Pistole C magazine (5.56mm HITP caseless)"
desc = "A 12-round, double-stack magazine for the Pistole C pistol. These rounds do okay damage with average performance against armor."
@@ -93,6 +102,7 @@
else
icon_state = "[base_icon_state]-0"
+
/obj/item/ammo_box/magazine/co9mm/inc
name = "pistol magazine (9mm incendiary)"
desc = "A 10-round double-stack magazine for standard-issue 9mm pistols. These incendiary rounds deal pitiful damage, but leave flaming trails which set targets ablaze."
diff --git a/code/modules/projectiles/boxes_magazines/external/rifle.dm b/code/modules/projectiles/boxes_magazines/external/rifle.dm
index 548350f20415..9224c0db84af 100644
--- a/code/modules/projectiles/boxes_magazines/external/rifle.dm
+++ b/code/modules/projectiles/boxes_magazines/external/rifle.dm
@@ -55,6 +55,9 @@
max_ammo = 20
multiple_sprites = AMMO_BOX_FULL_EMPTY
+/obj/item/ammo_box/magazine/skm_762_40/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/magazine/skm_762_40/extended
name = "extended assault rifle magazine (7.62x40mm CLIP)"
desc = "A very curved, 40-round magazine for the 7.62x40mm CLIP variants of the SKM assault rifle family. These rounds do good damage with good armor penetration."
@@ -102,6 +105,8 @@
max_ammo = 30
multiple_sprites = AMMO_BOX_FULL_EMPTY
+/obj/item/ammo_box/magazine/p16/empty
+ start_empty = TRUE
/obj/item/ammo_box/magazine/swiss
name = "\improper Swiss Cheese Magazine (5.56x45mm)"
@@ -133,3 +138,6 @@
max_ammo = 5
multiple_sprites = AMMO_BOX_PER_BULLET
w_class = WEIGHT_CLASS_TINY
+
+/obj/item/ammo_box/magazine/illestren_a850r/empty
+ start_empty = TRUE
diff --git a/code/modules/projectiles/boxes_magazines/external/smg.dm b/code/modules/projectiles/boxes_magazines/external/smg.dm
index 61b9eb78512a..4c464c0433d0 100644
--- a/code/modules/projectiles/boxes_magazines/external/smg.dm
+++ b/code/modules/projectiles/boxes_magazines/external/smg.dm
@@ -11,6 +11,9 @@
. = ..()
icon_state = "[base_icon_state]-[round(ammo_count(), 6)]"
+/obj/item/ammo_box/magazine/wt550m9/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/magazine/wt550m9/ap
name = "wt550 magazine (4.6x30mm AP)"
desc = "A compact, 30-round top-loading magazine for the WT-550 Automatic Rifle. These armor-piercing rounds are great at piercing protective equipment, but lose some stopping power."
@@ -97,6 +100,9 @@
. = ..()
icon_state = "c20r45-[round(ammo_count(),2)]"
+/obj/item/ammo_box/magazine/smgm45/empty
+ start_empty = TRUE
+
/obj/item/ammo_box/magazine/c45_firestorm_mag
name = "stick magazine (.45)"
desc = "A 28-round stick magazine for the toploading Firestorm submachine gun. These rounds do moderate damage, but struggle against armor."
diff --git a/code/modules/projectiles/boxes_magazines/generic_ammo_box.dm b/code/modules/projectiles/boxes_magazines/generic_ammo_box.dm
new file mode 100644
index 000000000000..2c88824623e2
--- /dev/null
+++ b/code/modules/projectiles/boxes_magazines/generic_ammo_box.dm
@@ -0,0 +1,53 @@
+/obj/item/ammo_box/generic
+ name = "generic ammo box"
+ desc = "A generic, unbranded box of ammo. It doesn't have great capacity, but it can hold a variety of different calibers."
+ max_ammo = 20
+ start_empty = TRUE
+ icon_state = "generic-ammo"
+ /// Does the box currently have an ammo type set?
+ var/ammo_set = FALSE
+ /// Name of the currently set ammo type
+ var/ammo_name
+
+/obj/item/ammo_box/generic/update_ammo_count()
+ . = ..()
+ if(LAZYLEN(stored_ammo) == 0)
+ ammo_set = FALSE
+ ammo_type = /obj/item/ammo_casing
+
+/obj/item/ammo_box/generic/proc/update_max_ammo(obj/item/ammo_casing/ammo)
+ if(ammo.bullet_per_box)
+ max_ammo = round(ammo.bullet_per_box)
+ else
+ max_ammo = 10
+
+ return
+
+/obj/item/ammo_box/generic/attackby(obj/item/attacking_obj, mob/user, params, silent, replace_spent)
+ . = ..()
+
+ if(!ammo_set && istype(attacking_obj, /obj/item/ammo_casing))
+ var/obj/item/ammo_casing/ammo_load = attacking_obj.type
+ ammo_type = ammo_load
+ ammo_set = TRUE
+ ammo_name = attacking_obj.name
+ update_max_ammo(attacking_obj)
+ to_chat(user, span_notice("You set the box to hold [attacking_obj]!"))
+
+ if(istype(attacking_obj, /obj/item/pen))
+ if(!user.is_literate())
+ to_chat(user, span_notice("You scribble illegibly on the cover of [src]!"))
+ return
+ var/inputvalue = stripped_input(user, "What would you like to label the box?", "Box Labelling", "", MAX_NAME_LEN)
+
+ if(!inputvalue)
+ return
+
+ if(user.canUseTopic(src, BE_CLOSE))
+ name = "[initial(src.name)][(inputvalue ? " - '[inputvalue]'" : null)]"
+
+/obj/item/ammo_box/generic/examine(mob/user)
+ . = ..()
+ . += span_notice("[ammo_set ? "It's set to hold [ammo_name]\s. The box can hold up to [max_ammo] rounds." : "It doesn't have an ammo type set. Use a bullet on the box to set it."]")
+ . += span_notice("You can use a pen on it to rename the box.")
+
diff --git a/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm b/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm
index 160e1bd5066d..658eef2d781c 100644
--- a/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm
+++ b/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm
@@ -66,7 +66,7 @@
var/list/ammo_list_no_empty = ammo_list(FALSE)
listclearnulls(ammo_list_no_empty)
for(var/obj/item/ammo_casing/casing_to_insert in attacking_box.stored_ammo)
- if(!((instant_load && attacking_box.instant_load) || (ammo_list_no_empty.len >= max_ammo) || do_after_mob(user, list(attacking_box), 1 SECONDS))) //stupid work around for revolvers
+ if(!((instant_load && attacking_box.instant_load) || (ammo_list_no_empty.len >= max_ammo) || do_after(user, 1 SECONDS, attacking_box))) //stupid work around for revolvers
break
var/did_load = give_round(casing_to_insert, replace_spent)
if(!did_load)
diff --git a/code/modules/projectiles/boxes_magazines/internal/misc.dm b/code/modules/projectiles/boxes_magazines/internal/misc.dm
index 1d4316560e92..55b749ac3333 100644
--- a/code/modules/projectiles/boxes_magazines/internal/misc.dm
+++ b/code/modules/projectiles/boxes_magazines/internal/misc.dm
@@ -1,9 +1,3 @@
-/obj/item/ammo_box/magazine/internal/hook
- name = "hook internal tube"
- ammo_type = /obj/item/ammo_casing/magic/hook
- caliber = "hook"
- max_ammo = 1
-
/obj/item/ammo_box/magazine/internal/bow
name = "bowstring"
ammo_type = /obj/item/ammo_casing/caseless/arrow
diff --git a/code/modules/projectiles/boxes_magazines/internal/revolver.dm b/code/modules/projectiles/boxes_magazines/internal/revolver.dm
index 43748f7afe7b..1198970c5146 100644
--- a/code/modules/projectiles/boxes_magazines/internal/revolver.dm
+++ b/code/modules/projectiles/boxes_magazines/internal/revolver.dm
@@ -28,15 +28,18 @@
/obj/item/ammo_box/magazine/internal/cylinder/pepperbox
name = "pepperbox revolver cylinder"
+ ammo_type = /obj/item/ammo_casing/a357
+ caliber = ".357"
max_ammo = 5
+ instant_load = FALSE
-/obj/item/ammo_box/magazine/internal/cylinder/rev45
+/obj/item/ammo_box/magazine/internal/cylinder/rev44
name = "cattleman revolver cylinder"
- ammo_type = /obj/item/ammo_casing/c45
- caliber = ".45"
+ ammo_type = /obj/item/ammo_casing/a44roum
+ caliber = ".44 Roumain"
max_ammo = 6
instant_load = FALSE
-/obj/item/ammo_box/magazine/internal/cylinder/rev45/montagne
+/obj/item/ammo_box/magazine/internal/cylinder/rev44/montagne
name = "montagne revolver cylinder"
instant_load = TRUE
diff --git a/code/modules/projectiles/boxes_magazines/internal/rifle.dm b/code/modules/projectiles/boxes_magazines/internal/rifle.dm
index 921ff98293a1..4f2f8c537958 100644
--- a/code/modules/projectiles/boxes_magazines/internal/rifle.dm
+++ b/code/modules/projectiles/boxes_magazines/internal/rifle.dm
@@ -6,13 +6,6 @@
max_ammo = 5
instant_load = TRUE
-/obj/item/ammo_box/magazine/internal/boltaction/enchanted
- max_ammo = 1
- ammo_type = /obj/item/ammo_casing/a8_50r
-
-/obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage
- ammo_type = /obj/item/ammo_casing/magic/arcane_barrage
-
/obj/item/ammo_box/magazine/internal/boltaction/solgov
name = "SSG-669C internal magazine"
ammo_type = /obj/item/ammo_casing/caseless/a858
diff --git a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm
index 38c99aec9372..29717fd9408b 100644
--- a/code/modules/projectiles/boxes_magazines/internal/shotgun.dm
+++ b/code/modules/projectiles/boxes_magazines/internal/shotgun.dm
@@ -27,6 +27,9 @@
max_ammo = 2
instant_load = TRUE
+/obj/item/ammo_box/magazine/internal/shot/dual/lethal
+ ammo_type = /obj/item/ammo_casing/shotgun/buckshot
+
/obj/item/ammo_box/magazine/internal/shot/improvised
name = "improvised shotgun internal magazine"
ammo_type = /obj/item/ammo_casing/shotgun/improvised
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index e9354e68d9d4..707f4805afe3 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -1,28 +1,11 @@
-
-#define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.6
-#define FIRING_PIN_REMOVAL_DELAY 50
-
-#define MANUFACTURER_NONE null
-#define MANUFACTURER_SHARPLITE "the Sharplite Defense logo"
-#define MANUFACTURER_SHARPLITE_NEW "the Nanotrasen-Sharplite logo"
-#define MANUFACTURER_HUNTERSPRIDE "the Hunter's Pride Arms and Ammunition logo"
-#define MANUFACTURER_SOLARARMORIES "the Solarbundswaffenkammer emblem"
-#define MANUFACTURER_SCARBOROUGH "the Scarborough Arms logo"
-#define MANUFACTURER_EOEHOMA "the Eoehoma Firearms emblem"
-#define MANUFACTURER_NANOTRASEN_OLD "an outdated Nanotrasen logo"
-#define MANUFACTURER_NANOTRASEN "the Nanotrasen logo"
-#define MANUFACTURER_BRAZIL "a green flag with a blue circle and a yellow diamond around it"
-#define MANUFACTURER_INTEQ "an orange crest with the letters 'IRMG'"
-#define MANUFACTURER_MINUTEMAN "the Lanchester City Firearms Plant logo"
-#define MANUFACTURER_DONKCO "the Donk! Co. logo"
-#define MANUFACTURER_PGF "the Etherbor Industries emblem"
-#define MANUFACTURER_IMPORT "Lanchester Import Co."
/obj/item/gun
name = "gun"
desc = "It's a gun. It's pretty terrible, though."
icon = 'icons/obj/guns/projectile.dmi'
- icon_state = "detective"
+ icon_state = "flatgun"
item_state = "gun"
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
custom_materials = list(/datum/material/iron=2000)
@@ -35,73 +18,185 @@
attack_verb = list("struck", "hit", "bashed")
pickup_sound = 'sound/items/handling/gun_pickup.ogg'
drop_sound = 'sound/items/handling/gun_drop.ogg'
+ //trigger guard on the weapon, hulks can't fire them with their big meaty fingers
+ trigger_guard = TRIGGER_GUARD_NORMAL
- /// The manufacturer of this weapon. For flavor mostly. If none, this will not show.
+ ///The manufacturer of this weapon. For flavor mostly. If none, this will not show.
var/manufacturer = MANUFACTURER_NONE
+/*
+ * Muzzle
+*/
+ ///Effect for the muzzle flash of the gun.
+ var/obj/effect/muzzle_flash/muzzle_flash
+ ///Icon state of the muzzle flash effect.
+ var/muzzleflash_iconstate
+ ///Brightness of the muzzle flash effect.
+ var/muzzle_flash_lum = 3
+ ///Color of the muzzle flash effect.
+ var/muzzle_flash_color = COLOR_VERY_SOFT_YELLOW
+
+/*
+ * Firing
+*/
var/fire_sound = 'sound/weapons/gun/pistol/shot.ogg'
var/vary_fire_sound = TRUE
var/fire_sound_volume = 50
var/dry_fire_sound = 'sound/weapons/gun/general/dry_fire.ogg'
- var/dry_fire_text = "click" //change this on non-gun things
- var/suppressed = null //whether or not a message is displayed when fired
- var/can_suppress = FALSE
+ var/dry_fire_text = "click"
+
+/*
+ * Reloading
+*/
+ var/obj/item/ammo_casing/chambered = null
+ ///Whether the gun can be tacloaded by slapping a fresh magazine directly on it
+ var/tac_reloads = TRUE
+ ///If we have the 'snowflake mechanic,' how long should it take to reload?
+ var/tactical_reload_delay = 1 SECONDS
+
+//BALLISTIC
+ ///Compatible magazines with the gun
+ var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
+ ///Whether the gun alarms when empty or not.
+ var/empty_alarm = FALSE
+ ///Do we eject the magazine upon runing out of ammo?
+ var/empty_autoeject = FALSE
+ ///Whether the gun supports multiple special mag types
+ var/special_mags = FALSE
+
+ ///Actual magazine currently contained within the gun
+ var/obj/item/ammo_box/magazine/magazine
+ ///whether the gun ejects the chambered casing
+ var/casing_ejector = TRUE
+ ///Whether the gun has an internal magazine or a detatchable one. Overridden by BOLT_TYPE_NO_BOLT.
+ var/internal_magazine = FALSE
+
+ ///Phrasing of the magazine in examine and notification messages; ex: magazine, box, etx
+ var/magazine_wording = "magazine"
+ ///Phrasing of the cartridge in examine and notification messages; ex: bullet, shell, dart, etc.
+ var/cartridge_wording = "bullet"
+
+ ///sound when inserting magazine
+ var/load_sound = 'sound/weapons/gun/general/magazine_insert_full.ogg'
+ ///sound when inserting an empty magazine
+ var/load_empty_sound = 'sound/weapons/gun/general/magazine_insert_empty.ogg'
+ ///volume of loading sound
+ var/load_sound_volume = 40
+ ///whether loading sound should vary
+ var/load_sound_vary = TRUE
+ ///Sound of ejecting a magazine
+ var/eject_sound = 'sound/weapons/gun/general/magazine_remove_full.ogg'
+ ///sound of ejecting an empty magazine
+ var/eject_empty_sound = 'sound/weapons/gun/general/magazine_remove_empty.ogg'
+ ///volume of ejecting a magazine
+ var/eject_sound_volume = 40
+ ///whether eject sound should vary
+ var/eject_sound_vary = TRUE
+
+//ENERGY
+ //What type of power cell this uses
+ var/obj/item/stock_parts/cell/gun/cell
+ var/cell_type = /obj/item/stock_parts/cell/gun
+ //Can it be charged in a recharger?
+ var/can_charge = TRUE
+ var/selfcharge = FALSE
+ var/charge_tick = 0
+ var/charge_delay = 4
+ //whether the gun's cell drains the cyborg user's cell to recharge
+ var/use_cyborg_cell = FALSE
+ ///Used for large and small cells
+ var/mag_size = MAG_SIZE_MEDIUM
+ //Time it takes to unscrew the cell
+ var/unscrewing_time = 2 SECONDS
+
+ ///if the gun's cell cannot be replaced
+ var/internal_cell = FALSE
+
+ var/list/ammo_type = list(/obj/item/ammo_casing/energy)
+ //The state of the select fire switch. Determines from the ammo_type list what kind of shot is fired next.
+ var/select = 1
+
+/*
+ * Operation
+*/
+ //whether or not a message is displayed when fired
+ var/suppressed = FALSE
var/suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
var/suppressed_volume = 60
- var/can_unsuppress = TRUE
- var/clumsy_check = TRUE
- var/obj/item/ammo_casing/chambered = null
- trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers
- var/sawn_desc = null //description change if weapon is sawn-off
- var/sawn_off = FALSE
- var/burst_size = 1 //how large a burst is
- var/fire_delay = 0 //rate of fire for burst firing and semi auto
- var/firing_burst = 0 //Prevent the weapon from firing again while already firing
- var/semicd = 0 //cooldown handler
- var/weapon_weight = WEAPON_LIGHT
- var/dual_wield_spread = 24 //additional spread when dual wielding
- var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once.
-
- var/projectile_damage_multiplier = 1 //Alters projectile damage multiplicatively based on this value. Use it for "better" or "worse" weapons that use the same ammo.
-
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
-
- var/list/attachment_options = list() //This.. works for now.. gun refactor soon
- var/obj/item/firing_pin/pin = /obj/item/firing_pin //standard firing pin for most guns
-
- var/can_flashlight = FALSE //if a flashlight can be added or removed if it already has one.
- var/obj/item/flashlight/seclite/gun_light
- var/datum/action/item_action/toggle_gunlight/alight
- var/gunlight_state = "flight"
- var/can_bayonet = FALSE //if a bayonet can be added or removed if it already has one.
- var/obj/item/kitchen/knife/bayonet
- var/knife_x_offset = 0
- var/knife_y_offset = 0
-
- var/ammo_x_offset = 0 //used for positioning ammo count overlay on sprite
- var/ammo_y_offset = 0
- var/flight_x_offset = 0
- var/flight_y_offset = 0
+ //true if the gun is wielded via twohanded component, shouldnt affect anything else
+ var/wielded = FALSE
+ //true if the gun is wielded after delay, should affects accuracy
+ var/wielded_fully = FALSE
+ ///Slowdown for wielding
+ var/wield_slowdown = 0.1
+ ///How long between wielding and firing in tenths of seconds
+ var/wield_delay = 0.4 SECONDS
+ ///Storing value for above
+ var/wield_time = 0
- //Zooming
- var/zoomable = FALSE //whether the gun generates a Zoom action on creation
- var/zoomed = FALSE //Zoom toggle
- var/zoom_amt = 3 //Distance in TURFs to move the user's screen forward (the "zoom" effect)
- var/zoom_out_amt = 0
- var/datum/action/toggle_scope_zoom/azoom
+// BALLISTIC
+ ///Whether the gun has to be racked each shot or not.
+ var/semi_auto = TRUE
+ ///The bolt type of the gun, affects quite a bit of functionality, see gun.dm in defines for bolt types: BOLT_TYPE_STANDARD; BOLT_TYPE_LOCKING; BOLT_TYPE_OPEN; BOLT_TYPE_NO_BOLT
+ var/bolt_type = BOLT_TYPE_STANDARD
+ ///Used for locking bolt and open bolt guns. Set a bit differently for the two but prevents firing when true for both.
+ var/bolt_locked = FALSE
+ ///Phrasing of the bolt in examine and notification messages; ex: bolt, slide, etc.
+ var/bolt_wording = "bolt"
+ ///length between individual racks
+ var/rack_delay = 5
+ ///time of the most recent rack, used for cooldown purposes
+ var/recent_rack = 0
+
+ ///Whether the gun can be sawn off by sawing tools
+ var/can_be_sawn_off = FALSE
+ //description change if weapon is sawn-off
+ var/sawn_desc = null
+ var/sawn_off = FALSE
+ ///sound of racking
+ var/rack_sound = 'sound/weapons/gun/general/bolt_rack.ogg'
+ ///volume of racking
+ var/rack_sound_volume = 60
+ ///whether racking sound should vary
+ var/rack_sound_vary = TRUE
+ ///sound of when the bolt is locked back manually
+ var/lock_back_sound = 'sound/weapons/gun/general/slide_lock_1.ogg'
+ ///volume of lock back
+ var/lock_back_sound_volume = 60
+ ///whether lock back varies
+ var/lock_back_sound_vary = TRUE
+
+ ///sound of dropping the bolt or releasing a slide
+ var/bolt_drop_sound = 'sound/weapons/gun/general/bolt_drop.ogg'
+ ///volume of bolt drop/slide release
+ var/bolt_drop_sound_volume = 60
+ ///empty alarm sound (if enabled)
+ var/empty_alarm_sound = 'sound/weapons/gun/general/empty_alarm.ogg'
+ ///empty alarm volume sound
+ var/empty_alarm_volume = 70
+ ///whether empty alarm sound varies
+ var/empty_alarm_vary = TRUE
+
+/*
+ * Stats
+*/
+ var/weapon_weight = WEAPON_LIGHT
+ //Alters projectile damage multiplicatively based on this value. Use it for "better" or "worse" weapons that use the same ammo.
+ var/projectile_damage_multiplier = 1
+ //Speed someone can be flung if its point blank
var/pb_knockback = 0
- var/wielded = FALSE // true if the gun is wielded via twohanded component, shouldnt affect anything else
-
- var/wielded_fully = FALSE // true if the gun is wielded after delay, should affects accuracy
-
+ //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once.
+ var/randomspread = TRUE
///How much the bullet scatters when fired while wielded.
var/spread = 4
///How much the bullet scatters when fired while unwielded.
var/spread_unwielded = 12
+ //additional spread when dual wielding
+ var/dual_wield_spread = 24
+
///Screen shake when the weapon is fired while wielded.
var/recoil = 0
@@ -112,44 +207,126 @@
///this is how much deviation the gun recoil can have, recoil pushes the screen towards the reverse angle you shot + some deviation which this is the max.
var/recoil_deviation = 22.5
- ///Slowdown for wielding
- var/wield_slowdown = 0.1
- ///How long between wielding and firing in tenths of seconds
- var/wield_delay = 0.4 SECONDS
- ///Storing value for above
- var/wield_time = 0
+ /// how many shots per burst, Ex: most machine pistols, M90, some ARs are 3rnd burst, while others like the GAR and laser minigun are 2 round burst.
+ var/burst_size = 3
+ ///The rate of fire when firing in a burst. Not the delay between bursts
+ var/burst_delay = 0.15 SECONDS
+ ///The rate of fire when firing full auto and semi auto, and between bursts; for bursts its fire delay + burst_delay after every burst
+ var/fire_delay = 0.2 SECONDS
+ //Prevent the weapon from firing again while already firing
+ var/firing_burst = 0
+
+/*
+ * Overlay
+*/
+ ///Used for positioning ammo count overlay on sprite
+ var/ammo_x_offset = 0
+ var/ammo_y_offset = 0
- ///Effect for the muzzle flash of the gun.
- var/obj/effect/muzzle_flash/muzzle_flash
- ///Icon state of the muzzle flash effect.
- var/muzzleflash_iconstate
- ///Brightness of the muzzle flash effect.
- var/muzzle_flash_lum = 3
- ///Color of the muzzle flash effect.
- var/muzzle_flash_color = COLOR_VERY_SOFT_YELLOW
+//BALLISTIC
+ ///Whether the sprite has a visible magazine or not
+ var/mag_display = FALSE
+ ///Whether the sprite has a visible ammo display or not
+ var/mag_display_ammo = FALSE
+ ///Whether the sprite has a visible indicator for being empty or not.
+ var/empty_indicator = FALSE
+ ///Whether the sprite has a visible magazine or not
+ var/show_magazine_on_sprite = FALSE
+ ///Whether the sprite has a visible ammo display or not
+ var/show_magazine_on_sprite_ammo = FALSE
+ ///Whether the gun supports multiple special mag types
+ var/unique_mag_sprites_for_variants = FALSE
+
+//ENERGY
+ //Do we handle overlays with base update_appearance()?
+ var/automatic_charge_overlays = TRUE
+ var/charge_sections = 4
+ //if this gun uses a stateful charge bar for more detail
+ var/shaded_charge = FALSE
+ //Modifies WHOS state //im SOMEWHAT this is wether or not the overlay changes based on the ammo type selected
+ var/modifystate = TRUE
+
+/*
+ * Attachment
+*/
+ ///The types of attachments allowed, a list of types. SUBTYPES OF AN ALLOWED TYPE ARE ALSO ALLOWED
+ var/list/valid_attachments = list()
+ ///Reference to our attachment holder to prevent subtypes having to call GetComponent
+ var/datum/component/attachment_holder/attachment_holder
+ ///Number of attachments that can fit on a given slot
+ var/list/slot_available = ATTACHMENT_DEFAULT_SLOT_AVAILABLE
+ ///Offsets for the slots on this gun. should be indexed by SLOT and then by X/Y
+ var/list/slot_offsets = list()
+
+/*
+ * Zooming
+*/
+ ///Whether the gun generates a Zoom action on creation
+ var/zoomable = FALSE
+ //Zoom toggle
+ var/zoomed = FALSE
+ ///Distance in TURFs to move the user's screen forward (the "zoom" effect)
+ var/zoom_amt = 3
+ var/zoom_out_amt = 0
+ var/datum/action/toggle_scope_zoom/azoom
- //gun saftey
+/*
+ * Safety
+*/
///Does this gun have a saftey and thus can toggle it?
var/has_safety = FALSE
///If the saftey on? If so, we can't fire the weapon
var/safety = FALSE
-
///The wording of safety. Useful for guns that have a non-standard safety system, like a revolver
var/safety_wording = "safety"
+/*
+ * Spawn Info (Stuff that becomes useless onces the gun is spawned, mostly here for mappers)
+*/
+ ///Attachments spawned on initialization. Should also be in valid attachments or it SHOULD(once i add that) fail
+ var/list/default_attachments = list()
+
+//BALLISTIC
+ ///Whether the gun will spawn loaded with a magazine
+ var/spawnwithmagazine = TRUE
+
+//ENERGY
+ //set to true so the gun is given an empty cell
+ var/dead_cell = FALSE
+
+// Need to sort
+ ///trigger guard on the weapon. Used for hulk mutations and ashies. I honestly dont know how usefult his is, id avoid touching it
+ trigger_guard = TRIGGER_GUARD_NORMAL
+
+ /// after initializing, we set the firemode to this
+ var/default_firemode = FIREMODE_SEMIAUTO
+ ///Firemode index, due to code shit this is the currently selected firemode
+ var/firemode_index
+ /// Our firemodes, subtract and add to this list as needed. NOTE that the autofire component is given on init when FIREMODE_FULLAUTO is here.
+ var/list/gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_BURST, FIREMODE_FULLAUTO, FIREMODE_OTHER, FIREMODE_OTHER_TWO)
+ /// A acoc list that determines the names of firemodes. Use if you wanna be weird and set the name of say, FIREMODE_OTHER to "Underbarrel grenade launcher" for example.
+ var/list/gun_firenames = list(FIREMODE_SEMIAUTO = "single", FIREMODE_BURST = "burst fire", FIREMODE_FULLAUTO = "full auto", FIREMODE_OTHER = "misc. fire", FIREMODE_OTHER_TWO = "very misc. fire")
+ ///BASICALLY: the little button you select firing modes from? this is jsut the prefix of the icon state of that. For example, if we set it as "laser", the fire select will use "laser_single" and so on.
+ var/fire_select_icon_state_prefix = ""
+ ///If true, we put "safety_" before fire_select_icon_state_prefix's prefix. ex. "safety_laser_single"
+ var/adjust_fire_select_icon_state_on_safety = FALSE
+
+ ///Are we firing a burst? If so, dont fire again until burst is done
+ var/currently_firing_burst = FALSE
+ ///This prevents gun from firing until the coodown is done, affected by lag
+ var/current_cooldown = 0
+
/obj/item/gun/Initialize()
. = ..()
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, PROC_REF(on_wield))
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, PROC_REF(on_unwield))
- if(pin)
- pin = new pin(src)
- if(gun_light)
- alight = new(src)
muzzle_flash = new(src, muzzleflash_iconstate)
build_zooming()
+ build_firemodes()
/obj/item/gun/ComponentInitialize()
. = ..()
+ attachment_holder = AddComponent(/datum/component/attachment_holder, slot_available, valid_attachments, slot_offsets, default_attachments)
AddComponent(/datum/component/two_handed)
/// triggered on wield of two handed item
@@ -161,10 +338,21 @@
user.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/gun, multiplicative_slowdown = wield_slowdown)
wield_time = world.time + wield_delay
if(wield_time > 0)
- if(do_mob(user, user, wield_delay, FALSE, TRUE, CALLBACK(src, PROC_REF(is_wielded)), ignore_loc_change = TRUE))
+ if(do_after(
+ user,
+ wield_delay,
+ user,
+ FALSE,
+ TRUE,
+ CALLBACK(src, PROC_REF(is_wielded)),
+ timed_action_flags = IGNORE_USER_LOC_CHANGE
+ )
+ )
wielded_fully = TRUE
+ return TRUE
else
wielded_fully = TRUE
+ return TRUE
/obj/item/gun/proc/is_wielded()
return wielded
@@ -173,73 +361,44 @@
/obj/item/gun/proc/on_unwield(obj/item/source, mob/user)
wielded = FALSE
wielded_fully = FALSE
+ zoom(user, forced_zoom = FALSE)
user.remove_movespeed_modifier(/datum/movespeed_modifier/gun)
/obj/item/gun/Destroy()
- if(isobj(pin)) //Can still be the initial path, then we skip
- QDEL_NULL(pin)
- if(gun_light)
- QDEL_NULL(gun_light)
- if(bayonet)
- QDEL_NULL(bayonet)
if(chambered) //Not all guns are chambered (EMP'ed energy guns etc)
QDEL_NULL(chambered)
if(azoom)
QDEL_NULL(azoom)
- if(isatom(suppressed)) //SUPPRESSED IS USED AS BOTH A TRUE/FALSE AND AS A REF, WHAT THE FUCKKKKKKKKKKKKKKKKK
- QDEL_NULL(suppressed)
if(muzzle_flash)
QDEL_NULL(muzzle_flash)
return ..()
/obj/item/gun/handle_atom_del(atom/A)
- if(A == pin)
- pin = null
if(A == chambered)
chambered = null
- update_appearance()
- if(A == bayonet)
- clear_bayonet()
- if(A == gun_light)
- clear_gunlight()
+ update_icon()
return ..()
/obj/item/gun/examine(mob/user)
. = ..()
- if(pin)
- . += "It has \a [pin] installed."
- . += "[pin] looks like it could be removed with some tools."
- else
- . += "It doesn't have a firing pin installed, and won't fire."
-
- if(gun_light)
- . += "It has \a [gun_light] [can_flashlight ? "" : "permanently "]mounted on it."
- if(can_flashlight) //if it has a light and this is false, the light is permanent.
- . += "[gun_light] looks like it can be unscrewed from [src]."
- else if(can_flashlight)
- . += "It has a mounting point for a seclite."
-
- if(bayonet)
- . += "It has \a [bayonet] [can_bayonet ? "" : "permanently "]affixed to it."
- if(can_bayonet) //if it has a bayonet and this is false, the bayonet is permanent.
- . += "[bayonet] looks like it can be unscrewed from [src]."
- else if(can_bayonet)
- . += "It has a bayonet lug on it."
-
if(has_safety)
. += "The safety is [safety ? "ON" : "OFF"]. Ctrl-Click to toggle the safety."
if(manufacturer)
. += "It has [manufacturer] engraved on it."
-
/obj/item/gun/equipped(mob/living/user, slot)
. = ..()
if(zoomed && user.get_active_held_item() != src)
zoom(user, user.dir, FALSE) //we can only stay zoomed in if it's in our hands //yeah and we only unzoom if we're actually zoomed using the gun!!
+/obj/item/gun/attack(mob/M as mob, mob/user)
+ if(user.a_intent == INTENT_HARM) //Flogging
+ return ..()
+ return
+
//called after the gun has successfully fired its chambered ammo.
-/obj/item/gun/proc/process_chamber()
+/obj/item/gun/proc/process_chamber(atom/shooter)
SEND_SIGNAL(src, COMSIG_GUN_CHAMBER_PROCESSED)
return FALSE
@@ -250,282 +409,278 @@
return FALSE
return TRUE
-/obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj)
- if(!safety)
- to_chat(user, "*[dry_fire_text]*")
- playsound(src, dry_fire_sound, 30, TRUE)
- return
- to_chat(user, "Safeties are active on the [src]! Turn them off to fire!")
-
-
-/obj/item/gun/proc/shoot_live_shot(mob/living/user, pointblank = 0, atom/pbtarget = null, message = 1)
- var/actual_angle = get_angle_with_scatter((user || get_turf(src)), pbtarget, rand(-recoil_deviation, recoil_deviation) + 180)
- var/muzzle_angle = Get_Angle(get_turf(src), pbtarget)
- if(muzzle_flash && !muzzle_flash.applied)
- handle_muzzle_flash(user, muzzle_angle)
-
- if(wielded_fully)
- simulate_recoil(user, recoil, actual_angle)
- else if(!wielded_fully)
- simulate_recoil(user, recoil_unwielded, actual_angle)
-
- if(suppressed)
- playsound(user, suppressed_sound, suppressed_volume, vary_fire_sound, ignore_walls = FALSE, extrarange = SILENCED_SOUND_EXTRARANGE, falloff_distance = 0)
- else
- playsound(user, fire_sound, fire_sound_volume, vary_fire_sound)
- if(message)
- if(pointblank)
- user.visible_message(
- span_danger("[user] fires [src] point blank at [pbtarget]!"),
- span_danger("You fire [src] point blank at [pbtarget]!"),
- span_hear("You hear a gunshot!"), COMBAT_MESSAGE_RANGE, pbtarget
- )
- to_chat(pbtarget, "[user] fires [src] point blank at you!")
- if(pb_knockback > 0 && ismob(pbtarget))
- var/mob/PBT = pbtarget
- var/atom/throw_target = get_edge_target_turf(PBT, user.dir)
- PBT.throw_at(throw_target, pb_knockback, 2)
- else
- user.visible_message(
- span_danger("[user] fires [src]!"),
- blind_message = span_hear("You hear a gunshot!"),
- vision_distance = COMBAT_MESSAGE_RANGE,
- ignored_mobs = user
- )
-
/obj/item/gun/emp_act(severity)
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
for(var/obj/O in contents)
O.emp_act(severity)
+
+/obj/item/gun/proc/recharge_newshot()
+ return
+
/obj/item/gun/afterattack(atom/target, mob/living/user, flag, params)
. = ..()
+ //No target? Why are we even firing anyways...
if(!target)
return
- if(firing_burst)
+ //If we are burst firing, don't fire, obviously
+ if(currently_firing_burst)
return
- if(flag) //It's adjacent, is the user, or is on the user's person
+ //This var happens when we are either clicking someone next to us or ourselves. Check if we don't want to fire...
+ if(flag)
if(target in user.contents) //can't shoot stuff inside us.
return
if(!ismob(target) || user.a_intent == INTENT_HARM) //melee attack
return
if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) //so we can't shoot ourselves (unless mouth selected)
return
+/* TODO: gunpointing is very broken, port the old skyrat gunpointing? its much better, usablity wise and rp wise?
if(ismob(target) && user.a_intent == INTENT_GRAB)
if(user.GetComponent(/datum/component/gunpoint))
to_chat(user, "You are already holding someone up!")
return
user.AddComponent(/datum/component/gunpoint, target, src)
return
+*/
+ // Good job, but we have exta checks to do...
+ return pre_fire(target, user, TRUE, flag, params, null)
+
+/obj/item/gun/proc/pre_fire(atom/target, mob/living/user, message = TRUE, flag, params = null, zone_override = "", bonus_spread = 0, dual_wielded_gun = FALSE)
+ add_fingerprint(user)
+
+ // If we have a cooldown, don't do anything, obviously
+ if(current_cooldown)
+ return
- if(istype(user))//Check if the user can use the gun, if the user isn't alive(turrets) assume it can.
- var/mob/living/L = user
- if(!can_trigger_gun(L))
+ //We check if the user can even use the gun, if not, we assume the user isn't alive(turrets) so we go ahead.
+ if(istype(user))
+ var/mob/living/living_user = user
+ if(!can_trigger_gun(living_user))
return
+ //If targetting the mouth, we do suicide instead.
if(flag)
if(user.zone_selected == BODY_ZONE_PRECISE_MOUTH)
handle_suicide(user, target, params)
return
- if(!can_shoot()) //Just because you can pull the trigger doesn't mean it can shoot.
+ //Just because we can pull the trigger doesn't mean it can fire. Mostly for safties.
+ if(!can_shoot())
shoot_with_empty_chamber(user)
return
- if(check_botched(user))
+ //we then check our weapon weight vs if we are being wielded...
+ if(weapon_weight == WEAPON_VERY_HEAVY && (!wielded_fully))
+ to_chat(user, "You need a fully secure grip to fire [src]!")
return
if(weapon_weight == WEAPON_HEAVY && (!wielded))
to_chat(user, "You need a more secure grip to fire [src]!")
return
- //DUAL (or more!) WIELDING
- var/bonus_spread = 0
+ //If we have the pacifist trait and a chambered round, don't fire. Honestly, pacifism quirk is pretty stupid, and as such we check again in process_fire() anyways
+ if(chambered)
+ if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
+ if(chambered.harmful) // Is the bullet chambered harmful?
+ to_chat(user, "[src] is lethally chambered! You don't want to risk harming anyone...")
+ return
+
+ //Dual wielding handling. Not the biggest fan of this, but it's here. Dual berettas not included
var/loop_counter = 0
- if(ishuman(user) && user.a_intent == INTENT_HARM)
- var/mob/living/carbon/human/H = user
- for(var/obj/item/gun/G in H.held_items)
- if(G == src || G.weapon_weight >= WEAPON_MEDIUM)
+ if(ishuman(user) && user.a_intent == INTENT_HARM && !dual_wielded_gun)
+ var/mob/living/carbon/human/our_cowboy = user
+ for(var/obj/item/gun/found_gun in our_cowboy.held_items)
+ if(found_gun == src || found_gun.weapon_weight >= WEAPON_MEDIUM)
continue
- else if(G.can_trigger_gun(user))
+ else if(found_gun.can_trigger_gun(user))
bonus_spread += dual_wield_spread
loop_counter++
- addtimer(CALLBACK(G, TYPE_PROC_REF(/obj/item/gun, process_fire), target, user, TRUE, params, null, bonus_spread), loop_counter)
+ addtimer(CALLBACK(found_gun, TYPE_PROC_REF(/obj/item/gun, pre_fire), target, user, TRUE, params, null, bonus_spread), loop_counter)
+
+ //get current firemode
+ var/current_firemode = gun_firemodes[firemode_index]
+ //FIREMODE_OTHER and its sister directs you to another proc for special handling
+ if(current_firemode == FIREMODE_OTHER)
+ return process_other(target, user, message, flag, params, zone_override, bonus_spread)
+ if(current_firemode == FIREMODE_OTHER_TWO)
+ return process_other_two(target, user, message, flag, params, zone_override, bonus_spread)
+ //if all of that succeded, we finally get to process firing
return process_fire(target, user, TRUE, params, null, bonus_spread)
-/obj/item/gun/proc/check_botched(mob/living/user, params)
- if(clumsy_check)
- if(istype(user))
- if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(40))
- to_chat(user, "You shoot yourself in the foot with [src]!")
- var/shot_leg = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
- process_fire(user, user, FALSE, params, shot_leg)
- SEND_SIGNAL(user, COMSIG_MOB_CLUMSY_SHOOT_FOOT)
- user.dropItemToGround(src, TRUE)
- return TRUE
-
-/obj/item/gun/can_trigger_gun(mob/living/user)
- . = ..()
- if(!handle_pins(user))
- return FALSE
+/obj/item/gun/proc/process_other(atom/target, mob/living/user, message = TRUE, flag, params = null, zone_override = "", bonus_spread = 0)
+ return //use this for 'underbarrels!!
-/obj/item/gun/proc/handle_pins(mob/living/user)
- if(pin)
- if(pin.pin_auth(user) || (pin.obj_flags & EMAGGED))
- return TRUE
- else
- pin.auth_fail(user)
- return FALSE
- else
- to_chat(user, "[src]'s trigger is locked. This weapon doesn't have a firing pin installed!")
- return FALSE
+/obj/item/gun/proc/process_other_two(atom/target, mob/living/user, message = TRUE, flag, params = null, zone_override = "", bonus_spread = 0)
+ return //reserved in case another fire mode is needed, if you need special behavior, put it here then call process_fire, or call process_fire and have the special behavior there
-/obj/item/gun/proc/recharge_newshot()
- return
+/**
+ * Handles everything involving firing.
+ * * gun.dm is still a fucking mess, and I will document everything next time i get to it... for now this will suffice.
+ *
+ * Returns TRUE or FALSE depending on if it actually fired a shot.
+ * Arguments:
+ * * target - The atom we are trying to hit.
+ * * user - The living mob firing the gun, if any.
+ * * message - Do we show the usual messages? eg. "x fires the y!"
+ * * params - Is the params string from byond [/atom/proc/Click] code, see that documentation.
+ * * zone_override - The bodypart we attempt to hit, sometimes hits another.
+ * * bonus_spread - Adds this value to spread, in this case used by dual wielding.
+ * * burst_firing - Not to be confused with currently_firing_burst. This var is TRUE when we are doing a burst except for the first shot in a burst, as to override the spam burst checks.
+ * * spread_override - Bullet spread is forcibly set to this. This is usually because of bursts attempting to share the same burst trajectory.
+ * * iteration - Which shot in a burst are we in.
+ */
+/obj/item/gun/proc/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0, burst_firing = FALSE, spread_override = 0, iteration = 0)
+ //OKAY, this prevents us from firing until our cooldown is done
+ if(!burst_firing) //if we're firing a burst, dont interfere to avoid issues
+ if(current_cooldown)
+ return FALSE
-/obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
- if(!user || !firing_burst)
- firing_burst = FALSE
+ //Check one last time for safeties...
+ if(!can_shoot())
+ shoot_with_empty_chamber(user)
+ currently_firing_burst = FALSE
return FALSE
- if(!issilicon(user))
- if(iteration > 1 && !(user.is_holding(src))) //for burst firing
- firing_burst = FALSE
+
+ //special hahnding for burst firing
+ if(burst_firing)
+ if(!user || !currently_firing_burst)
+ currently_firing_burst = FALSE
return FALSE
- if(chambered && chambered.BB)
+ if(!issilicon(user))
+ //If we aren't holding the gun, what are we doing, stop firing!
+ if(iteration > 1 && !(user.is_holding(src)))
+ currently_firing_burst = FALSE
+ return FALSE
+
+ //Do we have a round? If not, stop the whole chain, and if we do, check if the gun is chambered. Pacisim is pretty lame anyways.
+ if(chambered)
if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
if(chambered.harmful) // Is the bullet chambered harmful?
to_chat(user, "[src] is lethally chambered! You don't want to risk harming anyone...")
- return
- if(randomspread)
- sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
- else //Smart spread
- sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread))
- before_firing(target,user)
- if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src))
- shoot_with_empty_chamber(user)
- firing_burst = FALSE
- return FALSE
- else
- if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
- shoot_live_shot(user, 1, target, message)
- else
- shoot_live_shot(user, 0, target, message)
- if (iteration >= burst_size)
- firing_burst = FALSE
+ currently_firing_burst = FALSE //no burst 4 u
+ return FALSE
else
shoot_with_empty_chamber(user)
- firing_burst = FALSE
+ currently_firing_burst = FALSE
return FALSE
- process_chamber()
- update_appearance()
- return TRUE
-/obj/item/gun/proc/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
+ // we hold the total spread in this var
+ var/sprd
+ // if we ARE burst firing and don't have "randomspread", we add the burst's penalty on top of it.
+ if(burst_firing && !randomspread)
+ bonus_spread += burst_size * iteration
+
+ //override spread? usually happens only in bursts
+ if(spread_override && !randomspread)
+ sprd = spread_override
+ else
+ //Calculate spread
+ sprd = calculate_spread(user, bonus_spread)
+
+ before_firing(target,user)
+ //If we cant fire the round, just end the proc here. Otherwise, continue
+ if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd, src))
+ shoot_with_empty_chamber(user)
+ currently_firing_burst = FALSE
+ return FALSE
+ //Are we PBing someone? If so, set pointblank to TRUE
+ shoot_live_shot(user, (get_dist(user, target) <= 1), target, message) //Making sure whether the target is in vicinity for the pointblank shot
+
+ //process the chamber...
+ process_chamber(shooter = user)
+ update_appearance()
+ //get our current firemode...
+ var/current_firemode = gun_firemodes[firemode_index]
+
+ //If we are set to burst fire, then we burst fire!
+ if(burst_size > 1 && (current_firemode == FIREMODE_BURST) && !burst_firing)
+ currently_firing_burst = TRUE
+ for(var/i = 2 to burst_size) //we fire the first burst normally, hence why its 2
+ addtimer(CALLBACK(src, PROC_REF(process_fire), target, user, message, params, zone_override, 0, TRUE, sprd, i), burst_delay * (i - 1))
+
+ //if we have a fire delay, set up a cooldown
+ if(fire_delay && (!burst_firing && !currently_firing_burst))
+ current_cooldown = TRUE
+ addtimer(CALLBACK(src, PROC_REF(reset_current_cooldown)), fire_delay)
+ if(burst_firing && iteration >= burst_size)
+ current_cooldown = TRUE
+ addtimer(CALLBACK(src, PROC_REF(reset_current_cooldown)), fire_delay+burst_delay)
+ currently_firing_burst = FALSE
+
+ // update our inhands...
if(user)
- SEND_SIGNAL(user, COMSIG_MOB_FIRED_GUN, user, target, params, zone_override)
+ user.update_inv_hands()
- add_fingerprint(user)
+ SSblackbox.record_feedback("tally", "gun_fired", 1, type)
+ return TRUE
+
+/obj/item/gun/proc/reset_current_cooldown()
+ current_cooldown = FALSE
- if(semicd)
+/obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj)
+ if(!safety)
+ to_chat(user, "*[dry_fire_text]*")
+ playsound(src, dry_fire_sound, 30, TRUE)
return
+ to_chat(user, "Safeties are active on the [src]! Turn them off to fire!")
- var/sprd = 0
- var/randomized_gun_spread = 0
- var/rand_spr = rand()
- if(wielded_fully && spread)
- randomized_gun_spread = rand(0,spread)
- else if(!wielded_fully && spread_unwielded)
- randomized_gun_spread = rand(0,spread_unwielded)
+/obj/item/gun/proc/shoot_live_shot(mob/living/user, pointblank = FALSE, atom/pbtarget = null, message = TRUE)
+ var/actual_angle = get_angle_with_scatter((user || get_turf(src)), pbtarget, rand(-recoil_deviation, recoil_deviation) + 180)
+ var/muzzle_angle = Get_Angle(get_turf(src), pbtarget)
- if(HAS_TRAIT(user, TRAIT_POOR_AIM)) //nice shootin' tex
- bonus_spread += 25
- var/randomized_bonus_spread = rand(0, bonus_spread)
+ user.changeNext_move(clamp(fire_delay, 0, CLICK_CD_RANGE))
- if(burst_size > 1)
- firing_burst = TRUE
- for(var/i = 1 to burst_size)
- addtimer(CALLBACK(src, PROC_REF(process_burst), user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), fire_delay * (i - 1))
- else
- if(chambered)
- if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
- if(chambered.harmful) // Is the bullet chambered harmful?
- to_chat(user, "[src] is lethally chambered! You don't want to risk harming anyone...")
- return
- sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
- sprd = calculate_spread(user, sprd)
-
- before_firing(target,user)
- if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd, src))
- shoot_with_empty_chamber(user)
- return
- else
- if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
- shoot_live_shot(user, TRUE, target, message)
- else
- shoot_live_shot(user, FALSE, target, message)
- else
- shoot_with_empty_chamber(user)
- return
- process_chamber()
- update_appearance()
- if(fire_delay)
- semicd = TRUE
- addtimer(CALLBACK(src, PROC_REF(reset_semicd)), fire_delay)
+ if(muzzle_flash && !muzzle_flash.applied)
+ handle_muzzle_flash(user, muzzle_angle)
- if(user)
- user.update_inv_hands()
- SSblackbox.record_feedback("tally", "gun_fired", 1, type)
- return TRUE
+ if(wielded_fully)
+ simulate_recoil(user, recoil, actual_angle)
+ else if(!wielded_fully)
+ simulate_recoil(user, recoil_unwielded, actual_angle)
-/obj/item/gun/proc/reset_semicd()
- semicd = FALSE
+ if(suppressed)
+ playsound(user, suppressed_sound, suppressed_volume, vary_fire_sound, ignore_walls = FALSE, extrarange = SILENCED_SOUND_EXTRARANGE, falloff_distance = 0)
+ else
+ playsound(user, fire_sound, fire_sound_volume, vary_fire_sound)
+ if(message)
+ if(pointblank)
+ user.visible_message(
+ span_danger("[user] fires [src] point blank at [pbtarget]!"),
+ span_danger("You fire [src] point blank at [pbtarget]!"),
+ span_hear("You hear a gunshot!"), COMBAT_MESSAGE_RANGE, pbtarget
+ )
+ to_chat(pbtarget, "[user] fires [src] point blank at you!")
+ if(pb_knockback > 0 && ismob(pbtarget))
+ var/mob/PBT = pbtarget
+ var/atom/throw_target = get_edge_target_turf(PBT, user.dir)
+ PBT.throw_at(throw_target, pb_knockback, 2)
+ else
+ user.visible_message(
+ span_danger("[user] fires [src]!"),
+ blind_message = span_hear("You hear a gunshot!"),
+ vision_distance = COMBAT_MESSAGE_RANGE,
+ ignored_mobs = user
+ )
-/obj/item/gun/attack(mob/M as mob, mob/user)
- if(user.a_intent == INTENT_HARM) //Flogging
- if(bayonet)
- M.attackby(bayonet, user)
- return
- else
- return ..()
- return
+ //cloudy sent a meme in the discord. i dont know if its true, but i made this piece of code in honor of it
+ var/mob/living/carbon/human/living_human = user
+ if(istype(living_human))
+ if(!living_human.wear_neck)
+ return //if nothing on the neck, don't do anything
+ var/current_month = text2num(time2text(world.timeofday, "MM"))
+ var/static/regex/bian = regex("(?:^\\W*lesbian)", "i")
-/obj/item/gun/attack_obj(obj/O, mob/user)
- if(user.a_intent == INTENT_HARM)
- if(bayonet)
- O.attackby(bayonet, user)
- return
- return ..()
+ if(current_month == JUNE)
+ return //if it isn't june, don't do this easter egg
-/obj/item/gun/attackby(obj/item/I, mob/user, params)
- if(user.a_intent == INTENT_HARM)
- return ..()
- else if(istype(I, /obj/item/flashlight/seclite))
- if(!can_flashlight)
- return ..()
- var/obj/item/flashlight/seclite/S = I
- if(!gun_light)
- if(!user.transferItemToLoc(I, src))
- return
- to_chat(user, "You click [S] into place on [src].")
- set_gun_light(S)
- update_gunlight()
- alight = new(src)
- if(loc == user)
- alight.Grant(user)
- else if(istype(I, /obj/item/kitchen/knife))
- var/obj/item/kitchen/knife/K = I
- if(!can_bayonet || !K.bayonet || bayonet) //ensure the gun has an attachment point available, and that the knife is compatible with it.
- return ..()
- if(!user.transferItemToLoc(I, src))
- return
- to_chat(user, "You attach [K] to [src]'s bayonet lug.")
- bayonet = K
- update_appearance()
+ if(!findtext(bian, living_human.generic_adjective))
+ return //dont bother if we already are affected by it
- else
- return ..()
+ if(istype(living_human.wear_neck, /obj/item/clothing/neck/tie/lesbian) || living_human.wear_neck.icon_state == "lesbian")
+ var/use_space = "[living_human.generic_adjective ? " " : ""]"
+ living_human.generic_adjective = "lesbian[use_space][living_human.generic_adjective]" //i actually don't remember the meme. it was something like lesbians will stop working if they see another with a gun. or something.
/obj/item/gun/CtrlClick(mob/user)
. = ..()
@@ -550,150 +705,6 @@
update_appearance()
-
-/obj/item/gun/screwdriver_act(mob/living/user, obj/item/I)
- . = ..()
- if(.)
- return
- if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
- return
- attachment_options = list()
- get_gun_attachments()
- if(LAZYLEN(attachment_options) == 1)
- remove_gun_attachments(user, I, attachment_options[1])
- else if (LAZYLEN(attachment_options))
- var/picked_option = show_radial_menu(user, src, attachment_options, radius = 38, require_near = TRUE)
- remove_gun_attachments(user, I, picked_option)
-
-/obj/item/gun/proc/get_gun_attachments()
- if(can_flashlight && gun_light)
- attachment_options += list("Light" = image(icon = gun_light.icon, icon_state = gun_light.icon_state))
- if(can_bayonet && bayonet)
- attachment_options += list("Knife" = image(icon = bayonet.icon, icon_state = bayonet.icon_state))
-
-/obj/item/gun/proc/remove_gun_attachments(mob/living/user, obj/item/I, picked_option)
- if(picked_option == "Light")
- return remove_gun_attachment(user, I, gun_light, "unscrewed")
- else if(picked_option == "Knife")
- return remove_gun_attachment(user, I, bayonet, "unfix")
-
-/obj/item/gun/welder_act(mob/living/user, obj/item/I)
- . = ..()
- if(.)
- return
- if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
- return
- if(pin && user.is_holding(src))
- user.visible_message("[user] attempts to remove [pin] from [src] with [I].",
- "You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)", null, 3)
- if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, 5, volume = 50))
- if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay
- return
- user.visible_message("[pin] is spliced out of [src] by [user], melting part of the pin in the process.",
- "You splice [pin] out of [src] with [I], melting part of the pin in the process.", null, 3)
- QDEL_NULL(pin)
- return TRUE
-
-/obj/item/gun/wirecutter_act(mob/living/user, obj/item/I)
- . = ..()
- if(.)
- return
- if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
- return
- if(pin && user.is_holding(src))
- user.visible_message("[user] attempts to remove [pin] from [src] with [I].",
- "You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)", null, 3)
- if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50))
- if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay
- return
- user.visible_message("[pin] is ripped out of [src] by [user], mangling the pin in the process.",
- "You rip [pin] out of [src] with [I], mangling the pin in the process.", null, 3)
- QDEL_NULL(pin)
- return TRUE
-
-/obj/item/gun/proc/remove_gun_attachment(mob/living/user, obj/item/tool_item, obj/item/item_to_remove, removal_verb)
- if(tool_item)
- tool_item.play_tool_sound(src)
- to_chat(user, "You [removal_verb ? removal_verb : "remove"] [item_to_remove] from [src].")
- item_to_remove.forceMove(drop_location())
-
- if(Adjacent(user) && !issilicon(user))
- user.put_in_hands(item_to_remove)
-
- if(item_to_remove == bayonet)
- return clear_bayonet()
- else if(item_to_remove == gun_light)
- return clear_gunlight()
-
-/obj/item/gun/proc/clear_bayonet()
- if(!bayonet)
- return
- bayonet = null
- update_appearance()
- return TRUE
-
-/obj/item/gun/proc/clear_gunlight()
- if(!gun_light)
- return
- var/obj/item/flashlight/seclite/removed_light = gun_light
- set_gun_light(null)
- update_gunlight()
- removed_light.update_brightness()
- QDEL_NULL(alight)
- return TRUE
-
-/**
- * Swaps the gun's seclight, dropping the old seclight if it has not been qdel'd.
- *
- * Returns the former gun_light that has now been replaced by this proc.
- * Arguments:
- * * new_light - The new light to attach to the weapon. Can be null, which will mean the old light is removed with no replacement.
- */
-/obj/item/gun/proc/set_gun_light(obj/item/flashlight/seclite/new_light)
- // Doesn't look like this should ever happen? We're replacing our old light with our old light?
- if(gun_light == new_light)
- CRASH("Tried to set a new gun light when the old gun light was also the new gun light.")
-
- . = gun_light
-
- // If there's an old gun light that isn't being QDELETED, detatch and drop it to the floor.
- if(!QDELETED(gun_light))
- gun_light.set_light_flags(gun_light.light_flags & ~LIGHT_ATTACHED)
- if(gun_light.loc != get_turf(src))
- gun_light.forceMove(get_turf(src))
-
- // If there's a new gun light to be added, attach and move it to the gun.
- if(new_light)
- new_light.set_light_flags(new_light.light_flags | LIGHT_ATTACHED)
- if(new_light.loc != src)
- new_light.forceMove(src)
-
- gun_light = new_light
-
-/obj/item/gun/ui_action_click(mob/user, actiontype)
- if(istype(actiontype, alight))
- toggle_gunlight()
- else
- ..()
-
-/obj/item/gun/proc/toggle_gunlight()
- if(!gun_light)
- return
-
- var/mob/living/carbon/human/user = usr
- gun_light.on = !gun_light.on
- gun_light.update_brightness()
- to_chat(user, "You toggle the gunlight [gun_light.on ? "on":"off"].")
-
- playsound(user, gun_light.on ? gun_light.toggle_on_sound : gun_light.toggle_off_sound, 40, TRUE)
- update_gunlight()
-
-/obj/item/gun/proc/update_gunlight()
- update_appearance()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
-
/obj/item/gun/attack_hand(mob/user)
. = ..()
update_appearance()
@@ -714,27 +725,6 @@
/obj/item/gun/update_overlays()
. = ..()
- if(gun_light)
- var/mutable_appearance/flashlight_overlay
- var/state = "[gunlight_state][gun_light.on? "_on":""]" //Generic state.
- if(gun_light.icon_state in icon_states('icons/obj/guns/flashlights.dmi')) //Snowflake state?
- state = gun_light.icon_state
- flashlight_overlay = mutable_appearance('icons/obj/guns/flashlights.dmi', state)
- flashlight_overlay.pixel_x = flight_x_offset
- flashlight_overlay.pixel_y = flight_y_offset
- . += flashlight_overlay
-
- if(bayonet)
- var/mutable_appearance/knife_overlay
- var/state = "bayonet" //Generic state.
- if(bayonet.icon_state in icon_states('icons/obj/guns/bayonets.dmi')) //Snowflake state?
- state = bayonet.icon_state
- var/icon/bayonet_icons = 'icons/obj/guns/bayonets.dmi'
- knife_overlay = mutable_appearance(bayonet_icons, state)
- knife_overlay.pixel_x = knife_x_offset
- knife_overlay.pixel_y = knife_y_offset
- . += knife_overlay
-
if(ismob(loc) && has_safety)
var/mutable_appearance/safety_overlay
safety_overlay = mutable_appearance('icons/obj/guns/safety.dmi')
@@ -744,44 +734,69 @@
safety_overlay.icon_state = "[safety_wording]-off"
. += safety_overlay
+#define BRAINS_BLOWN_THROW_RANGE 2
+#define BRAINS_BLOWN_THROW_SPEED 1
+
/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer)
if(!ishuman(user) || !ishuman(target))
return
- if(semicd)
+ if(current_cooldown)
+ return
+
+ if(!can_shoot()) //Just because you can pull the trigger doesn't mean it can shoot.
+ shoot_with_empty_chamber(user)
return
if(user == target)
- target.visible_message("[user] sticks [src] in [user.p_their()] mouth, ready to pull the trigger...", \
- "You stick [src] in your mouth, ready to pull the trigger...")
+ target.visible_message(span_warning("[user] sticks [src] in [user.p_their()] mouth, ready to pull the trigger..."), \
+ span_userdanger("You stick [src] in your mouth, ready to pull the trigger..."))
else
- target.visible_message("[user] points [src] at [target]'s head, ready to pull the trigger...", \
- "[user] points [src] at your head, ready to pull the trigger...")
+ target.visible_message(span_warning("[user] points [src] at [target]'s head, ready to pull the trigger..."), \
+ span_userdanger("[user] points [src] at your head, ready to pull the trigger..."))
- semicd = TRUE
+ current_cooldown = TRUE
- if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH))
+ if(!bypass_timer && (!do_after(user, 100, target) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH))
if(user)
if(user == target)
- user.visible_message("[user] decided not to shoot.")
+ user.visible_message(span_notice("[user] decided not to shoot."))
else if(target && target.Adjacent(user))
- target.visible_message("[user] has decided to spare [target]", "[user] has decided to spare your life!")
- semicd = FALSE
+ target.visible_message(span_notice("[user] has decided to spare [target]."), span_notice("[user] has decided to spare your life!"))
+ current_cooldown = FALSE
return
- semicd = FALSE
+ current_cooldown = FALSE
- target.visible_message("[user] pulls the trigger!", "[(user == target) ? "You pull" : "[user] pulls"] the trigger!")
+ target.visible_message(span_warning("[user] pulls the trigger!"), span_userdanger("[(user == target) ? "You pull" : "[user] pulls"] the trigger!"))
- if(chambered && chambered.BB)
- chambered.BB.damage *= 5
+ if(chambered && chambered.BB && can_trigger_gun(user))
+ chambered.BB.damage *= 3
+ //Check is here for safeties and such, brain will be removed after
+ if(!pre_fire(target, user, TRUE, params, BODY_ZONE_HEAD))
+ return
+
+ var/obj/item/organ/brain/brain_to_blast = target.getorganslot(ORGAN_SLOT_BRAIN)
+ if(brain_to_blast)
+
+ //Check if the projectile is actually damaging and not of type STAMINA
+ if(chambered.BB.nodamage || !chambered.BB.damage || chambered.BB.damage_type == STAMINA)
+ return
+
+ //Remove brain of the mob shot
+ brain_to_blast.Remove(target)
- process_fire(target, user, TRUE, params, BODY_ZONE_HEAD)
+ var/turf/splat_turf = get_turf(target)
+ //Move the brain of the person shot to selected turf
+ brain_to_blast.forceMove(splat_turf)
-/obj/item/gun/proc/unlock() //used in summon guns and as a convience for admins
- if(pin)
- qdel(pin)
- pin = new /obj/item/firing_pin
+ var/turf/splat_target = get_ranged_target_turf(target, REVERSE_DIR(target.dir), BRAINS_BLOWN_THROW_RANGE)
+ var/datum/callback/gibspawner = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(spawn_atom_to_turf), /obj/effect/gibspawner/generic, brain_to_blast, 1, FALSE, target)
+ //Throw the brain that has been removed away and place a gibspawner on landing
+ brain_to_blast.throw_at(splat_target, BRAINS_BLOWN_THROW_RANGE, BRAINS_BLOWN_THROW_SPEED, callback = gibspawner)
+
+#undef BRAINS_BLOWN_THROW_RANGE
+#undef BRAINS_BLOWN_THROW_SPEED
//Happens before the actual projectile creation
/obj/item/gun/proc/before_firing(atom/target,mob/user)
@@ -793,10 +808,55 @@
// We do it like this in case theres some specific gun behavior for adjusting spread, like bipods or folded stocks
/obj/item/gun/proc/calculate_spread(mob/user, bonus_spread)
- return bonus_spread
+ ///our final spread value
+ var/sprd = 0
+ ///our randomized value after checking if we are wielded or not
+ var/randomized_gun_spread = 0
+ ///bonus
+ var/randomized_bonus_spread
+ // do we have poor aim
+ var/poor_aim = FALSE
+
+ //do we have bonus_spread ? If so, set sprd to it because it means a subtype's proc messed with it
+ sprd += bonus_spread
+
+ //reset bonus_spread for poor aim...
+ bonus_spread = 0
+
+ // if we have poor aim, we fuck the shooter over
+ if(HAS_TRAIT(user, TRAIT_POOR_AIM))
+ bonus_spread += 25
+ poor_aim = TRUE
+ // then we randomize the bonus spread
+ randomized_bonus_spread = rand(poor_aim ? 10 : 0, bonus_spread) //poor aim is no longer just a nusiance
+
+ //then, we mutiply previous bonus spread as it means dual wielding usually, it also means poor aim is also even more severe
+ randomized_bonus_spread *= DUALWIELD_PENALTY_EXTRA_MULTIPLIER
+
+ // we will then calculate gun spread depending on if we are fully wielding (after do_after) the gun or not
+ randomized_gun_spread = rand(0, wielded_fully ? spread : spread_unwielded)
+
+ //finally, we put it all together including if sprd has a value
+ sprd += randomized_gun_spread + randomized_bonus_spread
+
+ //clamp it down to avoid guns with negative spread to have worse recoil...
+ sprd = clamp(sprd, 0, INFINITY)
+
+ // im not sure what this does, i beleive its meant to make it so bullet spread goes in the opposite direction? get back to me on this - update,i have commented it out, however it appears be dapening spread. weird.
+ //sprd *= (rand() - 0.5)
+
+ //coin flip if we mutiply output by -1 so spread isn't JUST to the right
+ if(prob(50))
+ sprd *= -1
+
+ // then we round it up and send it!
+ sprd = round(sprd)
+
+ return sprd
/obj/item/gun/proc/simulate_recoil(mob/living/user, recoil_bonus = 0, firing_angle)
var/total_recoil = calculate_recoil(user, recoil_bonus)
+ total_recoil = clamp(total_recoil, 0 , INFINITY)
var/actual_angle = firing_angle + rand(-recoil_deviation, recoil_deviation) + 180
if(actual_angle > 360)
@@ -808,6 +868,7 @@
/obj/item/gun/proc/handle_muzzle_flash(mob/living/user, firing_angle)
var/atom/movable/flash_loc = user
var/prev_light = light_range
+
if(!light_on && (light_range <= muzzle_flash_lum))
set_light_range(muzzle_flash_lum)
set_light_color(muzzle_flash_color)
@@ -900,10 +961,7 @@
flash_loc.vis_contents -= muzzle_flash
muzzle_flash.applied = FALSE
-/////////////
-// ZOOMING //
-/////////////
-
+//I need to refactor this into an attachment
/datum/action/toggle_scope_zoom
name = "Toggle Scope"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_LYING
@@ -935,7 +993,11 @@
return
if(isnull(forced_zoom))
- zoomed = !zoomed
+ if((!zoomed && wielded_fully) || zoomed)
+ zoomed = !zoomed
+ else
+ to_chat(user, "You can't look down the scope without wielding [src]!")
+ zoomed = FALSE
else
zoomed = forced_zoom
@@ -956,5 +1018,58 @@
azoom = new()
azoom.gun = src
-#undef FIRING_PIN_REMOVAL_DELAY
-#undef DUALWIELD_PENALTY_EXTRA_MULTIPLIER
+/obj/item/gun/proc/build_firemodes()
+ if(FIREMODE_FULLAUTO in gun_firemodes)
+ AddComponent(/datum/component/automatic_fire, fire_delay)
+ SEND_SIGNAL(src, COMSIG_GUN_DISABLE_AUTOFIRE)
+ var/datum/action/item_action/our_action
+
+ if(gun_firemodes.len > 1)
+ our_action = new /datum/action/item_action/toggle_firemode(src)
+
+ for(var/i=1, i <= gun_firemodes.len+1, i++)
+ if(default_firemode == gun_firemodes[i])
+ firemode_index = i
+ if(gun_firemodes[i] == FIREMODE_FULLAUTO)
+ SEND_SIGNAL(src, COMSIG_GUN_ENABLE_AUTOFIRE)
+ if(our_action)
+ our_action.UpdateButtonIcon()
+ return
+
+ firemode_index = 1
+ CRASH("default_firemode isn't in the gun_firemodes list of [src.type]!! Defaulting to 1!!")
+
+/obj/item/gun/ui_action_click(mob/user, actiontype)
+ if(istype(actiontype, /datum/action/item_action/toggle_firemode))
+ fire_select(user)
+ else
+ ..()
+
+/obj/item/gun/proc/fire_select(mob/living/carbon/human/user)
+
+ //gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_BURST, FIREMODE_FULLAUTO, FIREMODE_OTHER)
+
+ firemode_index++
+ if(firemode_index > gun_firemodes.len)
+ firemode_index = 1 //reset to the first index if it's over the limit. Byond arrays start at 1 instead of 0, hence why its set to 1.
+
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode == FIREMODE_FULLAUTO)
+ SEND_SIGNAL(src, COMSIG_GUN_ENABLE_AUTOFIRE)
+ else
+ SEND_SIGNAL(src, COMSIG_GUN_DISABLE_AUTOFIRE)
+//wawa
+ to_chat(user, "Switched to [gun_firenames[current_firemode]].")
+ playsound(user, 'sound/weapons/gun/general/selector.ogg', 100, TRUE)
+ update_appearance()
+ for(var/datum/action/current_action as anything in actions)
+ current_action.UpdateButtonIcon()
+
+/datum/action/item_action/toggle_firemode/UpdateButtonIcon(status_only = FALSE, force = FALSE)
+ var/obj/item/gun/our_gun = target
+
+ var/current_firemode = our_gun.gun_firemodes[our_gun.firemode_index]
+ //tldr; if we have adjust_fire_select_icon_state_on_safety as true, we append "safety_" to the prefix, otherwise nothing.
+ var/safety_prefix = "[our_gun.adjust_fire_select_icon_state_on_safety ? "[our_gun.safety ? "safety_" : ""]" : ""]"
+ button_icon_state = "[safety_prefix][our_gun.fire_select_icon_state_prefix][current_firemode]"
+ return ..()
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 227abceffa01..7c75d8fe9f56 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -1,110 +1,51 @@
+#define EMPTY_GUN_HELPER(gun_type) \
+ /obj/item/gun/ballistic/##gun_type/no_mag { \
+ spawnwithmagazine = FALSE; \
+ }
+
///Subtype for any kind of ballistic gun
///This has a shitload of vars on it, and I'm sorry for that, but it does make making new subtypes really easy
/obj/item/gun/ballistic
desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason."
name = "projectile gun"
- icon_state = "pistol"
w_class = WEIGHT_CLASS_NORMAL
has_safety = TRUE
safety = TRUE
- ///sound when inserting magazine
- var/load_sound = 'sound/weapons/gun/general/magazine_insert_full.ogg'
- ///sound when inserting an empty magazine
- var/load_empty_sound = 'sound/weapons/gun/general/magazine_insert_empty.ogg'
- ///volume of loading sound
- var/load_sound_volume = 40
- ///whether loading sound should vary
- var/load_sound_vary = TRUE
- ///sound of racking
- var/rack_sound = 'sound/weapons/gun/general/bolt_rack.ogg'
- ///volume of racking
- var/rack_sound_volume = 60
- ///whether racking sound should vary
- var/rack_sound_vary = TRUE
- ///sound of when the bolt is locked back manually
- var/lock_back_sound = 'sound/weapons/gun/general/slide_lock_1.ogg'
- ///volume of lock back
- var/lock_back_sound_volume = 60
- ///whether lock back varies
- var/lock_back_sound_vary = TRUE
- ///Sound of ejecting a magazine
- var/eject_sound = 'sound/weapons/gun/general/magazine_remove_full.ogg'
- ///sound of ejecting an empty magazine
- var/eject_empty_sound = 'sound/weapons/gun/general/magazine_remove_empty.ogg'
- ///volume of ejecting a magazine
- var/eject_sound_volume = 40
- ///whether eject sound should vary
- var/eject_sound_vary = TRUE
- ///sound of dropping the bolt or releasing a slide
- var/bolt_drop_sound = 'sound/weapons/gun/general/bolt_drop.ogg'
- ///volume of bolt drop/slide release
- var/bolt_drop_sound_volume = 60
- ///empty alarm sound (if enabled)
- var/empty_alarm_sound = 'sound/weapons/gun/general/empty_alarm.ogg'
- ///empty alarm volume sound
- var/empty_alarm_volume = 70
- ///whether empty alarm sound varies
- var/empty_alarm_vary = TRUE
-
- ///Whether the gun will spawn loaded with a magazine
- var/spawnwithmagazine = TRUE
- ///Compatible magazines with the gun
- var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info
- ///Whether the sprite has a visible magazine or not
- var/mag_display = FALSE
- ///Whether the sprite has a visible ammo display or not
- var/mag_display_ammo = FALSE
- ///Whether the sprite has a visible indicator for being empty or not.
- var/empty_indicator = FALSE
- ///Whether the gun alarms when empty or not.
- var/empty_alarm = FALSE
- ///Do we eject the magazine upon runing out of ammo?
- var/empty_autoeject = FALSE
- ///Whether the gun supports multiple special mag types
- var/special_mags = FALSE
- ///The bolt type of the gun, affects quite a bit of functionality, see combat.dm defines for bolt types: BOLT_TYPE_STANDARD; BOLT_TYPE_LOCKING; BOLT_TYPE_OPEN; BOLT_TYPE_NO_BOLT
- var/bolt_type = BOLT_TYPE_STANDARD
- ///Used for locking bolt and open bolt guns. Set a bit differently for the two but prevents firing when true for both.
- var/bolt_locked = FALSE
- ///Whether the gun has to be racked each shot or not.
- var/semi_auto = TRUE
- ///Actual magazine currently contained within the gun
- var/obj/item/ammo_box/magazine/magazine
- ///whether the gun ejects the chambered casing
- var/casing_ejector = TRUE
- ///Whether the gun has an internal magazine or a detatchable one. Overridden by BOLT_TYPE_NO_BOLT.
- var/internal_magazine = FALSE
- ///Phrasing of the bolt in examine and notification messages; ex: bolt, slide, etc.
- var/bolt_wording = "bolt"
- ///Phrasing of the magazine in examine and notification messages; ex: magazine, box, etx
- var/magazine_wording = "magazine"
- ///Phrasing of the cartridge in examine and notification messages; ex: bullet, shell, dart, etc.
- var/cartridge_wording = "bullet"
- ///length between individual racks
- var/rack_delay = 5
- ///time of the most recent rack, used for cooldown purposes
- var/recent_rack = 0
- ///Whether the gun can be sawn off by sawing tools
- var/can_be_sawn_off = FALSE
-
- ///Whether the gun can be tacloaded by slapping a fresh magazine directly on it
- var/tac_reloads = TRUE //Snowflake mechanic no more.
- ///If we have the 'snowflake mechanic,' how long should it take to reload?
- var/tactical_reload_delay = 1 SECONDS
+ valid_attachments = list(
+ /obj/item/attachment/silencer,
+ /obj/item/attachment/laser_sight,
+ /obj/item/attachment/rail_light,
+ /obj/item/attachment/bayonet
+ )
+ slot_available = list(
+ ATTACHMENT_SLOT_MUZZLE = 1,
+ ATTACHMENT_SLOT_RAIL = 1
+ )
+ slot_offsets = list(
+ ATTACHMENT_SLOT_MUZZLE = list(
+ "x" = 26,
+ "y" = 20,
+ ),
+ ATTACHMENT_SLOT_RAIL = list(
+ "x" = 19,
+ "y" = 18,
+ )
+ )
/obj/item/gun/ballistic/Initialize()
. = ..()
- if (!spawnwithmagazine)
+ if (!spawnwithmagazine && !ispath(mag_type, /obj/item/ammo_box/magazine/internal))
bolt_locked = TRUE
update_appearance()
return
if (!magazine)
magazine = new mag_type(src)
+ if (!spawnwithmagazine)
+ get_ammo_list (drop_all = TRUE)
chamber_round()
update_appearance()
-
/obj/item/gun/ballistic/update_icon_state()
if(current_skin)
icon_state = "[unique_reskin[current_skin]][sawn_off ? "_sawn" : ""]"
@@ -118,10 +59,8 @@
. += "[icon_state]_bolt[bolt_locked ? "_locked" : ""]"
if (bolt_type == BOLT_TYPE_OPEN && bolt_locked)
. += "[icon_state]_bolt"
- if (suppressed)
- . += "[icon_state]_suppressor"
if (magazine)
- if (special_mags)
+ if (unique_mag_sprites_for_variants)
. += "[icon_state]_mag_[magazine.base_icon_state]"
if (!magazine.ammo_count())
. += "[icon_state]_mag_empty"
@@ -144,13 +83,13 @@
if(!chambered && empty_indicator)
. += "[icon_state]_empty"
-/obj/item/gun/ballistic/process_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE)
+/obj/item/gun/ballistic/process_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE, atom/shooter)
if(!semi_auto && from_firing)
return
var/obj/item/ammo_casing/casing = chambered //Find chambered round
if(istype(casing)) //there's a chambered round
if(casing_ejector || !from_firing)
- casing.on_eject()
+ casing.on_eject(shooter)
chambered = null
else if(empty_chamber)
chambered = null
@@ -179,13 +118,14 @@
bolt_locked = FALSE
if (user)
to_chat(user, "You rack the [bolt_wording] of \the [src].")
- process_chamber(!chambered, FALSE)
+ process_chamber(!chambered, FALSE, shooter = user)
if (bolt_type == BOLT_TYPE_LOCKING && !chambered)
bolt_locked = TRUE
playsound(src, lock_back_sound, lock_back_sound_volume, lock_back_sound_vary)
else
playsound(src, rack_sound, rack_sound_volume, rack_sound_vary)
update_appearance()
+ SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
///Drops the bolt from a locked position
/obj/item/gun/ballistic/proc/drop_bolt(mob/user = null)
@@ -197,12 +137,12 @@
update_appearance()
///Handles all the logic needed for magazine insertion
-/obj/item/gun/ballistic/proc/insert_magazine(mob/user, obj/item/ammo_box/magazine/AM, display_message = TRUE)
- if(!istype(AM, mag_type))
- to_chat(user, "\The [AM] doesn't seem to fit into \the [src]...")
+/obj/item/gun/ballistic/proc/insert_magazine(mob/user, obj/item/ammo_box/magazine/inserted_mag, display_message = TRUE)
+ if(!istype(inserted_mag, mag_type))
+ to_chat(user, "\The [inserted_mag] doesn't seem to fit into \the [src]...")
return FALSE
- if(user.transferItemToLoc(AM, src))
- magazine = AM
+ if(user.transferItemToLoc(inserted_mag, src))
+ magazine = inserted_mag
if (display_message)
to_chat(user, "You load a new [magazine_wording] into \the [src].")
if (magazine.ammo_count())
@@ -212,6 +152,7 @@
if (bolt_type == BOLT_TYPE_OPEN && !bolt_locked)
chamber_round(TRUE)
update_appearance()
+ SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
return TRUE
else
to_chat(user, "You cannot seem to get \the [src] out of your hands!")
@@ -232,8 +173,9 @@
if (display_message)
to_chat(user, "You pull the [magazine_wording] out of \the [src].")
update_appearance()
+ SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
if (tac_load)
- if(do_after(user, tactical_reload_delay, TRUE, src))
+ if(do_after(user, tactical_reload_delay, src, hidden = TRUE))
if (insert_magazine(user, tac_load, FALSE))
to_chat(user, "You perform a tactical reload on \the [src].")
else
@@ -244,6 +186,7 @@
if(user)
user.put_in_hands(old_mag)
update_appearance()
+ SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
/obj/item/gun/ballistic/can_shoot()
if(safety)
@@ -267,7 +210,7 @@
if (istype(A, /obj/item/ammo_casing) || istype(A, /obj/item/ammo_box))
if (bolt_type == BOLT_TYPE_NO_BOLT || internal_magazine)
if (chambered && !chambered.BB)
- chambered.on_eject()
+ chambered.on_eject(shooter = user)
chambered = null
var/num_loaded = magazine.attackby(A, user, params)
if (num_loaded)
@@ -278,53 +221,11 @@
A.update_appearance()
update_appearance()
return
- if(istype(A, /obj/item/suppressor))
- var/obj/item/suppressor/S = A
- if(!can_suppress)
- to_chat(user, "You can't seem to figure out how to fit [S] on [src]!")
- return
- if(!user.is_holding(src))
- to_chat(user, "You need be holding [src] to fit [S] to it!")
- return
- if(suppressed)
- to_chat(user, "[src] already has a suppressor!")
- return
- if(user.transferItemToLoc(A, src))
- to_chat(user, "You screw \the [S] onto \the [src].")
- install_suppressor(A)
- return
if (can_be_sawn_off)
if (sawoff(user, A))
return
return FALSE
-/obj/item/gun/ballistic/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
- if (sawn_off)
- bonus_spread += SAWN_OFF_ACC_PENALTY
- . = ..()
-
-///Installs a new suppressor, assumes that the suppressor is already in the contents of src
-/obj/item/gun/ballistic/proc/install_suppressor(obj/item/suppressor/S)
- suppressed = S
- w_class += S.w_class //so pistols do not fit in pockets when suppressed
- update_appearance()
-
-/obj/item/gun/ballistic/AltClick(mob/user)
- if (unique_reskin && !current_skin && user.canUseTopic(src, BE_CLOSE, NO_DEXTERITY))
- reskin_obj(user)
- return
- if(loc == user)
- if(suppressed && can_unsuppress)
- var/obj/item/suppressor/S = suppressed
- if(!user.is_holding(src))
- return ..()
- to_chat(user, "You unscrew \the [suppressed] from \the [src].")
- user.put_in_hands(suppressed)
- w_class -= S.w_class
- suppressed = null
- update_appearance()
- return
-
///Prefire empty checks for the bolt drop
/obj/item/gun/ballistic/proc/prefire_empty_checks()
if (!chambered && !get_ammo())
@@ -346,8 +247,11 @@
bolt_locked = TRUE
update_appearance()
-/obj/item/gun/ballistic/afterattack()
+/obj/item/gun/ballistic/pre_fire(atom/target, mob/living/user, message = TRUE, flag, params = null, zone_override = "", bonus_spread = 0, dual_wielded_gun = FALSE)
prefire_empty_checks()
+ return ..()
+
+/obj/item/gun/ballistic/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0, burst_firing = FALSE, spread_override = 0, iteration = 0)
. = ..() //The gun actually firing
postfire_empty_checks(.)
@@ -364,7 +268,10 @@
var/num_unloaded = 0
for(var/obj/item/ammo_casing/CB in get_ammo_list(FALSE, TRUE))
CB.forceMove(drop_location())
- CB.bounce_away(FALSE, NONE)
+
+ var/angle_of_movement =(rand(-3000, 3000) / 100) + dir2angle(turn(user.dir, 180))
+ CB.AddComponent(/datum/component/movable_physics, _horizontal_velocity = rand(350, 450) / 100, _vertical_velocity = rand(400, 450) / 100, _horizontal_friction = rand(20, 24) / 100, _z_gravity = PHYSICS_GRAV_STANDARD, _z_floor = 0, _angle_of_movement = angle_of_movement, _bounce_sound = CB.bounce_sfx_override)
+
num_unloaded++
SSblackbox.record_feedback("tally", "station_mess_created", 1, CB.name)
if (num_unloaded)
@@ -392,8 +299,6 @@
. += "It does not seem to have a round chambered."
if (bolt_locked)
. += "The [bolt_wording] is locked back and needs to be released before firing."
- if (suppressed)
- . += "It has a suppressor attached that can be removed with alt+click."
. += "You can [bolt_wording] [src] by pressing the unqiue action key. By default, this is space"
///Gets the number of bullets in the gun
@@ -422,14 +327,11 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list(
///Handles all the logic of sawing off guns,
/obj/item/gun/ballistic/proc/sawoff(mob/user, obj/item/saw)
- if(!saw.get_sharpness() || !is_type_in_typecache(saw, GLOB.gun_saw_types) && !saw.tool_behaviour == TOOL_SAW) //needs to be sharp. Otherwise turned off eswords can cut this.
+ if(!saw.get_sharpness() || !is_type_in_typecache(saw, GLOB.gun_saw_types) && saw.tool_behaviour != TOOL_SAW) //needs to be sharp. Otherwise turned off eswords can cut this.
return
if(sawn_off)
to_chat(user, "\The [src] is already shortened!")
return
- if(bayonet)
- to_chat(user, "You cannot saw-off \the [src] with \the [bayonet] attached!")
- return
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] begins to shorten \the [src].", "You begin to shorten \the [src]...")
@@ -460,16 +362,3 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list(
if(AC.BB)
process_fire(user, user, FALSE)
. = TRUE
-
-
-/obj/item/suppressor
- name = "suppressor"
- desc = "A syndicate small-arms suppressor for maximum espionage."
- icon = 'icons/obj/guns/projectile.dmi'
- icon_state = "suppressor"
- w_class = WEIGHT_CLASS_TINY
-
-
-/obj/item/suppressor/specialoffer
- name = "cheap suppressor"
- desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits most weapons."
diff --git a/code/modules/projectiles/guns/ballistic/assault.dm b/code/modules/projectiles/guns/ballistic/assault.dm
index d0b69480a106..ce500cda930b 100644
--- a/code/modules/projectiles/guns/ballistic/assault.dm
+++ b/code/modules/projectiles/guns/ballistic/assault.dm
@@ -1,10 +1,10 @@
/obj/item/gun/ballistic/automatic/assault
- burst_size = 1
- actions_types = list()
- wield_delay = 0.7 SECONDS
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+ wield_delay = 0.8 SECONDS
wield_slowdown = 0.6
- fire_delay = 1
+ fire_delay = 0.2 SECONDS
load_sound = 'sound/weapons/gun/rifle/ar_reload.ogg'
load_empty_sound = 'sound/weapons/gun/rifle/ar_reload.ogg'
@@ -17,23 +17,29 @@
/obj/item/gun/ballistic/automatic/assault/calculate_recoil(mob/user, recoil_bonus = 0)
var/gunslinger_bonus = 2
var/total_recoil = recoil_bonus
+
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger penalty
total_recoil += gunslinger_bonus
- total_recoil = clamp(total_recoil,0,INFINITY)
- return total_recoil
+
+ return ..(user, total_recoil)
/obj/item/gun/ballistic/automatic/assault/calculate_spread(mob/user, bonus_spread)
- var/gunslinger_bonus = 8
+ var/gunslinger_bonus = 16
var/total_spread = bonus_spread
+
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger penalty
total_spread += gunslinger_bonus
- total_spread = clamp(total_spread,0,INFINITY)
- return total_spread
+
+ return ..(user, total_spread)
/obj/item/gun/ballistic/automatic/assault/skm
name = "\improper SKM-24"
desc = "An obsolete model of assault rifle once used by CLIP. Legendary for its durability and low cost, surplus rifles are commonplace on the Frontier, and the design has been widely copied. Chambered in 7.62x40mm CLIP."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/frontier_import/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/frontier_import/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/frontier_import/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/frontier_import/onmob.dmi'
+
fire_sound = 'sound/weapons/gun/rifle/skm.ogg'
rack_sound = 'sound/weapons/gun/rifle/skm_cocked.ogg'
@@ -44,8 +50,8 @@
icon_state = "skm"
item_state = "skm"
- mag_display = TRUE
- special_mags = TRUE
+ show_magazine_on_sprite = TRUE
+ unique_mag_sprites_for_variants = TRUE
weapon_weight = WEAPON_MEDIUM
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
@@ -55,9 +61,10 @@
spread = 1
wield_delay = 0.7 SECONDS
-/obj/item/gun/ballistic/automatic/assault/skm/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.2 SECONDS)
+ fire_delay = 0.2 SECONDS
+
+/obj/item/gun/ballistic/automatic/assault/skm/no_mag
+ spawnwithmagazine = FALSE
/obj/item/gun/ballistic/automatic/assault/skm/pirate
name = "\improper Chopper"
@@ -71,6 +78,11 @@
name = "\improper SKM-44"
desc = "An obsolete model of assault rifle once used by CLIP. Most of these were seized from Frontiersmen armories or purchased in CLIP, then modified to IRMG standards. Chambered in 7.62x40mm CLIP."
+ icon = 'icons/obj/guns/manufacturer/inteq/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/inteq/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/inteq/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/inteq/onmob.dmi'
+
icon_state = "skm_inteq"
item_state = "skm_inteq"
manufacturer = MANUFACTURER_INTEQ
@@ -82,96 +94,91 @@
fire_sound = 'sound/weapons/gun/rifle/m16.ogg'
icon_state = "p16"
item_state = "p16"
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
mag_type = /obj/item/ammo_box/magazine/p16
spread = 2
wield_delay = 0.5 SECONDS
+
+ fire_delay = 0.18 SECONDS
+
rack_sound = 'sound/weapons/gun/rifle/m16_cocked.ogg'
load_sound = 'sound/weapons/gun/rifle/m16_reload.ogg'
load_empty_sound = 'sound/weapons/gun/rifle/m16_reload.ogg'
eject_sound = 'sound/weapons/gun/rifle/m16_unload.ogg'
eject_empty_sound = 'sound/weapons/gun/rifle/m16_unload.ogg'
-/obj/item/gun/ballistic/automatic/assault/p16/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.2 SECONDS)
+/obj/item/gun/ballistic/automatic/assault/p16/no_mag
+ spawnwithmagazine = FALSE
/obj/item/gun/ballistic/automatic/assault/p16/minutemen
name = "\improper CM-16"
desc = "The standard-issue rifle of CLIP and an extensively modified reproduction of the P-16. Chambered in 5.56mm."
+ icon = 'icons/obj/guns/manufacturer/clip_lanchester/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/clip_lanchester/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/clip_lanchester/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/clip_lanchester/onmob.dmi'
icon_state = "cm16"
item_state = "cm16"
/obj/item/gun/ballistic/automatic/assault/swiss_cheese
name = "\improper Swiss Cheese"
- desc = "An ancient longarm famous for its boxy, modular design. The DMA on this unit is, sadly, broken. Uses 5.56mm ammunition for Matter mode."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ desc = "An ancient longarm famous for its boxy, modular design. Mass produced by the Terran Confederation in ages past, these often mutiple century old designs have survied due to their sheer ruggedness. The DMA on this unit is sadly broken, but these rifles are known for their excellent burst fire. Uses 5.56mm ammunition for Matter mode."
+ icon = 'icons/obj/guns/manufacturer/solararmories/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/solararmories/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/solararmories/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/solararmories/onmob.dmi'
fire_sound = 'sound/weapons/gun/rifle/swiss.ogg'
icon_state = "swiss"
item_state = "swiss"
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
empty_indicator = TRUE
burst_size = 3
- fire_delay = 1.5
+ burst_delay = 0.08 SECONDS
+ fire_delay = 0.25 SECONDS
spread = 8
weapon_weight = WEAPON_MEDIUM
+ gun_firenames = list(FIREMODE_SEMIAUTO = "matter semi-auto", FIREMODE_BURST = "matter burst fire", FIREMODE_FULLAUTO = "matter full auto", FIREMODE_OTHER = "hybrid")
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_BURST, FIREMODE_FULLAUTO, FIREMODE_OTHER)
+
+ fire_select_icon_state_prefix = "swisschesse_"
+
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
mag_type = /obj/item/ammo_box/magazine/swiss
- actions_types = list(/datum/action/item_action/toggle_firemode)
manufacturer = MANUFACTURER_SOLARARMORIES
spread = 8
spread_unwielded = 15
-/obj/item/gun/ballistic/automatic/assault/swiss_cheese/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.65 SECONDS)
-
-/obj/item/gun/ballistic/automatic/assault/swiss_cheese/afterattack(atom/target, mob/living/user, flag, params)
- if(select == 2)
- to_chat(user, "You hear a strange sound from the DMA unit. It doesn't appear to be operational.")
- return
- else
- return ..()
-
-/obj/item/gun/ballistic/automatic/assault/swiss_cheese/burst_select()
- var/mob/living/carbon/human/user = usr
- switch(select)
- if(1)
- select = 2
- to_chat(user, "You switch to Hybrid.")
- if(2)
- select = 1
- burst_size = initial(burst_size)
- fire_delay = initial(fire_delay)
- to_chat(user, "You switch to [burst_size]-rnd Matter.")
-
- playsound(user, 'sound/weapons/gun/general/selector.ogg', 100, TRUE)
- update_appearance()
- for(var/datum/action/action as anything in actions)
- action.UpdateButtonIcon()
-
-#define E40_BALLISTIC_MODE 1
-#define E40_LASER_MODE 2
+/obj/item/gun/ballistic/automatic/assault/swiss_cheese/process_other(atom/target, mob/living/user, message = TRUE, flag, params = null, zone_override = "", bonus_spread = 0)
+ to_chat(user, "You hear a strange sound from the DMA unit. It doesn't appear to be operational.")
/obj/item/gun/ballistic/automatic/assault/e40
name = "\improper E-40 Hybrid Rifle"
- desc = "A Hybrid Assault Rifle, best known for being having a dual ballistic and laser system. Chambered in .229 Eoehoma caseless, and uses energy for lasers."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ desc = "A Hybrid Assault Rifle, best known for being having a dual ballistic/laser system along with an advanced ammo counter. Once an icon for bounty hunters, age has broken most down, so these end up in collector's hands or as shoddy Frontiersmen laser SMG conversions when in their inheritted stockpiles. But if one were to find one in working condition, it would be just as formidable as back then. Chambered in .229 Eoehoma caseless, and uses energy for lasers."
+ icon = 'icons/obj/guns/manufacturer/eoehoma/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/eoehoma/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/eoehoma/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/eoehoma/onmob.dmi'
icon_state = "e40"
item_state = "e40"
mag_type = /obj/item/ammo_box/magazine/e40
- can_suppress = FALSE
- actions_types = list(/datum/action/item_action/toggle_firemode)
var/obj/item/gun/energy/laser/e40_laser_secondary/secondary
+ fire_select_icon_state_prefix = "e40_"
+
+ fire_delay = 0.18 SECONDS
+ recoil_unwielded = 3
+
+ gun_firenames = list(FIREMODE_FULLAUTO = "full auto ballistic", FIREMODE_OTHER = "full auto laser")
+ gun_firemodes = list(FIREMODE_FULLAUTO, FIREMODE_OTHER)
+ default_firemode = FIREMODE_OTHER
weapon_weight = WEAPON_MEDIUM
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
empty_indicator = TRUE
fire_sound = 'sound/weapons/gun/laser/e40_bal.ogg'
manufacturer = MANUFACTURER_EOEHOMA
@@ -179,56 +186,84 @@
/obj/item/gun/ballistic/automatic/assault/e40/Initialize()
. = ..()
secondary = new /obj/item/gun/energy/laser/e40_laser_secondary(src)
- AddComponent(/datum/component/automatic_fire, 0.2 SECONDS)
RegisterSignal(secondary, COMSIG_ATOM_UPDATE_ICON, PROC_REF(secondary_update_icon))
SEND_SIGNAL(secondary, COMSIG_GUN_DISABLE_AUTOFIRE)
update_appearance()
+/obj/item/gun/ballistic/automatic/assault/e40/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/ammo_hud/eoehoma) // at long last... the ammo counter on the side of the sprite is functional...
+
/obj/item/gun/ballistic/automatic/assault/e40/do_autofire(datum/source, atom/target, mob/living/shooter, params)
- if(select == E40_LASER_MODE)
- secondary.do_autofire(source, target, shooter, params)
- else
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
return ..()
+ return secondary.do_autofire(source, target, shooter, params)
/obj/item/gun/ballistic/automatic/assault/e40/do_autofire_shot(datum/source, atom/target, mob/living/shooter, params)
- if(select == E40_LASER_MODE)
- secondary.do_autofire_shot(source, target, shooter, params)
- else
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
return ..()
+ return secondary.do_autofire_shot(source, target, shooter, params)
/obj/item/gun/ballistic/automatic/assault/e40/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread)
- if(select == E40_LASER_MODE)
- secondary.process_fire(target, user, message, params, zone_override, bonus_spread)
- else
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
return ..()
+ return secondary.process_fire(target, user, message, params, zone_override, bonus_spread)
/obj/item/gun/ballistic/automatic/assault/e40/can_shoot()
- if(select == E40_LASER_MODE)
- return secondary.can_shoot()
- else
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
return ..()
+ return secondary.can_shoot()
/obj/item/gun/ballistic/automatic/assault/e40/afterattack(atom/target, mob/living/user, flag, params)
- if(select == E40_LASER_MODE)
- secondary.afterattack(target, user, flag, params)
- else
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
return ..()
+ return secondary.afterattack(target, user, flag, params)
/obj/item/gun/ballistic/automatic/assault/e40/attackby(obj/item/attack_obj, mob/user, params)
if(istype(attack_obj, /obj/item/stock_parts/cell/gun))
- secondary.attackby(attack_obj, user, params)
+ return secondary.attackby(attack_obj, user, params)
if(istype(attack_obj, /obj/item/screwdriver))
- secondary.screwdriver_act(user, attack_obj,)
- else
- ..()
+ return secondary.screwdriver_act(user, attack_obj,)
+ return ..()
+
/obj/item/gun/ballistic/automatic/assault/e40/can_shoot()
- if(select == E40_LASER_MODE)
- return secondary.can_shoot()
- return ..()
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
+ return ..()
+ return secondary.can_shoot()
+
+/obj/item/gun/ballistic/automatic/assault/e40/on_wield(obj/item/source, mob/user)
+ wielded = TRUE
+ secondary.wielded = TRUE
+ INVOKE_ASYNC(src, .proc.do_wield, user)
+
+/obj/item/gun/ballistic/automatic/assault/e40/do_wield(mob/user)
+ . = ..()
+ secondary.wielded_fully = wielded_fully
+
+/// triggered on unwield of two handed item
+/obj/item/gun/ballistic/automatic/assault/e40/on_unwield(obj/item/source, mob/user)
+ . = ..()
+ secondary.wielded_fully = FALSE
+ secondary.wielded = FALSE
+
/obj/item/gun/ballistic/automatic/assault/e40/proc/secondary_update_icon()
- update_icon()
+ update_appearance()
+ SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
+
+/obj/item/gun/ballistic/automatic/assault/e40/process_other(atom/target, mob/living/user, message = TRUE, flag, params = null, zone_override = "", bonus_spread = 0)
+ secondary.pre_fire(target, user, message, flag, params, zone_override, bonus_spread)
+
+
+/obj/item/gun/ballistic/automatic/powered/get_cell()
+ return cell
/obj/item/gun/ballistic/automatic/assault/e40/update_overlays()
. = ..()
@@ -244,48 +279,44 @@
. += "[icon_state]_cell"
-/obj/item/gun/ballistic/automatic/assault/e40/burst_select()
- var/mob/living/carbon/human/user = usr
- switch(select)
- if(NONE)
- select = E40_BALLISTIC_MODE
- to_chat(user, "You switch to full automatic ballistic.")
- if(E40_BALLISTIC_MODE)
- select = E40_LASER_MODE
- to_chat(user, "You switch to full auto laser.")
- SEND_SIGNAL(src, COMSIG_GUN_DISABLE_AUTOFIRE)
- SEND_SIGNAL(secondary, COMSIG_GUN_ENABLE_AUTOFIRE)
- if(E40_LASER_MODE)
- select = E40_BALLISTIC_MODE
- to_chat(user, "You switch to full automatic ballistic.")
- SEND_SIGNAL(src, COMSIG_GUN_ENABLE_AUTOFIRE)
- SEND_SIGNAL(secondary, COMSIG_GUN_DISABLE_AUTOFIRE)
- playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
- update_icon()
- return
-
-
-
/obj/item/gun/ballistic/automatic/assault/e40/toggle_safety(mob/user, silent=FALSE)
. = ..()
secondary.toggle_safety(user, silent=TRUE)
+/obj/item/gun/ballistic/automatic/assault/e40/fire_select(mob/living/carbon/human/user)
+ . = ..()
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode == FIREMODE_OTHER)
+ SEND_SIGNAL(src, COMSIG_GUN_ENABLE_AUTOFIRE)
+ SEND_SIGNAL(src, COMSIG_GUN_SET_AUTOFIRE_SPEED, secondary.fire_delay)
+ else
+ SEND_SIGNAL(src, COMSIG_GUN_SET_AUTOFIRE_SPEED, fire_delay)
+ SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
+
//laser
/obj/item/gun/energy/laser/e40_laser_secondary
name = "secondary e40 laser gun"
- desc = "The laser component of a E-40 Hybrid Rifle. You probably shouldn't see this."
+ desc = "The laser component of a E-40 Hybrid Rifle. You probably shouldn't see this. If you can though, you should probably know lorewise, this is primary, the ballistic compontent in universe is secondary. Unfortunately, we cannot simulate this, So codewise this is secondary."
fire_sound = 'sound/weapons/gun/laser/e40_las.ogg'
w_class = WEIGHT_CLASS_NORMAL
ammo_type = list(/obj/item/ammo_casing/energy/laser/assault)
- fire_delay = 2
+ fire_delay = 0.2 SECONDS
+ gun_firemodes = list(FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_FULLAUTO
+
+ spread_unwielded = 20
//techinically a battle rifle, i'm putting it here for organisation sake
-/obj/item/gun/ballistic/automatic/vickland //weapon designed by Apogee-dev
+/obj/item/gun/ballistic/automatic/marksman/vickland //weapon designed by Apogee-dev
name = "\improper Vickland"
desc = "The pride of the Saint-Roumain Militia, the Vickland is a rare semi-automatic battle rifle produced by Hunter's Pride exclusively for SRM use. It is unusual in its class for its internal rotary magazine, which must be reloaded using stripper clips. Chambered in .308."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
fire_sound = 'sound/weapons/gun/rifle/vickland.ogg'
icon_state = "vickland"
item_state = "vickland"
@@ -294,12 +325,14 @@
internal_magazine = TRUE
mag_type = /obj/item/ammo_box/magazine/internal/vickland
fire_sound = 'sound/weapons/gun/rifle/vickland.ogg'
- burst_size = 0
- actions_types = list()
+
manufacturer = MANUFACTURER_HUNTERSPRIDE
+ zoomable = FALSE //no scope on it
rack_sound = 'sound/weapons/gun/rifle/ar_cock.ogg'
+ fire_delay = 0.4 SECONDS
+
spread_unwielded = 25
recoil = 0
recoil_unwielded = 4
diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm
index ec57fd588021..769ea9e7f57e 100644
--- a/code/modules/projectiles/guns/ballistic/automatic.dm
+++ b/code/modules/projectiles/guns/ballistic/automatic.dm
@@ -1,10 +1,9 @@
+
/obj/item/gun/ballistic/automatic
w_class = WEIGHT_CLASS_NORMAL
- var/select = 1
- can_suppress = TRUE
- burst_size = 3
- fire_delay = 2
- actions_types = list(/datum/action/item_action/toggle_firemode)
+
+ gun_firemodes = list(FIREMODE_SEMIAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
semi_auto = TRUE
fire_sound = 'sound/weapons/gun/smg/shot.ogg'
fire_sound_volume = 90
@@ -14,6 +13,7 @@
weapon_weight = WEAPON_MEDIUM
pickup_sound = 'sound/items/handling/rifle_pickup.ogg'
+ fire_delay = 0.4 SECONDS
wield_delay = 1 SECONDS
spread = 0
spread_unwielded = 13
@@ -21,166 +21,40 @@
recoil_unwielded = 4
wield_slowdown = 0.35
-/obj/item/gun/ballistic/automatic/update_overlays()
- . = ..()
- if(!select)
- . += "[initial(icon_state)]_semi"
- if(select == 1)
- . += "[initial(icon_state)]_burst"
-
-/obj/item/gun/ballistic/automatic/ui_action_click(mob/user, actiontype)
- if(istype(actiontype, /datum/action/item_action/toggle_firemode))
- burst_select()
- else
- ..()
-
-/obj/item/gun/ballistic/automatic/proc/burst_select()
- var/mob/living/carbon/human/user = usr
- select = !select
- if(!select)
- burst_size = 1
- fire_delay = 0
- to_chat(user, "You switch to semi-automatic.")
- else
- burst_size = initial(burst_size)
- fire_delay = initial(fire_delay)
- to_chat(user, "You switch to [burst_size]-rnd burst.")
-
- playsound(user, 'sound/weapons/gun/general/selector.ogg', 100, TRUE)
- update_appearance()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
-
-// SNIPER //
-
-/obj/item/gun/ballistic/automatic/sniper_rifle
- name = "sniper rifle"
- desc = "An anti-material rifle chambered in .50 BMG with a scope mounted on it. Its prodigious bulk requires both hands to use."
- icon_state = "sniper"
- item_state = "sniper"
- fire_sound = 'sound/weapons/gun/sniper/shot.ogg'
- fire_sound_volume = 90
- vary_fire_sound = FALSE
- load_sound = 'sound/weapons/gun/sniper/mag_insert.ogg'
- rack_sound = 'sound/weapons/gun/sniper/rack.ogg'
- suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
- recoil = 2
- weapon_weight = WEAPON_HEAVY
- mag_type = /obj/item/ammo_box/magazine/sniper_rounds
- fire_delay = 40
- burst_size = 1
- w_class = WEIGHT_CLASS_NORMAL
- zoomable = TRUE
- zoom_amt = 10 //Long range, enough to see in front of you, but no tiles behind you.
- zoom_out_amt = 5
- slot_flags = ITEM_SLOT_BACK
- actions_types = list()
- mag_display = TRUE
- manufacturer = MANUFACTURER_SCARBOROUGH
-
- spread = -5
- spread_unwielded = 20
- recoil = 0
- recoil_unwielded = 4
- wield_slowdown = 1
- wield_delay = 1.3 SECONDS
-
-/obj/item/gun/ballistic/automatic/sniper_rifle/syndicate
- name = "syndicate sniper rifle"
- desc = "A heavily-modified .50 BMG anti-material rifle utilized by Syndicate agents. Requires both hands to fire."
- can_suppress = TRUE
- can_unsuppress = TRUE
- pin = /obj/item/firing_pin/implant/pindicate
-
// Old Semi-Auto Rifle //
-/obj/item/gun/ballistic/automatic/surplus
+/obj/item/gun/ballistic/automatic/surplus //TODO: NEEDS TO BE REPLACED WITH PISTOL CARBINES OR LOWCAL SEMI-AUTO RIFLES
name = "surplus rifle"
desc = "One of countless cheap, obsolete rifles found throughout the Frontier. Its lack of lethality renders it mostly a deterrent. Chambered in 10mm."
icon_state = "surplus"
item_state = "moistnugget"
weapon_weight = WEAPON_HEAVY
mag_type = /obj/item/ammo_box/magazine/m10mm/rifle
- fire_delay = 10
+ fire_delay = 0.5 SECONDS
burst_size = 1
- can_unsuppress = TRUE
- can_suppress = TRUE
w_class = WEIGHT_CLASS_HUGE
slot_flags = ITEM_SLOT_BACK
- actions_types = list()
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
// Laser rifle (rechargeable magazine) //
-/obj/item/gun/ballistic/automatic/laser
+/obj/item/gun/ballistic/automatic/laser //TODO: REMOVE
name = "laser rifle"
desc = "Though sometimes mocked for the relatively weak firepower of their energy weapons, the logistic miracle of rechargeable ammunition has given Nanotrasen a decisive edge over many a foe."
icon_state = "oldrifle"
item_state = "arg"
mag_type = /obj/item/ammo_box/magazine/recharge
- fire_delay = 2
- can_suppress = FALSE
+ fire_delay = 0.2 SECONDS
burst_size = 0
- actions_types = list()
fire_sound = 'sound/weapons/laser.ogg'
casing_ejector = FALSE
-/obj/item/gun/ballistic/automatic/ebr
- name = "\improper M514 EBR"
- desc = "A reliable, high-powered battle rifle often found in the hands of Syndicate personnel and remnants, chambered in .308. Effective against personnel and armor alike."
- icon = 'icons/obj/guns/48x32guns.dmi'
- lefthand_file = 'icons/mob/inhands/weapons/64x_guns_left.dmi'
- righthand_file = 'icons/mob/inhands/weapons/64x_guns_right.dmi'
- icon_state = "ebr"
- item_state = "ebr"
- zoomable = TRUE
- mag_display = TRUE
- weapon_weight = WEAPON_MEDIUM
- w_class = WEIGHT_CLASS_BULKY
- mag_type = /obj/item/ammo_box/magazine/ebr
- fire_sound = 'sound/weapons/gun/rifle/shot_alt2.ogg'
- burst_size = 0
- actions_types = list()
- manufacturer = MANUFACTURER_SCARBOROUGH
-
- wield_slowdown = 2
- spread = -4
-
-/obj/item/gun/ballistic/automatic/gal
- name = "\improper CM-GAL-S"
- desc = "The standard issue DMR of CLIP. Dates back to the Xenofauna War, this particular model is in a carbine configuration, and, as such, is shorter than the standard model. Chambered in .308."
- icon = 'icons/obj/guns/48x32guns.dmi'
- fire_sound = 'sound/weapons/gun/rifle/shot.ogg'
- icon_state = "gal"
- item_state = "gal"
- zoomable = TRUE
- mag_display = TRUE
- weapon_weight = WEAPON_MEDIUM
- w_class = WEIGHT_CLASS_BULKY
- mag_type = /obj/item/ammo_box/magazine/gal
- fire_sound = 'sound/weapons/gun/rifle/gal.ogg'
- burst_size = 0
- actions_types = list()
- manufacturer = MANUFACTURER_MINUTEMAN
-
- wield_slowdown = 2
- spread = -4
-
-/obj/item/gun/ballistic/automatic/gal/inteq
- name = "\improper SsG-04"
- desc = "A marksman rifle purchased from CLIP and modified to suit IRMG's needs. Chambered in .308."
- icon_state = "gal-inteq"
- item_state = "gal-inteq"
-
/obj/item/gun/ballistic/automatic/zip_pistol
name = "makeshift pistol"
desc = "A makeshift zip gun cobbled together from various scrap bits and chambered in 9mm. It's a miracle it even works."
icon_state = "ZipPistol"
item_state = "ZipPistol"
mag_type = /obj/item/ammo_box/magazine/zip_ammo_9mm
- can_suppress = FALSE
actions_types = list()
- can_bayonet = FALSE
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
weapon_weight = WEAPON_LIGHT
diff --git a/code/modules/projectiles/guns/ballistic/gauss.dm b/code/modules/projectiles/guns/ballistic/gauss.dm
index 8fce353d8b22..3fdc2e55dadd 100644
--- a/code/modules/projectiles/guns/ballistic/gauss.dm
+++ b/code/modules/projectiles/guns/ballistic/gauss.dm
@@ -1,17 +1,20 @@
/obj/item/gun/ballistic/automatic/powered/gauss
name = "prototype gauss rifle"
desc = "An experimental Nanotrasen rifle with a high capacity. Useful for putting down crowds. Chambered in ferromagnetic pellets."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "gauss"
item_state = "arg"
slot_flags = 0
mag_type = /obj/item/ammo_box/magazine/gauss
fire_sound = 'sound/weapons/gun/gauss/magrifle.ogg'
load_sound = 'sound/weapons/gun/gauss/rifle_reload.ogg'
- can_suppress = FALSE
burst_size = 1
- fire_delay = 3
+ fire_delay = 0.3 SECONDS
spread = 0
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
empty_indicator = TRUE
weapon_weight = WEAPON_MEDIUM
w_class = WEIGHT_CLASS_BULKY
@@ -25,11 +28,16 @@
recoil_unwielded = 4
wield_slowdown = 0.75
wield_delay = 1 SECONDS
+ fire_select_icon_state_prefix = "pellet_"
/obj/item/gun/ballistic/automatic/powered/gauss/modelh
name = "Model H"
desc = "A standard-issue pistol exported from the Solarian Confederation. It fires slow flesh-rending ferromagnetic slugs at a high energy cost, however they are ineffective on any armor."
mag_type = /obj/item/ammo_box/magazine/modelh
+ icon = 'icons/obj/guns/manufacturer/solararmories/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/solararmories/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/solararmories/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/solararmories/onmob.dmi'
icon_state = "model-h"
item_state = "model-h"
fire_sound = 'sound/weapons/gun/gauss/modelh.ogg'
@@ -37,14 +45,18 @@
cell_type = /obj/item/stock_parts/cell/gun/solgov
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
- fire_delay = 0 //pistol
- mag_display = FALSE
+ fire_delay = 0.6 SECONDS //pistol, but heavy caliber.
+ show_magazine_on_sprite = FALSE
empty_indicator = FALSE
manufacturer = MANUFACTURER_SOLARARMORIES
- recoil = 1
+ recoil = 2
recoil_unwielded = 4
- spread = 3
+ spread = 6
spread_unwielded = 12
+ fire_select_icon_state_prefix = "slug_"
+
+/obj/item/gun/ballistic/automatic/powered/gauss/modelh/no_mag
+ spawnwithmagazine = FALSE
/obj/item/gun/ballistic/automatic/powered/gauss/modelh/suns
desc = "A standard-issue pistol exported from the Solarian Confederation. It fires slow flesh-rending ferromagnetic slugs at a high energy cost, however they are ineffective on any armor. It is painted in the colors of SUNS."
@@ -56,19 +68,22 @@
name = "Claris"
desc = "An antiquated Solarian rifle. Chambered in ferromagnetic pellets, just as the founding Solarians intended."
mag_type = /obj/item/ammo_box/magazine/internal/claris
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/solararmories/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/solararmories/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/solararmories/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/solararmories/onmob.dmi'
icon_state = "claris"
item_state = "claris"
fire_sound = 'sound/weapons/gun/gauss/claris.ogg'
load_sound = 'sound/weapons/gun/gauss/sniper_reload.ogg'
cell_type = /obj/item/stock_parts/cell/gun/solgov
- fire_delay = 2
+ fire_delay = 0.4 SECONDS
bolt_type = BOLT_TYPE_NO_BOLT
internal_magazine = TRUE
- casing_ejector = FALSE
- mag_display = FALSE
+ show_magazine_on_sprite = FALSE
empty_indicator = FALSE
manufacturer = MANUFACTURER_SOLARARMORIES
+ fire_select_icon_state_prefix = "pellet_"
/obj/item/gun/ballistic/automatic/powered/gauss/claris/suns
desc = "An antiquated Solarian rifle. Chambered in ferromagnetic pellets, just as the founding Solarians intended. Evidently, SUNS' founders echo the sentiment, as it appears to be painted in their colors."
@@ -79,23 +94,28 @@
name = "Solar 'GAR' Carbine"
desc = "A Solarian carbine, unusually modern for its producers. Launches ferromagnetic lances at alarming speeds."
mag_type = /obj/item/ammo_box/magazine/gar
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/solararmories/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/solararmories/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/solararmories/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/solararmories/onmob.dmi'
icon_state = "gar"
item_state = "gar"
fire_sound = 'sound/weapons/gun/gauss/gar.ogg'
load_sound = 'sound/weapons/gun/gauss/rifle_reload.ogg'
cell_type = /obj/item/stock_parts/cell/gun/solgov
- burst_size = 2
- fire_delay = 1
+ burst_size = 1
+
+ fire_delay = 0.2 SECONDS
+
actions_types = list()
empty_indicator = FALSE
manufacturer = MANUFACTURER_SOLARARMORIES
- wield_delay = 0.7 SECONDS
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
-/obj/item/gun/ballistic/automatic/powered/gauss/gar/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.2 SECONDS)
+ wield_delay = 0.7 SECONDS
+ fire_select_icon_state_prefix = "lance_"
/obj/item/gun/ballistic/automatic/powered/gauss/gar/suns
desc = "A Solarian carbine, unusually modern for its producers. It's just modern enough for SUNS, however, who have painted the weapon in their colors. Launches ferromagnetic lances at alarming speeds."
diff --git a/code/modules/projectiles/guns/ballistic/hmg.dm b/code/modules/projectiles/guns/ballistic/hmg.dm
index 3bd143e98b43..8a3e68b9a6ec 100644
--- a/code/modules/projectiles/guns/ballistic/hmg.dm
+++ b/code/modules/projectiles/guns/ballistic/hmg.dm
@@ -7,7 +7,10 @@
burst_size = 1
actions_types = list(/datum/action/item_action/deploy_bipod) //this is on hmg, as I need the same mechanics for a future gun. ideally, this would be an attachment, but that's still pending
drag_slowdown = 1.5
- fire_delay = 1
+ fire_delay = 0.1 SECONDS
+
+ gun_firemodes = list(FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_FULLAUTO
spread = 4
spread_unwielded = 80
@@ -85,7 +88,7 @@
if(!can_deploy)
to_chat(user, "You need to brace against something to deploy [src]'s bipod! Either lie on the floor or stand next to a waist high object like a table!")
return
- if(!do_mob(user, src, deploy_time, FALSE, TRUE, CALLBACK(src, PROC_REF(is_wielded))))
+ if(!do_after(user, deploy_time, src, NONE, TRUE, CALLBACK(src, PROC_REF(is_wielded))))
to_chat(user, "You need to hold still to deploy [src]'s bipod!")
return
playsound(src, 'sound/machines/click.ogg', 75, TRUE)
@@ -114,24 +117,26 @@
retract_bipod(user=user)
/obj/item/gun/ballistic/automatic/hmg/calculate_recoil(mob/user, recoil_bonus = 0)
- var/gunslinger_bonus = 1
+ var/gunslinger_bonus = 2
var/total_recoil = recoil_bonus
+
if(bipod_deployed)
total_recoil += deploy_recoil_bonus
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger penalty
total_recoil += gunslinger_bonus
- total_recoil = clamp(total_recoil,0,INFINITY)
- return total_recoil
+
+ return ..(user, total_recoil)
/obj/item/gun/ballistic/automatic/hmg/calculate_spread(mob/user, bonus_spread)
- var/gunslinger_bonus = 4
+ var/gunslinger_bonus = 20
var/total_spread = bonus_spread
+
if(bipod_deployed)
total_spread += deploy_spread_bonus
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger penalty
total_spread += gunslinger_bonus
- total_spread = clamp(total_spread,0,INFINITY)
- return total_spread
+
+ return ..(user, total_spread)
/obj/item/gun/ballistic/automatic/hmg/update_icon_state()
@@ -149,15 +154,22 @@
/obj/item/gun/ballistic/automatic/hmg/l6_saw
name = "\improper L6 SAW"
desc = "A heavy machine gun, designated 'L6 SAW'. Chambered in 7.12x82mm."
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
icon_state = "l6"
item_state = "l6closedmag"
base_icon_state = "l6"
+
mag_type = /obj/item/ammo_box/magazine/mm712x82
- can_suppress = FALSE
spread = 7
+
+ fire_delay = 0.1 SECONDS
+
bolt_type = BOLT_TYPE_OPEN
- mag_display = TRUE
- mag_display_ammo = TRUE
+ show_magazine_on_sprite = TRUE
+ show_magazine_on_sprite_ammo = TRUE
tac_reloads = FALSE
fire_sound = 'sound/weapons/gun/l6/shot.ogg'
rack_sound = 'sound/weapons/gun/l6/l6_rack.ogg'
@@ -165,10 +177,6 @@
manufacturer = MANUFACTURER_SCARBOROUGH
var/cover_open = FALSE
-/obj/item/gun/ballistic/automatic/hmg/l6_saw/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.1 SECONDS)
-
/obj/item/gun/ballistic/automatic/hmg/l6_saw/examine(mob/user)
. = ..()
. += "alt + click to [cover_open ? "close" : "open"] the dust cover."
@@ -212,26 +220,34 @@
/obj/item/gun/ballistic/automatic/hmg/solar //This thing fires a 5.56 equivalent, that's an LMG, not an HMG, get out
name = "\improper Solar"
desc = "A TerraGov LMG-169 designed in 169 FS, nicknamed 'Solar.' A inscription reads: 'PROPERTY OF TERRAGOV', with 'TERRAGOV' poorly scribbled out, and replaced by 'SOLAR ARMORIES'. Chambered in 4.73×33mm caseless ammunition."
+ icon = 'icons/obj/guns/manufacturer/solararmories/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/solararmories/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/solararmories/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/solararmories/onmob.dmi'
+
icon_state = "solar"
+
fire_sound = 'sound/weapons/gun/l6/shot.ogg'
- item_state = "arg"
mag_type = /obj/item/ammo_box/magazine/rifle47x33mm
spread = 7
- can_suppress = FALSE
- can_bayonet = FALSE
- mag_display = TRUE
+
+ fire_delay = 0.1 SECONDS
+
+ fire_select_icon_state_prefix = "caseless_"
+
+ show_magazine_on_sprite = TRUE
w_class = WEIGHT_CLASS_BULKY
manufacturer = MANUFACTURER_SOLARARMORIES
-/obj/item/gun/ballistic/automatic/hmg/solar/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.1 SECONDS)
-
/obj/item/gun/ballistic/automatic/hmg/skm_lmg
name = "\improper SKM-24u"
desc = "What appears to be a standard SKM-24 at first glance is actually a light machine gun conversion, with an extended, heavy barrel and overhauled internals. Its weight, bulk, and robust fire rate make it difficult to handle without using the bipod in a prone position or against appropriate cover such as a table. Chambered in 7.62x40mm CLIP."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/frontier_import/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/frontier_import/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/frontier_import/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/frontier_import/onmob.dmi'
+
icon_state = "skm_lmg"
item_state = "skm_lmg"
@@ -242,15 +258,18 @@
eject_sound = 'sound/weapons/gun/rifle/skm_unload.ogg'
eject_empty_sound = 'sound/weapons/gun/rifle/skm_unload.ogg'
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
- mag_display = TRUE
- special_mags = TRUE
+ show_magazine_on_sprite = TRUE
+ unique_mag_sprites_for_variants = TRUE
weapon_weight = WEAPON_MEDIUM
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
manufacturer = MANUFACTURER_IMPORT
mag_type = /obj/item/ammo_box/magazine/skm_762_40
+ fire_delay = 0.13 SECONDS
spread = 7 //you can hipfire, but why?
spread_unwielded = 25
@@ -265,7 +284,6 @@
/obj/item/gun/ballistic/automatic/hmg/skm_lmg/ComponentInitialize()
. = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS) //slower than other lmgs but faster than skm and most smgs
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/gun/ballistic/automatic/hmg/skm_lmg/extended //spawns with the proper extended magazine, for erts
diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm
index 614aa7a884c1..f18f97cd0f4f 100644
--- a/code/modules/projectiles/guns/ballistic/launchers.dm
+++ b/code/modules/projectiles/guns/ballistic/launchers.dm
@@ -4,18 +4,15 @@
/obj/item/gun/ballistic/revolver/grenadelauncher//this is only used for underbarrel grenade launchers at the moment, but admins can still spawn it if they feel like being assholes
desc = "A break-action, single-shot grenade launcher. A compact way to deliver a big boom."
name = "grenade launcher"
- icon = 'icons/obj/guns/48x32guns.dmi'
- icon_state = "dshotgun_sawn"
- item_state = "gun"
mag_type = /obj/item/ammo_box/magazine/internal/grenadelauncher
fire_sound = 'sound/weapons/gun/general/grenade_launch.ogg'
w_class = WEIGHT_CLASS_NORMAL
- pin = /obj/item/firing_pin/implant/pindicate
bolt_type = BOLT_TYPE_NO_BOLT
- fire_delay = 10
-
-/obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted
- pin = /obj/item/firing_pin
+ fire_delay = 1 SECONDS
+ semi_auto = TRUE
+ has_safety = FALSE
+ safety = FALSE
+ gate_offset = 0
/obj/item/gun/ballistic/revolver/grenadelauncher/attackby(obj/item/A, mob/user, params)
..()
@@ -28,7 +25,6 @@
icon = 'icons/mecha/mecha_equipment.dmi'
icon_state = "mecha_grenadelnchr"
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/grenademulti
- pin = /obj/item/firing_pin
/obj/item/gun/ballistic/revolver/grenadelauncher/cyborg/attack_self()
return
@@ -40,23 +36,27 @@
fire_sound = 'sound/weapons/gun/general/grenade_launch.ogg'
mag_type = /obj/item/ammo_box/magazine/m75
burst_size = 1
- fire_delay = 0
+ fire_delay = 0.4 SECONDS
actions_types = list()
casing_ejector = FALSE
/obj/item/gun/ballistic/rocketlauncher
name = "\improper PML-9"
desc = "A reusable rocket-propelled grenade launcher. The words \"NT this way\" and an arrow have been written near the barrel."
+
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+
icon_state = "rocketlauncher"
item_state = "rocketlauncher"
mag_type = /obj/item/ammo_box/magazine/internal/rocketlauncher
fire_sound = 'sound/weapons/gun/general/rocket_launch.ogg'
load_sound = 'sound/weapons/gun/general/rocket_load.ogg'
w_class = WEIGHT_CLASS_BULKY
- can_suppress = FALSE
- pin = /obj/item/firing_pin
burst_size = 1
- fire_delay = 0
+ fire_delay = 0.4 SECONDS
casing_ejector = FALSE
weapon_weight = WEAPON_HEAVY
bolt_type = BOLT_TYPE_NO_BOLT
@@ -66,9 +66,6 @@
tac_reloads = FALSE
manufacturer = MANUFACTURER_SCARBOROUGH
-/obj/item/gun/ballistic/rocketlauncher/unrestricted
- pin = /obj/item/firing_pin
-
/obj/item/gun/ballistic/rocketlauncher/afterattack()
. = ..()
magazine.get_round(FALSE) //Hack to clear the mag after it's fired
@@ -79,7 +76,12 @@
/obj/item/gun/ballistic/rocketlauncher/solgov
name = "Panzerfaust XII"
desc = "The standard recoiless rifle of the Solarian Confederation. Barely varies from previous models."
- icon = 'icons/obj/guns/48x32guns.dmi'
+
+ icon = 'icons/obj/guns/manufacturer/solararmories/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/solararmories/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/solararmories/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/solararmories/onmob.dmi'
+
icon_state = "panzerfaust"
item_state = "panzerfaust"
manufacturer = MANUFACTURER_SOLARARMORIES
diff --git a/code/modules/projectiles/guns/ballistic/marksman.dm b/code/modules/projectiles/guns/ballistic/marksman.dm
new file mode 100644
index 000000000000..46a9e2466290
--- /dev/null
+++ b/code/modules/projectiles/guns/ballistic/marksman.dm
@@ -0,0 +1,102 @@
+
+/obj/item/gun/ballistic/automatic/marksman
+ burst_size = 1
+ zoomable = TRUE //this var as true without setting anything else produces a 2x zoom
+ wield_slowdown = 2
+ wield_delay = 1 SECONDS
+
+// SNIPER //
+
+/obj/item/gun/ballistic/automatic/marksman/sniper_rifle
+ name = "sniper rifle"
+ desc = "An anti-material rifle chambered in .50 BMG with a scope mounted on it. Its prodigious bulk requires both hands to use."
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+ icon_state = "sniper"
+ item_state = "sniper"
+ fire_sound = 'sound/weapons/gun/sniper/shot.ogg'
+ fire_sound_volume = 90
+ vary_fire_sound = FALSE
+ load_sound = 'sound/weapons/gun/sniper/mag_insert.ogg'
+ rack_sound = 'sound/weapons/gun/sniper/rack.ogg'
+ suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
+ weapon_weight = WEAPON_HEAVY
+ mag_type = /obj/item/ammo_box/magazine/sniper_rounds
+ w_class = WEIGHT_CLASS_BULKY
+ zoom_amt = 10 //Long range, enough to see in front of you, but no tiles behind you.
+ zoom_out_amt = 5
+ slot_flags = ITEM_SLOT_BACK
+ actions_types = list()
+ show_magazine_on_sprite = TRUE
+ manufacturer = MANUFACTURER_SCARBOROUGH
+
+ spread = -5
+ spread_unwielded = 40
+ recoil = 5
+ recoil_unwielded = 50
+
+ wield_delay = 1.3 SECONDS
+
+EMPTY_GUN_HELPER(automatic/marksman/sniper_rifle)
+
+/obj/item/gun/ballistic/automatic/marksman/ebr //fuck this gun, its getting wiped soon enough
+ name = "\improper M514 EBR"
+ desc = "A reliable, high-powered battle rifle often found in the hands of Syndicate personnel and remnants, chambered in .308. Effective against personnel and armor alike."
+
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+
+ icon_state = "ebr"
+ item_state = "ebr"
+ zoomable = TRUE
+ show_magazine_on_sprite = TRUE
+ weapon_weight = WEAPON_MEDIUM
+ w_class = WEIGHT_CLASS_BULKY
+ mag_type = /obj/item/ammo_box/magazine/ebr
+ fire_sound = 'sound/weapons/gun/rifle/shot_alt2.ogg'
+ manufacturer = MANUFACTURER_SCARBOROUGH
+
+ wield_slowdown = 2
+ spread = -4
+
+EMPTY_GUN_HELPER(automatic/marksman/ebr)
+
+/obj/item/gun/ballistic/automatic/marksman/gal
+ name = "\improper CM-GAL-S"
+ desc = "The standard issue DMR of CLIP. Dates back to the Xenofauna War, this particular model is in a carbine configuration, and, as such, is shorter than the standard model. Chambered in .308."
+
+ icon = 'icons/obj/guns/manufacturer/clip_lanchester/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/clip_lanchester/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/clip_lanchester/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/clip_lanchester/onmob.dmi'
+
+ fire_sound = 'sound/weapons/gun/rifle/shot.ogg'
+ icon_state = "gal"
+ item_state = "gal"
+ show_magazine_on_sprite = TRUE
+ weapon_weight = WEAPON_MEDIUM
+ w_class = WEIGHT_CLASS_BULKY
+ mag_type = /obj/item/ammo_box/magazine/gal
+ fire_sound = 'sound/weapons/gun/rifle/gal.ogg'
+ burst_size = 0
+ actions_types = list()
+ manufacturer = MANUFACTURER_MINUTEMAN
+
+ wield_slowdown = 2
+ spread = -4
+ fire_select_icon_state_prefix = "clip_"
+ adjust_fire_select_icon_state_on_safety = TRUE
+
+/obj/item/gun/ballistic/automatic/marksman/gal/inteq
+ name = "\improper SsG-04"
+ desc = "A marksman rifle purchased from CLIP and modified to suit IRMG's needs. Chambered in .308."
+ icon = 'icons/obj/guns/manufacturer/inteq/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/inteq/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/inteq/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/inteq/onmob.dmi'
+ icon_state = "gal-inteq"
+ item_state = "gal-inteq"
diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm
index 1cb86fec256d..b2416462da39 100644
--- a/code/modules/projectiles/guns/ballistic/pistol.dm
+++ b/code/modules/projectiles/guns/ballistic/pistol.dm
@@ -1,48 +1,57 @@
/obj/item/gun/ballistic/automatic/pistol
+ bolt_type = BOLT_TYPE_LOCKING
+
+ vary_fire_sound = FALSE
+ fire_sound_volume = 90
+ bolt_wording = "slide"
+ weapon_weight = WEAPON_LIGHT
+ pickup_sound = 'sound/items/handling/gun_pickup.ogg'
+
+ recoil = 0.5 // apogee wants bloom, this is a placeholder until then to simulate the same concept.
+ recoil_unwielded = 3
+ recoil_backtime_multiplier = 1
+
+ wield_delay = 0.2 SECONDS
+ fire_delay = 0.2 SECONDS
+ spread = 5
+ spread_unwielded = 7
+ wield_slowdown = 0.15
+
+ muzzleflash_iconstate = "muzzle_flash_light"
+
+/obj/item/gun/ballistic/automatic/pistol/syndicate
name = "Stechkin"
desc = "A small, easily concealable 10mm handgun that bears Scarborough Arms stamps. Has a threaded barrel for suppressors."
icon_state = "pistol"
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+
w_class = WEIGHT_CLASS_SMALL
mag_type = /obj/item/ammo_box/magazine/m10mm
- can_suppress = TRUE
- burst_size = 1
- fire_delay = 0 //spam it as fast as you can
- actions_types = list()
- bolt_type = BOLT_TYPE_LOCKING
fire_sound = 'sound/weapons/gun/pistol/shot.ogg'
dry_fire_sound = 'sound/weapons/gun/pistol/dry_fire.ogg'
suppressed_sound = 'sound/weapons/gun/pistol/shot_suppressed.ogg'
+
load_sound = 'sound/weapons/gun/pistol/mag_insert_alt.ogg'
load_empty_sound = 'sound/weapons/gun/pistol/mag_insert_alt.ogg'
eject_sound = 'sound/weapons/gun/pistol/mag_release_alt.ogg'
eject_empty_sound = 'sound/weapons/gun/pistol/mag_release_alt.ogg'
- vary_fire_sound = FALSE
+
rack_sound = 'sound/weapons/gun/pistol/rack_small.ogg'
lock_back_sound = 'sound/weapons/gun/pistol/lock_small.ogg'
bolt_drop_sound = 'sound/weapons/gun/pistol/drop_small.ogg'
- fire_sound_volume = 90
- bolt_wording = "slide"
- weapon_weight = WEAPON_LIGHT
- pickup_sound = 'sound/items/handling/gun_pickup.ogg'
- fire_delay = 1
- manufacturer = MANUFACTURER_SCARBOROUGH
-
- wield_delay = 0.2 SECONDS
- spread = 2
- spread_unwielded = 5
- wield_slowdown = 0.15
- muzzleflash_iconstate = "muzzle_flash_light"
+ manufacturer = MANUFACTURER_SCARBOROUGH
-/obj/item/gun/ballistic/automatic/pistol/no_mag
- spawnwithmagazine = FALSE
+ spread = 6 //becuase its compact, spread is slightly worse
+ spread_unwielded = 9
+ recoil_unwielded = 2
-/obj/item/gun/ballistic/automatic/pistol/suppressed/Initialize(mapload)
- . = ..()
- var/obj/item/suppressor/S = new(src)
- install_suppressor(S)
+EMPTY_GUN_HELPER(automatic/pistol/syndicate)
-/obj/item/gun/ballistic/automatic/pistol/suns
+/obj/item/gun/ballistic/automatic/pistol/syndicate/suns
desc = "A small, easily concealable 10mm handgun that bears Scarborough Arms stamps. It is painted in the colors of SUNS."
icon_state = "pistol_suns"
@@ -51,9 +60,12 @@
desc = "A classic semi-automatic handgun, widely popular throughout the Frontier. An engraving on the slide marks it as a product of Hunter's Pride. Chambered in .45."
icon_state = "candor"
item_state = "hp_generic"
- w_class = WEIGHT_CLASS_NORMAL
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
mag_type = /obj/item/ammo_box/magazine/m45
- can_suppress = FALSE
fire_sound = 'sound/weapons/gun/pistol/candor.ogg'
rack_sound = 'sound/weapons/gun/pistol/candor_cocked.ogg'
lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg'
@@ -63,30 +75,37 @@
load_empty_sound = 'sound/weapons/gun/pistol/candor_reload.ogg'
eject_sound = 'sound/weapons/gun/pistol/candor_unload.ogg'
eject_empty_sound = 'sound/weapons/gun/pistol/candor_unload.ogg'
- recoil = -2
-/obj/item/gun/ballistic/automatic/pistol/candor/no_mag
- spawnwithmagazine = FALSE
+EMPTY_GUN_HELPER(automatic/pistol/candor)
/obj/item/gun/ballistic/automatic/pistol/candor/factory //also give this to the srm, their candors should probably look factory fresh from how well taken care of they are
- desc = "A classic semi-automatic handgun, widely popular throughout the Frontier. An engraving on the slide marks it as a product of Hunter's Pride. This example has been kept in especially good shape, and may as well be fresh out of the workshop. Chambered in .45."
+ desc = "A classic semi-automatic handgun, widely popular throughout the Frontier. An engraving on the slide marks it as a product of 'Hunter's Pride Arms and Ammunition'. This example has been kept in especially good shape, and may as well be fresh out of the workshop. Chambered in .45."
item_state = "hp_generic_fresh"
+EMPTY_GUN_HELPER(automatic/pistol/candor/factory)
+
/obj/item/gun/ballistic/automatic/pistol/candor/factory/update_overlays()
. = ..()
. += "[initial(icon_state)]_factory"
-/obj/item/gun/ballistic/automatic/pistol/candor/factory/no_mag
- spawnwithmagazine = FALSE
+/obj/item/gun/ballistic/automatic/pistol/candor/phenex
+ name = "\improper HP Phenex"
+ desc = "A uniquely modified version of the Candor, famously created by Hunter's Pride. Named after the daemonic Phoenix of legend that the Ashen Huntsman had once slain, this hell-kissed weapon is more visually intimidating than its original counterpart, but mechanically acts the same. Chambered in .45."
+ icon_state = "phenex"
+ item_state = "hp_phenex"
/obj/item/gun/ballistic/automatic/pistol/deagle
name = "\improper Desert Eagle"
desc = "An oversized handgun chambered in .50 AE. A true hand cannon."
+ icon = 'icons/obj/guns/manufacturer/frontier_import/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/frontier_import/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/frontier_import/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/frontier_import/onmob.dmi'
icon_state = "deagle"
force = 14
mag_type = /obj/item/ammo_box/magazine/m50
- can_suppress = FALSE
mag_display = TRUE
+ show_magazine_on_sprite = TRUE
fire_sound = 'sound/weapons/gun/pistol/deagle.ogg'
rack_sound = 'sound/weapons/gun/pistol/rack.ogg'
lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg'
@@ -96,11 +115,13 @@
load_empty_sound = 'sound/weapons/gun/pistol/deagle_reload.ogg'
eject_sound = 'sound/weapons/gun/pistol/deagle_unload.ogg'
eject_empty_sound = 'sound/weapons/gun/pistol/deagle_unload.ogg'
- fire_delay = 0.7 SECONDS
- recoil = 1
- recoil_unwielded = 2
- spread = 4
- spread_unwielded = 7
+ fire_delay = 0.6 SECONDS
+ recoil = 2
+ recoil_unwielded = 5
+ recoil_backtime_multiplier = 2
+
+ spread = 7
+ spread_unwielded = 14
/obj/item/gun/ballistic/automatic/pistol/deagle/gold
desc = "A gold-plated Desert Eagle folded over a million times by superior Martian gunsmiths. Uses .50 AE ammo."
@@ -116,37 +137,44 @@
name = "stechkin APS pistol"
desc = "A burst-fire machine pistol based on the stechkin model. Utilizes specialized 9mm magazines."
icon_state = "aps"
- w_class = WEIGHT_CLASS_SMALL
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+
+
mag_type = /obj/item/ammo_box/magazine/pistolm9mm
- can_suppress = FALSE
- burst_size = 3
- fire_delay = 2
- actions_types = list(/datum/action/item_action/toggle_firemode)
-/obj/item/gun/ballistic/automatic/pistol/stickman
- name = "flat gun"
- desc = "A 2 dimensional gun.. what?"
- icon_state = "flatgun"
- manufacturer = MANUFACTURER_NONE
+ fire_sound = 'sound/weapons/gun/pistol/shot.ogg'
+ dry_fire_sound = 'sound/weapons/gun/pistol/dry_fire.ogg'
+ suppressed_sound = 'sound/weapons/gun/pistol/shot_suppressed.ogg'
+
+ load_sound = 'sound/weapons/gun/pistol/mag_insert_alt.ogg'
+ load_empty_sound = 'sound/weapons/gun/pistol/mag_insert_alt.ogg'
+ eject_sound = 'sound/weapons/gun/pistol/mag_release_alt.ogg'
+ eject_empty_sound = 'sound/weapons/gun/pistol/mag_release_alt.ogg'
-/obj/item/gun/ballistic/automatic/pistol/stickman/pickup(mob/living/user)
- SHOULD_CALL_PARENT(0)
- to_chat(user, "As you try to pick up [src], it slips out of your grip..")
- if(prob(50))
- to_chat(user, "..and vanishes from your vision! Where the hell did it go?")
- qdel(src)
- user.update_icons()
- else
- to_chat(user, "..and falls into view. Whew, that was a close one.")
- user.dropItemToGround(src)
+ rack_sound = 'sound/weapons/gun/pistol/rack_small.ogg'
+ lock_back_sound = 'sound/weapons/gun/pistol/lock_small.ogg'
+ bolt_drop_sound = 'sound/weapons/gun/pistol/drop_small.ogg'
+
+ burst_size = 3
+ burst_delay = 0.1 SECONDS
+ fire_delay = 0.4 SECONDS
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_BURST)
+ default_firemode = FIREMODE_SEMIAUTO
/obj/item/gun/ballistic/automatic/pistol/commander
name = "\improper Commander"
desc = "A classic handgun in a tasteful black and stainless steel color scheme. An enamel Nanotrasen logo is set into the grips. Chambered in 9mm."
icon_state = "commander"
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
+
w_class = WEIGHT_CLASS_NORMAL
mag_type = /obj/item/ammo_box/magazine/co9mm
- can_suppress = FALSE
manufacturer = MANUFACTURER_NANOTRASEN
fire_sound = 'sound/weapons/gun/pistol/commander.ogg'
load_sound = 'sound/weapons/gun/pistol/mag_insert.ogg'
@@ -154,26 +182,36 @@
eject_sound = 'sound/weapons/gun/pistol/mag_release.ogg'
eject_empty_sound = 'sound/weapons/gun/pistol/mag_release.ogg'
-/obj/item/gun/ballistic/automatic/pistol/commander/no_mag
- spawnwithmagazine = FALSE
+ rack_sound = 'sound/weapons/gun/pistol/rack_small.ogg'
+ lock_back_sound = 'sound/weapons/gun/pistol/lock_small.ogg'
+ bolt_drop_sound = 'sound/weapons/gun/pistol/drop_small.ogg'
+
+EMPTY_GUN_HELPER(automatic/pistol/commander)
/obj/item/gun/ballistic/automatic/pistol/commander/inteq
name = "\improper Commissioner"
desc = "A handgun seized from Nanotrasen armories by deserting troopers and modified to IRMG's standards. A yellow IRMG shield is set into the grips. Chambered in 9mm."
+ icon = 'icons/obj/guns/manufacturer/inteq/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/inteq/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/inteq/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/inteq/onmob.dmi'
icon_state = "commander-inteq"
item_state = "commander-inteq"
manufacturer = MANUFACTURER_INTEQ
-/obj/item/gun/ballistic/automatic/pistol/commander/inteq/no_mag
- spawnwithmagazine = FALSE
+EMPTY_GUN_HELPER(automatic/pistol/commander/inteq)
/obj/item/gun/ballistic/automatic/pistol/commissar
name = "\improper Commissar"
desc = "A Nanotrasen-issue handgun, modified with a voice box to further enhance its effectiveness in troop discipline."
icon_state = "commander"
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
+
w_class = WEIGHT_CLASS_NORMAL
mag_type = /obj/item/ammo_box/magazine/co9mm
- can_suppress = FALSE
var/funnysounds = TRUE
var/cooldown = 0
load_sound = 'sound/weapons/gun/pistol/mag_insert.ogg'
@@ -181,6 +219,10 @@
eject_sound = 'sound/weapons/gun/pistol/mag_release.ogg'
eject_empty_sound = 'sound/weapons/gun/pistol/mag_release.ogg'
+ rack_sound = 'sound/weapons/gun/pistol/rack_small.ogg'
+ lock_back_sound = 'sound/weapons/gun/pistol/lock_small.ogg'
+ bolt_drop_sound = 'sound/weapons/gun/pistol/drop_small.ogg'
+
/obj/item/gun/ballistic/automatic/pistol/commissar/equipped(mob/living/user, slot)
..()
if(slot == ITEM_SLOT_HANDS && funnysounds) // We do this instead of equip_sound as we only want this to play when it's wielded
@@ -209,6 +251,7 @@
to_chat(user, "You toggle [src]'s vox audio functions.")
/obj/item/gun/ballistic/automatic/pistol/commissar/AltClick(mob/user)
+ . = ..()
if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if((cooldown < world.time - 200) && funnysounds)
@@ -225,6 +268,11 @@
name = "\improper Pistole C"
desc = "A favorite of the Terran Regency that is despised by the Solarian bureaucracy. Shifted out of military service centuries ago, though still popular among civilians. Chambered in 5.56mm caseless."
icon_state = "pistole-c"
+ icon = 'icons/obj/guns/manufacturer/solararmories/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/solararmories/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/solararmories/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/solararmories/onmob.dmi'
+
weapon_weight = WEAPON_LIGHT
w_class = WEIGHT_CLASS_SMALL
mag_type = /obj/item/ammo_box/magazine/pistol556mm
@@ -235,31 +283,46 @@
eject_sound = 'sound/weapons/gun/pistol/mag_release.ogg'
eject_empty_sound = 'sound/weapons/gun/pistol/mag_release.ogg'
+ rack_sound = 'sound/weapons/gun/pistol/rack_small.ogg'
+ lock_back_sound = 'sound/weapons/gun/pistol/lock_small.ogg'
+ bolt_drop_sound = 'sound/weapons/gun/pistol/drop_small.ogg'
+
+ fire_select_icon_state_prefix = "caseless_"
+
/obj/item/gun/ballistic/automatic/pistol/solgov/old
icon_state = "pistole-c-old"
-/obj/item/gun/ballistic/automatic/pistol/tec9
+/obj/item/gun/ballistic/automatic/pistol/tec9 //fucking kill this gun already my god
name = "\improper TEC-9 machine pistol"
desc = "A crude machine pistol designed to vomit 9mm ammunition at a truly eye-watering rate of fire."
icon_state = "tec9"
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+
+ fire_delay = 0.15 SECONDS
weapon_weight = WEAPON_LIGHT
- w_class = WEIGHT_CLASS_SMALL
+ w_class = WEIGHT_CLASS_NORMAL
mag_type = /obj/item/ammo_box/magazine/tec9
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
load_sound = 'sound/weapons/gun/pistol/mag_insert.ogg'
load_empty_sound = 'sound/weapons/gun/pistol/mag_insert.ogg'
eject_sound = 'sound/weapons/gun/pistol/mag_release.ogg'
eject_empty_sound = 'sound/weapons/gun/pistol/mag_release.ogg'
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
/obj/item/gun/ballistic/automatic/pistol/disposable
name = "disposable gun"
desc = "An exceedingly flimsy plastic gun that is extremely cheap to produce. You get what you pay for."
fire_sound = 'sound/weapons/gun/pistol/himehabu.ogg'
- icon_state = "disposable" //credit to discord user any% for the sprite
+
+ icon_state = "disposable" //credit to discord user 20nypercent for the sprite
w_class = WEIGHT_CLASS_NORMAL
mag_type = /obj/item/ammo_box/magazine/disposable
custom_materials = list(/datum/material/plastic=2000)
- can_suppress = FALSE
manufacturer = MANUFACTURER_NONE
has_safety = FALSE //thing barely costs anything, why would it have a safety?
safety = FALSE
@@ -272,17 +335,17 @@
to_chat(user, "Theres no magazine to replace!")
return
-/obj/item/gun/ballistic/automatic/pistol/disposable/pizza
- name = "pizza disposable gun"
- desc = "How horrible. Whoever you point at with this won't be very cheesed to meet you." //this is a warcrime against italians // IF YOU'RE GOING TO DO US DIRTY SPELL IT RIGHT
- icon_state = "disposable_pizza"
- custom_materials = list(/datum/material/pizza=2000)
-
//not technically a pistol but whatever
/obj/item/gun/ballistic/derringer
name = ".38 Derringer"
desc = "An easily concealable derringer. Uses .38 special ammo."
icon_state = "derringer"
+
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
mag_type = /obj/item/ammo_box/magazine/internal/derr38
fire_sound = 'sound/weapons/gun/revolver/shot.ogg'
load_sound = 'sound/weapons/gun/revolver/load_bullet.ogg'
@@ -311,6 +374,12 @@
/obj/item/gun/ballistic/derringer/traitor
name = "\improper .357 Syndicate Derringer"
desc = "An easily concealable derriger, if not for the bright red-and-black. Uses .357 ammo."
+
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+
icon_state = "derringer_syndie"
mag_type = /obj/item/ammo_box/magazine/internal/derr357
fire_sound_volume = 50 //Tactical stealth firing
@@ -321,16 +390,34 @@
icon_state = "derringer_gold"
mag_type = /obj/item/ammo_box/magazine/internal/derr357
+/obj/item/gun/ballistic/derringer/no_mag
+ spawnwithmagazine = FALSE
+
/obj/item/gun/ballistic/automatic/pistol/himehabu
name = "\improper Himehabu"
desc = "A very small .22 LR pistol. The long awaited successor to the Stechkin; It has become a favorite among syndicate spies. Chambered in .22 LR."
icon_state = "himehabu"
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+
+
w_class = WEIGHT_CLASS_TINY
mag_type = /obj/item/ammo_box/magazine/m22lr
- can_suppress = FALSE
fire_sound = 'sound/weapons/gun/pistol/himehabu.ogg'
+ load_sound = 'sound/weapons/gun/pistol/mag_insert_alt.ogg'
+ load_empty_sound = 'sound/weapons/gun/pistol/mag_insert_alt.ogg'
+ eject_sound = 'sound/weapons/gun/pistol/mag_release_alt.ogg'
+ eject_empty_sound = 'sound/weapons/gun/pistol/mag_release_alt.ogg'
+
+ rack_sound = 'sound/weapons/gun/pistol/rack_small.ogg'
+ lock_back_sound = 'sound/weapons/gun/pistol/lock_small.ogg'
+ bolt_drop_sound = 'sound/weapons/gun/pistol/drop_small.ogg'
+
recoil = -2
recoil_unwielded = -2
spread_unwielded = 0
wield_slowdown = 0
+
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index abbf62543f90..545cbf8bf117 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -7,8 +7,8 @@
#define REVOLVER_FLIP "flip the revolver by the trigger"
/obj/item/gun/ballistic/revolver
- name = "\improper .357 revolver"
- desc = "A weighty revolver with a Scarborough Arms logo engraved on the barrel. Uses .357 ammo." //usually used by syndicates
+ name = "i demand"
+ desc = "You feel as if you should make a 'adminhelp' if you see one of these, along with a 'github' report. You don't really understand what this means though."
icon_state = "revolver"
mag_type = /obj/item/ammo_box/magazine/internal/cylinder
fire_sound = 'sound/weapons/gun/revolver/shot.ogg'
@@ -25,7 +25,7 @@
var/spin_delay = 10
var/recent_spin = 0
manufacturer = MANUFACTURER_SCARBOROUGH
- fire_delay = 2
+ fire_delay = 0.4 SECONDS
spread_unwielded = 15
recoil = 0.5
recoil_unwielded = 2
@@ -35,6 +35,9 @@
dry_fire_text = "snap"
wield_slowdown = 0.3
+ gun_firemodes = list(FIREMODE_SEMIAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
safety_wording = "hammer"
var/gate_loaded = FALSE //for stupid wild west shit
@@ -57,7 +60,7 @@
. += "[base_icon_state || initial(icon_state)][safety ? "_hammer_up" : "_hammer_down"]"
-/obj/item/gun/ballistic/revolver/process_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE)
+/obj/item/gun/ballistic/revolver/process_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE, atom/shooter)
SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
return ..()
@@ -84,7 +87,9 @@
if(!casing_to_eject)
continue
casing_to_eject.forceMove(drop_location())
- casing_to_eject.bounce_away(FALSE, NONE)
+ var/angle_of_movement =(rand(-3000, 3000) / 100) + dir2angle(turn(user.dir, 180))
+ casing_to_eject.AddComponent(/datum/component/movable_physics, _horizontal_velocity = rand(450, 550) / 100, _vertical_velocity = rand(400, 450) / 100, _horizontal_friction = rand(20, 24) / 100, _z_gravity = PHYSICS_GRAV_STANDARD, _z_floor = 0, _angle_of_movement = angle_of_movement, _bounce_sound = casing_to_eject.bounce_sfx_override)
+
num_unloaded++
SSblackbox.record_feedback("tally", "station_mess_created", 1, casing_to_eject.name)
chamber_round(FALSE)
@@ -96,13 +101,13 @@
for(var/i in 1 to num_to_unload)
var/doafter_time = 0.4 SECONDS
- if(!do_mob(user,user,doafter_time))
+ if(!do_after(user, doafter_time, user))
break
- if(!eject_casing())
+ if(!eject_casing(user))
doafter_time = 0 SECONDS
else
num_unloaded++
- if(!do_mob(user,user,doafter_time))
+ if(!do_after(user, doafter_time, user))
break
chamber_round(TRUE, TRUE)
@@ -121,7 +126,9 @@
return FALSE
playsound(src, eject_sound, eject_sound_volume, eject_sound_vary)
casing_to_eject.forceMove(drop_location())
- casing_to_eject.bounce_away(FALSE, NONE)
+ var/angle_of_movement =(rand(-3000, 3000) / 100) + dir2angle(turn(user.dir, 180))
+ casing_to_eject.AddComponent(/datum/component/movable_physics, _horizontal_velocity = rand(350, 450) / 100, _vertical_velocity = rand(400, 450) / 100, _horizontal_friction = rand(20, 24) / 100, _z_gravity = PHYSICS_GRAV_STANDARD, _z_floor = 0, _angle_of_movement = angle_of_movement, _bounce_sound = casing_to_eject.bounce_sfx_override)
+
SSblackbox.record_feedback("tally", "station_mess_created", 1, casing_to_eject.name)
if(!gate_loaded)
magazine.stored_ammo[casing_index] = null
@@ -139,6 +146,12 @@
/obj/item/gun/ballistic/revolver/proc/insert_casing(mob/living/user, obj/item/ammo_casing/casing_to_insert, allow_ejection)
if(!casing_to_insert)
return FALSE
+
+// Check if the bullet's caliber matches the magazine's caliber.If not, send a warning message to the user and return FALSE.
+ if(casing_to_insert.caliber != magazine.caliber)
+ to_chat(user, "\The [casing_to_insert] is not suitable for [src].")
+ return FALSE
+
var/list/rounds = magazine.ammo_list()
var/obj/item/ammo_casing/slot = rounds[gate_offset+1] //byond arrays start at 1, so we add 1 to get the correct index
var/doafter_time = 0.4 SECONDS
@@ -160,7 +173,7 @@
else
if(slot)
if(!slot.BB && allow_ejection)
- if(do_mob(user,user,doafter_time))
+ if(!do_after(user, doafter_time, user))
eject_casing(user)
rounds = magazine.ammo_list()
@@ -179,8 +192,6 @@
to_chat(user, "You load the [cartridge_wording] into [src].")
return TRUE
-
-
/obj/item/gun/ballistic/revolver/attackby(obj/item/attacking_obj, mob/user, params)
if (istype(attacking_obj, /obj/item/ammo_casing) || istype(attacking_obj, /obj/item/ammo_box))
if(istype(attacking_obj, /obj/item/ammo_casing))
@@ -204,7 +215,7 @@
var/doafter_time = 0.8 SECONDS
if(magazine.instant_load && attacking_box.instant_load)
doafter_time = 0 SECONDS
- if(!do_mob(user,user,doafter_time))
+ if(!do_after(user, doafter_time, user))
break
if(!insert_casing(user, casing_to_insert, FALSE))
break
@@ -221,7 +232,7 @@
if(!casing_to_insert || (magazine.caliber && casing_to_insert.caliber != magazine.caliber) || (!magazine.caliber && casing_to_insert.type != magazine.ammo_type))
break
var/doafter_time = 0.4 SECONDS
- if(!do_mob(user,user,doafter_time))
+ if(!do_after(user, doafter_time, user))
break
if(!insert_casing(null, casing_to_insert, FALSE))
doafter_time = 0 SECONDS
@@ -229,7 +240,7 @@
num_loaded++
attacking_box.update_appearance()
attacking_box.stored_ammo -= casing_to_insert
- if(!do_mob(user,user,doafter_time))
+ if(!do_after(user, doafter_time, user))
break
switch(gate_load_direction)
if(REVOLVER_AUTO_ROTATE_RIGHT_LOADING)
@@ -269,8 +280,8 @@
to_chat(user, "You rack the [bolt_wording] of \the [src].")
playsound(src, rack_sound, rack_sound_volume, rack_sound_vary)
- chamber_round(TRUE)
- //playsound(src, rack_sound, rack_sound_volume, rack_sound_vary)
+ if(!safety && !semi_auto)
+ chamber_round(TRUE)
SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
update_appearance()
@@ -402,11 +413,14 @@
var/fan = FALSE
if(HAS_TRAIT(user, TRAIT_GUNSLINGER) && !semi_auto && !wielded && loc == user && !safety && !user.get_inactive_held_item())
fan = TRUE
+ fire_delay = 0 SECONDS
. = ..()
+ fire_delay = src::fire_delay
if(fan)
rack()
to_chat(user, "You fan the [bolt_wording] of \the [src]!")
- user.changeNext_move(CLICK_CD_RAPID)
+ balloon_alert_to_viewers("fans revolver!")
+ fire_delay = 0 SECONDS
/obj/item/gun/ballistic/revolver/shoot_live_shot(mob/living/user, pointblank, atom/pbtarget, message)
. = ..()
@@ -425,18 +439,21 @@
/obj/item/gun/ballistic/revolver/calculate_recoil(mob/user, recoil_bonus = 0)
var/gunslinger_bonus = -1
var/total_recoil = recoil_bonus
+
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger bonus
total_recoil += gunslinger_bonus
total_recoil = clamp(total_recoil,0,INFINITY)
- return total_recoil
+
+ return ..(user, total_recoil)
/obj/item/gun/ballistic/revolver/calculate_spread(mob/user, bonus_spread)
- var/gunslinger_bonus = -4
+ var/gunslinger_bonus = -8
var/total_spread = bonus_spread
+
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger bonus
total_spread += gunslinger_bonus
- total_spread = clamp(total_spread,0,INFINITY)
- return total_spread
+
+ return ..(user, total_spread)
/obj/item/gun/ballistic/revolver/pickup(mob/user)
. = ..()
@@ -445,22 +462,31 @@
/obj/item/gun/ballistic/revolver/proc/tryflip(mob/living/user)
if(HAS_TRAIT(user, TRAIT_GUNSLINGER))
if(COOLDOWN_FINISHED(src, flip_cooldown))
- if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(40))
- to_chat(user, "While trying to flip the [src] you pull the trigger and accidently shoot yourself!")
- var/flip_mistake = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_CHEST)
- process_fire(user, user, FALSE, flip_mistake)
- user.dropItemToGround(src, TRUE)
- return
COOLDOWN_START(src, flip_cooldown, 0.3 SECONDS)
SpinAnimation(5,1)
user.visible_message("[user] spins the [src] around their finger by the trigger. That’s pretty badass.")
playsound(src, 'sound/items/handling/ammobox_pickup.ogg', 20, FALSE)
return
+
+/obj/item/gun/ballistic/revolver/syndicate //mystery tool that we can use later
+ name = "\improper syndicate revolver"
+ desc = "A weighty revolver with a Scarborough Arms logo engraved on the barrel. Uses .357 ammo." //usually used by syndicates
+ icon_state = "revolver"
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
+
/obj/item/gun/ballistic/revolver/detective
name = "\improper HP Detective Special"
desc = "A small law enforcement firearm. Originally commissioned by Nanotrasen for their Private Investigation division, it has become extremely popular among independent civilians as a cheap, compact sidearm. Uses .38 Special rounds."
fire_sound = 'sound/weapons/gun/revolver/shot_light.ogg'
icon_state = "detective"
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38
obj_flags = UNIQUE_RENAME
semi_auto = TRUE //double action
@@ -472,15 +498,19 @@
"The Peacemaker" = "detective_peacemaker",
"Black Panther" = "detective_panther"
)
+ w_class = WEIGHT_CLASS_SMALL
manufacturer = MANUFACTURER_HUNTERSPRIDE
recoil = 0 //weaker than normal revolver, no recoil
+ fire_delay = 0.2 SECONDS
+
+EMPTY_GUN_HELPER(revolver/detective)
/obj/item/gun/ballistic/revolver/detective/ComponentInitialize()
. = ..()
AddComponent(/datum/component/ammo_hud/revolver) //note that the hud at the moment only supports 6 round revolvers, 7 or 5 isn't supported rn
-
-/obj/item/gun/ballistic/revolver/detective/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
+//...why...?
+/obj/item/gun/ballistic/revolver/detective/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0, burst_firing = FALSE, spread_override = 0, iteration = 0)
if(magazine.caliber != initial(magazine.caliber))
if(prob(100 - (magazine.ammo_count() * 5))) //minimum probability of 70, maximum of 95
playsound(user, fire_sound, fire_sound_volume, vary_fire_sound)
@@ -524,10 +554,22 @@
to_chat(user, "You remove the modifications on [src]. Now it will fire .38 rounds.")
return TRUE
+/obj/item/gun/ballistic/revolver/detective/no_mag
+ spawnwithmagazine = FALSE
+
+/obj/item/gun/ballistic/revolver/syndicate/no_mag
+ spawnwithmagazine = FALSE
+
+/obj/item/gun/ballistic/revolver/no_mag
+ spawnwithmagazine = FALSE
/obj/item/gun/ballistic/revolver/mateba
name = "\improper Unica 6 auto-revolver"
desc = "A high-powered revolver with a unique auto-reloading system. Uses .357 ammo."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "mateba"
manufacturer = MANUFACTURER_NONE
semi_auto = TRUE
@@ -541,167 +583,88 @@
icon_state = "goldrevolver"
fire_sound = 'sound/weapons/resonator_blast.ogg'
recoil = 8
- pin = /obj/item/firing_pin
manufacturer = MANUFACTURER_NONE
/obj/item/gun/ballistic/revolver/montagne
name = "\improper HP Montagne"
- desc = "An ornate break-open revolver issued to high-ranking members of the Saint-Roumain Militia. Chambered in .45."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ desc = "An ornate break-open revolver issued to high-ranking members of the Saint-Roumain Militia. Chambered in .44."
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
icon_state = "montagne"
manufacturer = MANUFACTURER_HUNTERSPRIDE
spread_unwielded = 15
recoil = 0
- mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev45/montagne
+ mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev44/montagne
/obj/item/gun/ballistic/revolver/montagne/ComponentInitialize()
. = ..()
AddComponent(/datum/component/ammo_hud/revolver)
+/obj/item/gun/ballistic/revolver/montagne/no_mag
+ spawnwithmagazine = FALSE
+
/obj/item/gun/ballistic/revolver/ashhand
name = "HP Ashhand"
desc = "A massive, long-barreled revolver often used by the Saint-Roumain Militia as protection against big game. Can only be reloaded one cartridge at a time due to its reinforced frame. Uses .45-70 ammo."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
icon_state = "ashhand"
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev4570
fire_sound = 'sound/weapons/gun/revolver/shot_hunting.ogg'
manufacturer = MANUFACTURER_HUNTERSPRIDE
gate_loaded = TRUE
+ fire_delay = 0.6 SECONDS
wield_slowdown = 0.5
- spread_unwielded = 5
- spread = 2
+ spread_unwielded = 20
+ spread = 6
recoil = 2
recoil_unwielded = 4
-// A gun to play Russian Roulette!
-// You can spin the chamber to randomize the position of the bullet.
-
/obj/item/gun/ballistic/revolver/ashhand/ComponentInitialize()
. = ..()
AddComponent(/datum/component/ammo_hud/revolver)
-/obj/item/gun/ballistic/revolver/russian
- name = "\improper Russian revolver"
- desc = "A Solarian revolver for particularly lethal drinking games. It has a mechanism requiring you to spin the chamber before each trigger pull. Uses .357 ammo."
- icon_state = "russianrevolver"
- mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357
- var/spun = FALSE
- manufacturer = MANUFACTURER_NONE
-
-/obj/item/gun/ballistic/revolver/russian/do_spin()
- . = ..()
- if(.)
- spun = TRUE
-
-/obj/item/gun/ballistic/revolver/russian/attackby(obj/item/A, mob/user, params)
- ..()
- if(get_ammo() > 0)
- spin()
- update_appearance()
- A.update_appearance()
- return
-
-/obj/item/gun/ballistic/revolver/russian/attack_self(mob/user)
- if(!spun)
- spin()
- spun = TRUE
- return
- ..()
-
-/obj/item/gun/ballistic/revolver/russian/afterattack(atom/target, mob/living/user, flag, params)
- . = ..(null, user, flag, params)
-
- if(flag)
- if(!(target in user.contents) && ismob(target))
- if(user.a_intent == INTENT_HARM) // Flogging action
- return
-
- if(isliving(user))
- if(!can_trigger_gun(user))
- return
- if(target != user)
- if(ismob(target))
- to_chat(user, "A mechanism prevents you from shooting anyone but yourself!")
- return
-
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(!spun)
- to_chat(user, "You need to spin \the [src]'s chamber first!")
- return
-
- spun = FALSE
-
- if(chambered)
- var/obj/item/ammo_casing/AC = chambered
- if(AC.fire_casing(user, user))
- playsound(user, fire_sound, fire_sound_volume, vary_fire_sound)
- var/zone = check_zone(user.zone_selected)
- var/obj/item/bodypart/affecting = H.get_bodypart(zone)
- if(zone == BODY_ZONE_HEAD || zone == BODY_ZONE_PRECISE_EYES || zone == BODY_ZONE_PRECISE_MOUTH)
- shoot_self(user, affecting)
- else
- user.visible_message("[user.name] cowardly fires [src] at [user.p_their()] [affecting.name]!", "You cowardly fire [src] at your [affecting.name]!", "You hear a gunshot!")
- chambered = null
- return
-
- user.visible_message("*click*")
- playsound(src, dry_fire_sound, 30, TRUE)
-
-/obj/item/gun/ballistic/revolver/russian/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
- add_fingerprint(user)
- playsound(src, dry_fire_sound, 30, TRUE)
- user.visible_message("[user.name] tries to fire \the [src] at the same time, but only succeeds at looking like an idiot.", "\The [src]'s anti-combat mechanism prevents you from firing it at the same time!")
-
-/obj/item/gun/ballistic/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = BODY_ZONE_HEAD)
- user.apply_damage(300, BRUTE, affecting)
- user.visible_message("[user.name] fires [src] at [user.p_their()] head!", "You fire [src] at your head!", "You hear a gunshot!")
-
-/obj/item/gun/ballistic/revolver/russian/soul
- name = "cursed Russian revolver"
- desc = "To play with this revolver requires wagering your very soul."
-
-/obj/item/gun/ballistic/revolver/russian/soul/shoot_self(mob/living/user)
- ..()
- var/obj/item/soulstone/anybody/revolver/SS = new /obj/item/soulstone/anybody/revolver(get_turf(src))
- if(!SS.transfer_soul("FORCE", user)) //Something went wrong
- qdel(SS)
- return
- user.visible_message("[user.name]'s soul is captured by \the [src]!", "You've lost the gamble! Your soul is forfeit!")
-
-/obj/item/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course.
- clumsy_check = 0
-
-/obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user)
- if((HAS_TRAIT(user, TRAIT_CLUMSY)) || (user.mind && user.mind.assigned_role == "Clown"))
- return ..()
- if(process_fire(user, user, FALSE, null, BODY_ZONE_HEAD))
- user.visible_message("[user] somehow manages to shoot [user.p_them()]self in the face!", "You somehow shoot yourself in the face! How the hell?!")
- user.emote("scream")
- user.drop_all_held_items()
- user.Paralyze(80)
-
/obj/item/gun/ballistic/revolver/firebrand
name = "\improper HP Firebrand"
desc = "An archaic precursor to revolver-type firearms, this gun was rendered completely obsolete millennia ago. While fast to fire, it is extremely inaccurate. Uses .357 ammo."
icon_state = "pepperbox"
item_state = "hp_generic_fresh"
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/pepperbox
spread = 20
manufacturer = MANUFACTURER_HUNTERSPRIDE
spread_unwielded = 50
- fire_delay = 0
+ fire_delay = 0 SECONDS
+ gate_offset = 4
semi_auto = TRUE
safety_wording = "safety"
+/obj/item/gun/ballistic/revolver/firebrand/no_mag
+ spawnwithmagazine = FALSE
+
/obj/item/gun/ballistic/revolver/shadow
name = "\improper HP Shadow"
- desc = "A mid-size revolver. Despite the antiquated design, it is cheap, reliable, and stylish, making it a favorite among fast-drawing spacers and the officers of various militaries, as well as small-time police units. Chambered in .45."
+ desc = "A mid-size revolver. Despite the antiquated design, it is cheap, reliable, and stylish, making it a favorite among fast-drawing spacers and the officers of various militaries, as well as small-time police units. Chambered in .44."
fire_sound = 'sound/weapons/gun/revolver/cattleman.ogg'
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
icon_state = "shadow"
- mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev45
+ item_state = "hp_generic"
+
+ mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev44
manufacturer = MANUFACTURER_HUNTERSPRIDE
obj_flags = UNIQUE_RENAME
gate_loaded = TRUE
@@ -716,14 +679,11 @@
)
recoil = 0 //weaker than normal revolver, no recoil
+ spread_unwielded = 10
/obj/item/gun/ballistic/revolver/shadow/ComponentInitialize()
. = ..()
AddComponent(/datum/component/ammo_hud/revolver)
-/obj/item/gun/ballistic/revolver/shadow/before_firing(atom/target, mob/user)
- . = ..()
- // if you go through the pain of not only using this shitty gun, but also with the fucking gunslinger quirk, you deserve this bonus. not a BIG bonus, but enough as an incentive to make people actually take the quirk.
- if(chambered.BB && (HAS_TRAIT(user, TRAIT_GUNSLINGER)))
- chambered.BB.damage += 5
- chambered.armour_penetration += 5
+/obj/item/gun/ballistic/revolver/shadow/no_mag
+ spawnwithmagazine = FALSE
diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm
index 60aa20ab3a50..1e7724c5c9fa 100644
--- a/code/modules/projectiles/guns/ballistic/rifle.dm
+++ b/code/modules/projectiles/guns/ballistic/rifle.dm
@@ -22,8 +22,11 @@
weapon_weight = WEAPON_MEDIUM
pickup_sound = 'sound/items/handling/rifle_pickup.ogg'
+ gun_firemodes = list(FIREMODE_SEMIAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
spread = -1
- spread_unwielded = 12
+ spread_unwielded = 48
recoil = -3
recoil_unwielded = 4
wield_slowdown = 1
@@ -33,11 +36,11 @@
. = ..()
. += "[icon_state]_bolt[bolt_locked ? "_locked" : ""]"
-/obj/item/gun/ballistic/rifle/rack(mob/user = null)
+/obj/item/gun/ballistic/rifle/rack(mob/living/user)
if (bolt_locked == FALSE)
to_chat(user, "You open the bolt of \the [src].")
playsound(src, rack_sound, rack_sound_volume, rack_sound_vary)
- process_chamber(FALSE, FALSE, FALSE)
+ process_chamber(FALSE, FALSE, FALSE, shooter = user)
bolt_locked = TRUE
update_appearance()
if (magazine && !magazine?.ammo_count() && empty_autoeject && !internal_magazine)
@@ -67,18 +70,20 @@
. = ..()
. += "The bolt is [bolt_locked ? "open" : "closed"]."
-///////////////////////
-// BOLT ACTION RIFLE //
-///////////////////////
-
/obj/item/gun/ballistic/rifle/illestren
name = "\improper HP Illestren"
desc = "A sturdy and conventional bolt-action rifle. One of Hunter's Pride's most successful firearms, the Illestren is popular among colonists, pirates, snipers, and countless others. Chambered in 8x50mmR."
+ icon_state = "illestren"
+ item_state = "illestren"
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
sawn_desc = "An Illestren rifle sawn down to a ridiculously small size. There was probably a reason it wasn't made this short to begin with, but it still packs a punch."
eject_sound = 'sound/weapons/gun/rifle/vickland_unload.ogg'
eject_empty_sound = 'sound/weapons/gun/rifle/vickland_unload.ogg'
- icon_state = "illestren"
- item_state = "illestren"
+
internal_magazine = FALSE
mag_type = /obj/item/ammo_box/magazine/illestren_a850r
empty_autoeject = TRUE
@@ -86,21 +91,23 @@
can_be_sawn_off = TRUE
manufacturer = MANUFACTURER_HUNTERSPRIDE
+/obj/item/gun/ballistic/rifle/illestren/empty //i had to name it empty instead of no_mag because else it wouldnt work with guncases. sorry!
+ spawnwithmagazine = FALSE
+
/obj/item/gun/ballistic/rifle/illestren/sawoff(mob/user)
. = ..()
if(.)
- spread = 36
- spread_unwielded = 108
- can_bayonet = FALSE
+ spread = 24
+ spread_unwielded = 30
item_state = "illestren_sawn"
mob_overlay_state = item_state
weapon_weight = WEAPON_MEDIUM //you can fire it onehanded, makes it worse than worse than useless onehanded, but you can
/obj/item/gun/ballistic/rifle/illestren/blow_up(mob/user)
- . = 0
+ . = FALSE
if(chambered && chambered.BB)
process_fire(user, user, FALSE)
- . = 1
+ . = TRUE
/obj/item/gun/ballistic/rifle/illestren/factory
desc = "A sturdy and conventional bolt-action rifle. One of Hunter's Pride's most successful firearms, this example has been kept in excellent shape and may as well be fresh out of the workshop. Chambered in 8x50mmR."
@@ -113,12 +120,26 @@
item_state = "illestren_factory_sawn"
mob_overlay_state = item_state
+/obj/item/gun/ballistic/rifle/illestren/sawn
+ name = "sawn-off Illestren rifle"
+ desc = "An Illestren rifle sawn down to a ridiculously small size. There was probably a reason it wasn't made this short to begin with, but it still packs a punch."
+ item_state = "illestren_sawn"
+ sawn_off = TRUE
+ weapon_weight = WEAPON_MEDIUM
+ w_class = WEIGHT_CLASS_NORMAL
+ slot_flags = ITEM_SLOT_BELT
+
/obj/item/gun/ballistic/rifle/solgov
name = "SSG-669C"
desc = "A bolt-action sniper rifle used by Solarian troops. Beloved for its rotary design and accuracy. Chambered in 8x58mm Caseless."
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/solgov
icon_state = "ssg669c"
item_state = "ssg669c"
+ icon = 'icons/obj/guns/manufacturer/solararmories/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/solararmories/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/solararmories/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/solararmories/onmob.dmi'
+
fire_sound = 'sound/weapons/gun/rifle/ssg669c.ogg'
can_be_sawn_off = FALSE
@@ -137,13 +158,19 @@
/obj/item/gun/ballistic/rifle/scout
name = "HP Scout"
desc = "A powerful bolt-action rifle usually given to mercenary hunters of the Saint-Roumain Militia, equally suited for taking down big game or two-legged game. Chambered in .300 Magnum."
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+ icon_state = "scout"
+ item_state = "scout"
+
mag_type = /obj/item/ammo_box/magazine/internal/boltaction/smile
fire_sound = 'sound/weapons/gun/rifle/scout.ogg'
rack_sound = 'sound/weapons/gun/rifle/scout_bolt_out.ogg'
bolt_drop_sound = 'sound/weapons/gun/rifle/scout_bolt_in.ogg'
- icon_state = "scout"
- item_state = "scout"
+
can_be_sawn_off = FALSE
zoomable = TRUE
@@ -152,57 +179,8 @@
manufacturer = MANUFACTURER_HUNTERSPRIDE
-/obj/item/gun/ballistic/rifle/illestren/enchanted
- name = "enchanted bolt-action rifle"
- desc = "Careful not to lose your head."
- var/guns_left = 30
- mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted
- can_be_sawn_off = FALSE
- manufacturer = MANUFACTURER_NONE
-
-/obj/item/gun/ballistic/rifle/illestren/enchanted/arcane_barrage
- name = "arcane barrage"
- desc = "Pew Pew Pew."
- fire_sound = 'sound/weapons/emitter.ogg'
- pin = /obj/item/firing_pin/magic
- icon = 'icons/obj/guns/projectile.dmi'
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
- icon_state = "arcane_barrage"
- item_state = "arcane_barrage"
- slot_flags = null
- can_bayonet = FALSE
- item_flags = NEEDS_PERMIT | DROPDEL | ABSTRACT | NOBLUDGEON
- flags_1 = NONE
- trigger_guard = TRIGGER_GUARD_ALLOW_ALL
-
- mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted/arcane_barrage
-
-/obj/item/gun/ballistic/rifle/illestren/enchanted/dropped()
- . = ..()
- guns_left = 0
-
-/obj/item/gun/ballistic/rifle/illestren/enchanted/proc/discard_gun(mob/living/user)
- user.throw_item(pick(oview(7,get_turf(user))))
-
-/obj/item/gun/ballistic/rifle/illestren/enchanted/arcane_barrage/discard_gun(mob/living/user)
- qdel(src)
-
-/obj/item/gun/ballistic/rifle/illestren/enchanted/attack_self()
- return
-
-/obj/item/gun/ballistic/rifle/illestren/enchanted/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
- . = ..()
- if(!.)
- return
- if(guns_left)
- var/obj/item/gun/ballistic/rifle/illestren/enchanted/gun = new type
- gun.guns_left = guns_left - 1
- discard_gun(user)
- user.swap_hand()
- user.put_in_hands(gun)
- else
- user.dropItemToGround(src, TRUE)
+/obj/item/gun/ballistic/rifle/scout/no_mag
+ spawnwithmagazine = FALSE
/obj/item/gun/ballistic/rifle/polymer
name = "polymer survivor rifle"
diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm
index 81344fa5a82a..1f15f8d01689 100644
--- a/code/modules/projectiles/guns/ballistic/shotgun.dm
+++ b/code/modules/projectiles/guns/ballistic/shotgun.dm
@@ -19,10 +19,14 @@
cartridge_wording = "shell"
tac_reloads = FALSE
pickup_sound = 'sound/items/handling/shotgun_pickup.ogg'
- fire_delay = 7
+ fire_delay = 0.7 SECONDS
pb_knockback = 2
manufacturer = MANUFACTURER_HUNTERSPRIDE
+ gun_firemodes = list(FIREMODE_SEMIAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+ fire_select_icon_state_prefix = "sg_"
+
wield_slowdown = 0.45
wield_delay = 0.8 SECONDS
@@ -48,7 +52,8 @@
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger bonus
total_recoil += gunslinger_bonus
total_recoil = clamp(total_recoil,0,INFINITY)
- return total_recoil
+
+ return ..(user, total_recoil)
// BRIMSTONE SHOTGUN //
@@ -57,20 +62,24 @@
desc = "A simple and sturdy pump-action shotgun sporting a 5-round capacity, manufactured by Hunter's Pride. Found widely throughout the Frontier in the hands of hunters, pirates, police, and countless others. Chambered in 12g."
sawn_desc = "A stockless and shortened pump-action shotgun. The worsened recoil and accuracy make it a poor sidearm anywhere beyond punching distance."
fire_sound = 'sound/weapons/gun/shotgun/brimstone.ogg'
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
icon_state = "brimstone"
item_state = "brimstone"
+ gun_firemodes = list(FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_FULLAUTO
+
mag_type = /obj/item/ammo_box/magazine/internal/shot/lethal
manufacturer = MANUFACTURER_HUNTERSPRIDE
- fire_delay = 1
-
- can_be_sawn_off = TRUE
+ fire_delay = 0.05 SECONDS //slamfire
+ rack_delay = 0.2 SECONDS
+ can_be_sawn_off = TRUE
-/obj/item/gun/ballistic/shotgun/brimstone/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.1 SECONDS)
/obj/item/gun/ballistic/shotgun/brimstone/sawoff(mob/user)
. = ..()
@@ -86,19 +95,25 @@
item_state = "illestren_factory_sawn" // i couldnt care about making another sprite, looks close enough
mob_overlay_state = item_state
+/obj/item/gun/ballistic/shotgun/brimstone/no_mag
+ spawnwithmagazine = FALSE
// HELLFIRE SHOTGUN //
/obj/item/gun/ballistic/shotgun/hellfire
name = "HP Hellfire"
desc = "A hefty pump-action riot shotgun with a seven-round tube, manufactured by Hunter's Pride. Especially popular among the Frontier's police forces. Chambered in 12g."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
icon_state = "hellfire"
item_state = "hellfire"
+
mag_type = /obj/item/ammo_box/magazine/internal/shot/riot
sawn_desc = "Come with me if you want to live."
- can_be_sawn_off = TRUE
+ can_be_sawn_off = TRUE
rack_sound = 'sound/weapons/gun/shotgun/rack_alt.ogg'
- fire_delay = 1
+ fire_delay = 0.1 SECONDS
/obj/item/gun/ballistic/shotgun/hellfire/sawoff(mob/user)
. = ..()
@@ -117,6 +132,8 @@
item_state = "dshotgun_sawn" // ditto
mob_overlay_state = item_state
+/obj/item/gun/ballistic/shotgun/hellfire/no_mag
+ spawnwithmagazine = FALSE
// Automatic Shotguns//
/obj/item/gun/ballistic/shotgun/automatic
spread = 4
@@ -124,8 +141,6 @@
recoil = 1
recoil_unwielded = 4
wield_delay = 0.65 SECONDS
-
-/obj/item/gun/ballistic/shotgun/automatic
manufacturer = MANUFACTURER_NANOTRASEN
/obj/item/gun/ballistic/shotgun/automatic/shoot_live_shot(mob/living/user)
@@ -139,16 +154,16 @@
desc = "A semi-automatic shotgun with tactical furniture and six-shell capacity underneath."
icon_state = "cshotgun"
item_state = "shotgun_combat"
- fire_delay = 5
+ fire_delay = 0.5 SECONDS
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
- w_class = WEIGHT_CLASS_HUGE
+ w_class = WEIGHT_CLASS_BULKY
/obj/item/gun/ballistic/shotgun/automatic/combat/compact
name = "compact combat shotgun"
desc = "A compact version of the semi-automatic combat shotgun. For close encounters."
icon_state = "cshotgunc"
mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact
- w_class = WEIGHT_CLASS_BULKY
+ w_class = WEIGHT_CLASS_NORMAL
weapon_weight = WEAPON_MEDIUM
//Dual Feed Shotgun
@@ -156,16 +171,20 @@
/obj/item/gun/ballistic/shotgun/automatic/dual_tube
name = "cycler shotgun"
desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types."
+
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
+
icon_state = "cycler"
+
mag_type = /obj/item/ammo_box/magazine/internal/shot/tube
w_class = WEIGHT_CLASS_HUGE
var/toggled = FALSE
var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine
semi_auto = TRUE
-/obj/item/gun/ballistic/shotgun/automatic/dual_tube/mindshield
- pin = /obj/item/firing_pin/implant/mindshield
-
/obj/item/gun/ballistic/shotgun/automatic/dual_tube/examine(mob/user)
. = ..()
. += "Alt-click to pump it."
@@ -199,27 +218,25 @@
// Bulldog shotgun //
-/obj/item/gun/ballistic/shotgun/bulldog
+/obj/item/gun/ballistic/shotgun/bulldog //TODO: REPATH TO LIKE /obj/item/gun/ballistic/shotgun/automatic/bulldog
name = "\improper Bulldog Shotgun"
desc = "A semi-automatic, magazine-fed shotgun designed for combat in tight quarters, manufactured by Scarborough Arms. A historical favorite of various Syndicate factions, especially the Gorlex Marauders."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
icon_state = "bulldog"
item_state = "bulldog"
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
- inhand_x_dimension = 32
- inhand_y_dimension = 32
+
weapon_weight = WEAPON_MEDIUM
mag_type = /obj/item/ammo_box/magazine/m12g
- can_suppress = FALSE
burst_size = 1
- fire_delay = 0
+ fire_delay = 0.4 SECONDS // this NEEDS the old delay.
fire_sound = 'sound/weapons/gun/shotgun/bulldog.ogg'
- actions_types = list()
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
empty_indicator = TRUE
empty_alarm = TRUE
- special_mags = TRUE
+ unique_mag_sprites_for_variants = TRUE
semi_auto = TRUE
internal_magazine = FALSE
casing_ejector = TRUE
@@ -227,6 +244,13 @@
pickup_sound = 'sound/items/handling/rifle_pickup.ogg'
manufacturer = MANUFACTURER_SCARBOROUGH
+ load_sound = 'sound/weapons/gun/rifle/ar_reload.ogg'
+ load_empty_sound = 'sound/weapons/gun/rifle/ar_reload.ogg'
+ eject_sound = 'sound/weapons/gun/rifle/ar_unload.ogg'
+ eject_empty_sound = 'sound/weapons/gun/rifle/ar_unload.ogg'
+
+ rack_sound = 'sound/weapons/gun/rifle/ar_cock.ogg'
+
spread = 4
spread_unwielded = 16
recoil = 1
@@ -234,8 +258,7 @@
wield_slowdown = 0.6
wield_delay = 0.65 SECONDS
-/obj/item/gun/ballistic/shotgun/bulldog/unrestricted
- pin = /obj/item/firing_pin
+EMPTY_GUN_HELPER(shotgun/bulldog)
/obj/item/gun/ballistic/shotgun/bulldog/inteq
name = "\improper Mastiff Shotgun"
@@ -243,9 +266,10 @@
icon_state = "bulldog-inteq"
item_state = "bulldog-inteq"
mag_type = /obj/item/ammo_box/magazine/m12g
- pin = /obj/item/firing_pin
manufacturer = MANUFACTURER_INTEQ
+EMPTY_GUN_HELPER(shotgun/bulldog/inteq)
+
/obj/item/gun/ballistic/shotgun/bulldog/suns
name = "\improper Bulldog-C Shotgun"
desc = "A variation of the Bulldog manufactured by Scarborough Arms for SUNS. Its shorter barrel is intended to provide additional maneuverability in personal defense scenarios."
@@ -255,15 +279,20 @@
/obj/item/gun/ballistic/shotgun/bulldog/minutemen //TODO: REPATH
name = "\improper CM-15"
desc = "A standard-issue shotgun of CLIP, most often used by boarding crews. Only compatible with specialized 8-round magazines."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/clip_lanchester/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/clip_lanchester/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/clip_lanchester/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/clip_lanchester/onmob.dmi'
+
mag_type = /obj/item/ammo_box/magazine/cm15_mag
icon_state = "cm15"
item_state = "cm15"
- pin = /obj/item/firing_pin
empty_alarm = FALSE
empty_indicator = FALSE
- special_mags = FALSE
+ unique_mag_sprites_for_variants = FALSE
manufacturer = MANUFACTURER_MINUTEMAN
+ fire_select_icon_state_prefix = "clip_"
+ adjust_fire_select_icon_state_on_safety = TRUE
/////////////////////////////
// DOUBLE BARRELED SHOTGUN //
@@ -274,8 +303,11 @@
desc = "A classic break action shotgun, hand-made in a Hunter's Pride workshop. Both barrels can be fired in quick succession or even simultaneously. Guns like this have been popular with hunters, sporters, and criminals for millennia. Chambered in 12g."
sawn_desc = "A break action shotgun cut down to the size of a sidearm. While the recoil is even harsher, it offers a lot of power in a very small package. Chambered in 12g."
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
- icon = 'icons/obj/guns/48x32guns.dmi'
base_icon_state = "dshotgun"
icon_state = "dshotgun"
@@ -297,12 +329,17 @@
"Stained Green" = "dshotgun_green"
)
semi_auto = TRUE
- can_be_sawn_off = TRUE
+ can_be_sawn_off = TRUE
bolt_type = BOLT_TYPE_NO_BOLT
pb_knockback = 3 // it's a super shotgun!
manufacturer = MANUFACTURER_HUNTERSPRIDE
bolt_wording = "barrel"
+ burst_delay = 0.05 SECONDS
+ burst_size = 2
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_BURST)
+ default_firemode = FIREMODE_SEMIAUTO
+
/obj/item/gun/ballistic/shotgun/doublebarrel/unique_action(mob/living/user)
if (bolt_locked == FALSE)
to_chat(user, "You snap open the [bolt_wording] of \the [src].")
@@ -311,7 +348,9 @@
var/num_unloaded = 0
for(var/obj/item/ammo_casing/casing_bullet in get_ammo_list(FALSE, TRUE))
casing_bullet.forceMove(drop_location())
- casing_bullet.bounce_away(FALSE, NONE)
+ var/angle_of_movement =(rand(-3000, 3000) / 100) + dir2angle(turn(user.dir, 180))
+ casing_bullet.AddComponent(/datum/component/movable_physics, _horizontal_velocity = rand(450, 550) / 100, _vertical_velocity = rand(400, 450) / 100, _horizontal_friction = rand(20, 24) / 100, _z_gravity = PHYSICS_GRAV_STANDARD, _z_floor = 0, _angle_of_movement = angle_of_movement, _bounce_sound = casing_bullet.bounce_sfx_override)
+
num_unloaded++
SSblackbox.record_feedback("tally", "station_mess_created", 1, casing_bullet.name)
if (num_unloaded)
@@ -368,6 +407,28 @@
item_state = "dshotgun_sawn"
mob_overlay_state = item_state
+/obj/item/gun/ballistic/shotgun/doublebarrel/no_mag
+ spawnwithmagazine = FALSE
+
+// sawn off beforehand
+/obj/item/gun/ballistic/shotgun/doublebarrel/presawn
+ name = "sawn-off double-barreled shotgun"
+ desc = "A break action shotgun cut down to the size of a sidearm. While the recoil is even harsher, it offers a lot of power in a very small package. Chambered in 12g."
+ sawn_off = TRUE
+ weapon_weight = WEAPON_MEDIUM
+ w_class = WEIGHT_CLASS_NORMAL
+ slot_flags = ITEM_SLOT_BELT
+
+ wield_slowdown = 0.25
+ wield_delay = 0.3 SECONDS //OP? maybe
+
+ spread = 8
+ spread_unwielded = 15
+ recoil = 3 //or not
+ recoil_unwielded = 5
+ item_state = "dshotgun_sawn"
+ mag_type = /obj/item/ammo_box/magazine/internal/shot/dual/lethal
+
/obj/item/gun/ballistic/shotgun/doublebarrel/roumain
name = "HP antique double-barreled shotgun"
desc = "A special-edition shotgun hand-made by Hunter's Pride with a high-quality walnut stock inlaid with brass scrollwork. Shotguns like this are very rare outside of the Saint-Roumain Militia's ranks. Otherwise functionally identical to a common double-barreled shotgun. Chambered in 12g."
@@ -388,6 +449,10 @@
name = "improvised shotgun"
desc = "A length of pipe and miscellaneous bits of scrap fashioned into a rudimentary single-shot shotgun."
icon = 'icons/obj/guns/projectile.dmi'
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
+ mob_overlay_icon = null
+
base_icon_state = "ishotgun"
icon_state = "ishotgun"
item_state = "ishotgun"
@@ -399,6 +464,9 @@
unique_reskin = null
var/slung = FALSE
+ gun_firemodes = list(FIREMODE_SEMIAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
/obj/item/gun/ballistic/shotgun/doublebarrel/improvised/attackby(obj/item/A, mob/user, params)
..()
if(istype(A, /obj/item/stack/cable_coil) && !sawn_off)
@@ -441,52 +509,6 @@
sawn_off = TRUE
slot_flags = ITEM_SLOT_BELT
-/obj/item/gun/ballistic/shotgun/doublebarrel/hook
- name = "hook modified sawn-off shotgun"
- desc = "Range isn't an issue when you can bring your victim to you."
- icon_state = "hookshotgun"
- icon = 'icons/obj/guns/projectile.dmi'
- item_state = "shotgun"
- load_sound = 'sound/weapons/gun/shotgun/insert_shell.ogg'
- mag_type = /obj/item/ammo_box/magazine/internal/shot/bounty
- w_class = WEIGHT_CLASS_BULKY
- weapon_weight = WEAPON_MEDIUM
- can_be_sawn_off = FALSE
- force = 16 //it has a hook on it
- attack_verb = list("slashed", "hooked", "stabbed")
- hitsound = 'sound/weapons/bladeslice.ogg'
- //our hook gun!
- var/obj/item/gun/magic/hook/bounty/hook
- var/toggled = FALSE
-
-/obj/item/gun/ballistic/shotgun/doublebarrel/hook/Initialize()
- . = ..()
- hook = new /obj/item/gun/magic/hook/bounty(src)
-
-/obj/item/gun/ballistic/shotgun/doublebarrel/hook/AltClick(mob/user)
- if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
- return
- if(toggled)
- to_chat(user,"You switch to the shotgun.")
- fire_sound = initial(fire_sound)
- else
- to_chat(user,"You switch to the hook.")
- fire_sound = 'sound/weapons/batonextend.ogg'
- toggled = !toggled
-
-/obj/item/gun/ballistic/shotgun/doublebarrel/hook/examine(mob/user)
- . = ..()
- if(toggled)
- . += "Alt-click to switch to the shotgun."
- else
- . += "Alt-click to switch to the hook."
-
-/obj/item/gun/ballistic/shotgun/doublebarrel/hook/afterattack(atom/target, mob/living/user, flag, params)
- if(toggled)
- hook.afterattack(target, user, flag, params)
- else
- return ..()
-
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/compact
name = "compact compact combat shotgun"
desc = "A compact version of the compact version of the semi automatic combat shotgun. For when you want a gun the same size as your brain."
@@ -494,7 +516,7 @@
mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact/compact
w_class = WEIGHT_CLASS_SMALL
sawn_desc = "You know, this isn't funny anymore."
- can_be_sawn_off = TRUE
+ can_be_sawn_off = TRUE
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/compact/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
if(prob(0 + (magazine.ammo_count() * 20))) //minimum probability of 20, maximum of 60
@@ -517,7 +539,7 @@
mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact/compact/compact
w_class = WEIGHT_CLASS_TINY
sawn_desc = "Sigh. This is a trigger attached to a bullet."
- can_be_sawn_off = TRUE
+ can_be_sawn_off = TRUE
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/compact/compact/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
if(prob(50)) //It's going to blow up.
@@ -549,7 +571,7 @@
attack_verb = list("bludgeoned", "smashed")
mag_type = /obj/item/ammo_box/magazine/internal/shot/sex
burst_size = 6
- fire_delay = 0.8
+ burst_delay = 0.04 SECONDS //?? very weird number
pb_knockback = 12
unique_reskin = null
recoil = 10
@@ -562,6 +584,8 @@
rack_sound_volume = 50
can_be_sawn_off = FALSE
manufacturer = MANUFACTURER_BRAZIL
+ gun_firemodes = list(FIREMODE_BURST)
+ default_firemode = FIREMODE_BURST
/obj/item/gun/ballistic/shotgun/doublebarrel/brazil/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
if(prob(0 + (magazine.ammo_count() * 10)))
@@ -582,10 +606,11 @@
base_icon_state = "shotgun_e"
icon_state = "shotgun_e"
burst_size = 100
- fire_delay = 0.1
+ fire_delay = 0.01 SECONDS
pb_knockback = 40
recoil = 100
recoil_unwielded = 200
+ recoil_backtime_multiplier = 1
fire_sound_volume = 100
mag_type = /obj/item/ammo_box/magazine/internal/shot/hundred
@@ -597,10 +622,10 @@
base_icon_state = "flamingarrow"
icon_state = "flamingarrow"
item_state = "flamingarrow"
- icon = 'icons/obj/guns/48x32guns.dmi'
- mob_overlay_icon = 'icons/mob/clothing/back.dmi'
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
inhand_x_dimension = 32
inhand_y_dimension = 32
mag_type = /obj/item/ammo_box/magazine/internal/shot/winchester
@@ -608,7 +633,7 @@
rack_sound = 'sound/weapons/gun/rifle/skm_cocked.ogg'
bolt_wording = "lever"
cartridge_wording = "bullet"
- can_be_sawn_off = TRUE
+ can_be_sawn_off = TRUE
wield_slowdown = 0.5
wield_delay = 0.65 SECONDS
@@ -619,6 +644,9 @@
recoil = 0
recoil_unwielded = 2
+/obj/item/gun/ballistic/shotgun/flamingarrow/no_mag
+ spawnwithmagazine = FALSE
+
/obj/item/gun/ballistic/shotgun/flamingarrow/update_icon_state()
. = ..()
if(current_skin)
@@ -632,6 +660,18 @@
if(!wielded)
SpinAnimation(7,1)
+/obj/item/gun/ballistic/shotgun/flamingarrow/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
+ var/fan = FALSE
+ if(HAS_TRAIT(user, TRAIT_GUNSLINGER) && !semi_auto && wielded_fully && loc == user && !safety)
+ fan = TRUE
+ fire_delay = 0.35 SECONDS
+ . = ..()
+ fire_delay = src::fire_delay
+ if(fan)
+ rack()
+ to_chat(user, "You quickly rack the [bolt_wording] of \the [src]!")
+ balloon_alert_to_viewers("quickly racks!")
+ fire_delay = 0 SECONDS
/obj/item/gun/ballistic/shotgun/flamingarrow/sawoff(mob/user)
. = ..()
@@ -681,9 +721,10 @@
/obj/item/gun/ballistic/shotgun/doublebarrel/twobore
name = "HP Huntsman"
desc = "A comically huge double-barreled rifle replete with brass inlays depicting flames and naturalistic scenes, clearly meant for the nastiest monsters the Frontier has to offer. If you want an intact trophy, don't aim for the head. Chambered in two-bore."
- icon = 'icons/obj/guns/48x32guns.dmi'
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
inhand_x_dimension = 32
inhand_y_dimension = 32
base_icon_state = "huntsman"
@@ -705,6 +746,9 @@
rack_sound_volume = 50
manufacturer = MANUFACTURER_HUNTERSPRIDE
+ gun_firemodes = list(FIREMODE_SEMIAUTO) //no dual burst for you
+ default_firemode = FIREMODE_SEMIAUTO
+
//Break-Action Rifle
/obj/item/gun/ballistic/shotgun/doublebarrel/beacon
name = "HP Beacon"
@@ -714,21 +758,16 @@
icon_state = "beacon"
item_state = "beacon"
unique_reskin = null
- icon = 'icons/obj/guns/48x32guns.dmi'
- mob_overlay_icon = 'icons/mob/clothing/back.dmi'
inhand_x_dimension = 32
inhand_y_dimension = 32
mag_type = /obj/item/ammo_box/magazine/internal/shot/beacon
fire_sound = 'sound/weapons/gun/revolver/shot_hunting.ogg'
- can_be_sawn_off=TRUE
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_MEDIUM
force = 10
- flags_1 = CONDUCT_1
- slot_flags = ITEM_SLOT_BACK
obj_flags = UNIQUE_RENAME
semi_auto = TRUE
- can_be_sawn_off = TRUE
+ can_be_sawn_off = TRUE
pb_knockback = 3
wield_slowdown = 0.7
spread_unwielded = 15
@@ -736,6 +775,9 @@
recoil = 0
recoil_unwielded = 5
+ gun_firemodes = list(FIREMODE_SEMIAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
/obj/item/gun/ballistic/shotgun/doublebarrel/beacon/sawoff(mob/user)
. = ..()
if(.)
@@ -744,10 +786,13 @@
wield_slowdown = 0.5
wield_delay = 0.5 SECONDS
- spread_unwielded = 5 //mostly the hunting revolver stats
- spread = 2
+ spread_unwielded = 20 //mostly the hunting revolver stats
+ spread = 6
recoil = 2
- recoil_unwielded = 3
+ recoil_unwielded = 4
+
+/obj/item/gun/ballistic/shotgun/doublebarrel/beacon/no_mag
+ spawnwithmagazine = FALSE
/obj/item/gun/ballistic/shotgun/doublebarrel/beacon/factory
desc = "A single-shot break-action rifle made by Hunter's Pride and sold to civilian hunters. This example has been kept in excellent shape and may as well be fresh out of the workshop. Uses .45-70 ammo."
@@ -761,3 +806,23 @@
if(.)
item_state = "beacon_factory_sawn"
mob_overlay_state = item_state
+
+//pre sawn off beacon
+/obj/item/gun/ballistic/shotgun/doublebarrel/beacon/presawn
+ name = "sawn-off HP Beacon"
+ sawn_desc= "A single-shot break-action pistol chambered in .45-70. A bit difficult to aim."
+ sawn_off = TRUE
+ w_class = WEIGHT_CLASS_NORMAL
+ slot_flags = ITEM_SLOT_BELT
+
+ weapon_weight = WEAPON_MEDIUM
+
+ item_state = "beacon_sawn"
+ mob_overlay_state = "beacon_sawn"
+ wield_slowdown = 0.5
+ wield_delay = 0.5 SECONDS
+
+ spread_unwielded = 20 //mostly the hunting revolver stats
+ spread = 6
+ recoil = 2
+ recoil_unwielded = 4
diff --git a/code/modules/projectiles/guns/ballistic/smg.dm b/code/modules/projectiles/guns/ballistic/smg.dm
index ce740644d712..2cb68fc09176 100644
--- a/code/modules/projectiles/guns/ballistic/smg.dm
+++ b/code/modules/projectiles/guns/ballistic/smg.dm
@@ -1,14 +1,18 @@
/obj/item/gun/ballistic/automatic/smg
- burst_size = 1
+ burst_size = 2
actions_types = list()
- fire_delay = 1
- spread = 4
+ fire_delay = 0.13 SECONDS
+
+ spread = 6
spread_unwielded = 10
wield_slowdown = 0.35
recoil_unwielded = 4
w_class = WEIGHT_CLASS_BULKY
- wield_delay = 0.4 SECONDS
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
+ wield_delay = 0.5 SECONDS
load_sound = 'sound/weapons/gun/smg/smg_reload.ogg'
load_empty_sound = 'sound/weapons/gun/smg/smg_reload.ogg'
@@ -16,60 +20,42 @@
eject_empty_sound = 'sound/weapons/gun/smg/smg_unload.ogg'
/obj/item/gun/ballistic/automatic/smg/calculate_recoil(mob/user, recoil_bonus = 0)
- var/gunslinger_bonus = 1
- var/total_recoil = recoil_bonus
+ var/gunslinger_bonus = 2
+ var/total_recoil
+ if(.)
+ total_recoil += .
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger penalty
total_recoil += gunslinger_bonus
- total_recoil = clamp(total_recoil,0,INFINITY)
- return total_recoil
+ . = total_recoil
+ return ..()
/obj/item/gun/ballistic/automatic/smg/calculate_spread(mob/user, bonus_spread)
- var/gunslinger_bonus = 4
+ var/gunslinger_bonus = 16
var/total_spread = bonus_spread
+ if(.)
+ total_spread += .
if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger penalty
total_spread += gunslinger_bonus
- total_spread = clamp(total_spread,0,INFINITY)
- return total_spread
-
-/obj/item/gun/ballistic/automatic/smg/proto
- name = "\improper Nanotrasen Saber SMG"
- desc = "A prototype full-auto 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors and a folding stock."
- icon_state = "saber"
- actions_types = list()
- mag_type = /obj/item/ammo_box/magazine/smgm9mm
- pin = null
- bolt_type = BOLT_TYPE_LOCKING
- mag_display = TRUE
- manufacturer = MANUFACTURER_NANOTRASEN_OLD
-
-/obj/item/gun/ballistic/automatic/smg/proto/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
-
-/obj/item/gun/ballistic/automatic/smg/proto/unrestricted
- pin = /obj/item/firing_pin
+ . = total_spread
+ return ..()
/obj/item/gun/ballistic/automatic/smg/c20r
name = "\improper C-20r SMG"
desc = "A bullpup .45 SMG designated 'C-20r.' Its buttstamp reads 'Scarborough Arms - Per falcis, per pravitas.'"
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
icon_state = "c20r"
item_state = "c20r"
+
mag_type = /obj/item/ammo_box/magazine/smgm45
- can_bayonet = TRUE
- can_suppress = FALSE
- knife_x_offset = 26
- knife_y_offset = 12
- mag_display = TRUE
- mag_display_ammo = TRUE
+ show_magazine_on_sprite = TRUE
+ show_magazine_on_sprite_ammo = TRUE
empty_indicator = TRUE
manufacturer = MANUFACTURER_SCARBOROUGH
-/obj/item/gun/ballistic/automatic/smg/c20r/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
-
-/obj/item/gun/ballistic/automatic/smg/c20r/unrestricted
- pin = /obj/item/firing_pin
+EMPTY_GUN_HELPER(automatic/smg/c20r)
/obj/item/gun/ballistic/automatic/smg/c20r/Initialize()
. = ..()
@@ -78,10 +64,12 @@
/obj/item/gun/ballistic/automatic/smg/c20r/cobra
name = "\improper Cobra 20"
desc = "An older model of SMG manufactured by Scarborough Arms, a predecessor to the military C-20 series. Chambered in .45. "
- can_bayonet = FALSE
icon_state = "cobra20"
item_state = "cobra20"
+/obj/item/gun/ballistic/automatic/smg/c20r/cobra/no_mag
+ spawnwithmagazine = FALSE
+
/obj/item/gun/ballistic/automatic/smg/c20r/suns
desc = "A bullpup .45 SMG designated 'C-20r.' Its buttstamp reads 'Scarborough Arms - Per falcis, per pravitas.' This one is painted in SUNS' colors."
icon_state = "c20r_suns"
@@ -90,32 +78,36 @@
/obj/item/gun/ballistic/automatic/smg/wt550
name = "\improper WT-550 Automatic Rifle"
desc = "An outdated PDW, used centuries ago by Nanotrasen security elements. Uses 4.6x30mm rounds."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "wt550"
item_state = "arg"
mag_type = /obj/item/ammo_box/magazine/wt550m9
- can_suppress = FALSE
- burst_size = 1
actions_types = list()
- can_bayonet = TRUE
- knife_x_offset = 25
- knife_y_offset = 12
- mag_display = TRUE
- mag_display_ammo = TRUE
+ show_magazine_on_sprite = TRUE
+ show_magazine_on_sprite_ammo = TRUE
empty_indicator = TRUE
manufacturer = MANUFACTURER_NANOTRASEN_OLD
fire_sound = 'sound/weapons/gun/smg/smg_heavy.ogg'
-/obj/item/gun/ballistic/automatic/smg/wt550/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
+/obj/item/gun/ballistic/automatic/smg/wt550/no_mag
+ spawnwithmagazine = FALSE
/obj/item/gun/ballistic/automatic/smg/mini_uzi
name = "\improper Type U3 Uzi"
desc = "A lightweight submachine gun, for when you really want someone dead. Uses 9mm rounds."
+
+ icon = 'icons/obj/guns/manufacturer/frontier_import/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/frontier_import/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/frontier_import/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/frontier_import/onmob.dmi'
icon_state = "uzi"
+
mag_type = /obj/item/ammo_box/magazine/uzim9mm
bolt_type = BOLT_TYPE_OPEN
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
fire_sound = 'sound/weapons/gun/smg/uzi.ogg'
rack_sound = 'sound/weapons/gun/smg/uzi_cocked.ogg'
@@ -129,126 +121,128 @@
spread_unwielded = 8
wield_slowdown = 0.25
wield_delay = 0.2 SECONDS
-
-/obj/item/gun/ballistic/automatic/smg/mini_uzi/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.1 SECONDS)
+ fire_delay = 0.1 SECONDS
/obj/item/gun/ballistic/automatic/smg/vector
name = "\improper Vector carbine"
desc = "A police carbine based on a pre-Night of Fire SMG design. Most of the complex workings have been removed for reliability. Chambered in 9mm."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "vector"
item_state = "vector"
mag_type = /obj/item/ammo_box/magazine/smgm9mm //you guys remember when the autorifle was chambered in 9mm
bolt_type = BOLT_TYPE_LOCKING
- mag_display = TRUE
+ show_magazine_on_sprite = TRUE
weapon_weight = WEAPON_LIGHT
fire_sound = 'sound/weapons/gun/smg/vector_fire.ogg'
-/obj/item/gun/ballistic/automatic/smg/vector/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
-
/obj/item/gun/ballistic/automatic/smg/m90
name = "\improper M-90gl Carbine"
desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off."
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
icon_state = "m90"
item_state = "m90"
+
mag_type = /obj/item/ammo_box/magazine/m556
- can_suppress = FALSE
- actions_types = list(/datum/action/item_action/toggle_firemode)
- var/obj/item/gun/ballistic/revolver/grenadelauncher/underbarrel
- burst_size = 3
- fire_delay = 2
- pin = /obj/item/firing_pin/implant/pindicate
- mag_display = TRUE
+ gun_firenames = list(FIREMODE_SEMIAUTO = "single", FIREMODE_BURST = "burst fire", FIREMODE_FULLAUTO = "full auto", FIREMODE_OTHER = "underbarrel grenade launcher")
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_BURST, FIREMODE_OTHER)
+ default_firemode = FIREMODE_SEMIAUTO
+ var/obj/item/gun/ballistic/revolver/grenadelauncher/secondary
+ show_magazine_on_sprite = TRUE
empty_indicator = TRUE
fire_sound = 'sound/weapons/gun/rifle/shot_alt.ogg'
manufacturer = MANUFACTURER_SCARBOROUGH
+ burst_size = 3
+ burst_delay = 0.1 SECONDS
+ fire_delay = 0.2 SECONDS
spread = 1
spread_unwielded = 8
wield_slowdown = 0.4
/obj/item/gun/ballistic/automatic/smg/m90/Initialize()
. = ..()
- underbarrel = new /obj/item/gun/ballistic/revolver/grenadelauncher(src)
+ secondary = new /obj/item/gun/ballistic/revolver/grenadelauncher(src)
+ RegisterSignal(secondary, COMSIG_ATOM_UPDATE_ICON, PROC_REF(secondary_update_icon))
update_appearance()
-/obj/item/gun/ballistic/automatic/smg/m90/unrestricted
- pin = /obj/item/firing_pin
+/obj/item/gun/ballistic/automatic/smg/m90/process_other(atom/target, mob/living/user, message = TRUE, flag, params = null, zone_override = "", bonus_spread = 0)
+ return secondary.pre_fire(target, user, message, params, zone_override, bonus_spread)
-/obj/item/gun/ballistic/automatic/smg/m90/unrestricted/Initialize()
- . = ..()
- underbarrel = new /obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted(src)
- update_appearance()
+/obj/item/gun/ballistic/automatic/smg/m90/can_shoot()
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
+ return ..()
+ return secondary.can_shoot()
/obj/item/gun/ballistic/automatic/smg/m90/afterattack(atom/target, mob/living/user, flag, params)
- if(select == 2)
- underbarrel.afterattack(target, user, flag, params)
- else
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
return ..()
+ return secondary.afterattack(target, user, flag, params)
-/obj/item/gun/ballistic/automatic/smg/m90/attackby(obj/item/A, mob/user, params)
- if(istype(A, /obj/item/ammo_casing))
- if(istype(A, underbarrel.magazine.ammo_type))
- underbarrel.attack_self()
- underbarrel.attackby(A, user, params)
- else
- ..()
+/obj/item/gun/ballistic/automatic/smg/m90/attackby(obj/item/attack_obj, mob/user, params)
+ if(istype(attack_obj, secondary.magazine.ammo_type))
+ secondary.unique_action()
+ return secondary.attackby(attack_obj, user, params)
+ return ..()
-/obj/item/gun/ballistic/automatic/smg/m90/update_overlays()
+
+/obj/item/gun/ballistic/automatic/smg/m90/can_shoot()
+ var/current_firemode = gun_firemodes[firemode_index]
+ if(current_firemode != FIREMODE_OTHER)
+ return ..()
+ return secondary.can_shoot()
+
+/obj/item/gun/ballistic/automatic/smg/m90/on_wield(obj/item/source, mob/user)
+ wielded = TRUE
+ secondary.wielded = TRUE
+ INVOKE_ASYNC(src, .proc.do_wield, user)
+
+/obj/item/gun/ballistic/automatic/smg/m90/do_wield(mob/user)
+ . = ..()
+ secondary.wielded_fully = wielded_fully
+
+/// triggered on unwield of two handed item
+/obj/item/gun/ballistic/automatic/smg/m90/on_unwield(obj/item/source, mob/user)
. = ..()
- switch(select)
- if(0)
- . += "[initial(icon_state)]_semi"
- if(1)
- . += "[initial(icon_state)]_burst"
- if(2)
- . += "[initial(icon_state)]_gren"
-
-/obj/item/gun/ballistic/automatic/smg/m90/burst_select()
- var/mob/living/carbon/human/user = usr
- switch(select)
- if(0)
- select = 1
- burst_size = initial(burst_size)
- fire_delay = initial(fire_delay)
- to_chat(user, "You switch to [burst_size]-rnd burst.")
- if(1)
- select = 2
- to_chat(user, "You switch to grenades.")
- if(2)
- select = 0
- burst_size = 1
- fire_delay = 0
- to_chat(user, "You switch to semi-auto.")
- playsound(user, 'sound/weapons/gun/general/selector.ogg', 100, TRUE)
+ secondary.wielded_fully = FALSE
+ secondary.wielded = FALSE
+
+
+/obj/item/gun/ballistic/automatic/smg/m90/proc/secondary_update_icon()
update_appearance()
- return
+ SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
+
/obj/item/gun/ballistic/automatic/smg/firestorm //weapon designed by Apogee-dev
name = "HP Firestorm"
desc = "An unconventional submachinegun, rarely issued to Saint-Roumain Militia mercenary hunters for outstanding situations where normal hunting weapons fall short. Chambered in .45."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/hunterspride/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/hunterspride/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/hunterspride/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/hunterspride/onmob.dmi'
+
icon_state = "firestorm"
item_state = "firestorm"
mag_type = /obj/item/ammo_box/magazine/c45_firestorm_mag
- can_suppress = FALSE
- special_mags = TRUE
+ unique_mag_sprites_for_variants = TRUE
burst_size = 1
actions_types = list()
- fire_delay = 1
+ fire_delay = 0.13 SECONDS
+ bolt_type = BOLT_TYPE_OPEN
rack_sound = 'sound/weapons/gun/smg/uzi_cocked.ogg'
fire_sound = 'sound/weapons/gun/smg/firestorm.ogg'
+
manufacturer = MANUFACTURER_HUNTERSPRIDE
wield_slowdown = 0.4
-/obj/item/gun/ballistic/automatic/smg/firestorm/Initialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
-
/obj/item/gun/ballistic/automatic/smg/firestorm/pan //spawns with pan magazine, can take sticks instead of just drums, not sure where this would be used, maybe erts?
spawnwithmagazine = FALSE
@@ -260,19 +254,23 @@
/obj/item/gun/ballistic/automatic/smg/cm5
name = "\improper CM-5"
desc = "The standard issue SMG of CLIP. One of the few firearm designs that were left mostly intact from the designs found on the UNSV Lichtenstein. Chambered in 9mm."
+ icon = 'icons/obj/guns/manufacturer/clip_lanchester/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/clip_lanchester/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/clip_lanchester/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/clip_lanchester/onmob.dmi'
+
icon_state = "cm5"
item_state = "cm5"
+
mag_type = /obj/item/ammo_box/magazine/smgm9mm
weapon_weight = WEAPON_LIGHT
fire_sound = 'sound/weapons/gun/smg/smg_heavy.ogg'
manufacturer = MANUFACTURER_MINUTEMAN
-/obj/item/gun/ballistic/automatic/smg/cm5/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
+ fire_select_icon_state_prefix = "clip_"
+ adjust_fire_select_icon_state_on_safety = TRUE
-/obj/item/gun/ballistic/automatic/smg/cm5/no_mag
- spawnwithmagazine = FALSE
+EMPTY_GUN_HELPER(automatic/smg/cm5)
/obj/item/gun/ballistic/automatic/smg/cm5/compact
name = "\improper CM-5c"
@@ -281,15 +279,13 @@
spread = 25
spread_unwielded = 40
+ fire_delay = 0.08 SECONDS
+
recoil = 1
recoil_unwielded = 2
wield_delay = 0.2 SECONDS
wield_slowdown = 0.15
-/obj/item/gun/ballistic/automatic/smg/cm5/compact/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.8 SECONDS)
-
/obj/item/gun/ballistic/automatic/smg/skm_carbine
name = "\improper SKM-24v"
desc = "The SKM-24v was a carbine modification of the SKM-24 during the Frontiersmen War. This, however, is just a shoddy imitation of that carbine, effectively an SKM-24 with a sawed down barrel and a folding wire stock. Can be fired with the stock folded, though accuracy suffers. Chambered in 4.6x30mm."
@@ -308,11 +304,9 @@
eject_empty_sound = 'sound/weapons/gun/rifle/skm_unload.ogg'
weapon_weight = WEAPON_MEDIUM
- w_class = WEIGHT_CLASS_BULKY
+ w_class = WEIGHT_CLASS_NORMAL
mag_type = /obj/item/ammo_box/magazine/skm_545_39
- actions_types = list(/datum/action/item_action/fold_stock) //once again, ideally an attatchment in the future
-
recoil = 2
recoil_unwielded = 6
@@ -322,88 +316,43 @@
wield_delay = 0.6 SECONDS
wield_slowdown = 0.35
- ///is the bipod deployed?
- var/stock_folded = FALSE
-
- ///we add these two values to recoi/spread when we have the bipod deployed
- var/stock_recoil_bonus = -2
- var/stock_spread_bonus = -5
-
- var/folded_slowdown = 0.6
- var/folded_wield_delay = 0.6 SECONDS
-
- var/unfolded_slowdown = 0.35
- var/unfolded_wield_delay = 0.2 SECONDS
-
-/obj/item/gun/ballistic/automatic/smg/skm_carbine/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
- AddElement(/datum/element/update_icon_updates_onmob)
-
-/datum/action/item_action/fold_stock
- name = "Fold/Unfold stock"
- desc = "Fold or unfold the stock for easier storage."
-
-/obj/item/gun/ballistic/automatic/smg/skm_carbine/ui_action_click(mob/user, action)
- if(!istype(action, /datum/action/item_action/fold_stock))
- return ..()
- fold(user)
-
-
-/obj/item/gun/ballistic/automatic/smg/skm_carbine/proc/fold(mob/user)
- if(stock_folded)
- to_chat(user, "You unfold the stock on the [src].")
- w_class = WEIGHT_CLASS_BULKY
- wield_delay = folded_wield_delay
- wield_slowdown = folded_slowdown
- else
- to_chat(user, "You fold the stock on the [src].")
- w_class = WEIGHT_CLASS_NORMAL
- wield_delay = unfolded_wield_delay
- wield_slowdown = unfolded_slowdown
-
- if(wielded)
- user.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/gun, multiplicative_slowdown = wield_slowdown)
-
- stock_folded = !stock_folded
- playsound(src, 'sound/weapons/empty.ogg', 100, 1)
- update_appearance()
-
-
-/obj/item/gun/ballistic/automatic/smg/skm_carbine/calculate_recoil(mob/user, recoil_bonus = 0)
- var/gunslinger_bonus = 1
- var/total_recoil = recoil_bonus
- if(!stock_folded)
- total_recoil += stock_recoil_bonus
- if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger penalty
- total_recoil += gunslinger_bonus
-
- total_recoil = clamp(total_recoil,0,INFINITY)
- return total_recoil
-
-/obj/item/gun/ballistic/automatic/smg/skm_carbine/calculate_spread(mob/user, bonus_spread)
- var/gunslinger_bonus = 4
- var/total_spread = bonus_spread
- if(!stock_folded)
- total_spread += stock_spread_bonus
- if(HAS_TRAIT(user, TRAIT_GUNSLINGER)) //gunslinger penalty
- total_spread += gunslinger_bonus
-
- total_spread = clamp(total_spread,0,INFINITY)
- return total_spread
-
-/obj/item/gun/ballistic/automatic/smg/skm_carbine/update_icon_state()
- . = ..()
- item_state = "[initial(item_state)][stock_folded ? "_nostock" : ""]"
- mob_overlay_state = "[initial(item_state)][stock_folded ? "_nostock" : ""]"
-
-/obj/item/gun/ballistic/automatic/smg/skm_carbine/update_overlays()
- . = ..()
- . += "[base_icon_state || initial(icon_state)][stock_folded ? "_nostock" : "_stock"]"
+ valid_attachments = list(
+ /obj/item/attachment/silencer,
+ /obj/item/attachment/laser_sight,
+ /obj/item/attachment/rail_light,
+ /obj/item/attachment/bayonet,
+ /obj/item/attachment/foldable_stock
+ )
+
+ slot_available = list(
+ ATTACHMENT_SLOT_MUZZLE = 1,
+ ATTACHMENT_SLOT_RAIL = 1,
+ ATTACHMENT_SLOT_STOCK = 1
+ )
+ slot_offsets = list(
+ ATTACHMENT_SLOT_MUZZLE = list(
+ "x" = 26,
+ "y" = 20,
+ ),
+ ATTACHMENT_SLOT_RAIL = list(
+ "x" = 19,
+ "y" = 18,
+ ),
+ ATTACHMENT_SLOT_STOCK = list(
+ "x" = 11,
+ "y" = 20,
+ )
+ )
+
+ default_attachments = list(/obj/item/attachment/foldable_stock)
/obj/item/gun/ballistic/automatic/smg/skm_carbine/inteq
name = "\improper SKM-44v Mongrel"
desc = "An SKM-44, further modified into a sub-machine gun by Inteq artificers with a new magazine well, collapsing stock, and shortened barrel. Faced with a surplus of SKM-44s and a shortage of other firearms, IRMG has made the most of their available materiel with conversions such as this. Chambered in 10mm."
+ icon = 'icons/obj/guns/manufacturer/inteq/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/inteq/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/inteq/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/inteq/onmob.dmi'
icon_state = "skm_inteqsmg"
item_state = "skm_inteqsmg"
@@ -423,18 +372,24 @@
recoil = 0
recoil_unwielded = 4
- stock_spread_bonus = -4
- stock_recoil_bonus = -1
-
wield_delay = 0.4 SECONDS
- folded_slowdown = 0.15
- folded_wield_delay = 0.2 SECONDS
-
- unfolded_slowdown = 0.35
- unfolded_wield_delay = 0.4 SECONDS
+ valid_attachments = list(
+ /obj/item/attachment/silencer,
+ /obj/item/attachment/laser_sight,
+ /obj/item/attachment/rail_light,
+ /obj/item/attachment/bayonet,
+ /obj/item/attachment/foldable_stock/inteq
+ )
+ default_attachments = list(/obj/item/attachment/foldable_stock/inteq)
-
-/obj/item/gun/ballistic/automatic/smg/skm_carbine/inteq/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
+/obj/item/gun/ballistic/automatic/smg/skm_carbine/inteq/proto
+ name = "\improper Nanotrasen Saber SMG"
+ desc = "A prototype full-auto 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors and a folding stock."
+ icon = 'icons/obj/guns/projectile.dmi'
+ icon_state = "saber"
+ item_state = "gun"
+ mag_type = /obj/item/ammo_box/magazine/smgm9mm
+ bolt_type = BOLT_TYPE_LOCKING
+ show_magazine_on_sprite = TRUE
+ manufacturer = MANUFACTURER_NANOTRASEN_OLD
diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm
index 4ce2819a902e..135a1b2d06b0 100644
--- a/code/modules/projectiles/guns/ballistic/toy.dm
+++ b/code/modules/projectiles/guns/ballistic/toy.dm
@@ -8,8 +8,6 @@
force = 0
throwforce = 0
burst_size = 3
- can_suppress = TRUE
- clumsy_check = 0
item_flags = NONE
casing_ejector = FALSE
manufacturer = MANUFACTURER_NANOTRASEN
@@ -20,20 +18,20 @@
. = ..()
. += "[icon_state]_toy"
-/obj/item/gun/ballistic/automatic/toy/unrestricted
- pin = /obj/item/firing_pin
-
/obj/item/gun/ballistic/automatic/toy/pistol
name = "foam force pistol"
desc = "A small, easily concealable toy handgun. Ages 8 and up."
- icon = 'icons/obj/guns/projectile.dmi'
+ icon = 'icons/obj/guns/manufacturer/scarborough/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/scarborough/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/scarborough/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/scarborough/onmob.dmi'
icon_state = "pistol" // WS edit - Fix various startup runtimes
bolt_type = BOLT_TYPE_LOCKING
w_class = WEIGHT_CLASS_SMALL
mag_type = /obj/item/ammo_box/magazine/toy/pistol
fire_sound = 'sound/items/syringeproj.ogg'
burst_size = 1
- fire_delay = 0
+ fire_delay = 0.2 SECONDS
actions_types = list()
recoil = -10 //its a toy...
recoil_unwielded = -10
@@ -45,23 +43,16 @@
magazine = new /obj/item/ammo_box/magazine/toy/pistol/riot(src)
return ..()
-/obj/item/gun/ballistic/automatic/toy/pistol/unrestricted
- pin = /obj/item/firing_pin
-
-/obj/item/gun/ballistic/automatic/toy/pistol/riot/unrestricted
- pin = /obj/item/firing_pin
-
/obj/item/gun/ballistic/shotgun/toy
name = "foam force shotgun"
desc = "A toy shotgun with wood furniture and a four-shell capacity underneath. Ages 8 and up."
+ icon_state = "shotgun"
force = 0
throwforce = 0
mag_type = /obj/item/ammo_box/magazine/internal/shot/toy
fire_sound = 'sound/items/syringeproj.ogg'
- clumsy_check = FALSE
item_flags = NONE
casing_ejector = FALSE
- can_suppress = FALSE
pb_knockback = 0
recoil = -10 //its a toy...
recoil_unwielded = -10
@@ -70,14 +61,11 @@
. = ..()
. += "[icon_state]_toy"
-/obj/item/gun/ballistic/shotgun/toy/process_chamber(empty_chamber = 0)
- ..()
+/obj/item/gun/ballistic/shotgun/toy/process_chamber(empty_chamber = 0, from_firing = TRUE, chamber_next_round = TRUE, atom/shooter)
+ . = ..()
if(chambered && !chambered.BB)
qdel(chambered)
-/obj/item/gun/ballistic/shotgun/toy/unrestricted
- pin = /obj/item/firing_pin
-
/obj/item/gun/ballistic/shotgun/toy/crossbow
name = "foam force crossbow"
desc = "A weapon favored by many overactive children. Ages 8 and up."
@@ -92,48 +80,36 @@
recoil = -10 //its a toy...
recoil_unwielded = -10
-/obj/item/gun/ballistic/automatic/smg/c20r/toy //This is the syndicate variant with syndicate firing pin and riot darts.
+/obj/item/gun/ballistic/automatic/smg/c20r/toy
name = "donksoft SMG"
desc = "A bullpup two-round burst toy SMG, designated 'C-20r'. Ages 8 and up."
- can_suppress = FALSE
item_flags = NONE
- mag_type = /obj/item/ammo_box/magazine/toy/smgm45/riot
+ mag_type = /obj/item/ammo_box/magazine/toy/smgm45
fire_sound = 'sound/items/syringeproj.ogg'
casing_ejector = FALSE
- clumsy_check = FALSE
manufacturer = MANUFACTURER_DONKCO
recoil = -10 //its a toy...
recoil_unwielded = -10
-/obj/item/gun/ballistic/automatic/smg/c20r/toy/unrestricted //Use this for actual toys
- pin = /obj/item/firing_pin
- mag_type = /obj/item/ammo_box/magazine/toy/smgm45
-
-/obj/item/gun/ballistic/automatic/smg/c20r/toy/unrestricted/riot
+/obj/item/gun/ballistic/automatic/smg/c20r/toy/riot
mag_type = /obj/item/ammo_box/magazine/toy/smgm45/riot
/obj/item/gun/ballistic/automatic/smg/c20r/toy/update_overlays()
. = ..()
. += "[icon_state]_toy"
-/obj/item/gun/ballistic/automatic/hmg/l6_saw/toy //This is the syndicate variant with syndicate firing pin and riot darts.
+/obj/item/gun/ballistic/automatic/hmg/l6_saw/toy
name = "donksoft LMG"
desc = "A heavily modified toy light machine gun, designated 'L6 SAW'. Ages 8 and up."
fire_sound = 'sound/items/syringeproj.ogg'
- can_suppress = FALSE
item_flags = NONE
- mag_type = /obj/item/ammo_box/magazine/toy/m762/riot
+ mag_type = /obj/item/ammo_box/magazine/toy/m762
casing_ejector = FALSE
- clumsy_check = FALSE
manufacturer = MANUFACTURER_DONKCO
recoil = -10 //its a toy...
recoil_unwielded = -10
-/obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/unrestricted //Use this for actual toys
- pin = /obj/item/firing_pin
- mag_type = /obj/item/ammo_box/magazine/toy/m762
-
-/obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/unrestricted/riot
+/obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/riot
mag_type = /obj/item/ammo_box/magazine/toy/m762/riot
/obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/update_overlays()
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index a6e424901d5e..abe3e3fd7b43 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -1,8 +1,8 @@
/obj/item/gun/energy
- icon_state = "energy"
name = "energy gun"
desc = "A basic energy-based gun."
icon = 'icons/obj/guns/energy.dmi'
+ icon_state = "laser"
muzzleflash_iconstate = "muzzle_flash_laser"
muzzle_flash_color = COLOR_SOFT_RED
@@ -10,36 +10,31 @@
has_safety = TRUE
safety = TRUE
- var/obj/item/stock_parts/cell/gun/cell //What type of power cell this uses
- var/cell_type = /obj/item/stock_parts/cell/gun
- var/modifystate = 0
- var/list/ammo_type = list(/obj/item/ammo_casing/energy)
- var/select = 1 //The state of the select fire switch. Determines from the ammo_type list what kind of shot is fired next.
- var/can_charge = TRUE //Can it be charged in a recharger?
- var/automatic_charge_overlays = TRUE //Do we handle overlays with base update_appearance()?
- var/charge_sections = 4
+ modifystate = FALSE
ammo_x_offset = 2
- var/shaded_charge = FALSE //if this gun uses a stateful charge bar for more detail
- var/selfcharge = 0
- var/charge_tick = 0
- var/charge_delay = 4
- var/use_cyborg_cell = FALSE //whether the gun's cell drains the cyborg user's cell to recharge
- var/dead_cell = FALSE //set to true so the gun is given an empty cell
-
- var/internal_cell = FALSE ///if the gun's cell cannot be replaced
- var/small_gun = FALSE ///if the gun is small and can only fit the small gun cell
- var/big_gun = FALSE ///if the gun is big and can fit the comically large gun cell
- var/unscrewing_time = 20 ///Time it takes to unscrew the cell
-
- ///Whether the gun can be tacloaded by slapping a fresh magazine directly on it
- var/tac_reloads = FALSE
- ///If we allow tacitcal reloads, how long should it take to reload?
- var/tactical_reload_delay = 1.2 SECONDS
-
- var/load_sound = 'sound/weapons/gun/general/magazine_insert_full.ogg' //Sound when inserting magazine. UPDATE PLEASE
- var/eject_sound = 'sound/weapons/gun/general/magazine_remove_full.ogg' //Sound of ejecting a cell. UPDATE PLEASE
- var/sound_volume = 40 //Volume of loading/unloading sounds
- var/load_sound_vary = TRUE //Should the load/unload sounds vary?
+
+ gun_firemodes = list(FIREMODE_SEMIAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
+ fire_select_icon_state_prefix = "laser_"
+
+ tac_reloads = FALSE
+ tactical_reload_delay = 1.2 SECONDS
+
+ valid_attachments = list(
+ /obj/item/attachment/laser_sight,
+ /obj/item/attachment/rail_light,
+ /obj/item/attachment/bayonet
+ )
+ slot_available = list(
+ ATTACHMENT_SLOT_RAIL = 1
+ )
+ slot_offsets = list(
+ ATTACHMENT_SLOT_RAIL = list(
+ "x" = 19,
+ "y" = 18,
+ )
+ )
/obj/item/gun/energy/emp_act(severity)
. = ..()
@@ -58,8 +53,8 @@
cell = new cell_type(src)
else
cell = new(src)
- if(!dead_cell)
- cell.give(cell.maxcharge)
+ if(dead_cell)
+ cell.use(cell.maxcharge)
update_ammo_types()
recharge_newshot(TRUE)
if(selfcharge)
@@ -128,54 +123,50 @@
return ..()
/obj/item/gun/energy/proc/insert_cell(mob/user, obj/item/stock_parts/cell/gun/C)
- if(small_gun && !istype(C, /obj/item/stock_parts/cell/gun/mini))
- to_chat(user, "\The [C] doesn't seem to fit into \the [src]...")
+ if(mag_size == MAG_SIZE_SMALL && !istype(C, /obj/item/stock_parts/cell/gun/mini))
+ to_chat(user, span_warning("\The [C] doesn't seem to fit into \the [src]..."))
return FALSE
- if(!big_gun && istype(C, /obj/item/stock_parts/cell/gun/large))
- to_chat(user, "\The [C] doesn't seem to fit into \the [src]...")
+ if(mag_size == MAG_SIZE_LARGE && !istype(C, /obj/item/stock_parts/cell/gun/large))
+ to_chat(user, span_warning("\The [C] doesn't seem to fit into \the [src]..."))
return FALSE
if(user.transferItemToLoc(C, src))
cell = C
- to_chat(user, "You load the [C] into \the [src].")
- playsound(src, load_sound, sound_volume, load_sound_vary)
+ to_chat(user, span_notice("You load the [C] into \the [src]."))
+ playsound(src, load_sound, load_sound_volume, load_sound_vary)
update_appearance()
return TRUE
else
- to_chat(user, "You cannot seem to get \the [src] out of your hands!")
+ to_chat(user, span_warning("You cannot seem to get \the [src] out of your hands!"))
return FALSE
/obj/item/gun/energy/proc/eject_cell(mob/user, obj/item/stock_parts/cell/gun/tac_load = null)
- playsound(src, load_sound, sound_volume, load_sound_vary)
+ playsound(src, load_sound, load_sound_volume, load_sound_vary)
cell.forceMove(drop_location())
var/obj/item/stock_parts/cell/gun/old_cell = cell
old_cell.update_appearance()
cell = null
- to_chat(user, "You pull the cell out of \the [src].")
+ to_chat(user, span_notice("You pull the cell out of \the [src]."))
update_appearance()
if(tac_load && tac_reloads)
- if(do_after(user, tactical_reload_delay, TRUE, src))
+ if(do_after(user, tactical_reload_delay, src, hidden = TRUE))
if(insert_cell(user, tac_load))
- to_chat(user, "You perform a tactical reload on \the [src].")
+ to_chat(user, span_notice("You perform a tactical reload on \the [src]."))
else
- to_chat(user, "You dropped the old cell, but the new one doesn't fit. How embarassing.")
+ to_chat(user, span_warning("You dropped the old cell, but the new one doesn't fit. How embarassing."))
else
- to_chat(user, "Your reload was interupted!")
+ to_chat(user, span_warning("Your reload was interupted!"))
return
user.put_in_hands(old_cell)
update_appearance()
-/obj/item/gun/energy/get_gun_attachments()
+/obj/item/gun/energy/screwdriver_act(mob/living/user, obj/item/I)
if(cell && !internal_cell)
- attachment_options += list("Cell" = image(icon = cell.icon, icon_state = cell.icon_state))
- ..()
-
-/obj/item/gun/energy/remove_gun_attachments(mob/living/user, obj/item/I, picked_option)
- if(picked_option == "Cell")
- if(I.use_tool(src, user, unscrewing_time, volume=100))
- eject_cell(user, I)
- return TRUE
- ..()
+ to_chat(user, span_notice("You begin unscrewing and pulling out the cell..."))
+ if(I.use_tool(src, user, unscrewing_time, volume = 100))
+ to_chat(user, span_notice("You remove the power cell."))
+ eject_cell(user)
+ return ..()
/obj/item/gun/energy/can_shoot(visuals)
if(safety && !visuals)
@@ -204,7 +195,7 @@
if(!chambered.BB)
chambered.newshot()
-/obj/item/gun/energy/process_chamber()
+/obj/item/gun/energy/process_chamber(atom/shooter)
if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired...
var/obj/item/ammo_casing/energy/shot = chambered
cell.use(shot.e_cost)//... drain the cell cell
@@ -217,11 +208,6 @@
process_chamber() // If the gun was drained and then recharged, load a new shot.
return ..()
-/obj/item/gun/energy/process_burst(mob/living/user, atom/target, message = TRUE, params = null, zone_override="", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
- if(!chambered && can_shoot())
- process_chamber() // Ditto.
- return ..()
-
/obj/item/gun/energy/proc/select_fire(mob/living/user)
select++
if (select > ammo_type.len)
@@ -230,7 +216,7 @@
fire_sound = shot.fire_sound
fire_delay = shot.delay
if (shot.select_name)
- to_chat(user, "[src] is now set to [shot.select_name].")
+ to_chat(user, span_notice("[src] is now set to [shot.select_name]."))
chambered = null
playsound(user, 'sound/weapons/gun/general/selector.ogg', 100, TRUE)
recharge_newshot(TRUE)
@@ -308,13 +294,13 @@
if(!BB)
. = ""
else if(BB.nodamage || !BB.damage || BB.damage_type == STAMINA)
- user.visible_message("[user] tries to light [user.p_their()] [A.name] with [src], but it doesn't do anything. Dumbass.")
+ user.visible_message(span_danger("[user] tries to light [user.p_their()] [A.name] with [src], but it doesn't do anything. Dumbass."))
playsound(user, E.fire_sound, 50, TRUE)
playsound(user, BB.hitsound_non_living, 50, TRUE)
cell.use(E.e_cost)
. = ""
else if(BB.damage_type != BURN)
- user.visible_message("[user] tries to light [user.p_their()] [A.name] with [src], but only succeeds in utterly destroying it. Dumbass.")
+ user.visible_message(span_danger("[user] tries to light [user.p_their()] [A.name] with [src], but only succeeds in utterly destroying it. Dumbass."))
playsound(user, E.fire_sound, 50, TRUE)
playsound(user, BB.hitsound_non_living, 50, TRUE)
cell.use(E.e_cost)
@@ -324,10 +310,16 @@
playsound(user, E.fire_sound, 50, TRUE)
playsound(user, BB.hitsound_non_living, 50, TRUE)
cell.use(E.e_cost)
- . = "[user] casually lights their [A.name] with [src]. Damn."
+ . = span_danger("[user] casually lights their [A.name] with [src]. Damn.")
/obj/item/gun/energy/examine(mob/user)
. = ..()
+ var/obj/item/ammo_casing/energy/shot = ammo_type[select]
if(ammo_type.len > 1)
- . += "You can switch firemodes by pressing the unqiue action key. By default, this is space"
+ . += "You can switch firemodes by pressing the unique action key. By default, this is space"
+ if(cell)
+ . += "\The [name]'s cell has [cell.percent()]% charge remaining."
+ . += "\The [name] has [round(cell.charge/shot.e_cost)] shots remaining on [shot.select_name] mode."
+ else
+ . += span_notice("\The [name] doesn't seem to have a cell!")
diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm
index 1423eedf81ba..90bfa9a8ead1 100644
--- a/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -1,19 +1,20 @@
/obj/item/gun/energy/e_gun
name = "energy rifle"
desc = "A basic hybrid energy gun with two settings: disable and kill."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "energy"
item_state = null //so the human update icon uses the icon_state instead.
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
- modifystate = 1
- can_flashlight = TRUE
+ modifystate = TRUE
ammo_x_offset = 2
- flight_x_offset = 15
- flight_y_offset = 10
dual_wield_spread = 60
manufacturer = MANUFACTURER_SHARPLITE_NEW
-/obj/item/gun/energy/e_gun/mindshield
- pin = /obj/item/firing_pin/implant/mindshield
+/obj/item/gun/energy/e_gun/empty_cell
+ dead_cell = TRUE
/obj/item/gun/energy/e_gun/mini
name = "miniature energy gun"
@@ -22,29 +23,22 @@
item_state = "gun"
w_class = WEIGHT_CLASS_SMALL
cell_type = /obj/item/stock_parts/cell/gun/mini
- small_gun = TRUE
+ mag_size = MAG_SIZE_SMALL
throwforce = 11 //This is funny, trust me.
ammo_x_offset = 2
charge_sections = 3
- can_flashlight = FALSE // Can't attach or detach the flashlight, and override it's icon update
- gunlight_state = "mini-light"
- flight_x_offset = 19
- flight_y_offset = 13
-
wield_delay = 0.2 SECONDS
wield_slowdown = 0.15
spread = 2
spread_unwielded = 5
-/obj/item/gun/energy/e_gun/mini/Initialize()
- set_gun_light(new /obj/item/flashlight/seclite(src))
- return ..()
+/obj/item/gun/energy/e_gun/mini/empty_cell
+ dead_cell = TRUE
/obj/item/gun/energy/e_gun/hades
name = "SL AL-655 'Hades' energy rifle"
desc = "The standard issue rifle of Nanotrasen's Security Forces. Most have been put in long term storage following the ICW, and usually aren't issued to low ranking security divisions."
- icon = 'icons/obj/guns/48x32guns.dmi'
icon_state = "energytac"
ammo_x_offset = 2
charge_sections = 5
@@ -55,14 +49,15 @@
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
+ fire_delay = 0.2 SECONDS
+
wield_delay = 0.7 SECONDS
wield_slowdown = 0.6
spread_unwielded = 20
-/obj/item/gun/energy/e_gun/hades/Initialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.2 SECONDS)
-
/obj/item/gun/energy/e_gun/old
name = "prototype energy gun"
desc = "NT-P:01 Prototype Energy Gun. Early stage development of a unique laser rifle that has a multifaceted energy lens, allowing the gun to alter the form of projectile it fires on command. The project was a dud, and Nanotrasen later acquired Sharplite to suit its laser weapon needs."
@@ -71,12 +66,6 @@
ammo_type = list(/obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/electrode/old)
manufacturer = MANUFACTURER_NANOTRASEN_OLD
-/obj/item/gun/energy/e_gun/mini/practice_phaser
- name = "practice phaser"
- desc = "A modified version of the basic phaser gun, this one fires less concentrated energy bolts designed for target practice."
- ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser/practice)
- icon_state = "decloner"
-
/obj/item/gun/energy/e_gun/hos
name = "\improper X-01 MultiPhase Energy Gun"
desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time."
@@ -107,10 +96,9 @@
desc = "The \"Dynamic Rapid-Apprehension of the Guilty\" net is a revolution in law enforcement technology."
icon_state = "dragnet"
item_state = "dragnet"
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
ammo_type = list(/obj/item/ammo_casing/energy/net, /obj/item/ammo_casing/energy/trap)
- can_flashlight = FALSE
ammo_x_offset = 1
/obj/item/gun/energy/e_gun/dragnet/snare
@@ -127,7 +115,6 @@
w_class = WEIGHT_CLASS_HUGE
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
weapon_weight = WEAPON_HEAVY
- can_flashlight = FALSE
trigger_guard = TRIGGER_GUARD_NONE
ammo_x_offset = 2
@@ -137,7 +124,6 @@
icon_state = "nucgun"
item_state = "nucgun"
charge_delay = 5
- pin = null
can_charge = FALSE
internal_cell = TRUE
ammo_x_offset = 2
@@ -198,7 +184,7 @@
item_state = "gun"
ammo_x_offset = 2
charge_sections = 6
- small_gun = TRUE
+ mag_size = MAG_SIZE_SMALL
wield_delay = 0.2 SECONDS
wield_slowdown = 0.15
@@ -228,9 +214,10 @@
charge_sections = 3
weapon_weight = WEAPON_LIGHT
-/obj/item/gun/energy/e_gun/smg/Initialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.13 SECONDS)
+ fire_delay = 0.13 SECONDS
+
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
/obj/item/gun/energy/e_gun/iot
name = "\improper E-SG 500 Second Edition"
@@ -241,7 +228,7 @@
inhand_y_dimension = 64
icon_state = "iotshotgun"
item_state = "shotgun_combat"
- shaded_charge = 1
+ shaded_charge = TRUE
w_class = WEIGHT_CLASS_BULKY
ammo_type = list(/obj/item/ammo_casing/energy/disabler/scatter/ultima, /obj/item/ammo_casing/energy/laser/ultima)
var/obj/item/modular_computer/integratedNTOS
@@ -250,12 +237,13 @@
/obj/item/gun/energy/e_gun/e11
name = "E-11 hybrid energy rifle"
desc = "A hybrid energy gun fondly remembered as one of the worst weapons ever made. It hurts, but that's only if it manages to hit its target."
+ icon = 'icons/obj/guns/manufacturer/eoehoma/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/eoehoma/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/eoehoma/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/eoehoma/onmob.dmi'
icon_state = "e11"
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser/eoehoma)
- can_flashlight = TRUE
ammo_x_offset = 0
- flight_x_offset = 20
- flight_y_offset = 9
spread = 80
spread_unwielded = 140
dual_wield_spread = 140
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 5f39d407d749..2ca71649a6f7 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -1,6 +1,6 @@
/obj/item/gun/energy/kinetic_accelerator
name = "kinetic accelerator"
- desc = "A self recharging, ranged self-defense and rock pulverizing tool that does increased damage in low pressure. EXOCON does not condone use of this weapon against other sentient life."
+ desc = "A self recharging, ranged self-defense and rock pulverizing tool that does increased damage in low pressure. EXOCOM does not condone use of this weapon against other sentient life."
icon_state = "kineticgun"
item_state = "kineticgun"
ammo_type = list(/obj/item/ammo_casing/energy/kinetic)
@@ -8,14 +8,8 @@
item_flags = NONE
obj_flags = UNIQUE_RENAME
weapon_weight = WEAPON_LIGHT
- can_flashlight = TRUE
- flight_x_offset = 15
- flight_y_offset = 9
automatic_charge_overlays = FALSE
- can_bayonet = TRUE
- knife_x_offset = 20
- knife_y_offset = 12
- internal_cell = TRUE
+ internal_cell = TRUE //prevents you from giving it an OP cell - WS Edit
custom_price = 750
w_class = WEIGHT_CLASS_BULKY
@@ -28,12 +22,18 @@
var/overheat = FALSE
var/mob/holder
-
var/max_mod_capacity = 100
var/list/modkits = list()
var/recharge_timerid
+ slot_offsets = list(
+ ATTACHMENT_SLOT_RAIL = list(
+ "x" = 24,
+ "y" = 13,
+ )
+ )
+
/obj/item/gun/energy/kinetic_accelerator/shoot_with_empty_chamber(mob/living/user)
playsound(src, dry_fire_sound, 30, TRUE) //click sound but no to_chat message to cut on spam
return
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 4c924ef49ccf..eff3d67b2df1 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -1,6 +1,7 @@
/obj/item/gun/energy/laser
name = "SL L-204 laser gun"
desc = "A basic energy-based laser gun that fires concentrated beams of light which pass through glass and thin metal."
+
icon_state = "laser"
item_state = "laser"
w_class = WEIGHT_CLASS_NORMAL
@@ -14,22 +15,33 @@
spread = 0
spread_unwielded = 10
+/obj/item/gun/energy/laser/empty_cell
+ dead_cell = TRUE
+
/obj/item/gun/energy/laser/practice
name = "practice laser gun"
desc = "A modified version of the L-204 laser gun, this one fires less concentrated energy bolts designed for target practice."
ammo_type = list(/obj/item/ammo_casing/energy/laser/practice)
- clumsy_check = TRUE
item_flags = NONE
/obj/item/gun/energy/laser/retro
name ="SL L-104 retro laser gun"
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "retro"
desc = "An antiquated model of the basic lasergun, no longer used or sold by Sharplite. Nevertheless, the sheer popularity of this model makes it a somewhat common sight to this day."
ammo_x_offset = 3
manufacturer = MANUFACTURER_SHARPLITE
+
/obj/item/gun/energy/laser/captain
name = "antique laser gun"
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "caplaser"
item_state = null
desc = "This is the SL X-00, an antique laser gun, out of production for decades and well beyond anyone's capacity to recreate. All craftsmanship is of the highest quality. It is decorated with ashdrake leather and chrome. The gun menaces with spikes of energy. On the item is an image of a space station. The station is exploding."
@@ -47,8 +59,6 @@
/obj/item/gun/energy/laser/captain/scattershot
name = "scatter shot laser rifle"
- icon_state = "lasercannon"
- item_state = "laser"
desc = "An industrial-grade heavy-duty laser rifle with a modified laser lens to scatter its shot into multiple smaller lasers. The inner-core can self-charge for theoretically infinite use."
ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser)
shaded_charge = FALSE
@@ -74,8 +84,7 @@
icon_state = "cshotgun"
item_state = "shotgun"
desc = "A combat shotgun gutted and refitted with an internal laser system. Can switch between taser and scattered disabler shots."
- shaded_charge = 0
- pin = /obj/item/firing_pin/implant/mindshield
+ shaded_charge = FALSE
ammo_type = list(/obj/item/ammo_casing/energy/disabler/scatter, /obj/item/ammo_casing/energy/electrode)
manufacturer = MANUFACTURER_NONE
@@ -87,19 +96,15 @@
icon_state = "lasercannon"
item_state = "laser"
w_class = WEIGHT_CLASS_BULKY
- big_gun = TRUE
+ mag_size = MAG_SIZE_LARGE
cell_type = "/obj/item/stock_parts/cell/gun/large"
force = 10
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
ammo_type = list(/obj/item/ammo_casing/energy/laser/accelerator)
- pin = null
ammo_x_offset = 3
manufacturer = MANUFACTURER_SHARPLITE
-/obj/item/gun/energy/lasercannon/unrestricted
- pin = /obj/item/firing_pin
-
/obj/item/ammo_casing/energy/laser/accelerator
projectile_type = /obj/projectile/beam/laser/accelerator
select_name = "accelerator"
@@ -123,7 +128,6 @@
icon_state = "xray"
item_state = null
ammo_type = list(/obj/item/ammo_casing/energy/xray)
- pin = null
ammo_x_offset = 3
////////Laser Tag////////////////////
@@ -134,8 +138,6 @@
desc = "A retro laser gun modified to fire harmless blue beams of light. Sound effects included!"
ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag)
item_flags = NONE
- clumsy_check = FALSE
- pin = /obj/item/firing_pin/tag/blue
ammo_x_offset = 2
selfcharge = TRUE
manufacturer = MANUFACTURER_NONE
@@ -149,8 +151,6 @@
desc = "A retro laser gun modified to fire harmless beams red of light. Sound effects included!"
ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag)
item_flags = NONE
- clumsy_check = FALSE
- pin = /obj/item/firing_pin/tag/red
ammo_x_offset = 2
selfcharge = TRUE
manufacturer = MANUFACTURER_NONE
@@ -161,6 +161,9 @@
/obj/item/gun/energy/laser/iot
name = "\improper SL E-255 Ultimate"
desc = "An energy shotgun with an integrated computer system for surveillance and statistics tracking."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
+
lefthand_file = 'icons/mob/inhands/weapons/64x_guns_left.dmi'
righthand_file = 'icons/mob/inhands/weapons/64x_guns_right.dmi'
inhand_x_dimension = 64
@@ -192,11 +195,15 @@
/obj/item/gun/energy/laser/hitscanpistol
name = "experimental laser gun"
desc = "A highly experimental laser gun, with unknown inner workings. It has no markings besides a \"GROUP A\" inscription on the barrel."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "hitscangun"
item_state = "gun"
ammo_x_offset = 2
charge_sections = 4
- small_gun = TRUE
+ mag_size = MAG_SIZE_SMALL
w_class = WEIGHT_CLASS_NORMAL
cell_type = /obj/item/stock_parts/cell/gun/mini
ammo_type = list(/obj/item/ammo_casing/energy/lasergun/hitscan)
@@ -211,6 +218,10 @@
/obj/item/gun/energy/laser/e10
name = "E-10 laser pistol"
desc = "A very old laser weapon. Despite the extreme age of some of these weapons, they are sometimes preferred to newer, mass-produced Nanotrasen laser weapons."
+ icon = 'icons/obj/guns/manufacturer/eoehoma/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/eoehoma/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/eoehoma/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/eoehoma/onmob.dmi'
icon_state = "e10"
w_class = WEIGHT_CLASS_SMALL
@@ -227,10 +238,14 @@
name = "E-50 energy emitter"
desc = "A heavy and extremely powerful laser. Sets targets on fire and kicks ass, but it uses a massive amount of energy per shot and is generally awkward to handle."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/eoehoma/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/eoehoma/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/eoehoma/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/eoehoma/onmob.dmi'
icon_state = "e50"
+ item_state = "e50"
- big_gun = TRUE
+ mag_size = MAG_SIZE_LARGE
cell_type = /obj/item/stock_parts/cell/gun/large
ammo_type = list(/obj/item/ammo_casing/energy/laser/eoehoma/e50)
weapon_weight = WEAPON_HEAVY
diff --git a/code/modules/projectiles/guns/energy/laser_gatling.dm b/code/modules/projectiles/guns/energy/laser_gatling.dm
index b21e176b92e8..22e6e57d8817 100644
--- a/code/modules/projectiles/guns/energy/laser_gatling.dm
+++ b/code/modules/projectiles/guns/energy/laser_gatling.dm
@@ -105,6 +105,12 @@
icon_state = "minigun_spin"
item_state = "minigun"
slowdown = 1
+
+ fire_delay = 0.1 SECONDS
+
+ gun_firemodes = list(FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_FULLAUTO
+
slot_flags = null
w_class = WEIGHT_CLASS_HUGE
custom_materials = null
@@ -121,7 +127,6 @@
ammo_pack = loc
AddElement(/datum/element/update_icon_blocker)
- AddComponent(/datum/component/automatic_fire, 0.15 SECONDS)
return ..()
/obj/item/gun/energy/minigun/Destroy()
diff --git a/code/modules/projectiles/guns/energy/mounted.dm b/code/modules/projectiles/guns/energy/mounted.dm
index 4dc5cae77558..cf67db9fd5ae 100644
--- a/code/modules/projectiles/guns/energy/mounted.dm
+++ b/code/modules/projectiles/guns/energy/mounted.dm
@@ -6,7 +6,6 @@
item_state = "armcannonstun4"
force = 5
selfcharge = 1
- can_flashlight = FALSE
trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses neural signals instead
/obj/item/gun/energy/e_gun/advtaser/mounted/dropped()//if somebody manages to drop this somehow...
diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm
index 9ed110dfa041..c2e5b4cb2933 100644
--- a/code/modules/projectiles/guns/energy/pulse.dm
+++ b/code/modules/projectiles/guns/energy/pulse.dm
@@ -1,7 +1,10 @@
/obj/item/gun/energy/pulse
name = "pulse rifle"
desc = "A top-of-the-line, heavy-duty, multifaceted energy rifle with three firing modes. The gold standard for Nanotrasen's heavier security specialists."
- icon = 'icons/obj/guns/48x32guns.dmi'
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "pulse"
item_state = null
w_class = WEIGHT_CLASS_BULKY
@@ -24,8 +27,22 @@
/obj/item/gun/energy/pulse/emp_act(severity)
return
-/obj/item/gun/energy/pulse/prize
- pin = /obj/item/firing_pin
+/obj/item/gun/energy/pulse/carbine
+ name = "pulse carbine"
+ desc = "A next-generation pulse weapon for Nanotrasen's security forces. High production costs and logistical issues have limited its deployment to specialist Loss Prevention and Emergency Response units."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
+ w_class = WEIGHT_CLASS_BULKY
+ slot_flags = ITEM_SLOT_BACK
+ icon_state = "pulse_carbine"
+ item_state = null
+ internal_cell = FALSE
+ mag_size = MAG_SIZE_LARGE //haha gun go brr
+ cell_type = /obj/item/stock_parts/cell/gun/large
+ ammo_x_offset = 2
+ charge_sections = 4
/obj/item/gun/energy/pulse/prize/Initialize()
. = ..()
@@ -41,33 +58,13 @@
GLOB.poi_list -= src
. = ..()
-/obj/item/gun/energy/pulse/loyalpin
- pin = /obj/item/firing_pin
-
-/obj/item/gun/energy/pulse/carbine
- name = "pulse carbine"
- desc = "A next-generation pulse weapon for Nanotrasen's security forces. High production costs and logistical issues have limited its deployment to specialist Loss Prevention and Emergency Response units."
- icon = 'icons/obj/guns/energy.dmi'
- w_class = WEIGHT_CLASS_BULKY
- slot_flags = ITEM_SLOT_BACK
- icon_state = "pulse_carbine"
- item_state = null
- internal_cell = FALSE
- big_gun = TRUE //haha gun go brr
- cell_type = /obj/item/stock_parts/cell/gun/large
- can_flashlight = TRUE
- flight_x_offset = 18
- flight_y_offset = 12
- ammo_x_offset = 2
- charge_sections = 4
-
-/obj/item/gun/energy/pulse/carbine/loyalpin
- pin = /obj/item/firing_pin/implant/mindshield
-
/obj/item/gun/energy/pulse/pistol
name = "pulse pistol"
desc = "A pulse rifle in an easily concealed handgun package with low capacity."
- icon = 'icons/obj/guns/energy.dmi'
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
icon_state = "pulse_pistol"
@@ -76,9 +73,6 @@
ammo_x_offset = 2
charge_sections = 4
-/obj/item/gun/energy/pulse/pistol/loyalpin
- pin = /obj/item/firing_pin/implant/mindshield
-
/obj/item/gun/energy/pulse/destroyer
name = "pulse destroyer"
desc = "A heavy-duty energy rifle built for pure destruction."
@@ -87,10 +81,3 @@
/obj/item/gun/energy/pulse/destroyer/attack_self(mob/living/user)
to_chat(user, "[src.name] has three settings, and they are all DESTROY.")
-
-/obj/item/gun/energy/pulse/pistol/m1911
- name = "\improper Candor-P"
- desc = "A compact pulse core in a classic handgun frame for Nanotrasen officers. It's not the size of the gun, it's the size of the hole it puts through people."
- icon_state = "m1911"
- item_state = "gun"
- cell_type = /obj/item/stock_parts/cell/infinite
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 5a01abfdc0f1..09de7690b5ea 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -6,9 +6,8 @@
shaded_charge = FALSE
ammo_x_offset = 2
ammo_y_offset = 2
- can_flashlight = FALSE
w_class = WEIGHT_CLASS_HUGE
- big_gun = TRUE //yes, you can put the comically large cell in it. No, you aren't getting it roundstart. You slut.
+ mag_size = MAG_SIZE_LARGE //yes, you can put the comically large cell in it. No, you aren't getting it roundstart. You slut.
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
ammo_type = list(/obj/item/ammo_casing/energy/ion)
@@ -17,6 +16,9 @@
/obj/item/gun/energy/ionrifle/emp_act(severity)
return
+/obj/item/gun/energy/ionrifle/empty_cell
+ dead_cell = TRUE
+
/obj/item/gun/energy/ionrifle/carbine
name = "ion carbine"
desc = "The MK.II Prototype Ion Projector is a lightweight carbine version of the larger ion rifle, built to be ergonomic and efficient."
@@ -25,17 +27,12 @@
slot_flags = ITEM_SLOT_BELT
ammo_x_offset = 2
ammo_y_offset = 0
- pin = null
- can_flashlight = TRUE
- flight_x_offset = 18
- flight_y_offset = 11
/obj/item/gun/energy/decloner
name = "biological demolecularisor"
desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements."
icon_state = "decloner"
ammo_type = list(/obj/item/ammo_casing/energy/declone)
- pin = null
ammo_x_offset = 1
/obj/item/gun/energy/decloner/update_overlays()
@@ -44,20 +41,16 @@
if(!QDELETED(cell) && (cell.charge > shot.e_cost))
. += "decloner_spin"
-/obj/item/gun/energy/decloner/unrestricted
- pin = /obj/item/firing_pin
- ammo_type = list(/obj/item/ammo_casing/energy/declone/weak)
-
/obj/item/gun/energy/floragun
name = "floral somatoray"
desc = "A tool that discharges controlled radiation which induces mutation in plant cells."
icon_state = "flora"
item_state = "gun"
ammo_type = list(/obj/item/ammo_casing/energy/flora/yield, /obj/item/ammo_casing/energy/flora/mut, /obj/item/ammo_casing/energy/flora/revolution)
- modifystate = 1
+ modifystate = TRUE
ammo_x_offset = 1
selfcharge = 1
- shaded_charge = 1
+ shaded_charge = TRUE
/obj/item/gun/energy/meteorgun
name = "meteor gun"
@@ -67,7 +60,6 @@
w_class = WEIGHT_CLASS_BULKY
ammo_type = list(/obj/item/ammo_casing/energy/meteor)
cell_type = /obj/item/stock_parts/cell/potato
- clumsy_check = 0 //Admin spawn only, might as well let clowns use it.
selfcharge = 1
/obj/item/gun/energy/meteorgun/pen
@@ -102,26 +94,17 @@
overheat_time = 20
holds_charge = TRUE
unique_frequency = TRUE
- can_flashlight = FALSE
max_mod_capacity = 0
manufacturer = MANUFACTURER_SCARBOROUGH
-/obj/item/gun/energy/kinetic_accelerator/crossbow/halloween
- name = "candy corn crossbow"
- desc = "A weapon favored by Syndicate trick-or-treaters."
- icon_state = "crossbow_halloween"
- item_state = "crossbow"
- ammo_type = list(/obj/item/ammo_casing/energy/bolt/halloween)
-
/obj/item/gun/energy/kinetic_accelerator/crossbow/large
name = "energy crossbow"
desc = "A reverse engineered weapon using syndicate technology."
icon_state = "crossbowlarge"
w_class = WEIGHT_CLASS_NORMAL
custom_materials = list(/datum/material/iron=4000)
- suppressed = null
+ suppressed = FALSE
ammo_type = list(/obj/item/ammo_casing/energy/bolt/large)
- pin = null
manufacturer = MANUFACTURER_NONE
@@ -229,7 +212,7 @@
if(istype(WH))
WH.gun = WEAKREF(src)
-/obj/item/gun/energy/wormhole_projector/process_chamber()
+/obj/item/gun/energy/wormhole_projector/process_chamber(atom/shooter)
..()
select_fire()
@@ -285,10 +268,14 @@
can_charge = FALSE
use_cyborg_cell = TRUE
+ fire_delay = 0.3 SECONDS
+
+ gun_firemodes = list(FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_FULLAUTO
+
/obj/item/gun/energy/printer/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
- AddComponent(/datum/component/automatic_fire, 0.3 SECONDS)
/obj/item/gun/energy/printer/emp_act()
return
@@ -336,12 +323,10 @@
ammo_type = list(/obj/item/ammo_casing/energy/temp, /obj/item/ammo_casing/energy/temp/hot)
cell_type = /obj/item/stock_parts/cell/gun/upgraded
ammo_x_offset = 2
- pin = null
/obj/item/gun/energy/temperature/security
name = "security temperature gun"
desc = "A weapon that can only be used to its full potential by the truly robust."
- pin = /obj/item/firing_pin
/obj/item/gun/energy/laser/instakill
name = "instakill rifle"
@@ -401,9 +386,9 @@
shaded_charge = TRUE
weapon_weight = WEAPON_HEAVY
-/obj/item/gun/energy/tesla_cannon/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.1 SECONDS)
+ fire_delay = 0.1 SECONDS
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
/obj/item/gun/energy/buster
name = "replica buster cannon"
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index fc11a632e039..e70c46cc76f6 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -1,11 +1,10 @@
/obj/item/gun/energy/taser
name = "taser gun"
desc = "A low-capacity, energy-based stun gun used by security teams to subdue targets at range."
- icon_state = "taser"
+ icon_state = "advtaser"
item_state = null //so the human update icon uses the icon_state instead.
ammo_type = list(/obj/item/ammo_casing/energy/electrode)
ammo_x_offset = 3
-
spread = 2
spread_unwielded = 4
@@ -22,22 +21,21 @@
/obj/item/gun/energy/e_gun/advtaser/cyborg
name = "cyborg taser"
desc = "An integrated hybrid taser that draws directly from a cyborg's power cell. The weapon contains a limiter to prevent the cyborg's power cell from overheating."
- can_flashlight = FALSE
can_charge = FALSE
use_cyborg_cell = TRUE
/obj/item/gun/energy/disabler
name = "disabler"
desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse."
+ icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi'
icon_state = "disabler"
item_state = null
ammo_type = list(/obj/item/ammo_casing/energy/disabler)
ammo_x_offset = 2
- can_flashlight = TRUE
- flight_x_offset = 15
- flight_y_offset = 10
manufacturer = MANUFACTURER_SHARPLITE_NEW
-
spread = 2
spread_unwielded = 4
@@ -50,5 +48,9 @@
/obj/item/gun/energy/disabler/e60
name = "E-60"
desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse."
+ icon = 'icons/obj/guns/manufacturer/eoehoma/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/eoehoma/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/eoehoma/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/eoehoma/onmob.dmi'
icon_state = "e60"
manufacturer = MANUFACTURER_EOEHOMA
diff --git a/code/modules/projectiles/guns/gunhud.dm b/code/modules/projectiles/guns/gunhud.dm
index 9d1a40db8bb6..3dad98f54219 100644
--- a/code/modules/projectiles/guns/gunhud.dm
+++ b/code/modules/projectiles/guns/gunhud.dm
@@ -18,9 +18,6 @@
// Ammo counter
#define ui_ammocounter "EAST-1:28,CENTER+1:25"
-///The gun needs to update the gun hud!
-#define COMSIG_UPDATE_AMMO_HUD "update_ammo_hud"
-
/datum/hud
var/atom/movable/screen/ammo_counter
@@ -233,6 +230,7 @@
/datum/component/ammo_hud/laser/cybersun
prefix = "cybersun_"
+//please be aware, this only supports 6 round revolvers. It is comically easy to support more or less rounds,like in game there are 7 round and 5 round revolvers, but that requires sprites, and i'm lasy
/datum/component/ammo_hud/revolver
prefix = "revolver_"
@@ -285,3 +283,55 @@
round_images += current_bullet_image
hud.update_overlays(round_images)
+
+/datum/component/ammo_hud/eoehoma
+ backing_color = "#cb001a"
+
+/datum/component/ammo_hud/eoehoma/update_hud()
+ var/obj/item/gun/ballistic/automatic/assault/e40/pew = parent
+ var/obj/item/gun/energy/laser/e40_laser_secondary/pew_secondary = pew.secondary
+ hud.maptext = null
+ hud.icon_state = "[prefix]backing"
+
+ var/indicator
+ var/rounds = num2text(get_accurate_ammo_count(pew))
+ var/oth_o
+ var/oth_t
+ var/oth_h
+
+ var/current_firemode = pew.gun_firemodes[pew.firemode_index]
+ if(current_firemode == FIREMODE_FULLAUTO)
+ if(!pew.magazine)
+ hud.set_hud(backing_color, "[prefix]oe", "[prefix]te", "[prefix]he", "[prefix]no_mag")
+ return
+ if(!pew.get_ammo())
+ hud.set_hud(backing_color, "[prefix]oe", "[prefix]te", "[prefix]he", "[prefix]empty_flash")
+ return
+ rounds = num2text(get_accurate_ammo_count(pew))
+ indicator = "bullet"
+ else
+ if(!pew_secondary.cell)
+ hud.set_hud(backing_color, "[prefix]oe", "[prefix]te", "[prefix]he", "[prefix]no_mag")
+ return
+ if(!get_accurate_laser_count(pew_secondary))
+ hud.set_hud(backing_color, "[prefix]oe", "[prefix]te", "[prefix]he", "[prefix]empty_flash_laser")
+ return
+ rounds = num2text(get_accurate_laser_count(pew_secondary))
+ indicator = "laser"
+
+
+ switch(length(rounds))
+ if(1)
+ oth_o = "[prefix]o[rounds[1]]"
+ if(2)
+ oth_o = "[prefix]o[rounds[2]]"
+ oth_t = "[prefix]t[rounds[1]]"
+ if(3)
+ oth_o = "[prefix]o[rounds[3]]"
+ oth_t = "[prefix]t[rounds[2]]"
+ oth_h = "[prefix]h[rounds[1]]"
+ else
+ oth_o = "[prefix]o9"
+ oth_t = "[prefix]t9"
+ oth_h = "[prefix]h9"
+ hud.set_hud(backing_color, oth_o, oth_t, oth_h, indicator)
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
deleted file mode 100644
index 63c4ef8aa2d0..000000000000
--- a/code/modules/projectiles/guns/magic.dm
+++ /dev/null
@@ -1,87 +0,0 @@
-/obj/item/gun/magic
- name = "staff of nothing"
- desc = "This staff is boring to watch because even though it came first you've seen everything it can do in other staves for years."
- icon = 'icons/obj/guns/magic.dmi'
- icon_state = "staffofnothing"
- item_state = "staff"
- lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' //not really a gun and some toys use these inhands
- righthand_file = 'icons/mob/inhands/items_righthand.dmi'
- fire_sound = 'sound/weapons/emitter.ogg'
- flags_1 = CONDUCT_1
- w_class = WEIGHT_CLASS_HUGE
- var/checks_antimagic = TRUE
- var/max_charges = 6
- var/charges = 0
- var/recharge_rate = 4
- var/charge_tick = 0
- var/can_charge = TRUE
- var/ammo_type
- var/no_den_usage
- clumsy_check = 0
- trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses magic instead
- pin = /obj/item/firing_pin/magic
-
-/obj/item/gun/magic/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread)
- if(no_den_usage)
- var/area/A = get_area(user)
- if(istype(A, /area/wizard_station))
- add_fingerprint(user)
- to_chat(user, "You know better than to violate the security of The Den, best wait until you leave to use [src].")
- return
- else
- no_den_usage = 0
- if(checks_antimagic && user.anti_magic_check(TRUE, FALSE, FALSE, 0, TRUE))
- add_fingerprint(user)
- to_chat(user, "Something is interfering with [src].")
- return
- . = ..()
-
-/obj/item/gun/magic/can_shoot()
- return charges
-
-/obj/item/gun/magic/recharge_newshot()
- if (charges && chambered && !chambered.BB)
- chambered.newshot()
-
-/obj/item/gun/magic/process_chamber()
- if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired...
- charges--//... drain a charge
- recharge_newshot()
-
-/obj/item/gun/magic/Initialize()
- . = ..()
- charges = max_charges
- if(ammo_type)
- chambered = new ammo_type(src)
- if(can_charge)
- START_PROCESSING(SSobj, src)
-
-
-/obj/item/gun/magic/Destroy()
- if(can_charge)
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-
-/obj/item/gun/magic/process()
- if (charges >= max_charges)
- charge_tick = 0
- return
- charge_tick++
- if(charge_tick < recharge_rate)
- return 0
- charge_tick = 0
- charges++
- if(charges == 1)
- recharge_newshot()
- return 1
-
-
-/obj/item/gun/magic/shoot_with_empty_chamber(mob/living/user as mob|obj)
- to_chat(user, "The [name] whizzles quietly.")
-
-/obj/item/gun/magic/vv_edit_var(var_name, var_value)
- . = ..()
- switch(var_name)
- if(NAMEOF(src, charges))
- recharge_newshot()
diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm
deleted file mode 100644
index e8f1683d21a1..000000000000
--- a/code/modules/projectiles/guns/magic/staff.dm
+++ /dev/null
@@ -1,142 +0,0 @@
-/obj/item/gun/magic/staff
- slot_flags = ITEM_SLOT_BACK
- lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
- item_flags = NEEDS_PERMIT | NO_MAT_REDEMPTION
-
-/obj/item/gun/magic/staff/change
- name = "staff of change"
- desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
- fire_sound = 'sound/magic/staff_change.ogg'
- ammo_type = /obj/item/ammo_casing/magic/change
- icon_state = "staffofchange"
- item_state = "staffofchange"
-
-/obj/item/gun/magic/staff/animate
- name = "staff of animation"
- desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
- fire_sound = 'sound/magic/staff_animation.ogg'
- ammo_type = /obj/item/ammo_casing/magic/animate
- icon_state = "staffofanimation"
- item_state = "staffofanimation"
-
-/obj/item/gun/magic/staff/healing
- name = "staff of healing"
- desc = "An artefact that spits bolts of restoring magic which can remove ailments of all kinds and even raise the dead."
- fire_sound = 'sound/magic/staff_healing.ogg'
- ammo_type = /obj/item/ammo_casing/magic/heal
- icon_state = "staffofhealing"
- item_state = "staffofhealing"
-
-/obj/item/gun/magic/staff/healing/handle_suicide() //Stops people trying to commit suicide to heal themselves
- return
-
-/obj/item/gun/magic/staff/chaos
- name = "staff of chaos"
- desc = "An artefact that spits bolts of chaotic magic that can potentially do anything."
- fire_sound = 'sound/magic/staff_chaos.ogg'
- ammo_type = /obj/item/ammo_casing/magic/chaos
- icon_state = "staffofchaos"
- item_state = "staffofchaos"
- max_charges = 10
- recharge_rate = 2
- no_den_usage = 1
- var/allowed_projectile_types = list(/obj/projectile/magic/change, /obj/projectile/magic/animate, /obj/projectile/magic/resurrection,
- /obj/projectile/magic/death, /obj/projectile/magic/teleport, /obj/projectile/magic/door, /obj/projectile/magic/aoe/fireball,
- /obj/projectile/magic/spellblade, /obj/projectile/magic/arcane_barrage, /obj/projectile/magic/locker, /obj/projectile/magic/flying,
- /obj/projectile/magic/bounty, /obj/projectile/magic/antimagic, /obj/projectile/magic/fetch, /obj/projectile/magic/sapping,
- /obj/projectile/magic/necropotence, /obj/projectile/magic, /obj/projectile/temp/chill, /obj/projectile/magic/wipe)
-
-/obj/item/gun/magic/staff/chaos/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
- chambered.projectile_type = pick(allowed_projectile_types)
- . = ..()
-
-/obj/item/gun/magic/staff/door
- name = "staff of door creation"
- desc = "An artefact that spits bolts of transformative magic that can create doors in walls."
- fire_sound = 'sound/magic/staff_door.ogg'
- ammo_type = /obj/item/ammo_casing/magic/door
- icon_state = "staffofdoor"
- item_state = "staffofdoor"
- max_charges = 10
- recharge_rate = 2
- no_den_usage = 1
-
-/obj/item/gun/magic/staff/honk
- name = "staff of the honkmother"
- desc = "Honk."
- fire_sound = 'sound/items/airhorn.ogg'
- ammo_type = /obj/item/ammo_casing/magic/honk
- icon_state = "honker"
- item_state = "honker"
- max_charges = 4
- recharge_rate = 8
-
-/obj/item/gun/magic/staff/spellblade
- name = "spellblade"
- desc = "A deadly combination of laziness and boodlust, this blade allows the user to dismember their enemies without all the hard work of actually swinging the sword."
- fire_sound = 'sound/magic/fireball.ogg'
- ammo_type = /obj/item/ammo_casing/magic/spellblade
- icon_state = "spellblade"
- item_state = "spellblade"
- lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
- hitsound = 'sound/weapons/rapierhit.ogg'
- force = 20
- armour_penetration = 75
- block_chance = 50
- sharpness = IS_SHARP
- max_charges = 4
-
-/obj/item/gun/magic/staff/spellblade/Initialize()
- . = ..()
- AddComponent(/datum/component/butchering, 15, 125, 0, hitsound)
-
-/obj/item/gun/magic/staff/spellblade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(attack_type == PROJECTILE_ATTACK)
- final_block_chance = 0
- return ..()
-
-/obj/item/gun/magic/staff/locker
- name = "staff of the locker"
- desc = "An artefact that expells encapsulating bolts, for incapacitating thy enemy."
- fire_sound = 'sound/magic/staff_change.ogg'
- ammo_type = /obj/item/ammo_casing/magic/locker
- icon_state = "locker"
- item_state = "locker"
- max_charges = 6
- recharge_rate = 4
-
-//yes, they don't have sounds. they're admin staves, and their projectiles will play the chaos bolt sound anyway so why bother?
-
-/obj/item/gun/magic/staff/flying
- name = "staff of flying"
- desc = "An artefact that spits bolts of graceful magic that can make something fly."
- fire_sound = 'sound/magic/staff_healing.ogg'
- ammo_type = /obj/item/ammo_casing/magic/flying
- icon_state = "staffofflight"
- item_state = "staffofflight"
-
-/obj/item/gun/magic/staff/sapping
- name = "staff of sapping"
- desc = "An artefact that spits bolts of sapping magic that can make something sad."
- fire_sound = 'sound/magic/staff_change.ogg'
- ammo_type = /obj/item/ammo_casing/magic/sapping
- icon_state = "staffofsapping"
- item_state = "staffofsapping"
-
-/obj/item/gun/magic/staff/necropotence
- name = "staff of necropotence"
- desc = "An artefact that spits bolts of death magic that can repurpose the soul."
- fire_sound = 'sound/magic/staff_change.ogg'
- ammo_type = /obj/item/ammo_casing/magic/necropotence
- icon_state = "staffofnecropotence"
- item_state = "staffofnecropotence"
-
-/obj/item/gun/magic/staff/wipe
- name = "staff of possession"
- desc = "An artefact that spits bolts of mind-unlocking magic that can let ghosts invade the victim's mind."
- fire_sound = 'sound/magic/staff_change.ogg'
- ammo_type = /obj/item/ammo_casing/magic/wipe
- icon_state = "staffofwipe"
- item_state = "staffofwipe"
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
deleted file mode 100644
index c6a25127878a..000000000000
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ /dev/null
@@ -1,266 +0,0 @@
-//For use in prob() to determine if an empty wand will shoot once then break.
-#define WAND_WREST_CHANCE (1/121)
-
-/obj/item/gun/magic/wand
- name = "wand"
- desc = "You shouldn't have this."
- ammo_type = /obj/item/ammo_casing/magic
- icon_state = "nothingwand"
- item_state = "wand"
- base_icon_state = "nothingwand"
- w_class = WEIGHT_CLASS_SMALL
- can_charge = FALSE
- max_charges = 100 //100, 50, 50, 34 (max charge distribution by 25%ths)
- var/variable_charges = TRUE
-
-/obj/item/gun/magic/wand/Initialize()
- if(prob(75) && variable_charges) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges
- if(prob(33))
- max_charges = CEILING(max_charges / 3, 1)
- else
- max_charges = CEILING(max_charges / 2, 1)
- return ..()
-
-/obj/item/gun/magic/wand/examine(mob/user)
- . = ..()
- . += "Has [charges] charge\s remaining."
-
-/obj/item/gun/magic/wand/update_icon_state()
- icon_state = "[base_icon_state][charges ? null : "-drained"]"
- return ..()
-
-/obj/item/gun/magic/wand/attack(atom/target, mob/living/user)
- if(target == user)
- return
- ..()
-
-/obj/item/gun/magic/wand/afterattack(atom/target, mob/living/user)
- var/wrested = FALSE
- if(!charges)
- wrested = shoot_with_empty_chamber(user)
- if(!wrested)
- return
- if(target == user)
- if(no_den_usage)
- var/area/A = get_area(user)
- if(istype(A, /area/wizard_station))
- to_chat(user, "You know better than to violate the security of The Den, best wait until you leave to use [src].")
- return
- else
- no_den_usage = 0
- zap_self(user)
- else
- . = ..()
- if(wrested)
- to_chat(user,"[src] overloads and disintegrates.")
- qdel(src)
- return
- update_appearance()
-
-/obj/item/gun/magic/wand/shoot_with_empty_chamber(mob/living/user)
- if(prob(100*WAND_WREST_CHANCE))
- to_chat(user,"You manage to activate [src] one last time.")
- charges++
- recharge_newshot()
- return TRUE
- return ..()
-
-/obj/item/gun/magic/wand/proc/zap_self(mob/living/user)
- user.visible_message("[user] zaps [user.p_them()]self with [src].")
- playsound(user, fire_sound, 50, TRUE)
- user.log_message("zapped [user.p_them()]self with a [src]", LOG_ATTACK)
-
-
-/////////////////////////////////////
-//WAND OF DEATH
-/////////////////////////////////////
-
-/obj/item/gun/magic/wand/death
- name = "wand of death"
- desc = "This deadly wand overwhelms the victim's body with pure energy, slaying them without fail."
- fire_sound = 'sound/magic/wandodeath.ogg'
- ammo_type = /obj/item/ammo_casing/magic/death
- icon_state = "deathwand"
- base_icon_state = "deathwand"
- max_charges = 3 //3, 2, 2, 1
-
-/obj/item/gun/magic/wand/death/zap_self(mob/living/user)
- ..()
- charges--
- if(user.anti_magic_check())
- user.visible_message("[src] has no effect on [user]!")
- return
- if(isliving(user))
- var/mob/living/L = user
- if(L.mob_biotypes & MOB_UNDEAD) //negative energy heals the undead
- user.revive(full_heal = TRUE, admin_revive = TRUE)
- to_chat(user, "You feel great!")
- return
- to_chat(user, "You irradiate yourself with pure negative energy! \
- [pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?")]\
- ")
- user.death(FALSE)
-
-/obj/item/gun/magic/wand/death/debug
- desc = "In some obscure circles, this is known as the 'cloning tester's friend'."
- max_charges = 500
- variable_charges = FALSE
- can_charge = TRUE
- recharge_rate = 1
-
-
-/////////////////////////////////////
-//WAND OF HEALING
-/////////////////////////////////////
-
-/obj/item/gun/magic/wand/resurrection
- name = "wand of healing"
- desc = "This wand uses healing magics to heal and revive. They are rarely utilized within the Wizard Federation for some reason."
- ammo_type = /obj/item/ammo_casing/magic/heal
- fire_sound = 'sound/magic/staff_healing.ogg'
- icon_state = "revivewand"
- base_icon_state = "revivewand"
- max_charges = 10 //10, 5, 5, 4
-
-/obj/item/gun/magic/wand/resurrection/zap_self(mob/living/user)
- ..()
- charges--
- if(user.anti_magic_check())
- user.visible_message("[src] has no effect on [user]!")
- return
- if(isliving(user))
- var/mob/living/L = user
- if(L.mob_biotypes & MOB_UNDEAD) //positive energy harms the undead
- to_chat(user, "You irradiate yourself with pure positive energy! \
- [pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?")]\
- ")
- user.death(0)
- return
- user.revive(full_heal = TRUE, admin_revive = TRUE)
- to_chat(user, "You feel great!")
-
-/obj/item/gun/magic/wand/resurrection/debug //for testing
- desc = "Is it possible for something to be even more powerful than regular magic? This wand is."
- max_charges = 500
- variable_charges = FALSE
- can_charge = TRUE
- recharge_rate = 1
-
-/////////////////////////////////////
-//WAND OF POLYMORPH
-/////////////////////////////////////
-
-/obj/item/gun/magic/wand/polymorph
- name = "wand of polymorph"
- desc = "This wand is attuned to chaos and will radically alter the victim's form."
- ammo_type = /obj/item/ammo_casing/magic/change
- icon_state = "polywand"
- base_icon_state = "polywand"
- fire_sound = 'sound/magic/staff_change.ogg'
- max_charges = 10 //10, 5, 5, 4
-
-/obj/item/gun/magic/wand/polymorph/zap_self(mob/living/user)
- ..() //because the user mob ceases to exists by the time wabbajack fully resolves
-
- wabbajack(user)
- charges--
-
-/////////////////////////////////////
-//WAND OF TELEPORTATION
-/////////////////////////////////////
-
-/obj/item/gun/magic/wand/teleport
- name = "wand of teleportation"
- desc = "This wand will wrench targets through space and time to move them somewhere else."
- ammo_type = /obj/item/ammo_casing/magic/teleport
- fire_sound = 'sound/magic/wand_teleport.ogg'
- icon_state = "telewand"
- base_icon_state = "telewand"
- max_charges = 10 //10, 5, 5, 4
- no_den_usage = TRUE
-
-/obj/item/gun/magic/wand/teleport/zap_self(mob/living/user)
- if(do_teleport(user, user, 10, channel = TELEPORT_CHANNEL_MAGIC))
- var/datum/effect_system/smoke_spread/smoke = new
- smoke.set_up(3, user.loc)
- smoke.start()
- charges--
- ..()
-
-/obj/item/gun/magic/wand/safety
- name = "wand of safety"
- desc = "This wand will use the lightest of bluespace currents to gently place the target somewhere safe."
- ammo_type = /obj/item/ammo_casing/magic/safety
- fire_sound = 'sound/magic/wand_teleport.ogg'
- icon_state = "telewand"
- base_icon_state = "telewand"
- max_charges = 10 //10, 5, 5, 4
- no_den_usage = FALSE
-
-/obj/item/gun/magic/wand/safety/zap_self(mob/living/user)
- var/turf/origin = get_turf(user)
- var/turf/destination = find_safe_turf()
-
- if(do_teleport(user, destination, channel=TELEPORT_CHANNEL_MAGIC))
- for(var/t in list(origin, destination))
- var/datum/effect_system/smoke_spread/smoke = new
- smoke.set_up(0, t)
- smoke.start()
- ..()
-
-/obj/item/gun/magic/wand/safety/debug
- desc = "This wand has 'find_safe_turf()' engraved into its blue wood. Perhaps it's a secret message?"
- max_charges = 500
- variable_charges = FALSE
- can_charge = TRUE
- recharge_rate = 1
-
-
-/////////////////////////////////////
-//WAND OF DOOR CREATION
-/////////////////////////////////////
-
-/obj/item/gun/magic/wand/door
- name = "wand of door creation"
- desc = "This particular wand can create doors in any wall for the unscrupulous wizard who shuns teleportation magics."
- ammo_type = /obj/item/ammo_casing/magic/door
- icon_state = "doorwand"
- base_icon_state = "doorwand"
- fire_sound = 'sound/magic/staff_door.ogg'
- max_charges = 20 //20, 10, 10, 7
- no_den_usage = 1
-
-/obj/item/gun/magic/wand/door/zap_self(mob/living/user)
- to_chat(user, "You feel vaguely more open with your feelings.")
- charges--
- ..()
-
-/////////////////////////////////////
-//WAND OF FIREBALL
-/////////////////////////////////////
-
-/obj/item/gun/magic/wand/fireball
- name = "wand of fireball"
- desc = "This wand shoots scorching balls of fire that explode into destructive flames."
- fire_sound = 'sound/magic/fireball.ogg'
- ammo_type = /obj/item/ammo_casing/magic/fireball
- icon_state = "firewand"
- base_icon_state = "firewand"
- max_charges = 8 //8, 4, 4, 3
-
-/obj/item/gun/magic/wand/fireball/zap_self(mob/living/user)
- ..()
- explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2)
- charges--
-
-/////////////////////////////////////
-//WAND OF NOTHING
-/////////////////////////////////////
-
-/obj/item/gun/magic/wand/nothing
- name = "wand of nothing"
- desc = "It's not just a stick, it's a MAGIC stick?"
- ammo_type = /obj/item/ammo_casing/magic/nothing
-
-
-#undef WAND_WREST_CHANCE
diff --git a/code/modules/projectiles/guns/faction/gezena/energy_gunsword.dm b/code/modules/projectiles/guns/manufacturer/etherbor/energy_gunsword.dm
similarity index 73%
rename from code/modules/projectiles/guns/faction/gezena/energy_gunsword.dm
rename to code/modules/projectiles/guns/manufacturer/etherbor/energy_gunsword.dm
index 8684fa867288..4053b5f4d8a6 100644
--- a/code/modules/projectiles/guns/faction/gezena/energy_gunsword.dm
+++ b/code/modules/projectiles/guns/manufacturer/etherbor/energy_gunsword.dm
@@ -1,16 +1,18 @@
-/obj/item/gun/energy/kalix //blue //todo: fix up belt_mirror.dmi, it's incomprehensible
+/obj/item/gun/energy/kalix
name = "Etherbor BG-12"
- desc = "Brought to you by Etherbor Industries, proudly based within the PGF, is the BG-12 energy beam gun! The BG-12 is Etherbor's current newest civilian energy weapon model."
+ desc = "Etherbor Industries's current civilian energy weapon model. The BG-12 energy beam gun is identical to the military model, minus the removal of the full auto mode. Otherwise, it's no different from older hunting beams from Kalixcis's history."
icon_state = "kalixgun"
item_state = "kalixgun"
- icon = 'icons/obj/guns/faction/gezena/energy.dmi'
- lefthand_file = 'icons/obj/guns/faction/gezena/lefthand.dmi'
- righthand_file = 'icons/obj/guns/faction/gezena/righthand.dmi'
- mob_overlay_icon = 'icons/mob/clothing/faction/gezena/belt.dmi'
- w_class = WEIGHT_CLASS_NORMAL
+ icon = 'icons/obj/guns/manufacturer/etherbor/48x32.dmi'
+ lefthand_file = 'icons/obj/guns/manufacturer/etherbor/lefthand.dmi'
+ righthand_file = 'icons/obj/guns/manufacturer/etherbor/righthand.dmi'
+ mob_overlay_icon = 'icons/obj/guns/manufacturer/etherbor/onmob.dmi'
+ w_class = WEIGHT_CLASS_BULKY
modifystate = TRUE
+ fire_delay = 0.16 SECONDS
+
wield_delay = 0.7 SECONDS
wield_slowdown = 0.35
@@ -40,19 +42,19 @@
damage = 25
armour_penetration = -10
+/obj/item/gun/energy/kalix/empty_cell
+ dead_cell = TRUE
+
/obj/item/gun/energy/kalix/pgf
name = "Etherbor BG-16"
- desc = "An advanced variant of the BG-12, the BG-16 is the military-grade beam gun designed and manufactured by Etherbor Industries as the standard-issue close-range weapon of the PGF."
+ desc = "The BG-16 is the military-grade beam gun designed and manufactured by Etherbor Industries as the standard-issue close-range weapon of the PGF."
icon_state = "pgfgun"
item_state = "pgfgun"
+ w_class = WEIGHT_CLASS_NORMAL
cell_type = /obj/item/stock_parts/cell/gun/pgf
ammo_type = list(/obj/item/ammo_casing/energy/pgf , /obj/item/ammo_casing/energy/disabler/hitscan)
-/obj/item/gun/energy/kalix/pgf/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.16 SECONDS)
-
/obj/projectile/beam/hitscan/kalix/pgf
name = "concentrated energy"
tracer_type = /obj/effect/projectile/tracer/pgf
@@ -67,13 +69,12 @@
fire_sound = 'sound/weapons/gun/energy/kalixsmg.ogg'
delay = 1
-/obj/item/gun/energy/kalix/pistol //blue //todo: fix up belt_mirror.dmi, it's incomprehensible
+/obj/item/gun/energy/kalix/pistol //blue
name = "Etherbor SG-8"
- desc = "Etherbor's current and sidearm offering. While intended for marines, it's also available for civillians"
+ desc = "Etherbor's current and sidearm offering. While marketed for the military, it's also available for civillians as an upgrade over older and obsolete beam pistols."
icon_state = "kalixpistol"
item_state = "kalixpistol"
- w_class = WEIGHT_CLASS_SMALL
-
+ w_class = WEIGHT_CLASS_NORMAL
modifystate = FALSE
wield_delay = 0.2 SECONDS
@@ -93,18 +94,24 @@
e_cost = 1250 //10 shots per cell
delay = 0
+/obj/item/gun/energy/kalix/pistol/empty_cell
+ dead_cell = TRUE
+
/obj/item/gun/energy/kalix/pgf/heavy
name = "Etherbor HBG-7"
- desc = "The HBG-7 is the standard-issue rifle weapon of the PGF. If the stopping power and fire rate isn't enough, it comes with a DMR mode that has greater armor piercing for dealing with armored targets."
+ desc = "The HBG-7 is the standard-issue rifle weapon of the PGF. It comes with a special DMR mode that has greater armor piercing for dealing with armored targets."
icon_state = "pgfheavy"
item_state = "pgfheavy"
- icon = 'icons/obj/guns/faction/gezena/48x32.dmi'
- mob_overlay_icon = 'icons/mob/clothing/faction/gezena/back.dmi'
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
modifystate = FALSE
+ gun_firemodes = list(FIREMODE_SEMIAUTO, FIREMODE_FULLAUTO)
+ default_firemode = FIREMODE_SEMIAUTO
+
+ fire_delay = 0.2 SECONDS
+
wield_delay = 0.7 SECONDS
wield_slowdown = 0.6
@@ -113,10 +120,6 @@
ammo_type = list(/obj/item/ammo_casing/energy/pgf/assault, /obj/item/ammo_casing/energy/pgf/sniper)
-/obj/item/gun/energy/kalix/pgf/heavy/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/automatic_fire, 0.2 SECONDS)
-
/obj/item/ammo_casing/energy/pgf/assault
select_name = "AR"
projectile_type = /obj/projectile/beam/hitscan/kalix/pgf/assault
@@ -152,7 +155,7 @@
/obj/item/gun/energy/kalix/pgf/heavy/sniper
name = "Etherbor HBG-7L"
- desc = "HBG-7 with a longer barrel and scope. Intended to get the best use out of the DMR mode, it suffers if used normally from longer wield times and slowdown"
+ desc = "HBG-7 with a longer barrel and scope. Intended to get the best use out of the DMR mode, it suffers from longer wield times and slowdown, but it's longer barrel makes it ideal for accuracy."
icon_state = "pgfheavy_sniper"
item_state = "pgfheavy_sniper"
diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm
index fad4f485aa88..b131b03ec148 100644
--- a/code/modules/projectiles/guns/misc/beam_rifle.dm
+++ b/code/modules/projectiles/guns/misc/beam_rifle.dm
@@ -29,10 +29,9 @@
w_class = WEIGHT_CLASS_BULKY
ammo_type = list(/obj/item/ammo_casing/energy/beam_rifle/hitscan)
internal_cell = FALSE //prevents you from giving it an OP cell - WS Edit //shut up dumb nerd
- big_gun = TRUE
+ mag_size = MAG_SIZE_LARGE
cell_type = "/obj/item/stock_parts/cell/gun/large"
canMouseDown = TRUE
- pin = null
var/aiming = FALSE
var/aiming_time = 12
var/aiming_time_fire_threshold = 5
@@ -82,7 +81,6 @@
cell_type = /obj/item/stock_parts/cell/infinite
aiming_time = 0
recoil = 0
- pin = /obj/item/firing_pin
/obj/item/gun/energy/beam_rifle/equipped(mob/user)
set_user(user)
diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm
index 888e680479ea..161aa216b866 100644
--- a/code/modules/projectiles/guns/misc/blastcannon.dm
+++ b/code/modules/projectiles/guns/misc/blastcannon.dm
@@ -8,7 +8,6 @@
force = 10
fire_sound = 'sound/weapons/blastcannon.ogg'
item_flags = NONE
- clumsy_check = FALSE
randomspread = FALSE
var/hugbox = TRUE
@@ -26,11 +25,6 @@
debug_power = 80
bombcheck = FALSE
-/obj/item/gun/blastcannon/Initialize()
- . = ..()
- if(!pin)
- pin = new
-
/obj/item/gun/blastcannon/Destroy()
QDEL_NULL(bomb)
return ..()
diff --git a/code/modules/projectiles/guns/misc/chem_gun.dm b/code/modules/projectiles/guns/misc/chem_gun.dm
index 6d9c5eda699d..7c99b7156000 100644
--- a/code/modules/projectiles/guns/misc/chem_gun.dm
+++ b/code/modules/projectiles/guns/misc/chem_gun.dm
@@ -10,7 +10,6 @@
throw_range = 7
force = 4
custom_materials = list(/datum/material/iron=2000)
- clumsy_check = FALSE
fire_sound = 'sound/items/syringeproj.ogg'
var/time_per_syringe = 250
var/syringes_left = 4
@@ -30,7 +29,7 @@
/obj/item/gun/chem/can_shoot()
return syringes_left
-/obj/item/gun/chem/process_chamber()
+/obj/item/gun/chem/process_chamber(atom/shooter)
if(chambered && !chambered.BB && syringes_left)
chambered.newshot()
diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm
index 34af73b855c6..809c15682cd4 100644
--- a/code/modules/projectiles/guns/misc/syringe_gun.dm
+++ b/code/modules/projectiles/guns/misc/syringe_gun.dm
@@ -8,7 +8,6 @@
throw_range = 7
force = 4
custom_materials = list(/datum/material/iron=2000)
- clumsy_check = 0
fire_sound = 'sound/items/syringeproj.ogg'
var/list/syringes = list()
var/max_syringes = 1
@@ -30,7 +29,7 @@
/obj/item/gun/syringe/can_shoot()
return syringes.len
-/obj/item/gun/syringe/process_chamber()
+/obj/item/gun/syringe/process_chamber(atom/shooter)
if(chambered && !chambered.BB) //we just fired
recharge_newshot()
@@ -81,7 +80,6 @@
w_class = WEIGHT_CLASS_SMALL
force = 2 //Also very weak because it's smaller
suppressed = TRUE //Softer fire sound
- can_unsuppress = FALSE //Permanently silenced
/obj/item/gun/syringe/dna
name = "modified syringe gun"
diff --git a/code/modules/projectiles/guns/powered.dm b/code/modules/projectiles/guns/powered.dm
index 698826436b18..a9ab2f6365f4 100644
--- a/code/modules/projectiles/guns/powered.dm
+++ b/code/modules/projectiles/guns/powered.dm
@@ -1,21 +1,6 @@
/obj/item/gun/ballistic/automatic/powered
mag_type = /obj/item/ammo_box/magazine/gauss
- can_suppress = FALSE
-
- var/obj/item/stock_parts/cell/cell
- var/cell_type = /obj/item/stock_parts/cell/gun
- var/charge_sections = 3
- var/empty_battery_sound = FALSE // play empty alarm if no battery
-
- var/shaded_charge = FALSE //if this gun uses a stateful charge bar for more detail
- var/automatic_charge_overlays = TRUE //Do we handle overlays with base update_appearance()?
-
- var/internal_cell = FALSE ///if the gun's cell cannot be replaced
- var/small_gun = FALSE ///if the gun is small and can only fit the small gun cell
- var/big_gun = FALSE ///if the gun is big and can fit the comically large gun cell
- var/unscrewing_time = 2 SECONDS ///Time it takes to unscrew the cell
- var/sound_volume = 40 //Volume of loading/unloading cell sounds
-
+ charge_sections = 3
/obj/item/gun/ballistic/automatic/powered/Initialize()
. = ..()
@@ -52,10 +37,6 @@
/obj/item/gun/ballistic/automatic/powered/get_cell()
return cell
-/obj/item/gun/ballistic/automatic/powered/nopin
- pin = null
- spawnwithmagazine = FALSE
-
//the things below were taken from energy gun code. blame whoever coded this, not me
/obj/item/gun/ballistic/automatic/powered/attackby(obj/item/A, mob/user, params)
if (!internal_cell && istype(A, /obj/item/stock_parts/cell/gun))
@@ -65,24 +46,24 @@
return ..()
/obj/item/gun/ballistic/automatic/powered/proc/insert_cell(mob/user, obj/item/stock_parts/cell/gun/C)
- if(small_gun && !istype(C, /obj/item/stock_parts/cell/gun/mini))
- to_chat(user, "[C] doesn't seem to fit into [src]...")
+ if(mag_size == MAG_SIZE_SMALL && !istype(C, /obj/item/stock_parts/cell/gun/mini))
+ to_chat(user, "\The [C] doesn't seem to fit into \the [src]...")
return FALSE
- if(!big_gun && istype(C, /obj/item/stock_parts/cell/gun/large))
- to_chat(user, "[C] doesn't seem to fit into [src]...")
+ if(mag_size == MAG_SIZE_LARGE && !istype(C, /obj/item/stock_parts/cell/gun/large))
+ to_chat(user, "\The [C] doesn't seem to fit into \the [src]...")
return FALSE
if(user.transferItemToLoc(C, src))
cell = C
- to_chat(user, "You load [C] into [src].")
- playsound(src, load_sound, sound_volume, load_sound_vary)
+ to_chat(user, "You load the [C] into \the [src].")
+ playsound(src, load_sound, load_sound_volume, load_sound_vary)
update_appearance()
return TRUE
else
- to_chat(user, "You cannot seem to get [src] out of your hands!")
+ to_chat(user, "You cannot seem to get \the [src] out of your hands!")
return FALSE
/obj/item/gun/ballistic/automatic/powered/proc/eject_cell(mob/user, obj/item/stock_parts/cell/gun/tac_load = null)
- playsound(src, load_sound, sound_volume, load_sound_vary)
+ playsound(src, load_sound, load_sound_volume, load_sound_vary)
cell.forceMove(drop_location())
var/obj/item/stock_parts/cell/gun/old_cell = cell
cell = null
@@ -92,7 +73,7 @@
update_appearance()
/obj/item/gun/ballistic/automatic/powered/screwdriver_act(mob/living/user, obj/item/I)
- if(cell && !internal_cell && !bayonet && (!gun_light || !can_flashlight))
+ if(cell && !internal_cell)
to_chat(user, "You begin unscrewing and pulling out the cell...")
if(I.use_tool(src, user, unscrewing_time, volume=100))
to_chat(user, "You remove the power cell.")
diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm
deleted file mode 100644
index 20bcdc4e63d9..000000000000
--- a/code/modules/projectiles/pins.dm
+++ /dev/null
@@ -1,343 +0,0 @@
-/obj/item/firing_pin
- name = "electronic firing pin"
- desc = "A small authentication device, to be inserted into a firearm receiver to allow operation. NT safety regulations require all new designs to incorporate one."
- icon = 'icons/obj/device.dmi'
- icon_state = "firing_pin"
- item_state = "pen"
- flags_1 = CONDUCT_1
- w_class = WEIGHT_CLASS_TINY
- attack_verb = list("poked")
- var/fail_message = "INVALID USER."
- var/selfdestruct = 0 // Explode when user check is failed.
- var/force_replace = 0 // Can forcefully replace other pins.
- var/pin_removeable = 0 // Can be replaced by any pin.
- var/obj/item/gun/gun
-
-/obj/item/firing_pin/New(newloc)
- ..()
- if(istype(newloc, /obj/item/gun))
- gun = newloc
-
-/obj/item/firing_pin/afterattack(atom/target, mob/user, proximity_flag)
- . = ..()
- if(proximity_flag)
- if(istype(target, /obj/item/gun))
- var/obj/item/gun/G = target
- var/obj/item/firing_pin/old_pin = G.pin
- if(old_pin && (force_replace || old_pin.pin_removeable))
- to_chat(user, "You remove [old_pin] from [G].")
- if(Adjacent(user))
- user.put_in_hands(old_pin)
- else
- old_pin.forceMove(G.drop_location())
- old_pin.gun_remove(user)
-
- if(!G.pin)
- if(!user.temporarilyRemoveItemFromInventory(src))
- return
- gun_insert(user, G)
- to_chat(user, "You insert [src] into [G].")
- else
- to_chat(user, "This firearm already has a firing pin installed.")
-
-/obj/item/firing_pin/emag_act(mob/user)
- if(obj_flags & EMAGGED)
- return
- obj_flags |= EMAGGED
- to_chat(user, "You override the authentication mechanism.")
-
-/obj/item/firing_pin/proc/gun_insert(mob/living/user, obj/item/gun/G)
- gun = G
- forceMove(gun)
- gun.pin = src
- return
-
-/obj/item/firing_pin/proc/gun_remove(mob/living/user)
- gun.pin = null
- gun = null
- return
-
-/obj/item/firing_pin/proc/pin_auth(mob/living/user)
- return TRUE
-
-/obj/item/firing_pin/proc/auth_fail(mob/living/user)
- if(user)
- user.show_message(fail_message, MSG_VISUAL)
- if(selfdestruct)
- if(user)
- user.show_message("SELF-DESTRUCTING... ", MSG_VISUAL)
- to_chat(user, "[gun] explodes!")
- explosion(get_turf(gun), -1, 0, 2, 3)
- if(gun)
- qdel(gun)
-
-
-/obj/item/firing_pin/magic
- name = "magic crystal shard"
- desc = "A small enchanted shard which allows magical weapons to fire."
-
-
-// Test pin, works only near firing range.
-/obj/item/firing_pin/test_range
- name = "test-range firing pin"
- desc = "This safety firing pin allows weapons to be fired within proximity to a firing range."
- fail_message = "TEST RANGE CHECK FAILED."
- pin_removeable = TRUE
-
-/obj/item/firing_pin/test_range/pin_auth(mob/living/user)
- if(!istype(user))
- return FALSE
- if (istype(get_area(user), /area/ship/security/range))
- return TRUE
- return FALSE
-
-
-// Implant pin, checks for implant
-/obj/item/firing_pin/implant
- name = "implant-keyed firing pin"
- desc = "This is a security firing pin which only authorizes users who are implanted with a certain device."
- fail_message = "IMPLANT CHECK FAILED."
- var/obj/item/implant/req_implant = null
-
-/obj/item/firing_pin/implant/pin_auth(mob/living/user)
- if(user)
- for(var/obj/item/implant/I in user.implants)
- if(req_implant && I.type == req_implant)
- return TRUE
- return FALSE
-
-/obj/item/firing_pin/implant/mindshield
- name = "mindshield firing pin"
- desc = "This Security firing pin authorizes the weapon for only mindshield-implanted users."
- icon_state = "firing_pin_loyalty"
- req_implant = /obj/item/implant/mindshield
-
-/obj/item/firing_pin/implant/pindicate
- name = "syndicate firing pin"
- icon_state = "firing_pin_pindi"
- req_implant = /obj/item/implant/weapons_auth
-
-
-
-// Honk pin, clown's joke item.
-// Can replace other pins. Replace a pin in cap's laser for extra fun!
-/obj/item/firing_pin/clown
- name = "hilarious firing pin"
- desc = "Advanced clowntech that can convert any firearm into a far more useful object."
- color = "#FFFF00"
- fail_message = "HONK!"
- force_replace = TRUE
-
-/obj/item/firing_pin/clown/pin_auth(mob/living/user)
- playsound(src, 'sound/items/bikehorn.ogg', 50, TRUE)
- return FALSE
-
-// Ultra-honk pin, clown's deadly joke item.
-// A gun with ultra-honk pin is useful for clown and useless for everyone else.
-/obj/item/firing_pin/clown/ultra
- name = "ultra hilarious firing pin"
-
-/obj/item/firing_pin/clown/ultra/pin_auth(mob/living/user)
- playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE)
- if(QDELETED(user)) //how the hell...?
- stack_trace("/obj/item/firing_pin/clown/ultra/pin_auth called with a [isnull(user) ? "null" : "invalid"] user.")
- return TRUE
- if(HAS_TRAIT(user, TRAIT_CLUMSY)) //clumsy
- return TRUE
- if(user.mind)
- if(user.mind.assigned_role == "Clown") //traitor clowns can use this, even though they're technically not clumsy
- return TRUE
- if(user.mind.has_antag_datum(/datum/antagonist/nukeop/clownop)) //clown ops aren't clumsy by default and technically don't have an assigned role of "Clown", but come on, they're basically clowns
- return TRUE
- if(user.mind.has_antag_datum(/datum/antagonist/nukeop/leader/clownop)) //Wanna hear a funny joke?
- return TRUE //The clown op leader antag datum isn't a subtype of the normal clown op antag datum.
- return FALSE
-
-/obj/item/firing_pin/clown/ultra/gun_insert(mob/living/user, obj/item/gun/G)
- ..()
- G.clumsy_check = FALSE
-
-/obj/item/firing_pin/clown/ultra/gun_remove(mob/living/user)
- gun.clumsy_check = initial(gun.clumsy_check)
- ..()
-
-// Now two times deadlier!
-/obj/item/firing_pin/clown/ultra/selfdestruct
- name = "super ultra hilarious firing pin"
- desc = "Advanced clowntech that can convert any firearm into a far more useful object. It has a small nitrobananium charge on it."
- selfdestruct = TRUE
-
-
-// DNA-keyed pin.
-// When you want to keep your toys for yourself.
-/obj/item/firing_pin/dna
- name = "DNA-keyed firing pin"
- desc = "This is a DNA-locked firing pin which only authorizes one user. Attempt to fire once to DNA-link."
- icon_state = "firing_pin_dna"
- fail_message = "DNA CHECK FAILED."
- var/unique_enzymes = null
-
-/obj/item/firing_pin/dna/afterattack(atom/target, mob/user, proximity_flag)
- . = ..()
- if(proximity_flag && iscarbon(target))
- var/mob/living/carbon/M = target
- if(M.dna && M.dna.unique_enzymes)
- unique_enzymes = M.dna.unique_enzymes
- to_chat(user, "DNA-LOCK SET.")
-
-/obj/item/firing_pin/dna/pin_auth(mob/living/carbon/user)
- if(user && user.dna && user.dna.unique_enzymes)
- if(user.dna.unique_enzymes == unique_enzymes)
- return TRUE
- return FALSE
-
-/obj/item/firing_pin/dna/auth_fail(mob/living/carbon/user)
- if(!unique_enzymes)
- if(user && user.dna && user.dna.unique_enzymes)
- unique_enzymes = user.dna.unique_enzymes
- to_chat(user, "DNA-LOCK SET.")
- else
- ..()
-
-/obj/item/firing_pin/dna/dredd
- desc = "This is a DNA-locked firing pin which only authorizes one user. Attempt to fire once to DNA-link. It has a small explosive charge on it."
- selfdestruct = TRUE
-
-// Paywall pin, brought to you by ARMA 3 DLC.
-// Checks if the user has a valid bank account on an ID and if so attempts to extract a one-time payment to authorize use of the gun. Otherwise fails to shoot.
-/obj/item/firing_pin/paywall
- name = "paywall firing pin"
- desc = "A firing pin with a built-in configurable paywall."
- color = "#FFD700"
- fail_message = ""
- var/list/gun_owners = list() //list of people who've accepted the license prompt. If this is the multi-payment pin, then this means they accepted the waiver that each shot will cost them money
- var/payment_amount //how much gets paid out to license yourself to the gun
- var/obj/item/card/id/pin_owner
- var/multi_payment = FALSE //if true, user has to pay everytime they fire the gun
- var/owned = FALSE
- var/active_prompt = FALSE //purchase prompt to prevent spamming it
-
-/obj/item/firing_pin/paywall/attack_self(mob/user)
- multi_payment = !multi_payment
- to_chat(user, "You set the pin to [(multi_payment) ? "process payment for every shot" : "one-time license payment"].")
-
-/obj/item/firing_pin/paywall/examine(mob/user)
- . = ..()
- if(pin_owner)
- . += "This firing pin is currently authorized to pay into the account of [pin_owner.registered_name]."
-
-/obj/item/firing_pin/paywall/gun_insert(mob/living/user, obj/item/gun/G)
- if(!pin_owner)
- to_chat(user, "ERROR: Please swipe valid identification card before installing firing pin!")
- return
- gun = G
- forceMove(gun)
- gun.pin = src
- if(multi_payment)
- gun.desc += " This [gun.name] has a per-shot cost of [payment_amount] credit[(payment_amount > 1) ? "s" : ""]."
- return
- gun.desc += " This [gun.name] has a license permit cost of [payment_amount] credit[(payment_amount > 1) ? "s" : ""]."
- return
-
-
-/obj/item/firing_pin/paywall/gun_remove(mob/living/user)
- gun.desc = initial(desc)
- ..()
-
-/obj/item/firing_pin/paywall/attackby(obj/item/M, mob/user, params)
- if(istype(M, /obj/item/card/id))
- var/obj/item/card/id/id = M
- if(!id.registered_account)
- to_chat(user, "ERROR: Identification card lacks registered bank account!")
- return
- if(id != pin_owner && owned)
- to_chat(user, "ERROR: This firing pin has already been authorized!")
- return
- if(id == pin_owner)
- to_chat(user, "You unlink the card from the firing pin.")
- gun_owners -= user
- pin_owner = null
- owned = FALSE
- return
- var/transaction_amount = input(user, "Insert valid deposit amount for gun purchase", "Money Deposit") as null|num
- if(transaction_amount < 1)
- to_chat(user, "ERROR: Invalid amount designated.")
- return
- if(!transaction_amount)
- return
- pin_owner = id
- owned = TRUE
- payment_amount = transaction_amount
- gun_owners += user
- to_chat(user, "You link the card to the firing pin.")
-
-/obj/item/firing_pin/paywall/pin_auth(mob/living/user)
- if(!istype(user))//nice try commie
- return FALSE
- if(ishuman(user))
- var/datum/bank_account/credit_card_details
- var/mob/living/carbon/human/H = user
- if(H.get_bank_account())
- credit_card_details = H.get_bank_account()
- if(H in gun_owners)
- if(multi_payment && credit_card_details)
- if(credit_card_details.has_money(payment_amount))
- pin_owner.registered_account.transfer_money(credit_card_details, payment_amount)
- return TRUE
- to_chat(user, "ERROR: User balance insufficent for successful transaction!")
- return FALSE
- return TRUE
- if(credit_card_details && !active_prompt)
- var/license_request = alert(usr, "Do you wish to pay [payment_amount] credit[(payment_amount > 1) ? "s" : ""] for [(multi_payment) ? "each shot of [gun.name]" : "usage license of [gun.name]"]?", "Weapon Purchase", "Yes", "No")
- active_prompt = TRUE
- if(!user.canUseTopic(src, BE_CLOSE))
- active_prompt = FALSE
- return FALSE
- switch(license_request)
- if("Yes")
- if(credit_card_details.has_money(payment_amount))
- pin_owner.registered_account.transfer_money(credit_card_details, payment_amount)
- gun_owners += H
- to_chat(user, "Gun license purchased, have a secure day!")
- active_prompt = FALSE
- return FALSE //we return false here so you don't click initially to fire, get the prompt, accept the prompt, and THEN the gun
- to_chat(user, "ERROR: User balance insufficent for successful transaction!")
- return FALSE
- if("No")
- to_chat(user, "ERROR: User has declined to purchase gun license!")
- return FALSE
- to_chat(user, "ERROR: User has no valid bank account to substract neccesary funds from!")
- return FALSE
-
-// Laser tag pins
-/obj/item/firing_pin/tag
- name = "laser tag firing pin"
- desc = "A recreational firing pin, used in laser tag units to ensure users have their vests on."
- fail_message = "SUIT CHECK FAILED."
- var/obj/item/clothing/suit/suit_requirement = null
- var/tagcolor = ""
-
-/obj/item/firing_pin/tag/pin_auth(mob/living/user)
- if(ishuman(user))
- var/mob/living/carbon/human/M = user
- if(istype(M.wear_suit, suit_requirement))
- return TRUE
- to_chat(user, "You need to be wearing [tagcolor] laser tag armor!")
- return FALSE
-
-/obj/item/firing_pin/tag/red
- name = "red laser tag firing pin"
- icon_state = "firing_pin_red"
- suit_requirement = /obj/item/clothing/suit/redtag
- tagcolor = "red"
-
-/obj/item/firing_pin/tag/blue
- name = "blue laser tag firing pin"
- icon_state = "firing_pin_blue"
- suit_requirement = /obj/item/clothing/suit/bluetag
- tagcolor = "blue"
-
-/obj/item/firing_pin/Destroy()
- if(gun)
- gun.pin = null
- return ..()
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 7cc9b1c6ebb4..66adeb53ac59 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -1,7 +1,3 @@
-
-#define MOVES_HITSCAN -1 //Not actually hitscan but close as we get without actual hitscan.
-#define MUZZLE_EFFECT_PIXEL_INCREMENT 17 //How many pixels to move the muzzle flash up so your character doesn't look like they're shitting out lasers.
-
/obj/projectile
name = "projectile"
icon = 'icons/obj/projectiles.dmi'
@@ -133,7 +129,7 @@
var/homing_offset_y = 0
var/damage = 10
- var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
+ var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE, STAMINA are the only things that should be in here
var/nodamage = FALSE //Determines if the projectile will skip any damage inflictions
var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb
///How much armor this projectile pierces.
@@ -209,7 +205,11 @@
SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle)
// i know that this is probably more with wands and gun mods in mind, but it's a bit silly that the projectile on_hit signal doesn't ping the projectile itself.
// maybe we care what the projectile thinks! See about combining these via args some time when it's not 5AM
- SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle)
+ var/obj/item/bodypart/hit_limb
+ if(isliving(target))
+ var/mob/living/L = target
+ hit_limb = L.check_limb_hit(def_zone)
+ SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb)
var/turf/target_loca = get_turf(target)
var/hitx
@@ -259,7 +259,7 @@
new impact_effect_type(target_loca, hitx, hity)
var/organ_hit_text = ""
- var/limb_hit = L.check_limb_hit(def_zone)//to get the correct message info.
+ var/limb_hit = hit_limb
if(limb_hit)
organ_hit_text = " in \the [parse_zone(limb_hit)]"
if(suppressed==SUPPRESSED_VERY)
@@ -302,7 +302,7 @@
if(firer && HAS_TRAIT(firer, TRAIT_NICE_SHOT))
best_angle += NICE_SHOT_RICOCHET_BONUS
for(var/mob/living/L in range(ricochet_auto_aim_range, src.loc))
- if(L.stat == DEAD || !isInSight(src, L))
+ if(L.stat == DEAD || !isInSight(src, L) || L == firer)
continue
var/our_angle = abs(closer_angle_difference(Angle, Get_Angle(src.loc, L.loc)))
if(our_angle < best_angle)
@@ -490,7 +490,7 @@
if(direct_target)
return TRUE
// If target not able to use items, move and stand - or if they're just dead, pass over.
- if(L.stat == DEAD || (!hit_stunned_targets && HAS_TRAIT(L, TRAIT_IMMOBILIZED) && HAS_TRAIT(L, TRAIT_FLOORED) && HAS_TRAIT(L, TRAIT_HANDS_BLOCKED)))
+ if(L.stat || (!hit_stunned_targets && HAS_TRAIT(L, TRAIT_IMMOBILIZED) && HAS_TRAIT(L, TRAIT_FLOORED) && HAS_TRAIT(L, TRAIT_HANDS_BLOCKED)))
return FALSE
return TRUE
diff --git a/code/modules/projectiles/projectile/bullets/gauss.dm b/code/modules/projectiles/projectile/bullets/gauss.dm
index 0955745ed798..6011adb61c88 100644
--- a/code/modules/projectiles/projectile/bullets/gauss.dm
+++ b/code/modules/projectiles/projectile/bullets/gauss.dm
@@ -5,7 +5,8 @@
icon_state = "gauss-pellet"
damage = 25
range = 35
- light_color = COLOR_SOFT_RED
+ light_system = 2
+ light_color = MOVABLE_LIGHT
light_range = 3
// Ferromagnetic Lance (GAR AR)
diff --git a/code/modules/projectiles/projectile/bullets/revolver.dm b/code/modules/projectiles/projectile/bullets/revolver.dm
index 7ec48a74b970..0c62fe5b3d4f 100644
--- a/code/modules/projectiles/projectile/bullets/revolver.dm
+++ b/code/modules/projectiles/projectile/bullets/revolver.dm
@@ -152,3 +152,20 @@
armour_penetration = -45
ricochet_incidence_leeway = 20
ricochet_chance = 65
+
+// 44 Short (Roumain & Shadow)
+
+/obj/projectile/bullet/a44roum
+ name = ".44 roumain bullet"
+ damage = 25
+
+/obj/projectile/bullet/a44roum/rubber
+ name = ".44 roumain bullet"
+ damage = 7
+ stamina = 38
+ armour_penetration = -20
+
+/obj/projectile/bullet/a44roum/hp
+ name = ".44 roumain bullet"
+ damage = 45
+ armour_penetration = -20
diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm
index ddd3319122c7..f7b963cff94b 100644
--- a/code/modules/projectiles/projectile/bullets/rifle.dm
+++ b/code/modules/projectiles/projectile/bullets/rifle.dm
@@ -77,5 +77,5 @@
/obj/projectile/bullet/c299
name = ".229 Eoehoma caseless bullet"
- damage = 25
- armour_penetration = 20
+ damage = 20
+ armour_penetration = 10
diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm
index e102c4c3b48f..ba9c8c88d7f8 100644
--- a/code/modules/projectiles/projectile/bullets/shotgun.dm
+++ b/code/modules/projectiles/projectile/bullets/shotgun.dm
@@ -18,7 +18,7 @@
/obj/projectile/bullet/incendiary/shotgun/dragonsbreath
name = "dragonsbreath pellet"
- damage = 5
+ damage = 8
armour_penetration = -35
/obj/projectile/bullet/slug/stun
diff --git a/code/modules/projectiles/projectile/energy/misc.dm b/code/modules/projectiles/projectile/energy/misc.dm
index 81fed69d516a..11f948ddb415 100644
--- a/code/modules/projectiles/projectile/energy/misc.dm
+++ b/code/modules/projectiles/projectile/energy/misc.dm
@@ -23,3 +23,22 @@
icon_state = "pulse1"
damage = 0
damage_type = BURN
+
+/obj/projectile/energy/plasmabolt
+ name = "ionized plasma"
+ damage = 25
+ armour_penetration = -10
+ range = 8
+ damage_type = BURN
+ icon_state = "blastwave"
+ color = "#00ff00"
+ hitsound = 'sound/weapons/sear.ogg'
+
+/obj/projectile/energy/plasmabolt/on_hit(atom/target, blocked = FALSE)
+ . = ..()
+ if(iscarbon(target))
+ var/mob/living/carbon/M = target
+ M.adjust_bodytemperature(350)
+ if(prob(35))
+ M.adjust_fire_stacks(15)
+ M.IgniteMob()
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
deleted file mode 100644
index 458c19d053da..000000000000
--- a/code/modules/projectiles/projectile/magic.dm
+++ /dev/null
@@ -1,736 +0,0 @@
-/obj/projectile/magic
- name = "bolt"
- icon_state = "energy"
- damage = 0
- damage_type = OXY
- nodamage = TRUE
- armour_penetration = 100
- flag = "magic"
-
-/obj/projectile/magic/death
- name = "bolt of death"
- icon_state = "pulse1_bl"
-
-/obj/projectile/magic/death/on_hit(target)
- . = ..()
- if(ismob(target))
- var/mob/M = target
- if(M.anti_magic_check())
- M.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- if(isliving(M))
- var/mob/living/L = M
- if(L.mob_biotypes & MOB_UNDEAD) //negative energy heals the undead
- if(L.hellbound && L.stat == DEAD)
- return BULLET_ACT_BLOCK
- if(L.revive(full_heal = TRUE, admin_revive = TRUE))
- L.grab_ghost(force = TRUE)
- to_chat(L, "You rise with a start, you're undead!!!")
- else if(L.stat != DEAD)
- to_chat(L, "You feel great!")
- else
- L.death(0)
- else
- M.death(0)
-
-/obj/projectile/magic/resurrection
- name = "bolt of resurrection"
- icon_state = "ion"
- damage = 0
- damage_type = OXY
- nodamage = TRUE
-
-/obj/projectile/magic/resurrection/on_hit(mob/living/carbon/target)
- . = ..()
- if(isliving(target))
- if(target.anti_magic_check())
- target.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- if(target.mob_biotypes & MOB_UNDEAD) //positive energy harms the undead
- target.death(0)
- else
- if(target.hellbound && target.stat == DEAD)
- return BULLET_ACT_BLOCK
- if(target.revive(full_heal = TRUE, admin_revive = TRUE))
- target.grab_ghost(force = TRUE) // even suicides
- to_chat(target, "You rise with a start, you're alive!!!")
- else if(target.stat != DEAD)
- to_chat(target, "You feel great!")
-
-/obj/projectile/magic/teleport
- name = "bolt of teleportation"
- icon_state = "bluespace"
- damage = 0
- damage_type = OXY
- nodamage = TRUE
- var/inner_tele_radius = 0
- var/outer_tele_radius = 6
-
-/obj/projectile/magic/teleport/on_hit(mob/target)
- . = ..()
- if(ismob(target))
- var/mob/M = target
- if(M.anti_magic_check())
- M.visible_message("[src] fizzles on contact with [target]!")
- return BULLET_ACT_BLOCK
- var/teleammount = 0
- var/teleloc = target
- if(!isturf(target))
- teleloc = target.loc
- for(var/atom/movable/stuff in teleloc)
- if(!stuff.anchored && stuff.loc && !isobserver(stuff))
- if(do_teleport(stuff, stuff, 10, channel = TELEPORT_CHANNEL_MAGIC))
- teleammount++
- var/datum/effect_system/smoke_spread/smoke = new
- smoke.set_up(max(round(4 - teleammount),0), stuff.loc) //Smoke drops off if a lot of stuff is moved for the sake of sanity
- smoke.start()
-
-/obj/projectile/magic/safety
- name = "bolt of safety"
- icon_state = "bluespace"
- damage = 0
- damage_type = OXY
- nodamage = TRUE
-
-/obj/projectile/magic/safety/on_hit(atom/target)
- . = ..()
- if(ismob(target))
- var/mob/M = target
- if(M.anti_magic_check())
- M.visible_message("[src] fizzles on contact with [target]!")
- return BULLET_ACT_BLOCK
- if(isturf(target))
- return BULLET_ACT_HIT
-
- var/turf/origin_turf = get_turf(target)
- var/turf/destination_turf = find_safe_turf()
-
- if(do_teleport(target, destination_turf, channel=TELEPORT_CHANNEL_MAGIC))
- for(var/t in list(origin_turf, destination_turf))
- var/datum/effect_system/smoke_spread/smoke = new
- smoke.set_up(0, t)
- smoke.start()
-
-/obj/projectile/magic/door
- name = "bolt of door creation"
- icon_state = "energy"
- damage = 0
- damage_type = OXY
- nodamage = TRUE
- var/list/door_types = list(/obj/structure/mineral_door/wood, /obj/structure/mineral_door/iron, /obj/structure/mineral_door/silver, /obj/structure/mineral_door/gold, /obj/structure/mineral_door/uranium, /obj/structure/mineral_door/sandstone, /obj/structure/mineral_door/transparent/plasma, /obj/structure/mineral_door/transparent/diamond)
-
-/obj/projectile/magic/door/on_hit(atom/target)
- . = ..()
- if(istype(target, /obj/machinery/door))
- OpenDoor(target)
- else
- var/turf/T = get_turf(target)
- if(isclosedturf(T) && !isindestructiblewall(T))
- CreateDoor(T)
-
-/obj/projectile/magic/door/proc/CreateDoor(turf/T)
- var/door_type = pick(door_types)
- var/obj/structure/mineral_door/D = new door_type(T)
- T.ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
- D.Open()
-
-/obj/projectile/magic/door/proc/OpenDoor(obj/machinery/door/D)
- if(istype(D, /obj/machinery/door/airlock))
- var/obj/machinery/door/airlock/A = D
- A.locked = FALSE
- D.open()
-
-/obj/projectile/magic/change
- name = "bolt of change"
- icon_state = "ice_1"
- damage = 0
- damage_type = BURN
- nodamage = TRUE
-
-/obj/projectile/magic/change/on_hit(atom/change)
- . = ..()
- if(ismob(change))
- var/mob/M = change
- if(M.anti_magic_check())
- M.visible_message("[src] fizzles on contact with [M]!")
- qdel(src)
- return BULLET_ACT_BLOCK
- wabbajack(change)
- qdel(src)
-
-/proc/wabbajack(mob/living/M)
- if(!istype(M) || M.stat == DEAD || M.notransform || (GODMODE & M.status_flags))
- return
-
- M.notransform = TRUE
- ADD_TRAIT(M, TRAIT_IMMOBILIZED, MAGIC_TRAIT)
- ADD_TRAIT(M, TRAIT_HANDS_BLOCKED, MAGIC_TRAIT)
- M.icon = null
- M.cut_overlays()
- M.invisibility = INVISIBILITY_ABSTRACT
-
- var/list/contents = M.contents.Copy()
-
- if(iscyborg(M))
- var/mob/living/silicon/robot/Robot = M
- // Disconnect AI's in shells
- if(Robot.connected_ai)
- Robot.connected_ai.disconnect_shell()
- if(Robot.mmi)
- qdel(Robot.mmi)
- Robot.notify_ai(NEW_BORG)
- else
- for(var/obj/item/W in contents)
- if(!M.dropItemToGround(W))
- qdel(W)
-
- var/mob/living/new_mob
-
- var/randomize = pick("monkey","robot","slime","xeno","humanoid","animal")
- switch(randomize)
- if("monkey")
- new_mob = new /mob/living/carbon/monkey(M.loc)
-
- if("robot")
- var/robot = pick(200;/mob/living/silicon/robot,
- /mob/living/silicon/robot/modules/syndicate,
- /mob/living/silicon/robot/modules/syndicate/medical,
- /mob/living/silicon/robot/modules/syndicate/saboteur,
- 200;/mob/living/simple_animal/drone/polymorphed)
- new_mob = new robot(M.loc)
- if(issilicon(new_mob))
- new_mob.gender = M.gender
- new_mob.invisibility = 0
- new_mob.job = "Cyborg"
- var/mob/living/silicon/robot/Robot = new_mob
- Robot.lawupdate = FALSE
- Robot.connected_ai = null
- Robot.mmi.transfer_identity(M) //Does not transfer key/client.
- Robot.clear_inherent_laws(0)
- Robot.clear_zeroth_law(0)
-
- if("slime")
- new_mob = new /mob/living/simple_animal/slime/random(M.loc)
-
- if("xeno")
- var/Xe
- if(M.ckey)
- Xe = pick(/mob/living/carbon/alien/humanoid/hunter,/mob/living/carbon/alien/humanoid/sentinel)
- else
- Xe = pick(/mob/living/carbon/alien/humanoid/hunter,/mob/living/simple_animal/hostile/alien/sentinel)
- new_mob = new Xe(M.loc)
-
- if("animal")
- var/path = pick(/mob/living/simple_animal/hostile/carp,
- /mob/living/simple_animal/hostile/bear,
- /mob/living/simple_animal/hostile/mushroom,
- /mob/living/simple_animal/hostile/statue,
- /mob/living/simple_animal/hostile/retaliate/bat,
- /mob/living/simple_animal/hostile/retaliate/goat,
- /mob/living/simple_animal/hostile/killertomato,
- /mob/living/simple_animal/hostile/poison/giant_spider,
- /mob/living/simple_animal/hostile/poison/giant_spider/hunter,
- /mob/living/simple_animal/hostile/blob/blobbernaut/independent,
- /mob/living/simple_animal/hostile/carp/ranged,
- /mob/living/simple_animal/hostile/carp/ranged/chaos,
- /mob/living/simple_animal/hostile/asteroid/basilisk/watcher,
- /mob/living/simple_animal/hostile/asteroid/goliath/beast,
- /mob/living/simple_animal/hostile/headcrab,
- /mob/living/simple_animal/hostile/morph,
- /mob/living/simple_animal/hostile/stickman,
- /mob/living/simple_animal/hostile/stickman/dog,
- /mob/living/simple_animal/hostile/megafauna/dragon/lesser,
- /mob/living/simple_animal/hostile/gorilla,
- /mob/living/simple_animal/parrot,
- /mob/living/simple_animal/pet/dog/corgi,
- /mob/living/simple_animal/crab,
- /mob/living/simple_animal/pet/dog/pug,
- /mob/living/simple_animal/pet/cat,
- /mob/living/simple_animal/mouse,
- /mob/living/simple_animal/chicken,
- /mob/living/simple_animal/cow,
- /mob/living/simple_animal/hostile/lizard,
- /mob/living/simple_animal/pet/fox,
- /mob/living/simple_animal/butterfly,
- /mob/living/simple_animal/pet/cat/cak,
- /mob/living/simple_animal/chick)
- new_mob = new path(M.loc)
-
- if("humanoid")
- new_mob = new /mob/living/carbon/human(M.loc)
-
- if(prob(50))
- var/list/chooseable_races = list()
- for(var/speciestype in subtypesof(/datum/species))
- var/datum/species/S = speciestype
- if(initial(S.changesource_flags) & WABBAJACK)
- chooseable_races += speciestype
-
- if(chooseable_races.len)
- new_mob.set_species(pick(chooseable_races))
-
- var/datum/preferences/A = new() //Randomize appearance for the human
- A.copy_to(new_mob, icon_updates=0)
-
- var/mob/living/carbon/human/H = new_mob
- H.update_hair()
- H.update_body_parts(TRUE)
- H.dna.update_dna_identity()
-
- if(!new_mob)
- return
-
- // Some forms can still wear some items
- for(var/obj/item/W in contents)
- new_mob.equip_to_appropriate_slot(W)
-
- M.log_message("became [new_mob.real_name]", LOG_ATTACK, color="orange")
-
- new_mob.a_intent = INTENT_HARM
-
- M.wabbajack_act(new_mob)
-
- to_chat(new_mob, "Your form morphs into that of a [randomize].")
-
- var/poly_msg = get_policy(POLICY_POLYMORPH)
- if(poly_msg)
- to_chat(new_mob, poly_msg)
-
- M.transfer_observers_to(new_mob)
-
- qdel(M)
- return new_mob
-
-/obj/projectile/magic/animate
- name = "bolt of animation"
- icon_state = "red_1"
- damage = 0
- damage_type = BURN
- nodamage = TRUE
-
-/obj/projectile/magic/animate/on_hit(atom/target, blocked = FALSE)
- target.animate_atom_living(firer)
- ..()
-
-/atom/proc/animate_atom_living(mob/living/owner = null)
- if((isitem(src) || isstructure(src)) && !is_type_in_list(src, GLOB.protected_objects))
- if(istype(src, /obj/structure/statue/petrified))
- var/obj/structure/statue/petrified/P = src
- if(P.petrified_mob)
- var/mob/living/L = P.petrified_mob
- var/mob/living/simple_animal/hostile/statue/S = new(P.loc, owner)
- S.name = "statue of [L.name]"
- if(owner)
- S.faction = list("[REF(owner)]")
- S.icon = P.icon
- S.icon_state = P.icon_state
- S.copy_overlays(P, TRUE)
- S.color = P.color
- S.atom_colours = P.atom_colours.Copy()
- if(L.mind)
- L.mind.transfer_to(S)
- if(owner)
- to_chat(S, "You are an animate statue. You cannot move when monitored, but are nearly invincible and deadly when unobserved! Do not harm [owner], your creator.")
- P.forceMove(S)
- return
- else
- var/obj/O = src
- if(istype(O, /obj/item/gun))
- new /mob/living/simple_animal/hostile/mimic/copy/ranged(loc, src, owner)
- else
- new /mob/living/simple_animal/hostile/mimic/copy(loc, src, owner)
-
- else if(istype(src, /mob/living/simple_animal/hostile/mimic/copy))
- // Change our allegiance!
- var/mob/living/simple_animal/hostile/mimic/copy/C = src
- if(owner)
- C.ChangeOwner(owner)
-
-/obj/projectile/magic/spellblade
- name = "blade energy"
- icon_state = "lavastaff"
- damage = 15
- damage_type = BURN
- flag = "magic"
- dismemberment = 50
- nodamage = FALSE
-
-/obj/projectile/magic/spellblade/on_hit(target)
- if(ismob(target))
- var/mob/M = target
- if(M.anti_magic_check())
- M.visible_message("[src] vanishes on contact with [target]!")
- qdel(src)
- return BULLET_ACT_BLOCK
- . = ..()
-
-/obj/projectile/magic/arcane_barrage
- name = "arcane bolt"
- icon_state = "arcane_barrage"
- damage = 20
- damage_type = BURN
- nodamage = FALSE
- armour_penetration = 0
- flag = "magic"
- hitsound = 'sound/weapons/barragespellhit.ogg'
-
-/obj/projectile/magic/arcane_barrage/on_hit(target)
- if(ismob(target))
- var/mob/M = target
- if(M.anti_magic_check())
- M.visible_message("[src] vanishes on contact with [target]!")
- qdel(src)
- return BULLET_ACT_BLOCK
- . = ..()
-
-
-/obj/projectile/magic/locker
- name = "locker bolt"
- icon_state = "locker"
- nodamage = TRUE
- flag = "magic"
- var/weld = TRUE
- var/created = FALSE //prevents creation of more then one locker if it has multiple hits
- var/locker_suck = TRUE
- var/obj/structure/closet/locker_temp_instance = /obj/structure/closet/decay
-
-/obj/projectile/magic/locker/Initialize()
- . = ..()
- locker_temp_instance = new(src)
-
-/obj/projectile/magic/locker/prehit_pierce(atom/A)
- . = ..()
- if(isliving(A) && locker_suck)
- var/mob/living/M = A
- if(M.anti_magic_check()) // no this doesn't check if ..() returned to phase through do I care no it's magic ain't gotta explain shit
- M.visible_message("[src] vanishes on contact with [A]!")
- return PROJECTILE_DELETE_WITHOUT_HITTING
- if(!locker_temp_instance.insertion_allowed(M))
- return
- M.forceMove(src)
- return PROJECTILE_PIERCE_PHASE
-
-/obj/projectile/magic/locker/on_hit(target)
- if(created)
- return ..()
- if(LAZYLEN(contents))
- for(var/atom/movable/AM in contents)
- locker_temp_instance.insert(AM)
- locker_temp_instance.welded = weld
- locker_temp_instance.update_appearance()
- created = TRUE
- return ..()
-
-/obj/projectile/magic/locker/Destroy()
- locker_suck = FALSE
- RemoveElement(/datum/element/connect_loc, projectile_connections) //We do this manually so the forcemoves don't "hit" us. This behavior is kinda dumb, someone refactor this
- for(var/atom/movable/AM in contents)
- AM.forceMove(get_turf(src))
- . = ..()
-
-/obj/structure/closet/decay
- breakout_time = 600
- icon_welded = null
- var/magic_icon = "cursed"
- var/weakened_icon = "decursed"
- var/auto_destroy = TRUE
-
-/obj/structure/closet/decay/Initialize()
- . = ..()
- if(auto_destroy)
- addtimer(CALLBACK(src, PROC_REF(bust_open)), 5 MINUTES)
- addtimer(CALLBACK(src, PROC_REF(magicly_lock)), 5)
-
-/obj/structure/closet/decay/proc/magicly_lock()
- if(!welded)
- return
- icon_state = magic_icon
- update_appearance()
-
-/obj/structure/closet/decay/after_weld(weld_state)
- if(weld_state)
- unmagify()
-
-/obj/structure/closet/decay/proc/decay()
- animate(src, alpha = 0, time = 30)
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), src), 30)
-
-/obj/structure/closet/decay/open(mob/living/user, force = FALSE)
- . = ..()
- if(.)
- if(icon_state == magic_icon) //check if we used the magic icon at all before giving it the lesser magic icon
- unmagify()
- else
- addtimer(CALLBACK(src, PROC_REF(decay)), 15 SECONDS)
-
-/obj/structure/closet/decay/proc/unmagify()
- icon_state = weakened_icon
- update_appearance()
- addtimer(CALLBACK(src, PROC_REF(decay)), 15 SECONDS)
- icon_welded = "welded"
-
-/obj/projectile/magic/flying
- name = "bolt of flying"
- icon_state = "flight"
-
-/obj/projectile/magic/flying/on_hit(target)
- . = ..()
- if(isliving(target))
- var/mob/living/L = target
- if(L.anti_magic_check())
- L.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- var/atom/throw_target = get_edge_target_turf(L, angle2dir(Angle))
- L.throw_at(throw_target, 200, 4)
-
-/obj/projectile/magic/bounty
- name = "bolt of bounty"
- icon_state = "bounty"
-
-/obj/projectile/magic/bounty/on_hit(target)
- . = ..()
- if(isliving(target))
- var/mob/living/L = target
- if(L.anti_magic_check() || !firer)
- L.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- L.apply_status_effect(STATUS_EFFECT_BOUNTY, firer)
-
-/obj/projectile/magic/antimagic
- name = "bolt of antimagic"
- icon_state = "antimagic"
-
-/obj/projectile/magic/antimagic/on_hit(target)
- . = ..()
- if(isliving(target))
- var/mob/living/L = target
- if(L.anti_magic_check())
- L.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- L.apply_status_effect(STATUS_EFFECT_ANTIMAGIC)
-
-/obj/projectile/magic/fetch
- name = "bolt of fetching"
- icon_state = "fetch"
-
-/obj/projectile/magic/fetch/on_hit(target)
- . = ..()
- if(isliving(target))
- var/mob/living/L = target
- if(L.anti_magic_check() || !firer)
- L.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- var/atom/throw_target = get_edge_target_turf(L, get_dir(L, firer))
- L.throw_at(throw_target, 200, 4)
-
-/obj/projectile/magic/sapping
- name = "bolt of sapping"
- icon_state = "sapping"
-
-/obj/projectile/magic/sapping/on_hit(target)
- . = ..()
- if(ismob(target))
- var/mob/M = target
- if(M.anti_magic_check())
- M.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, src, /datum/mood_event/sapped)
-
-/obj/projectile/magic/necropotence
- name = "bolt of necropotence"
- icon_state = "necropotence"
-
-/obj/projectile/magic/necropotence/on_hit(target)
- . = ..()
- if(isliving(target))
- var/mob/living/L = target
- if(L.anti_magic_check() || !L.mind || !L.mind.hasSoul)
- L.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- to_chat(L, "Your body feels drained and there is a burning pain in your chest.")
- L.maxHealth -= 20
- L.health = min(L.health, L.maxHealth)
- if(L.maxHealth <= 0)
- to_chat(L, "Your weakened soul is completely consumed by the [src]!")
- L.mind.hasSoul = FALSE
- for(var/obj/effect/proc_holder/spell/spell in L.mind.spell_list)
- spell.charge_counter = spell.charge_max
- spell.recharging = FALSE
- spell.update_appearance()
-
-/obj/projectile/magic/fortify
- name = "bolt of light"
- icon_state = "spark"
-
-/obj/projectile/magic/fortify/on_hit(target)
- . = ..()
- if(isliving(target))
- var/mob/living/L = target
- if(L.anti_magic_check() || !L.mind || !L.mind.hasSoul)
- L.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- to_chat(L, "You feel your body flood with magical strength! Your flesh feels cleansed, and somehow... tougher.")
- L.maxHealth += 20
- L.heal_overall_damage(20, 20)
- L.apply_damage(-200, CLONE)//cleanses cellular damage
- if(L.mind.hasSoul == FALSE)//restores consumed souls
- to_chat(L, "You feel a warm light in your chest... the [src] has restored something you'd long forgotten.")
- L.mind.hasSoul = TRUE
- if(L.hellbound == 1)
- L.hellbound = 0//devil economy in shambles
- for(var/obj/effect/proc_holder/spell/spell in L.mind.spell_list)
- spell.charge_counter = spell.charge_max
- spell.recharging = FALSE
- spell.update_appearance()
-
-/obj/projectile/magic/wipe
- name = "bolt of possession"
- icon_state = "wipe"
-
-/obj/projectile/magic/wipe/on_hit(target)
- . = ..()
- if(iscarbon(target))
- var/mob/living/carbon/M = target
- if(M.anti_magic_check())
- M.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- for(var/x in M.get_traumas())//checks to see if the victim is already going through possession
- if(istype(x, /datum/brain_trauma/special/imaginary_friend/trapped_owner))
- M.visible_message("[src] vanishes on contact with [target]!")
- return BULLET_ACT_BLOCK
- to_chat(M, "Your mind has been opened to possession!")
- possession_test(M)
- return BULLET_ACT_HIT
-
-/obj/projectile/magic/wipe/proc/possession_test(mob/living/carbon/M)
- var/datum/brain_trauma/special/imaginary_friend/trapped_owner/trauma = M.gain_trauma(/datum/brain_trauma/special/imaginary_friend/trapped_owner)
- var/poll_message = "Do you want to play as [M.real_name]?"
- if(M.mind && M.mind.assigned_role)
- poll_message = "[poll_message] Job:[M.mind.assigned_role]."
- if(M.mind && M.mind.special_role)
- poll_message = "[poll_message] Status:[M.mind.special_role]."
- else if(M.mind)
- var/datum/antagonist/A = M.mind.has_antag_datum(/datum/antagonist/)
- if(A)
- poll_message = "[poll_message] Status:[A.name]."
- var/list/mob/dead/observer/candidates = pollCandidatesForMob(poll_message, ROLE_PAI, null, FALSE, 100, M)
- if(M.stat == DEAD)//boo.
- return
- if(LAZYLEN(candidates))
- var/mob/dead/observer/C = pick(candidates)
- to_chat(M, "You have been noticed by a ghost and it has possessed you!")
- var/oldkey = M.key
- M.ghostize(0)
- M.key = C.key
- trauma.friend.key = oldkey
- trauma.friend.reset_perspective(null)
- trauma.friend.Show()
- trauma.friend_initialized = TRUE
- else
- to_chat(M, "Your mind has managed to go unnoticed in the spirit world.")
- qdel(trauma)
-
-/obj/projectile/magic/aoe
- name = "Area Bolt"
- desc = "What the fuck does this do?!"
- damage = 0
- var/proxdet = TRUE
-
-/obj/projectile/magic/aoe/Range()
- if(proxdet)
- for(var/mob/living/L in range(1, get_turf(src)))
- if(L.stat != DEAD && L != firer && !L.anti_magic_check())
- return Bump(L)
- ..()
-
-
-/obj/projectile/magic/aoe/lightning
- name = "lightning bolt"
- icon_state = "tesla_projectile" //Better sprites are REALLY needed and appreciated!~
- damage = 15
- damage_type = BURN
- nodamage = FALSE
- speed = 0.3
- flag = "magic"
-
- var/zap_power = 20000
- var/zap_range = 15
- var/zap_flags = ZAP_MOB_DAMAGE | ZAP_MOB_STUN | ZAP_OBJ_DAMAGE
- var/chain
- var/mob/living/caster
-
-/obj/projectile/magic/aoe/lightning/fire(setAngle)
- if(caster)
- chain = caster.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
- ..()
-
-/obj/projectile/magic/aoe/lightning/on_hit(target)
- . = ..()
- if(ismob(target))
- var/mob/M = target
- if(M.anti_magic_check())
- visible_message("[src] fizzles on contact with [target]!")
- qdel(src)
- return BULLET_ACT_BLOCK
- tesla_zap(src, zap_range, zap_power, zap_flags)
- qdel(src)
-
-/obj/projectile/magic/aoe/lightning/Destroy()
- qdel(chain)
- . = ..()
-
-/obj/projectile/magic/aoe/fireball
- name = "bolt of fireball"
- icon_state = "fireball"
- damage = 10
- damage_type = BRUTE
- nodamage = FALSE
-
- //explosion values
- var/exp_heavy = 0
- var/exp_light = 2
- var/exp_flash = 3
- var/exp_fire = 2
-
-/obj/projectile/magic/aoe/fireball/on_hit(target)
- . = ..()
- if(ismob(target))
- var/mob/living/M = target
- if(M.anti_magic_check())
- visible_message("[src] vanishes into smoke on contact with [target]!")
- return BULLET_ACT_BLOCK
- M.take_overall_damage(0,10) //between this 10 burn, the 10 brute, the explosion brute, and the onfire burn, your at about 65 damage if you stop drop and roll immediately
- var/turf/T = get_turf(target)
- explosion(T, -1, exp_heavy, exp_light, exp_flash, 0, flame_range = exp_fire)
-
-/obj/projectile/magic/aoe/fireball/infernal
- name = "infernal fireball"
- exp_heavy = -1
- exp_light = -1
- exp_flash = 4
- exp_fire= 5
-
-/obj/projectile/magic/aoe/fireball/infernal/on_hit(target)
- . = ..()
- if(ismob(target))
- var/mob/living/M = target
- if(M.anti_magic_check())
- return BULLET_ACT_BLOCK
- var/turf/T = get_turf(target)
- for(var/i=0, i<50, i+=10)
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), T, -1, exp_heavy, exp_light, exp_flash, FALSE, FALSE, exp_fire), i)
-
-//still magic related, but a different path
-
-/obj/projectile/temp/chill
- name = "bolt of chills"
- icon_state = "ice_2"
- damage = 0
- damage_type = BURN
- nodamage = FALSE
- armour_penetration = 100
- temperature = -200 // Cools you down greatly per hit
- flag = "magic"
-
-/obj/projectile/magic/nothing
- name = "bolt of nothing"
diff --git a/code/modules/projectiles/projectile/magic/spellcard.dm b/code/modules/projectiles/projectile/magic/spellcard.dm
deleted file mode 100644
index 464586d2f8a4..000000000000
--- a/code/modules/projectiles/projectile/magic/spellcard.dm
+++ /dev/null
@@ -1,6 +0,0 @@
-/obj/projectile/spellcard
- name = "enchanted card"
- desc = "A piece of paper enchanted to give it extreme durability and stiffness, along with a very hot burn to anyone unfortunate enough to get hit by a charged one."
- icon_state = "spellcard"
- damage_type = BURN
- damage = 2
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index f62a3a32035d..86f4e05226e4 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -389,7 +389,7 @@
for(var/addiction in cached_addictions)
var/datum/reagent/A = addiction
if(istype(R, A))
- A.addiction_stage = -15 // you're satisfied for a good while.
+ A.addiction_stage = -30 // you're satisfied for a good while.
need_mob_update += R.on_mob_life(C)
if(can_overdose)
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index 0985ce758976..2fa26e8f4bfb 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -1,12 +1,12 @@
/proc/translate_legacy_chem_id(id)
- switch (id)
- if ("sacid")
+ switch(id)
+ if("sacid")
return "sulphuricacid"
- if ("facid")
+ if("facid")
return "fluorosulfuricacid"
- if ("co2")
+ if("co2")
return "carbondioxide"
- if ("mine_salve")
+ if("mine_salve")
return "minerssalve"
else
return ckey(id)
@@ -15,11 +15,11 @@
name = "chem dispenser"
desc = "Creates and dispenses chemicals."
density = TRUE
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/chem_machines.dmi'
icon_state = "dispenser"
base_icon_state = "dispenser"
use_power = IDLE_POWER_USE
- idle_power_usage = 40
+ idle_power_usage = IDLE_DRAW_MINIMAL
interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE
resistance_flags = FIRE_PROOF | ACID_PROOF
circuit = /obj/item/circuitboard/machine/chem_dispenser
@@ -451,7 +451,7 @@
/obj/machinery/chem_dispenser/drinks
name = "soda dispenser"
desc = "Contains a large reservoir of soft drinks."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/chem_machines.dmi'
icon_state = "soda_dispenser"
base_icon_state = "soda_dispenser"
has_panel_overlay = FALSE
@@ -470,14 +470,14 @@
/datum/reagent/consumable/tea,
/datum/reagent/consumable/icetea,
/datum/reagent/consumable/space_cola,
- /datum/reagent/consumable/spacemountainwind,
- /datum/reagent/consumable/dr_gibb,
+ /datum/reagent/consumable/comet_trail,
+ /datum/reagent/consumable/tadrixx,
/datum/reagent/consumable/space_up,
/datum/reagent/consumable/tonic,
/datum/reagent/consumable/sodawater,
/datum/reagent/consumable/lemon_lime,
- /datum/reagent/consumable/pwr_game,
- /datum/reagent/consumable/shamblers,
+ /datum/reagent/consumable/pacfuel,
+ /datum/reagent/consumable/shoal_punch,
/datum/reagent/consumable/sugar,
/datum/reagent/consumable/pineapplejuice,
/datum/reagent/consumable/orangejuice,
@@ -489,7 +489,7 @@
)
upgrade_reagents = null
emagged_reagents = list(
- /datum/reagent/consumable/ethanol/thirteenloko,
+ /datum/reagent/consumable/ethanol/vimukti,
/datum/reagent/consumable/ethanol/whiskey_cola,
/datum/reagent/toxin/mindbreaker,
/datum/reagent/toxin/staminatoxin
@@ -509,7 +509,7 @@
name = "booze dispenser"
desc = "Contains a large reservoir of the good stuff."
base_icon_state = "booze_dispenser"
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/chem_machines.dmi'
icon_state = "booze_dispenser"
circuit = /obj/item/circuitboard/machine/chem_dispenser/drinks/beer
dispensable_reagents = list(
diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm
index b3a0cfee615d..88e7973dd29c 100644
--- a/code/modules/reagents/chemistry/machinery/chem_heater.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm
@@ -1,11 +1,11 @@
/obj/machinery/chem_heater
name = "chemical heater"
density = TRUE
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/chem_machines.dmi'
icon_state = "mixer0b"
base_icon_state = "mixer"
use_power = IDLE_POWER_USE
- idle_power_usage = 40
+ idle_power_usage = IDLE_DRAW_MINIMAL
resistance_flags = FIRE_PROOF | ACID_PROOF
circuit = /obj/item/circuitboard/machine/chem_heater
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 602c37710a57..c9791666b54f 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -3,11 +3,11 @@
desc = "Used to separate chemicals and distribute them in a variety of forms."
density = TRUE
layer = BELOW_OBJ_LAYER
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/chem_machines.dmi'
icon_state = "mixer0"
base_icon_state = "mixer"
use_power = IDLE_POWER_USE
- idle_power_usage = 20
+ idle_power_usage = IDLE_DRAW_MINIMAL
resistance_flags = FIRE_PROOF | ACID_PROOF
circuit = /obj/item/circuitboard/machine/chem_master
diff --git a/code/modules/reagents/chemistry/machinery/chem_press.dm b/code/modules/reagents/chemistry/machinery/chem_press.dm
index 80500efc78bf..43cd01e63b65 100644
--- a/code/modules/reagents/chemistry/machinery/chem_press.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_press.dm
@@ -1,7 +1,7 @@
/obj/machinery/chem_press
name = "pill press"
desc = "A press operated by hand to produce pills in a variety of forms."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/chem_machines.dmi'
icon_state = "press"
pass_flags = PASSTABLE
use_power = FALSE
@@ -26,17 +26,17 @@
/obj/machinery/chem_press/Initialize()
. = ..()
beaker = new /obj/item/reagent_containers/glass/beaker/large(src)
- beaker_overlay = image(icon = 'icons/obj/chemical.dmi', icon_state = "press_beaker")
- bottle_overlay = image(icon = 'icons/obj/chemical.dmi', icon_state = "press_bottle")
+ beaker_overlay = image(icon = 'icons/obj/chemical/chem_machines.dmi', icon_state = "press_beaker")
+ bottle_overlay = image(icon = 'icons/obj/chemical/chem_machines.dmi', icon_state = "press_bottle") //shouldn't this use mutable_appearance...?
/obj/machinery/chem_press/examine(mob/user)
. = ..()
- . += "There's a small screw that can help to adjust the pill size."
- . += "There's a small dial you could push with a screwdriver to adjust the pill color."
+ . += span_notice("There's a small screw that can help to adjust the pill size.")
+ . += span_notice("There's a small dial you could push with a screwdriver to adjust the pill color.")
if(!bottle)
- . += "The pill bottle slot is empty."
+ . += span_notice("The pill bottle slot is empty.")
if(!beaker)
- . += "The beaker slot is empty."
+ . += span_notice("The beaker slot is empty.")
/obj/machinery/chem_press/attack_hand(mob/user)
. = ..()
diff --git a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm
index 2c6f5ed38186..7b5656521209 100644
--- a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm
@@ -1,7 +1,7 @@
/obj/machinery/chem_dispenser/chem_synthesizer //formerly SCP-294 made by mrty, but now only for testing purposes
name = "\improper debug chemical synthesizer"
desc = "If you see this, yell at adminbus."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/chem_machines.dmi'
icon_state = "dispenser"
base_icon_state = "dispenser"
amount = 10
diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm
index 1fefd1d55031..6c85e75ccd86 100644
--- a/code/modules/reagents/chemistry/machinery/pandemic.dm
+++ b/code/modules/reagents/chemistry/machinery/pandemic.dm
@@ -5,11 +5,11 @@
name = "PanD.E.M.I.C 2200"
desc = "Used to work with viruses."
density = TRUE
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "pandemic0"
base_icon_state = "pandemic"
- use_power = TRUE
- idle_power_usage = 20
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_MINIMAL
resistance_flags = ACID_PROOF
circuit = /obj/item/circuitboard/computer/pandemic
unique_icon = TRUE
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index 5e5bd21747dc..5beaca629934 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -8,8 +8,8 @@
base_icon_state = "juicer"
layer = BELOW_OBJ_LAYER
use_power = IDLE_POWER_USE
- idle_power_usage = 5
- active_power_usage = 100
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MEDIUM
circuit = /obj/item/circuitboard/machine/reagentgrinder
pass_flags = PASSTABLE
resistance_flags = ACID_PROOF
@@ -261,10 +261,11 @@
operating = FALSE
/obj/machinery/reagentgrinder/proc/juice()
- power_change()
if(!beaker || machine_stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
return
+ set_active_power()
operate_for(50, juicing = TRUE)
+ set_idle_power()
for(var/obj/item/i in holdingitems)
if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
@@ -281,10 +282,11 @@
remove_object(I)
/obj/machinery/reagentgrinder/proc/grind(mob/user)
- power_change()
if(!beaker || machine_stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
return
+ set_active_power()
operate_for(60)
+ set_idle_power()
for(var/i in holdingitems)
if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
@@ -310,10 +312,11 @@
/obj/machinery/reagentgrinder/proc/mix(mob/user)
//For butter and other things that would change upon shaking or mixing
- power_change()
if(!beaker || machine_stat & (NOPOWER|BROKEN))
return
+ set_active_power()
operate_for(50, juicing = TRUE)
+ set_idle_power()
addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/reagentgrinder, mix_complete)), 50)
/obj/machinery/reagentgrinder/proc/mix_complete()
diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
index 7c67609593d5..e93e6f3117ca 100644
--- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm
+++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
@@ -3,7 +3,7 @@
/obj/machinery/smoke_machine
name = "smoke machine"
desc = "A machine with a centrifuge installed into it. It produces smoke with any reagents you put into the machine."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/chem_machines.dmi'
icon_state = "smoke0"
base_icon_state = "smoke"
density = TRUE
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index a35a8c91542a..66465dfafb17 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -77,6 +77,9 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
///How good of an accelerant is this reagent
var/accelerant_quality = 0
+ ///The section of the autowiki chem table this reagent will be under
+ var/category = "Misc"
+
/datum/reagent/New()
. = ..()
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 123afbcf387c..10519c75c434 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -87,30 +87,30 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/beer
name = "Beer"
- description = "An alcoholic beverage brewed since ancient times on Old Earth. Still popular today."
+ description = "An alcoholic beverage, brewed originally to keep a safe source of drinking water. A timeless classic."
color = "#664300" // rgb: 102, 67, 0
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 25
- taste_description = "piss water"
+ taste_description = "bad water"
glass_name = "glass of beer"
- glass_desc = "A freezing pint of beer."
+ glass_desc = "A pint of beer."
/datum/reagent/consumable/ethanol/beer/light
name = "Light Beer"
- description = "An alcoholic beverage brewed since ancient times on Old Earth. This variety has reduced calorie and alcohol content."
+ description = "An alcoholic beverage, brewed originally to keep a safe source of drinking water. This variety has reduced calorie and alcohol content."
boozepwr = 5 //Space Europeans hate it
taste_description = "dish water"
glass_name = "glass of light beer"
- glass_desc = "A freezing pint of watery light beer."
+ glass_desc = "A pint of watery light beer."
/datum/reagent/consumable/ethanol/beer/green
name = "Green Beer"
- description = "An alcoholic beverage brewed since ancient times on Old Earth. This variety is dyed a festive green."
+ description = "An alcoholic beverage, brewed originally to keep a safe source of drinking water. This variety is dyed green, but you're not sure why."
color = "#A8E61D"
- taste_description = "green piss water"
+ taste_description = "green bad water"
glass_icon_state = "greenbeerglass"
glass_name = "glass of green beer"
- glass_desc = "A freezing pint of green beer. Festive."
+ glass_desc = "A pint of green beer. You get the feeling this had some sort of meaning, once."
/datum/reagent/consumable/ethanol/beer/green/on_mob_life(mob/living/carbon/M)
if(M.color != color)
@@ -122,12 +122,12 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/kahlua
name = "Kahlua"
- description = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936!"
+ description = "A widely known coffee-flavoured liqueur. Still labeled under an old name from Earth, despite the loss of history."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
glass_icon_state = "kahluaglass"
- glass_name = "glass of RR coffee liquor"
- glass_desc = "DAMN, THIS THING LOOKS ROBUST!"
+ glass_name = "glass of coffee liquor"
+ glass_desc = "Bitter from the coffee and alcohol alike!"
shot_glass_icon_state = "shotglasscream"
/datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/carbon/M)
@@ -141,23 +141,23 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/whiskey
name = "Whiskey"
- description = "A superb and well-aged single-malt whiskey. Damn."
+ description = "A well-aged whiskey."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 75
taste_description = "molasses"
glass_icon_state = "whiskeyglass"
glass_name = "glass of whiskey"
- glass_desc = "The silky, smokey whiskey goodness inside the glass makes the drink look very classy."
+ glass_desc = "Often described as having a silky mouthfeel and a smokey aftertaste. The brown-amber color catches the light very well."
shot_glass_icon_state = "shotglassbrown"
/datum/reagent/consumable/ethanol/whiskey/kong
name = "Kong"
- description = "Makes You Go Ape!®"
+ description = "Makes You Go Ape!"
color = "#332100" // rgb: 51, 33, 0
addiction_threshold = 15
taste_description = "the grip of a giant ape"
glass_name = "glass of Kong"
- glass_desc = "Makes You Go Ape!®"
+ glass_desc = "Makes You Go Ape!"
/datum/reagent/consumable/ethanol/whiskey/kong/addiction_act_stage1(mob/living/M)
if(prob(5))
@@ -200,21 +200,21 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.hallucination += hal_amt //conscious dreamers can be treasurers to their own currency
..()
-/datum/reagent/consumable/ethanol/thirteenloko
- name = "Thirteen Loko"
- description = "A potent mixture of caffeine and alcohol."
+/datum/reagent/consumable/ethanol/vimukti
+ name = "Vimukti"
+ description = "A potent, fermented sweet lichen drink from the Shoal."
color = "#ce871d"
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 80
quality = DRINK_GOOD
overdose_threshold = 60
addiction_threshold = 30
- taste_description = "jitters and death"
- glass_icon_state = "thirteen_loko_glass"
- glass_name = "glass of Thirteen Loko"
- glass_desc = "This is a glass of Thirteen Loko, it appears to be of the highest quality. The drink, not the glass."
+ taste_description = "oily syrup"
+ glass_icon_state = "vimukti_glass"
+ glass_name = "glass of Vimukti"
+ glass_desc = "A spiritually-taxing drink from the Shoal. Numerous warnings about this drink tell you to not drink too much, lest you incur some sort of wrath... or an overdose of a psychoactive lichen."
-/datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/carbon/M)
+/datum/reagent/consumable/ethanol/vimukti/on_mob_life(mob/living/carbon/M)
M.drowsyness = max(0,M.drowsyness-7)
M.AdjustSleeping(-40)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
@@ -222,12 +222,12 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.Jitter(5)
return ..()
-/datum/reagent/consumable/ethanol/thirteenloko/overdose_start(mob/living/M)
+/datum/reagent/consumable/ethanol/vimukti/overdose_start(mob/living/M)
to_chat(M, "Your entire body violently jitters as you start to feel queasy. You really shouldn't have drank all of that [name]!")
M.Jitter(20)
M.Stun(15)
-/datum/reagent/consumable/ethanol/thirteenloko/overdose_process(mob/living/M)
+/datum/reagent/consumable/ethanol/vimukti/overdose_process(mob/living/M)
if(prob(7) && iscarbon(M))
var/obj/item/I = M.get_active_held_item()
if(I)
@@ -260,18 +260,18 @@ All effects don't start immediately, but rather get worse over time; the rate is
if(prob(1) && iscarbon(M))
var/datum/disease/D = new /datum/disease/heart_failure
M.ForceContractDisease(D)
- to_chat(M, "You're pretty sure you just felt your heart stop for a second there..")
+ to_chat(M, "You're pretty sure you just felt your heart stop for a second there...")
M.playsound_local(M, 'sound/effects/singlebeat.ogg', 100, 0)
/datum/reagent/consumable/ethanol/vodka
name = "Vodka"
- description = "Number one drink that also serves as fuel."
+ description = "A clear, hard liquor. Doubles as a flammable fuel source, if you really need it."
color = "#0064C8" // rgb: 0, 100, 200
boozepwr = 65
taste_description = "grain alcohol"
glass_icon_state = "ginvodkaglass"
glass_name = "glass of vodka"
- glass_desc = "The glass contain wodka. Xynta."
+ glass_desc = "It's almost difficult to tell the glass is full of vodka until you tip it around. The smell makes your nose wrinkle... but it might just be worth it."
shot_glass_icon_state = "shotglassclear"
/datum/reagent/consumable/ethanol/vodka/on_mob_life(mob/living/carbon/M)
@@ -280,14 +280,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/bilk
name = "Bilk"
- description = "This appears to be beer mixed with milk. Disgusting."
+ description = "This appears to be beer mixed with milk. Creative...?"
color = "#895C4C" // rgb: 137, 92, 76
nutriment_factor = 2 * REAGENTS_METABOLISM
boozepwr = 15
taste_description = "desperation and lactate"
glass_icon_state = "glass_brown"
glass_name = "glass of bilk"
- glass_desc = "A brew of milk and beer. For those alcoholics who fear osteoporosis."
+ glass_desc = "A brew of milk and beer. You have to wonder if this was made by accident just from the smell."
/datum/reagent/consumable/ethanol/bilk/on_mob_life(mob/living/carbon/M)
if(M.getBruteLoss() && prob(10))
@@ -297,14 +297,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/threemileisland
name = "Three Mile Island Iced Tea"
- description = "Made for a woman, strong enough for a man."
+ description = "The extreme version of fruity cocktails."
color = "#666340" // rgb: 102, 99, 64
boozepwr = 10
quality = DRINK_FANTASTIC
- taste_description = "dryness"
+ taste_description = "sweet dryness"
glass_icon_state = "threemileislandglass"
glass_name = "Three Mile Island Ice Tea"
- glass_desc = "A glass of this is sure to prevent a meltdown."
+ glass_desc = "A glass of Three Mile Island Ice Tea, named after a cordoned-off set of islands on Earth, for some reason. You almost can't taste the alcohol in it..."
/datum/reagent/consumable/ethanol/threemileisland/on_mob_life(mob/living/carbon/M)
M.set_drugginess(50)
@@ -312,75 +312,75 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/gin
name = "Gin"
- description = "It's gin. In space. I say, good sir."
+ description = "A very sharp alcohol, with a flavor that's distinctly fresh."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
- taste_description = "an alcoholic christmas tree"
+ taste_description = "an alcoholic pine tree"
glass_icon_state = "ginvodkaglass"
glass_name = "glass of gin"
- glass_desc = "A crystal clear glass of Griffeater gin."
+ glass_desc = "A glass of gin, made with a specific type of berry that leaves it smelling like the tree it came from. It's enough to wet your eyes."
/datum/reagent/consumable/ethanol/rum
name = "Rum"
- description = "Yohoho and all that."
+ description = "The liquor of choice for sailors and spacers alike."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 60
taste_description = "spiked butterscotch"
glass_icon_state = "rumglass"
glass_name = "glass of rum"
- glass_desc = "Now you want to Pray for a pirate suit, don't you?"
+ glass_desc = "There's no need to worry about being seen as a pirate with one of these. If you add enough ice and let it melt, it'll turn into grog."
shot_glass_icon_state = "shotglassbrown"
/datum/reagent/consumable/ethanol/tequila
name = "Tequila"
- description = "A strong and mildly flavoured, Mexican produced spirit. Feeling thirsty, hombre?"
+ description = "A strongly flavoured spirit."
color = "#FFFF91" // rgb: 255, 255, 145
boozepwr = 70
taste_description = "paint stripper"
glass_icon_state = "tequilaglass"
glass_name = "glass of tequila"
- glass_desc = "Now all that's missing is the weird colored shades!"
+ glass_desc = "Despite the strong, woody taste, there's just enough sweetness to keep you coming for more."
shot_glass_icon_state = "shotglassgold"
/datum/reagent/consumable/ethanol/vermouth
name = "Vermouth"
- description = "You suddenly feel a craving for a martini..."
+ description = "A fine wine to go with a meal."
color = "#91FF91" // rgb: 145, 255, 145
boozepwr = 45
taste_description = "dry alcohol"
glass_icon_state = "vermouthglass"
glass_name = "glass of vermouth"
- glass_desc = "You wonder why you're even drinking this straight."
+ glass_desc = "Vermouth was used as a medicine in the past, and the flavor makes sure to remind you of that."
shot_glass_icon_state = "shotglassclear"
/datum/reagent/consumable/ethanol/wine
name = "Wine"
- description = "A premium alcoholic beverage made from distilled grape juice."
+ description = "An alcoholic beverage made from fermented grapes of all kinds."
color = "#7E4043" // rgb: 126, 64, 67
boozepwr = 35
taste_description = "bitter sweetness"
glass_icon_state = "wineglass"
glass_name = "glass of wine"
- glass_desc = "A very classy looking drink."
+ glass_desc = "Deeply red wine in a glass. You're not enough of a sommelier to really describe how it smells."
shot_glass_icon_state = "shotglassred"
/datum/reagent/consumable/ethanol/lizardwine
- name = "Kalixcis Wine"
- description = "A relatively popular Kalixcane beverage, made by infusing cacti in ethanol."
+ name = "Blueflame Pyrecask"
+ description = "A popular Zohil beverage, made by infusing specially-gathered cacti and grapes in ethanol."
color = "#7E4043" // rgb: 126, 64, 67
boozepwr = 45
quality = DRINK_FANTASTIC
- taste_description = "scaley sweetness"
+ taste_description = "warm sweetness"
/datum/reagent/consumable/ethanol/grappa
name = "Grappa"
- description = "A fine Italian brandy, for when regular wine just isn't alcoholic enough for you."
+ description = "A fine brandy mixed with spirits."
color = "#F8EBF1"
boozepwr = 60
taste_description = "classy bitter sweetness"
glass_icon_state = "grappa"
glass_name = "glass of grappa"
- glass_desc = "A fine drink originally made to prevent waste by using the leftovers from winemaking."
+ glass_desc = "Despite being made from the recycled remains of wine grapes, it's not bad at all."
/datum/reagent/consumable/ethanol/amaretto
name = "Amaretto"
@@ -390,28 +390,28 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "fruity and nutty sweetness"
glass_icon_state = "amarettoglass"
glass_name = "glass of amaretto"
- glass_desc = "A sweet and syrupy looking drink."
+ glass_desc = "A sweet and syrupy looking alcohol. You're lucky it wasn't lost to history."
/datum/reagent/consumable/ethanol/cognac
name = "Cognac"
- description = "A sweet and strongly alcoholic drink, made after numerous distillations and years of maturing. Classy as fornication."
+ description = "A sweet and strongly alcoholic drink, made after numerous distillations and years of maturing."
color = "#AB3C05" // rgb: 171, 60, 5
boozepwr = 75
- taste_description = "angry and irish"
+ taste_description = "sharp and relaxing"
glass_icon_state = "cognacglass"
glass_name = "glass of cognac"
- glass_desc = "Damn, you feel like some kind of French aristocrat just by holding this."
+ glass_desc = "You wonder how many exhausted Solarian bureaucrats are drinking this the same way you are, right now."
shot_glass_icon_state = "shotglassbrown"
/datum/reagent/consumable/ethanol/absinthe
name = "Absinthe"
- description = "A powerful alcoholic drink. Rumored to cause hallucinations but does not."
+ description = "A powerful alcoholic drink. Rumored to cause hallucinations if taken irresponsibly."
color = rgb(10, 206, 0)
boozepwr = 80 //Very strong even by default
taste_description = "death and licorice"
glass_icon_state = "absinthe"
glass_name = "glass of absinthe"
- glass_desc = "It's as strong as it smells."
+ glass_desc = "The smell is enough to bring you to the verge of tears. The hint of liquorice threatens to bring you over the edge."
shot_glass_icon_state = "shotglassgreen"
/datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/carbon/M)
@@ -421,13 +421,13 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/hooch
name = "Hooch"
- description = "Either someone's failure at cocktail making or attempt in alcohol production. In any case, do you really want to drink that?"
+ description = "Low quality, low grade, and low expectations."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 100
taste_description = "pure resignation"
glass_icon_state = "glass_brown2"
glass_name = "Hooch"
- glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
+ glass_desc = "You can't help but feel like you'd rather drink anything else right now, just from looking at it."
/datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M)
if(M.mind && M.mind.assigned_role == "Assistant")
@@ -440,67 +440,67 @@ All effects don't start immediately, but rather get worse over time; the rate is
description = "A dark alcoholic beverage made with malted barley and yeast."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 65
- taste_description = "hearty barley ale"
+ taste_description = "hearty alcoholic grains"
glass_icon_state = "aleglass"
glass_name = "glass of ale"
- glass_desc = "A freezing pint of delicious Ale."
+ glass_desc = "A pint of ale. A classic for the working class."
/datum/reagent/consumable/ethanol/goldschlager
name = "Goldschlager"
- description = "100 proof cinnamon schnapps, made for alcoholic teen girls on spring break."
+ description = "100 proof cinnamon schnapps, made for the Student Unions' unbearable tastes."
color = "#FFFF91" // rgb: 255, 255, 145
boozepwr = 25
quality = DRINK_VERYGOOD
taste_description = "burning cinnamon"
glass_icon_state = "goldschlagerglass"
glass_name = "glass of goldschlager"
- glass_desc = "100% proof that teen girls will drink anything with gold in it."
+ glass_desc = "Extremely high proof, with cinnamon to boot. At least the light catches the gold flakes nicely enough to distract you from the imminent sting."
shot_glass_icon_state = "shotglassgold"
/datum/reagent/consumable/ethanol/patron
name = "Patron"
- description = "Tequila with silver in it, a favorite of alcoholic women in the club scene."
+ description = "Tequila with silver in it, often found in nightclubs."
color = "#585840" // rgb: 88, 88, 64
boozepwr = 60
quality = DRINK_VERYGOOD
taste_description = "metallic and expensive"
glass_icon_state = "patronglass"
glass_name = "glass of patron"
- glass_desc = "Drinking patron in the bar, with all the subpar ladies."
+ glass_desc = "A glass of Patron. The silver is for show, but you can't help but wonder how you would show it off to anyone."
shot_glass_icon_state = "shotglassclear"
/datum/reagent/consumable/ethanol/gintonic
name = "Gin and Tonic"
- description = "An all time classic, mild cocktail."
+ description = "A classic cocktail, with quinine for flavor."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 25
quality = DRINK_NICE
taste_description = "mild and tart"
glass_icon_state = "gintonicglass"
glass_name = "Gin and Tonic"
- glass_desc = "A mild but still great cocktail. Drink up, like a true Englishman."
+ glass_desc = "A mild, venerable cocktail. You wonder if the quinine is doing anything for you."
/datum/reagent/consumable/ethanol/rum_coke
name = "Rum and Coke"
description = "Rum, mixed with cola."
- taste_description = "cola"
+ taste_description = "cola and alcohol"
boozepwr = 40
quality = DRINK_NICE
color = "#6b2f01"
glass_icon_state = "whiskeycolaglass"
glass_name = "Rum and Coke"
- glass_desc = "The classic go-to of space-fratboys."
+ glass_desc = "The classic for mixing drinks on the fly."
/datum/reagent/consumable/ethanol/cuba_libre
- name = "Cuba Libre"
- description = "Viva la Revolucion! Viva Cuba Libre!"
+ name = "Frontier Libre"
+ description = "For a freer Frontier, everywhere!"
color = "#692e01"
boozepwr = 50
quality = DRINK_GOOD
taste_description = "a refreshing marriage of citrus and rum"
glass_icon_state = "cubalibreglass"
- glass_name = "Cuba Libre"
- glass_desc = "A classic mix of rum, cola, and lime. A favorite of revolutionaries everywhere!"
+ glass_name = "Frontier Libre"
+ glass_desc = "A mix of rum, cola, and lime. A favorite of among independent spacers and the Frontiersmen alike, who named it in the spirit of securing a free Frontier."
/datum/reagent/consumable/ethanol/whiskey_cola
name = "Whiskey Cola"
@@ -508,55 +508,55 @@ All effects don't start immediately, but rather get worse over time; the rate is
color = "#602a00"
boozepwr = 70
quality = DRINK_NICE
- taste_description = "cola"
+ taste_description = "sweet soda and bitter alcohol"
glass_icon_state = "whiskeycolaglass"
glass_name = "whiskey cola"
- glass_desc = "An innocent-looking mixture of cola and whiskey. Delicious."
+ glass_desc = "An sweet-and-bitter mixture of cola and whiskey."
/datum/reagent/consumable/ethanol/martini
name = "Classic Martini"
- description = "Vermouth with Gin. Not quite how 007 enjoyed it, but still delicious."
+ description = "Vermouth with gin."
color = "#9e8c67"
boozepwr = 60
quality = DRINK_NICE
- taste_description = "dry class"
+ taste_description = "dry"
glass_icon_state = "martiniglass"
glass_name = "Classic Martini"
- glass_desc = "Damn, the bartender even stirred it, not shook it."
+ glass_desc = "Rumored to be a favorite amongst the Evidenzkompanien, much to their chagrin."
/datum/reagent/consumable/ethanol/vodkamartini
name = "Vodka Martini"
- description = "Vodka with Gin. Not quite how 007 enjoyed it, but still delicious."
+ description = "Vodka with gin."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 65
quality = DRINK_NICE
taste_description = "shaken, not stirred"
glass_icon_state = "martiniglass"
glass_name = "Vodka martini"
- glass_desc ="A bastardisation of the classic martini. Still great."
+ glass_desc ="Rumored to be a favorite amongst the Verwaltungskompanien, to their entertainment."
/datum/reagent/consumable/ethanol/white_russian
- name = "White Russian"
- description = "That's just, like, your opinion, man..."
+ name = "White Gezenan"
+ description = "Cream and vodka."
color = "#A68340" // rgb: 166, 131, 64
boozepwr = 50
quality = DRINK_GOOD
taste_description = "bitter cream"
glass_icon_state = "whiterussianglass"
- glass_name = "White Russian"
- glass_desc = "A very nice looking drink. But that's just, like, your opinion, man."
+ glass_name = "White Gezenan"
+ glass_desc = "A mix of traditionally PGF-sourced vodka and cream derived from nut milk. You can still drink this if you're not from Gezena, though."
/datum/reagent/consumable/ethanol/screwdrivercocktail
name = "Screwdriver"
- description = "Vodka, mixed with plain ol' orange juice. The result is surprisingly delicious."
+ description = "Vodka mixed with orange juice."
color = "#A68310" // rgb: 166, 131, 16
boozepwr = 55
quality = DRINK_NICE
taste_description = "oranges"
glass_icon_state = "screwdriverglass"
glass_name = "Screwdriver"
- glass_desc = "A simple, yet superb mixture of Vodka and orange juice. Just the thing for the tired engineer."
+ glass_desc = "You won't be turning any screws with this, but you're far from lamenting that."
/datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_life(mob/living/carbon/M)
var/static/list/increased_rad_loss = list("Station Engineer", "Atmospheric Technician", "Chief Engineer")
@@ -572,18 +572,18 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "sweet 'n creamy"
glass_icon_state = "booger"
glass_name = "Booger"
- glass_desc = "Ewww..."
+ glass_desc = "The name isn't selling the drink very well, is it..."
/datum/reagent/consumable/ethanol/bloody_mary
name = "Bloody Mary"
- description = "A strange yet pleasurable mixture made of vodka, tomato and lime juice. Or at least you THINK the red stuff is tomato juice."
+ description = "A strange yet pleasurable mixture made of vodka, tomato and lime juice."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 55
quality = DRINK_GOOD
taste_description = "tomatoes with a hint of lime"
glass_icon_state = "bloodymaryglass"
glass_name = "Bloody Mary"
- glass_desc = "Tomato juice, mixed with Vodka and a li'l bit of lime. Tastes like liquid murder."
+ glass_desc = "Tomato juice, mixed with Vodka and a li'l bit of lime. The taste is acquired, and usually acquired through tgrying to use it as a hangover remedy."
/datum/reagent/consumable/ethanol/bloody_mary/on_mob_life(mob/living/carbon/C)
if(C.blood_volume < BLOOD_VOLUME_NORMAL)
@@ -592,14 +592,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/brave_bull
name = "Brave Bull"
- description = "It's just as effective as Dutch-Courage!"
+ description = "Liquid courage is as good as any courage!"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 60
quality = DRINK_NICE
taste_description = "alcoholic bravery"
glass_icon_state = "bravebullglass"
glass_name = "Brave Bull"
- glass_desc = "Tequila and Coffee liqueur, brought together in a mouthwatering mixture. Drink up."
+ glass_desc = "Tequila and coffee liqueur, brought together to give you the will to pick fights. Don't drink enough to ruin your sense of safety, though."
var/tough_text
/datum/reagent/consumable/ethanol/brave_bull/on_mob_metabolize(mob/living/M)
@@ -615,14 +615,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/tequila_sunrise
name = "Tequila Sunrise"
- description = "Tequila, Grenadine, and Orange Juice."
+ description = "Tequila, grenadine, and orange juice."
color = "#FFE48C" // rgb: 255, 228, 140
boozepwr = 45
quality = DRINK_GOOD
taste_description = "oranges with a hint of pomegranate"
glass_icon_state = "tequilasunriseglass"
glass_name = "tequila Sunrise"
- glass_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..."
+ glass_desc = "You feel a distinct sense of nostalgia - when's the last time you felt the sun on your face?"
var/obj/effect/light_holder
/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_metabolize(mob/living/M)
@@ -643,14 +643,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/toxins_special
name = "Toxins Special"
- description = "This thing is ON FIRE! CALL THE DAMN SHUTTLE!"
+ description = "It's a bit tasteless to name your drink after industrial accidents."
color = "#780162"
boozepwr = 25
quality = DRINK_VERYGOOD
taste_description = "spicy toxins"
glass_icon_state = "toxinsspecialglass"
glass_name = "Toxins Special"
- glass_desc = "Whoah, this thing is on FIRE!"
+ glass_desc = "Traditionally lit with a welder while the server is blindfolded, but you don't want to cause an ACTUAL accident here."
shot_glass_icon_state = "toxinsspecialglass"
/datum/reagent/consumable/ethanol/toxins_special/on_mob_life(mob/living/M)
@@ -659,15 +659,15 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/beepsky_smash
name = "Beepsky Smash"
- description = "Drink this and prepare for the LAW."
+ description = "A drink for those who pick fights with automated security."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 60 //THE FIST OF THE LAW IS STRONG AND HARD
quality = DRINK_GOOD
metabolization_rate = 0.5
- taste_description = "JUSTICE"
+ taste_description = "electrified justice"
glass_icon_state = "beepskysmashglass"
glass_name = "Beepsky Smash"
- glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW."
+ glass_desc = "Heavy, hot and strong. Just like the sting of a stunbaton."
overdose_threshold = 40
var/datum/brain_trauma/special/beepsky/B
@@ -700,26 +700,26 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.gain_trauma(/datum/brain_trauma/mild/phobia/security, TRAUMA_RESILIENCE_BASIC)
/datum/reagent/consumable/ethanol/irish_cream
- name = "Irish Cream"
- description = "Whiskey-imbued cream, what else would you expect from the Irish?"
+ name = "Zohil Cream"
+ description = "Whiskey-imbued cream."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 50
quality = DRINK_NICE
taste_description = "creamy alcohol"
glass_icon_state = "irishcreamglass"
- glass_name = "Irish Cream"
- glass_desc = "It's cream, mixed with whiskey. What else would you expect from the Irish?"
+ glass_name = "Zohil Cream"
+ glass_desc = "Cream mixed with whiskey. Don't expect to learn anything about the Blueflame from just a drink, though."
/datum/reagent/consumable/ethanol/manly_dorf
- name = "The Manly Dorf"
- description = "Beer and Ale, brought together in a delicious mix. Intended for true men only."
+ name = "The Shortstop"
+ description = "Beer and ale, brought together in a very grain-flavored mix."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 100 //For the manly only
quality = DRINK_NICE
- taste_description = "hair on your chest and your chin"
+ taste_description = "fire in your chest and windburn on your chin"
glass_icon_state = "manlydorfglass"
- glass_name = "The Manly Dorf"
- glass_desc = "A manly concoction made from Ale and Beer. Intended for true men only."
+ glass_name = "The Shortstop"
+ glass_desc = "A concoction made from ale and beer. Named after a joke that only short people would order this to prove a point."
var/dorf_mode
/datum/reagent/consumable/ethanol/manly_dorf/on_mob_metabolize(mob/living/carbon/human/badlands_chugs)
@@ -742,14 +742,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/longislandicedtea
name = "Long Island Iced Tea"
- description = "The liquor cabinet, brought together in a delicious mix. Intended for middle-aged alcoholic women only."
+ description = "The entire liquor cabinet brought together with enough sugar to hide it."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
quality = DRINK_VERYGOOD
taste_description = "a mixture of cola and alcohol"
glass_icon_state = "longislandicedteaglass"
glass_name = "Long Island Iced Tea"
- glass_desc = "The liquor cabinet, brought together in a delicious mix. Intended for middle-aged alcoholic women only."
+ glass_desc = "The entire liquor cabinet brought together with enough sugar to hide it."
/datum/reagent/consumable/ethanol/moonshine
@@ -763,103 +763,86 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
/datum/reagent/consumable/ethanol/b52
- name = "B-52"
- description = "Coffee, Irish Cream, and cognac. You will get bombed."
+ name = "AM-G"
+ description = "Coffee liquor, Zohil Cream, and cognac."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 85
quality = DRINK_GOOD
- taste_description = "angry and irish"
+ taste_description = "angry and intense"
glass_icon_state = "b52glass"
- glass_name = "B-52"
- glass_desc = "Kahlua, Irish Cream, and cognac. You will get bombed."
+ glass_name = "AM-G"
+ glass_desc = "Coffee liquor, Zohil Cream, and cognac. Enough to make you hide before the blast."
shot_glass_icon_state = "b52glass"
/datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/M)
playsound(M, 'sound/effects/explosion_distant.ogg', 100, FALSE)
/datum/reagent/consumable/ethanol/irishcoffee
- name = "Irish Coffee"
- description = "Coffee, and alcohol. More fun than a Mimosa to drink in the morning."
+ name = "Gezenan Coffee"
+ description = "Coffee, and alcohol. Traditionally enjoyed in the morning on lazy days."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
quality = DRINK_NICE
taste_description = "giving up on the day"
glass_icon_state = "irishcoffeeglass"
- glass_name = "Irish Coffee"
- glass_desc = "Coffee and alcohol. More fun than a Mimosa to drink in the morning."
+ glass_name = "Gezenan Coffee"
+ glass_desc = "Coffee and alcohol. Traditionally enjoyed in the morning on lazy days."
/datum/reagent/consumable/ethanol/margarita
name = "Margarita"
- description = "On the rocks with salt on the rim. Arriba~!"
+ description = "A fruity, tropical drink with a salted rim around the glass."
color = "#8CFF8C" // rgb: 140, 255, 140
boozepwr = 35
quality = DRINK_NICE
taste_description = "dry and salty"
glass_icon_state = "margaritaglass"
glass_name = "Margarita"
- glass_desc = "On the rocks with salt on the rim. Arriba~!"
+ glass_desc = "On the rocks with salt on the rim. Apparently the name meant something in a language long lost on Earth."
/datum/reagent/consumable/ethanol/black_russian
- name = "Black Russian"
- description = "For the lactose-intolerant. Still as classy as a White Russian."
+ name = "Black Rachnid"
+ description = "An alternative take to the White Gezenan. Doubles as an option for those who can't handle lactose."
color = "#360000" // rgb: 54, 0, 0
boozepwr = 70
quality = DRINK_NICE
taste_description = "bitterness"
glass_icon_state = "blackrussianglass"
- glass_name = "Black Russian"
- glass_desc = "For the lactose-intolerant. Still as classy as a White Russian."
+ glass_name = "Black Rachnid"
+ glass_desc = "An alternative take to the White Gezenan. Doubles as an option for those who can't handle lactose."
/datum/reagent/consumable/ethanol/manhattan
- name = "Manhattan"
- description = "The Detective's undercover drink of choice. He never could stomach gin..."
+ name = "Twelve Crossings"
+ description = "A mixed drink popularized by a murder mystery book series from Teceti."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 30
quality = DRINK_NICE
taste_description = "mild dryness"
glass_icon_state = "manhattanglass"
- glass_name = "Manhattan"
- glass_desc = "The Detective's undercover drink of choice. He never could stomach gin..."
-
-
-/datum/reagent/consumable/ethanol/manhattan_proj
- name = "Manhattan Project"
- description = "A scientist's drink of choice, for pondering ways to blow up the sector."
- color = "#664300" // rgb: 102, 67, 0
- boozepwr = 45
- quality = DRINK_VERYGOOD
- taste_description = "death, the destroyer of worlds"
- glass_icon_state = "proj_manhattanglass"
- glass_name = "Manhattan Project"
- glass_desc = "A scientist's drink of choice, for thinking how to blow up the sector."
-
-
-/datum/reagent/consumable/ethanol/manhattan_proj/on_mob_life(mob/living/carbon/M)
- M.set_drugginess(30)
- return ..()
+ glass_name = "Twelve Crossings"
+ glass_desc = "A mixed drink popularized by a murder mystery book series from Teceti. The Detective's undercover drink of choice. He never could stomach gin..."
/datum/reagent/consumable/ethanol/whiskeysoda
name = "Whiskey Soda"
- description = "For the more refined griffon."
+ description = "Whiskey and soda water, a simple mixed drink."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 70
quality = DRINK_NICE
taste_description = "soda"
glass_icon_state = "whiskeysodaglass2"
glass_name = "whiskey soda"
- glass_desc = "Ultimate refreshment."
+ glass_desc = "Bitter and refreshing."
/datum/reagent/consumable/ethanol/antifreeze
name = "Anti-freeze"
- description = "The ultimate refreshment. Not what it sounds like."
+ description = "The ultimate refreshment. Not actually made of antifreeze!"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
quality = DRINK_NICE
- taste_description = "Jack Frost's piss"
+ taste_description = "frigid heat"
glass_icon_state = "antifreeze"
glass_name = "Anti-freeze"
- glass_desc = "The ultimate refreshment."
+ glass_desc = "Vodka, cream, and ice. No actual antifreeze included, of course."
/datum/reagent/consumable/ethanol/antifreeze/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(20 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, M.get_body_temp_normal() + 20) //310.15 is the normal bodytemp.
@@ -867,14 +850,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/barefoot
name = "Barefoot"
- description = "Barefoot and pregnant."
+ description = "To be enjoyed on the beach or by a pool. You should keep your shoes on, though."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
quality = DRINK_VERYGOOD
taste_description = "creamy berries"
glass_icon_state = "b&p"
glass_name = "Barefoot"
- glass_desc = "Barefoot and pregnant."
+ glass_desc = "To be enjoyed on the beach or by a pool. You should keep your shoes on, though."
/datum/reagent/consumable/ethanol/barefoot/on_mob_life(mob/living/carbon/M)
if(ishuman(M)) //Barefoot causes the imbiber to quickly regenerate brute trauma if they're not wearing shoes.
@@ -893,40 +876,40 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "refreshing cold"
glass_icon_state = "snowwhite"
glass_name = "Snow White"
- glass_desc = "A cold refreshment."
+ glass_desc = "A cold refreshment of beer and lemon-lime soda. Not exactly princess material, is it?"
/datum/reagent/consumable/ethanol/demonsblood //Prevents the imbiber from being dragged into a pool of blood by a slaughter demon.
name = "Demon's Blood"
- description = "AHHHH!!!!"
+ description = "A mix of two sodas, rum, and... real blood."
color = "#820000" // rgb: 130, 0, 0
boozepwr = 75
quality = DRINK_VERYGOOD
taste_description = "sweet tasting iron"
glass_icon_state = "demonsblood"
- glass_name = "Demons Blood"
- glass_desc = "Just looking at this thing makes the hair at the back of your neck stand up."
+ glass_name = "Demon's Blood"
+ glass_desc = "A drink made with the blood of the server or the patron, which usually results in said patron being thrown out. While most substitute real blood for a saline solution, that drink is actually referred to as 'Demon's Sweat'."
/datum/reagent/consumable/ethanol/devilskiss //If eaten by a slaughter demon, the demon will regret it.
name = "Devil's Kiss"
- description = "Creepy time!"
+ description = "Asking for a kiss to go with the blood drawing is pushing it."
color = "#A68310" // rgb: 166, 131, 16
boozepwr = 70
quality = DRINK_VERYGOOD
taste_description = "bitter iron"
glass_icon_state = "devilskiss"
- glass_name = "Devils Kiss"
- glass_desc = "Creepy time!"
+ glass_name = "Devil's Kiss"
+ glass_desc = "The boozier cousin of the Demon's Blood. Typically served in a glass shaped to specifically cut and draw blood from the patron's lip... which deters most."
/datum/reagent/consumable/ethanol/vodkatonic
name = "Vodka and Tonic"
- description = "For when a gin and tonic isn't Russian enough."
+ description = "The stronger sibling of the Gin and Tonic."
color = "#0064C8" // rgb: 0, 100, 200
boozepwr = 70
quality = DRINK_NICE
taste_description = "tart bitterness"
glass_icon_state = "vodkatonicglass"
- glass_name = "vodka and tonic"
- glass_desc = "For when a gin and tonic isn't Russian enough."
+ glass_name = "Vodka and Tonic"
+ glass_desc = "The stronger sibling of the Gin and Tonic."
/datum/reagent/consumable/ethanol/ginfizz
@@ -943,55 +926,55 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/bahama_mama
name = "Bahama Mama"
- description = "A tropical cocktail with a complex blend of flavors."
+ description = "A tropical cocktail with a complex blend of fruity flavors."
color = "#FF7F3B" // rgb: 255, 127, 59
boozepwr = 35
quality = DRINK_GOOD
taste_description = "pineapple, coconut, and a hint of coffee"
glass_icon_state = "bahama_mama"
glass_name = "Bahama Mama"
- glass_desc = "A tropical cocktail with a complex blend of flavors."
+ glass_desc = "A tropical cocktail with a complex blend of fruity flavors. It makes you think about going on vacation someday..."
/datum/reagent/consumable/ethanol/singulo
name = "Singulo"
- description = "A blue-space beverage!"
+ description = "Named after a tragic industrial accident!"
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 35
quality = DRINK_VERYGOOD
taste_description = "concentrated matter"
glass_icon_state = "singulo"
glass_name = "Singulo"
- glass_desc = "A blue-space beverage."
+ glass_desc = "Named after a tragic industrial accident involving a singularity escaping containment. This drink doesn't taste particularly commemorative - it's too enjoyable!"
/datum/reagent/consumable/ethanol/sbiten
name = "Sbiten"
- description = "A spicy Vodka! Might be a little hot for the little guys!"
+ description = "Vodka with capsaicin for the extra feeling of intense warmth."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 70
quality = DRINK_GOOD
taste_description = "hot and spice"
glass_icon_state = "sbitenglass"
glass_name = "Sbiten"
- glass_desc = "A spicy mix of Vodka and Spice. Very hot."
+ glass_desc = "Vodka with capsaicin for the extra feeling of intense warmth. Difficult to take large swallows."
/datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(50 * TEMPERATURE_DAMAGE_COEFFICIENT, 0 , M.dna.species.bodytemp_heat_damage_limit) //310.15 is the normal bodytemp.
return ..()
/datum/reagent/consumable/ethanol/red_mead
- name = "Red Mead"
- description = "The true Viking drink! Even though it has a strange red color."
+ name = "Drop-pod"
+ description = "A commemorative drink, made in the name of those who died during failed orbital drop-pod landings."
color = "#C73C00" // rgb: 199, 60, 0
boozepwr = 31 //Red drinks are stronger
quality = DRINK_GOOD
taste_description = "sweet and salty alcohol"
glass_icon_state = "red_meadglass"
- glass_name = "Red Mead"
- glass_desc = "A true Viking's beverage, made with the blood of their enemies."
+ glass_name = "Drop-pod"
+ glass_desc = "A commemorative drink, made in the name of those who died during failed orbital drop-pod landings. Technically intended to use the blood of your enemies, but..."
/datum/reagent/consumable/ethanol/mead
name = "Mead"
- description = "A Viking drink, though a cheap one."
+ description = "Fermented honey. The gentler sibling to the beer."
color = "#664300" // rgb: 102, 67, 0
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 30
@@ -999,17 +982,17 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "sweet, sweet alcohol"
glass_icon_state = "meadglass"
glass_name = "Mead"
- glass_desc = "A drink from Valhalla."
+ glass_desc = "Fermented honey. The gentler sibling to the beer - and almost just as old."
/datum/reagent/consumable/ethanol/iced_beer
- name = "Iced Beer"
- description = "A beer which is so cold the air around it freezes."
+ name = "Iced beer"
+ description = "Iced beer, served in a chilled glass."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 15
taste_description = "refreshingly cold"
glass_icon_state = "iced_beerglass"
glass_name = "iced beer"
- glass_desc = "A beer so frosty, the air around it freezes."
+ glass_desc = "Iced beer, served in a chilled glass. It's cold enough to leave a trail in the air."
/datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-20 * TEMPERATURE_DAMAGE_COEFFICIENT, T0C) //310.15 is the normal bodytemp.
@@ -1017,25 +1000,25 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/grog
name = "Grog"
- description = "Watered-down rum, Nanotrasen approves!"
+ description = "Watered-down rum, to really stretch out your alcohol rations. A Belter classic."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 1 //Basically nothing
taste_description = "a poor excuse for alcohol"
glass_icon_state = "grogglass"
glass_name = "Grog"
- glass_desc = "A fine and cepa drink for Space."
+ glass_desc = "Watered-down rum, to really stretch out your alcohol rations. A Belter classic."
/datum/reagent/consumable/ethanol/aloe
name = "Aloe"
- description = "So very, very, very good."
+ description = "Zohil Cream and watermelon juice. Mellows out the alcoholic bite for a mild drink."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
quality = DRINK_VERYGOOD
taste_description = "sweet 'n creamy"
glass_icon_state = "aloe"
glass_name = "Aloe"
- glass_desc = "Very, very, very good."
+ glass_desc = "Zohil Cream and watermelon juice. Mellows out the alcoholic bite for a mild drink."
/datum/reagent/consumable/ethanol/andalusia
name = "Andalusia"
@@ -1046,51 +1029,51 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "lemons"
glass_icon_state = "andalusia"
glass_name = "Andalusia"
- glass_desc = "A nice, strangely named drink."
+ glass_desc = "A nice, strangely named drink. Theoretically named after a particular region on Terra, but no one's quite sure where."
/datum/reagent/consumable/ethanol/alliescocktail
- name = "Allies Cocktail"
- description = "A drink made from your allies. Not as sweet as those made from your enemies."
+ name = "Canton Cocktail"
+ description = "A drink intended to be shared across the Solarian cantons."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
quality = DRINK_NICE
taste_description = "bitter yet free"
glass_icon_state = "alliescocktail"
- glass_name = "Allies cocktail"
- glass_desc = "A drink made from your allies."
+ glass_name = "Canton cocktail"
+ glass_desc = "A drink intended to be shared across the Solarian cantons."
/datum/reagent/consumable/ethanol/acid_spit
- name = "Acid Spit"
- description = "A drink for the daring, can be deadly if incorrectly prepared!"
+ name = "Cracked Moon"
+ description = "Typically made on a dare by CLIP-BARD crews. It's deadly if incorrectly prepared!"
color = "#365000" // rgb: 54, 80, 0
boozepwr = 70
quality = DRINK_VERYGOOD
- taste_description = "stomach acid"
+ taste_description = "alien stomach acid"
glass_icon_state = "acidspitglass"
- glass_name = "Acid Spit"
- glass_desc = "A drink from Nanotrasen. Made from live aliens."
+ glass_name = "Cracked Moon"
+ glass_desc = "Typically made on a dare by CLIP-BARD crews. It's deadly if incorrectly prepared!"
/datum/reagent/consumable/ethanol/amasec
- name = "Amasec"
- description = "Official drink of the Nanotrasen Gun-Club!"
+ name = "Ren Kirsi"
+ description = "A Teceian drink mainly enjoyed on The Ring and it's sibling colonies."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
quality = DRINK_GOOD
taste_description = "dark and metallic"
glass_icon_state = "amasecglass"
- glass_name = "Amasec"
- glass_desc = "Always handy before COMBAT!!!"
+ glass_name = "Ren Kirsi"
+ glass_desc = "There's no way you're getting your hands on metal shavings from The Ring itself, but it's the thought that counts."
/datum/reagent/consumable/ethanol/changelingsting
name = "Changeling Sting"
- description = "You take a tiny sip and feel a burning sensation..."
+ description = "Made by the superstitous. Keeps the changelings away... whereever they may be."
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 50
quality = DRINK_GOOD
taste_description = "your brain coming out your nose"
glass_icon_state = "changelingsting"
glass_name = "Changeling Sting"
- glass_desc = "A stingy drink."
+ glass_desc = "Made by the superstitous. Keeps the changelings away... whereever they may be."
/datum/reagent/consumable/ethanol/changelingsting/on_mob_life(mob/living/carbon/M)
if(M.mind) //Changeling Sting assists in the recharging of changeling chemicals.
@@ -1101,26 +1084,26 @@ All effects don't start immediately, but rather get worse over time; the rate is
return ..()
/datum/reagent/consumable/ethanol/irishcarbomb
- name = "Irish Car Bomb"
- description = "Mmm, tastes like the free Irish state."
+ name = "Lightspeed"
+ description = "A shot of Zohil cream in a pinch of ale, meant to be downed in one chug - hits you as fast as the name."
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 25
quality = DRINK_GOOD
- taste_description = "the spirit of Ireland"
+ taste_description = "the rush of hyperspace"
glass_icon_state = "irishcarbomb"
- glass_name = "Irish Car Bomb"
- glass_desc = "An Irish car bomb."
+ glass_name = "Lightspeed"
+ glass_desc = "A shot of Zohil cream in a pinch of ale, meant to be downed in one chug - hits you as fast as the name."
/datum/reagent/consumable/ethanol/syndicatebomb
- name = "Syndicate Bomb"
- description = "Tastes like terrorism!"
+ name = "Gorlex Surprise"
+ description = "Infamously named after the accusations of Syndicate-led bombings of space installations. It's a blast!"
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 90
quality = DRINK_GOOD
- taste_description = "purified antagonism"
+ taste_description = "anti-Nanotrasen sentiments"
glass_icon_state = "syndicatebomb"
- glass_name = "Syndicate Bomb"
- glass_desc = "A syndicate bomb."
+ glass_name = "Gorlex Surprise"
+ glass_desc = "Infamously named after the accusations of Syndicate-led bombings of space installations. It's a blast!"
/datum/reagent/consumable/ethanol/syndicatebomb/on_mob_life(mob/living/carbon/M)
if(prob(5))
@@ -1128,50 +1111,50 @@ All effects don't start immediately, but rather get worse over time; the rate is
return ..()
/datum/reagent/consumable/ethanol/hiveminderaser
- name = "Hivemind Eraser"
+ name = "Hivemind"
description = "A vessel of pure flavor."
color = "#FF80FC" // rgb: 255, 128, 252
boozepwr = 40
quality = DRINK_GOOD
taste_description = "psychic links"
glass_icon_state = "hiveminderaser"
- glass_name = "Hivemind Eraser"
- glass_desc = "For when even mindshields can't save you."
+ glass_name = "Hivemind"
+ glass_desc = "A legend around this drink states that drinking this at the same time as someone else links your mind with theirs. Are you going to find out?"
/datum/reagent/consumable/ethanol/erikasurprise
- name = "Erika Surprise"
- description = "The surprise is, it's green!"
+ name = "Terraformer Surprise"
+ description = "It's as green as the first terraforming experiments, allegedly."
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 35
quality = DRINK_VERYGOOD
taste_description = "tartness and bananas"
glass_icon_state = "erikasurprise"
- glass_name = "Erika Surprise"
- glass_desc = "The surprise is, it's green!"
+ glass_name = "Terraformer Surprise"
+ glass_desc = "It's as green as the first terraforming experiments, allegedly."
/datum/reagent/consumable/ethanol/driestmartini
- name = "Driest Martini"
- description = "Only for the experienced. You think you see sand floating in the glass."
+ name = "Saltflat"
+ description = "Nigh-dehydratingly dry. Intended to be a challenge."
nutriment_factor = 1 * REAGENTS_METABOLISM
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 65
quality = DRINK_GOOD
taste_description = "a beach"
glass_icon_state = "driestmartiniglass"
- glass_name = "Driest Martini"
- glass_desc = "Only for the experienced. You think you see sand floating in the glass."
+ glass_name = "Saltflat"
+ glass_desc = "Nigh-dehydratingly dry. Intended to be a challenge."
/datum/reagent/consumable/ethanol/bananahonk
- name = "Banana Honk"
- description = "A drink from Clown Heaven."
+ name = "Creamtruck"
+ description = "A distinctly non-kid friendly equivalent to the ice cream truck."
nutriment_factor = 1 * REAGENTS_METABOLISM
color = "#FFFF91" // rgb: 255, 255, 140
boozepwr = 60
quality = DRINK_GOOD
- taste_description = "a bad joke"
+ taste_description = "bananas and cream"
glass_icon_state = "bananahonkglass"
- glass_name = "Banana Honk"
- glass_desc = "A drink from Clown Heaven."
+ glass_name = "Creamtruck"
+ glass_desc = "A distinctly non-kid friendly equivalent to the ice cream truck."
/datum/reagent/consumable/ethanol/bananahonk/on_mob_life(mob/living/carbon/M)
if((ishuman(M) && M.job == "Clown") || ismonkey(M))
@@ -1180,16 +1163,16 @@ All effects don't start immediately, but rather get worse over time; the rate is
return ..() || .
/datum/reagent/consumable/ethanol/silencer
- name = "Silencer"
- description = "A drink from Mime Heaven."
+ name = "Choker"
+ description = "It takes a moment of quiet to really appreciate some drinks - this one doesn't give you the illusion of choice."
nutriment_factor = 1 * REAGENTS_METABOLISM
color = "#664300" // rgb: 102, 67, 0
- boozepwr = 59 //Proof that clowns are better than mimes right here
+ boozepwr = 59
quality = DRINK_GOOD
- taste_description = "a pencil eraser"
+ taste_description = "peace and quiet"
glass_icon_state = "silencerglass"
- glass_name = "Silencer"
- glass_desc = "A drink from Mime Heaven."
+ glass_name = "Choker"
+ glass_desc = "It takes a moment of quiet to really appreciate some drinks - this one doesn't give you the illusion of choice."
/datum/reagent/consumable/ethanol/silencer/on_mob_life(mob/living/carbon/M)
if(ishuman(M) && M.mind?.miming)
@@ -1200,18 +1183,18 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/drunkenblumpkin
name = "Drunken Blumpkin"
- description = "A weird mix of whiskey and blumpkin juice."
+ description = "A weird mix of whiskey and... chlorine-pumpkin juice?"
color = "#1EA0FF" // rgb: 102, 67, 0
boozepwr = 50
quality = DRINK_VERYGOOD
taste_description = "molasses and a mouthful of pool water"
glass_icon_state = "drunkenblumpkin"
glass_name = "Drunken Blumpkin"
- glass_desc = "A drink for the drunks."
+ glass_desc = "A drink for the confused hydropon worker."
/datum/reagent/consumable/ethanol/whiskey_sour //Requested since we had whiskey cola and soda but not sour.
name = "Whiskey Sour"
- description = "Lemon juice/whiskey/sugar mixture. Moderate alcohol content."
+ description = "A mix of lemon juice, whiskey, and sugar."
color = rgb(255, 201, 49)
boozepwr = 35
quality = DRINK_GOOD
@@ -1222,35 +1205,16 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/hcider
name = "Hard Cider"
- description = "Apple juice, for adults."
+ description = "The alcoholic sibling to apple cider."
color = "#CD6839"
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 25
taste_description = "the season that falls between summer and winter"
glass_icon_state = "whiskeyglass"
glass_name = "hard cider"
- glass_desc = "Tastes like autumn... no wait, fall!"
+ glass_desc = "Sharper tasting, alcoholic apple cider."
shot_glass_icon_state = "shotglassbrown"
-
-/datum/reagent/consumable/ethanol/fetching_fizz //A reference to one of my favorite games of all time. Pulls nearby ores to the imbiber!
- name = "Fetching Fizz"
- description = "Whiskey sour/iron/uranium mixture resulting in a highly magnetic slurry. Mild alcohol content." //Requires no alcohol to make but has alcohol anyway because ~magic~
- color = rgb(255, 91, 15)
- boozepwr = 10
- quality = DRINK_VERYGOOD
- metabolization_rate = 0.1 * REAGENTS_METABOLISM
- taste_description = "charged metal" // the same as teslium, honk honk.
- glass_icon_state = "fetching_fizz"
- glass_name = "Fetching Fizz"
- glass_desc = "Induces magnetism in the imbiber. Started as a barroom prank but evolved to become popular with miners and scrappers. Metallic aftertaste."
-
-
-/datum/reagent/consumable/ethanol/fetching_fizz/on_mob_life(mob/living/carbon/M)
- for(var/obj/item/stack/ore/O in orange(3, M))
- step_towards(O, get_turf(M))
- return ..()
-
//Another reference. Heals those in critical condition extremely quickly.
/datum/reagent/consumable/ethanol/hearty_punch
name = "Hearty Punch"
@@ -1262,7 +1226,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "bravado in the face of disaster"
glass_icon_state = "hearty_punch"
glass_name = "Hearty Punch"
- glass_desc = "Aromatic beverage served piping hot. According to folk tales it can almost wake the dead."
+ glass_desc = "An aromatic beverage, served piping hot. According to folktales, it can almost wake the dead."
/datum/reagent/consumable/ethanol/hearty_punch/on_mob_life(mob/living/carbon/M)
if(M.health <= 0)
@@ -1295,7 +1259,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "da bomb"
glass_icon_state = "atomicbombglass"
glass_name = "Atomic Bomb"
- glass_desc = "Nanotrasen cannot take legal responsibility for your actions after imbibing."
+ glass_desc = "Devastating to you and everyone around you, especially if you get drunk enough from it."
/datum/reagent/consumable/ethanol/atomicbomb/on_mob_life(mob/living/carbon/M)
M.set_drugginess(50)
@@ -1353,7 +1317,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
metabolization_rate = 1 * REAGENTS_METABOLISM
glass_icon_state = "neurotoxinglass"
glass_name = "Neurotoxin"
- glass_desc = "A drink that is guaranteed to knock you silly."
+ glass_desc = "The story goes that this drink was made on a bet between Cybersun chemists, debating if a drink could be used to put down a suspected Nanotrasen spy. While morphine wasn't supposed to be used, it put them down all the same."
/datum/reagent/consumable/ethanol/neurotoxin/proc/pickt()
return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG))
@@ -1365,7 +1329,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
if(prob(20))
M.adjustStaminaLoss(10)
M.drop_all_held_items()
- to_chat(M, "You cant feel your hands!")
+ to_chat(M, "You can't feel your hands!")
if(current_cycle > 5)
if(prob(20))
var/t = pickt()
@@ -1390,17 +1354,17 @@ All effects don't start immediately, but rather get worse over time; the rate is
..()
/datum/reagent/consumable/ethanol/hippies_delight
- name = "Hippie's Delight"
- description = "You just don't get it maaaan."
+ name = "Between the Mandibles"
+ description = "Mushroom-supplied hallucinogens and strong alcohol."
color = "#664300" // rgb: 102, 67, 0
nutriment_factor = 0
boozepwr = 0 //custom drunk effect
quality = DRINK_FANTASTIC
metabolization_rate = 0.2 * REAGENTS_METABOLISM
- taste_description = "giving peace a chance"
+ taste_description = "two finger-sized bites on your tongue"
glass_icon_state = "hippiesdelightglass"
- glass_name = "Hippie's Delight"
- glass_desc = "A drink enjoyed by people during the 1960's."
+ glass_name = "Between the Mandibles"
+ glass_desc = "Named after a request from a clueless spacer who asked for Rachnid venom to be mixed in a house special. While Rachnids don't have venom glands, this'll have you reeling all the same."
/datum/reagent/consumable/ethanol/hippies_delight/on_mob_life(mob/living/carbon/M)
if (!M.slurring)
@@ -1436,7 +1400,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/eggnog
name = "Eggnog"
- description = "For enjoying the most wonderful time of the year."
+ description = "For enjoying the Winter Solstice."
color = "#fcfdc6" // rgb: 252, 253, 198
nutriment_factor = 2 * REAGENTS_METABOLISM
boozepwr = 1
@@ -1444,34 +1408,17 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "custard and alcohol"
glass_icon_state = "glass_yellow"
glass_name = "eggnog"
- glass_desc = "For enjoying the most wonderful time of the year."
-
-
-/datum/reagent/consumable/ethanol/narsour
- name = "Nar'Sour"
- description = "Side effects include self-mutilation and hoarding plasteel."
- color = RUNE_COLOR_DARKRED
- boozepwr = 10
- quality = DRINK_FANTASTIC
- taste_description = "bloody"
- glass_icon_state = "narsour"
- glass_name = "Nar'Sour"
- glass_desc = "A new hit cocktail inspired by THE ARM Breweries will have you shouting Fuu ma'jin in no time!"
-
-/datum/reagent/consumable/ethanol/narsour/on_mob_life(mob/living/carbon/M)
- M.cultslurring = min(M.cultslurring + 3, 3)
- M.stuttering = min(M.stuttering + 3, 3)
- ..()
+ glass_desc = "For enjoying the Winter Solstice."
/datum/reagent/consumable/ethanol/triple_sec
name = "Triple Sec"
description = "A sweet and vibrant orange liqueur."
color = "#ffcc66"
boozepwr = 30
- taste_description = "a warm flowery orange taste which recalls the ocean air and summer wind of the caribbean"
+ taste_description = "a warm flowery orange taste which recalls the ocean air and summer wind of distant shores"
glass_icon_state = "glass_orange"
glass_name = "Triple Sec"
- glass_desc = "A glass of straight Triple Sec."
+ glass_desc = "A glass of straight triple sec. Citrusy and warm."
/datum/reagent/consumable/ethanol/creme_de_menthe
name = "Creme de Menthe"
@@ -1481,17 +1428,17 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "a minty, cool, and invigorating splash of cold streamwater"
glass_icon_state = "glass_green"
glass_name = "Creme de Menthe"
- glass_desc = "You can almost feel the first breath of spring just looking at it."
+ glass_desc = "Bright green and minty - enough to tell you what it's going to taste like."
/datum/reagent/consumable/ethanol/creme_de_cacao
name = "Creme de Cacao"
- description = "A chocolatey liqueur excellent for adding dessert notes to beverages and bribing sororities."
+ description = "A chocolatey liqueur excellent for adding dessert notes to beverages."
color = "#996633"
boozepwr = 20
taste_description = "a slick and aromatic hint of chocolates swirling in a bite of alcohol"
glass_icon_state = "glass_brown"
glass_name = "Creme de Cacao"
- glass_desc = "A million hazing lawsuits and alcohol poisonings have started with this humble ingredient."
+ glass_desc = "Creme de Cacao - chocolate-wine, essentially. Not milk chocolate, so expect some bite."
/datum/reagent/consumable/ethanol/creme_de_coconut
name = "Creme de Coconut"
@@ -1501,7 +1448,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "a sweet milky flavor with notes of toasted sugar"
glass_icon_state = "glass_white"
glass_name = "Creme de Coconut"
- glass_desc = "An unintimidating glass of coconut liqueur."
+ glass_desc = "A white glass of coconut liqueur."
/datum/reagent/consumable/ethanol/quadruple_sec
name = "Quadruple Sec"
@@ -1509,10 +1456,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
color = "#cc0000"
boozepwr = 35
quality = DRINK_GOOD
- taste_description = "an invigorating bitter freshness which suffuses your being; no enemy of the corporation will go unrobusted this day"
+ taste_description = "an invigorating bitter freshness which suffuses your being; you can take on anyone who messes with your vessel"
glass_icon_state = "quadruple_sec"
glass_name = "Quadruple Sec"
- glass_desc = "An intimidating and lawful beverage dares you to violate the law and make its day. Still can't drink it on duty, though."
+ glass_desc = "A glass of Quadruple Sec. Popularized for being a mixed drink of choice across multiple independent security agencies, and notably among Nanotrasen's internal security culture. It's not recommended to drink while manning a vessel, though!"
/datum/reagent/consumable/ethanol/quadruple_sec/on_mob_life(mob/living/carbon/M)
//Securidrink in line with the Screwdriver for engineers or Nothing for mimes
@@ -1524,14 +1471,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/quintuple_sec
name = "Quintuple Sec"
- description = "Law, Order, Alcohol, and Police Brutality distilled into one single elixir of JUSTICE."
+ description = "Law, order and alcohol distilled into one single elixir."
color = "#ff3300"
boozepwr = 55
quality = DRINK_FANTASTIC
- taste_description = "THE LAW"
+ taste_description = "drinking on duty"
glass_icon_state = "quintuple_sec"
glass_name = "Quintuple Sec"
- glass_desc = "Now you are become law, destroyer of clowns."
+ glass_desc = "The logical endpoint of the Quadruple Sec. Often had in the hands of senior security staff, though you really should not be drinking this while on-duty."
/datum/reagent/consumable/ethanol/quintuple_sec/on_mob_life(mob/living/carbon/M)
//Securidrink in line with the Screwdriver for engineers or Nothing for mimes but STRONG..
@@ -1546,14 +1493,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/grasshopper
name = "Grasshopper"
- description = "A fresh and sweet dessert shooter. Difficult to look manly while drinking this."
+ description = "A fresh and sweet dessert shooter."
color = "#00ff00"
boozepwr = 25
quality = DRINK_GOOD
taste_description = "chocolate and mint dancing around your mouth"
glass_icon_state = "grasshopper"
glass_name = "Grasshopper"
- glass_desc = "You weren't aware edible beverages could be that green."
+ glass_desc = "Named after a particularly green insect. Theoretically, there's always adding vodka to this and making it a Flying Grasshopper..."
/datum/reagent/consumable/ethanol/stinger
name = "Stinger"
@@ -1564,7 +1511,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "a slap on the face in the best possible way"
glass_icon_state = "stinger"
glass_name = "Stinger"
- glass_desc = "You wonder what would happen if you pointed this at a heat source..."
+ glass_desc = "A brandy-and-menthe mixed drink to end the day with. While often found in the hands of the upper class, there's nothing wrong with feeling a little fancy."
/datum/reagent/consumable/ethanol/bastion_bourbon
name = "Bastion Bourbon"
@@ -1664,13 +1611,13 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/sake
name = "Sake"
- description = "A sweet rice wine of questionable legality and extreme potency."
+ description = "A sweet rice wine."
color = "#DDDDDD"
boozepwr = 70
taste_description = "sweet rice wine"
glass_icon_state = "sakecup"
glass_name = "cup of sake"
- glass_desc = "A traditional cup of sake."
+ glass_desc = "A cup of sake. Capable of being served hot, cold, or at room temperature, and served in a traditionally-sized little cup."
/datum/reagent/consumable/ethanol/peppermint_patty
name = "Peppermint Patty"
@@ -1681,7 +1628,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
quality = DRINK_GOOD
glass_icon_state = "peppermint_patty"
glass_name = "Peppermint Patty"
- glass_desc = "A boozy minty hot cocoa that warms your belly on a cold night."
+ glass_desc = "A boozy, minty hot cocoa that warms your belly on a cold night."
/datum/reagent/consumable/ethanol/peppermint_patty/on_mob_life(mob/living/carbon/M)
M.apply_status_effect(/datum/status_effect/throat_soothed)
@@ -1689,15 +1636,15 @@ All effects don't start immediately, but rather get worse over time; the rate is
..()
/datum/reagent/consumable/ethanol/alexander
- name = "Alexander"
- description = "Named after a Greek hero, this mix is said to embolden a user's shield as if they were in a phalanx."
+ name = "Ash-Shield"
+ description = "While not a traditional trickwine by any means, this mix is said to embolden a user's shield under certain circumstance."
color = "#F5E9D3"
boozepwr = 50
quality = DRINK_GOOD
taste_description = "bitter, creamy cacao"
glass_icon_state = "alexander"
- glass_name = "Alexander"
- glass_desc = "A creamy, indulgent delight that is stronger than it seems."
+ glass_name = "Ash-Shield"
+ glass_desc = "While not a traditional trickwine by any means (and considered in poor taste in mixing), this drink is said to embolden the shield in the imbiber's hand. Just don't let it engender passivity."
var/obj/item/shield/mighty_shield
/datum/reagent/consumable/ethanol/alexander/on_mob_metabolize(mob/living/L)
@@ -1721,37 +1668,37 @@ All effects don't start immediately, but rather get worse over time; the rate is
..()
/datum/reagent/consumable/ethanol/amaretto_alexander
- name = "Amaretto Alexander"
- description = "A weaker version of the Alexander, what it lacks in strength it makes up for in flavor."
+ name = "Happy Huntsman"
+ description = "A cousin of the Ash-Shield, what it lacks in strength (and mysterious power), it makes up for in flavor."
color = "#DBD5AE"
boozepwr = 35
quality = DRINK_VERYGOOD
taste_description = "sweet, creamy cacao"
glass_icon_state = "alexanderam"
- glass_name = "Amaretto Alexander"
- glass_desc = "A creamy, indulgent delight that is in fact as gentle as it seems."
+ glass_name = "Happy Huntsman"
+ glass_desc = "A gentle, creamy drink, enjoyed on rare occasions by the Saint Roumain's followers."
/datum/reagent/consumable/ethanol/sidecar
- name = "Sidecar"
- description = "The one ride you'll gladly give up the wheel for."
+ name = "Bridge Bunny"
+ description = "You're happy to not pilot the ship after having one of these."
color = "#FFC55B"
boozepwr = 45
quality = DRINK_GOOD
taste_description = "delicious freedom"
glass_icon_state = "sidecar"
- glass_name = "Sidecar"
- glass_desc = "The one ride you'll gladly give up the wheel for."
+ glass_name = "Bridge Bunny"
+ glass_desc = "You're happy to not pilot the ship after having one of these."
/datum/reagent/consumable/ethanol/between_the_sheets
name = "Between the Sheets"
- description = "A provocatively named classic. Funny enough, doctors recommend drinking it before taking a nap."
+ description = "A provocatively named classic."
color = "#F4C35A"
boozepwr = 55
quality = DRINK_GOOD
- taste_description = "seduction"
+ taste_description = "rum, lemons, and mild embarrassment"
glass_icon_state = "between_the_sheets"
glass_name = "Between the Sheets"
- glass_desc = "The only drink that comes with a label reminding you of Nanotrasen's zero-tolerance promiscuity policy."
+ glass_desc = "Also known as The Maiden's Prayer, if you're not willing to say the original name aloud."
/datum/reagent/consumable/ethanol/between_the_sheets/on_mob_life(mob/living/L)
..()
@@ -1767,15 +1714,15 @@ All effects don't start immediately, but rather get worse over time; the rate is
L.adjustFireLoss(-0.2)
/datum/reagent/consumable/ethanol/kamikaze
- name = "Kamikaze"
- description = "Divinely windy."
+ name = "Mothball"
+ description = "Vodka, triple sec, and lime juice. Moth dust not usually included."
color = "#EEF191"
boozepwr = 60
quality = DRINK_GOOD
- taste_description = "divine windiness"
+ taste_description = "fluttery sour-sweetness"
glass_icon_state = "kamikaze"
- glass_name = "Kamikaze"
- glass_desc = "Divinely windy."
+ glass_name = "Mothball"
+ glass_desc = "Made in an attempt to commemorate the supposed original place mothpeople were created in, though it was since disproven. While moth dust could be used as a garnish, don't go asking for it unless you are one."
/datum/reagent/consumable/ethanol/mojito
name = "Mojito"
@@ -1789,15 +1736,15 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "A drink that looks as refreshing as it tastes."
/datum/reagent/consumable/ethanol/moscow_mule
- name = "Moscow Mule"
- description = "A chilly drink that reminds you of the Derelict."
+ name = "Gorlex Gator"
+ description = "A chilly drink made in remembrance of Gorlex IV."
color = "#EEF1AA"
boozepwr = 30
quality = DRINK_GOOD
taste_description = "refreshing spiciness"
glass_icon_state = "moscow_mule"
- glass_name = "Moscow Mule"
- glass_desc = "A chilly drink that reminds you of the Derelict."
+ glass_name = "Gorlex Gator"
+ glass_desc = "A chilly drink made in remembrance of Gorlex IV. It's not a wise idea to go ordering this when the PGF are in town, though."
/datum/reagent/consumable/ethanol/fernet
name = "Fernet"
@@ -1806,7 +1753,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
boozepwr = 80
taste_description = "utter bitterness"
glass_name = "glass of fernet"
- glass_desc = "A glass of pure Fernet. Only an absolute madman would drink this alone." //Hi Kevum
+ glass_desc = "A glass of pure Fernet. Intensely bitter and reserved to being a digestive more than something to be enjoyed." //Hi Kevum
/datum/reagent/consumable/ethanol/fernet/on_mob_life(mob/living/carbon/M)
if(M.nutrition <= NUTRITION_LEVEL_STARVING)
@@ -1816,15 +1763,15 @@ All effects don't start immediately, but rather get worse over time; the rate is
return ..()
/datum/reagent/consumable/ethanol/fernet_cola
- name = "Fernet Cola"
+ name = "Weldline"
description = "A very popular and bittersweet digestif, ideal after a heavy meal. Best served on a sawed-off cola bottle as per tradition."
color = "#390600" // rgb: 57, 6,
boozepwr = 25
quality = DRINK_NICE
taste_description = "sweet relief"
glass_icon_state = "godlyblend"
- glass_name = "glass of fernet cola"
- glass_desc = "A sawed-off cola bottle filled with Fernet Cola. Nothing better after eating like a lardass."
+ glass_name = "glass of weldline"
+ glass_desc = "A shorn-off cola bottle filled with fernet and cola soft drink. A tradition among cargo workers and hull technicians is to use a welder to cut the cola can in half."
/datum/reagent/consumable/ethanol/fernet_cola/on_mob_life(mob/living/carbon/M)
if(M.nutrition <= NUTRITION_LEVEL_STARVING)
@@ -1834,7 +1781,6 @@ All effects don't start immediately, but rather get worse over time; the rate is
return ..()
/datum/reagent/consumable/ethanol/fanciulli
-
name = "Fanciulli"
description = "What if the Manhattan cocktail ACTUALLY used a bitter herb liquour? Helps you sober up." //also causes a bit of stamina damage to symbolize the afterdrink lazyness
color = "#CA933F" // rgb: 202, 147, 63
@@ -1843,7 +1789,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "a sweet sobering mix"
glass_icon_state = "fanciulli"
glass_name = "glass of fanciulli"
- glass_desc = "A glass of Fanciulli. It's just Manhattan with Fernet."
+ glass_desc = "A glass of Fanciulli: a Manhattan with fernet mixed in. Bitter enough to knock some sense into your drunk self."
/datum/reagent/consumable/ethanol/fanciulli/on_mob_life(mob/living/carbon/M)
M.adjust_nutrition(-5)
@@ -1858,15 +1804,15 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/branca_menta
- name = "Branca Menta"
+ name = "Mirage"
description = "A refreshing mixture of bitter Fernet with mint creme liquour."
color = "#4B5746" // rgb: 75, 87, 70
boozepwr = 35
quality = DRINK_GOOD
taste_description = "a bitter freshness"
glass_icon_state= "minted_fernet"
- glass_name = "glass of branca menta"
- glass_desc = "A glass of Branca Menta, perfect for those lazy and hot Sunday summer afternoons." //Get lazy literally by drinking this
+ glass_name = "glass of Mirage"
+ glass_desc = "A glass of fernet and mint creme liquor, enjoyed on the warmer days on Teceti." //Get lazy literally by drinking this
/datum/reagent/consumable/ethanol/branca_menta/on_mob_life(mob/living/carbon/M)
@@ -2014,7 +1960,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "auspicious occasions and bad decisions"
glass_icon_state = "champagne_glass"
glass_name = "Champagne"
- glass_desc = "The flute clearly displays the slowly rising bubbles."
+ glass_desc = "A sparkling wine, traditionally served in a flute that clearly displays the slowly rising bubbles."
/datum/reagent/consumable/ethanol/wizz_fizz
@@ -2023,7 +1969,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
color = "#4235d0" //Just pretend that the triple-sec was blue curacao.
boozepwr = 50
quality = DRINK_GOOD
- taste_description = "friendship! It is magic, after all"
+ taste_description = "whimsy and carbonation"
glass_icon_state = "wizz_fizz"
glass_name = "Wizz Fizz"
glass_desc = "The glass bubbles and froths with an almost magical intensity."
@@ -2037,48 +1983,36 @@ All effects don't start immediately, but rather get worse over time; the rate is
return ..()
/datum/reagent/consumable/ethanol/bug_spray
- name = "Bug Spray"
+ name = "Stunball"
description = "A harsh, acrid, bitter drink, for those who need something to brace themselves."
color = "#33ff33"
boozepwr = 50
quality = DRINK_GOOD
- taste_description = "the pain of ten thousand slain mosquitos"
+ taste_description = "the distinct sense of drinking diluted poison"
glass_icon_state = "bug_spray"
- glass_name = "Bug Spray"
- glass_desc = "Your eyes begin to water as the sting of alcohol reaches them."
-
-/datum/reagent/consumable/ethanol/bug_spray/on_mob_life(mob/living/carbon/M)
-//Bugs should not drink Bug spray.
- if(ismoth(M) || isflyperson(M) || isspiderperson(M))
- M.adjustToxLoss(1,0)
- return ..()
-/datum/reagent/consumable/ethanol/bug_spray/on_mob_metabolize(mob/living/carbon/M)
-
- if(ismoth(M) || isflyperson(M))
- M.emote("scream")
- return ..()
-
+ glass_name = "Stunball"
+ glass_desc = "Made in protest of the Mothball mixed drink being recognized by the Interstellar Bartenders Association, who refute the idea of a singular point of origin. The taste is as spiteful as its history."
/datum/reagent/consumable/ethanol/applejack
name = "Applejack"
- description = "The perfect beverage for when you feel the need to horse around."
+ description = "The officially sponsored drink by the National Association for Anti-Gravity Automobile Dragracing (NAAGAD)."
color = "#ff6633"
boozepwr = 20
- taste_description = "an honest day's work at the orchard"
+ taste_description = "resisting gravity through brandy"
glass_icon_state = "applejack_glass"
glass_name = "Applejack"
- glass_desc = "You feel like you could drink this all neight."
+ glass_desc = "You lament you can't watch any Agrav Races while out here."
/datum/reagent/consumable/ethanol/jack_rose
- name = "Jack Rose"
- description = "A light cocktail perfect for sipping with a slice of pie."
+ name = "Jackalope"
+ description = "A light cocktail named after a famous anti-gravity racer."
color = "#ff6633"
boozepwr = 15
quality = DRINK_NICE
taste_description = "a sweet and sour slice of apple"
glass_icon_state = "jack_rose"
- glass_name = "Jack Rose"
- glass_desc = "Enough of these, and you really will start to suppose your toeses are roses."
+ glass_name = "Jackalope"
+ glass_desc = "Enough of these, and you might feel like you're floating. Just don't think you can pilot!"
/datum/reagent/consumable/ethanol/turbo
name = "Turbo"
@@ -2089,11 +2023,11 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "the outlaw spirit"
glass_icon_state = "turbo"
glass_name = "Turbo"
- glass_desc = "A turbulent cocktail for outlaw hoverbikers."
+ glass_desc = "A turbulent cocktail for outlaw hoverbikers. Not officially recognized by National Association for Anti-Gravity Automobile Dragracing (NAAGAD)... but they're sticks in the mud, anyway!"
/datum/reagent/consumable/ethanol/turbo/on_mob_life(mob/living/carbon/M)
if(prob(4))
- to_chat(M, "[pick("You feel disregard for the rule of law.", "You feel pumped!", "Your head is pounding.", "Your thoughts are racing..")]")
+ to_chat(M, "[pick("You feel disregard for the rule of law.", "You feel pumped!", "Your head is pounding.", "Your thoughts are racing...")]")
M.adjustStaminaLoss(-M.drunkenness * 0.25)
return ..()
@@ -2106,7 +2040,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "simpler times"
glass_icon_state = "old_timer"
glass_name = "Old Timer"
- glass_desc = "WARNING! May cause premature aging!"
+ glass_desc = "You might not be the target audience of this drink if you're still out in the Frontier, though."
/datum/reagent/consumable/ethanol/old_timer/on_mob_life(mob/living/carbon/M)
if(prob(20))
@@ -2119,9 +2053,6 @@ All effects don't start immediately, but rather get worse over time; the rate is
N.update_hair()
if(N.age > N.dna.species.species_age_max * 0.8)
N.become_nearsighted(type)
- if(N.gender == MALE)
- N.facial_hairstyle = "Beard (Very Long)"
- N.update_hair()
if(N.age > N.dna.species.species_age_max * 1.2) //Best not let people get older than this or i might incur G-ds wrath
M.visible_message("[M] becomes older than any man should be.. and crumbles into dust!")
@@ -2135,49 +2066,42 @@ All effects don't start immediately, but rather get worse over time; the rate is
color = "#ffe65b"
boozepwr = 60
quality = DRINK_GOOD
- taste_description = "artifical fruityness"
+ taste_description = "artifical fruitiness"
glass_icon_state = "rubberneck"
glass_name = "Rubberneck"
- glass_desc = "A popular drink amongst those adhering to an all synthetic diet."
+ glass_desc = "A popular drink amongst those adhering to an all-synthetic diet, popularized briefly as a counterculture movement."
/datum/reagent/consumable/ethanol/duplex
- name = "Duplex"
+ name = "North-South"
description = "An inseparable combination of two fruity drinks."
color = "#50e5cf"
boozepwr = 25
quality = DRINK_NICE
taste_description = "green apples and blue raspberries"
glass_icon_state = "duplex"
- glass_name = "Duplex"
- glass_desc = "To imbibe one component separately from the other is consider a great faux pas."
+ glass_name = "North-South"
+ glass_desc = "A fruity drink made, apparently, to represent North and South Teceti. You're supposed to hold it in a way that both vials pour together - one on top of the other."
/datum/reagent/consumable/ethanol/trappist
- name = "Trappist Beer"
- description = "A strong dark ale brewed by space-monks."
+ name = "Trapper's Beer"
+ description = "A strong dark ale brewed by the Saint Roumain Militia."
color = "#390c00"
boozepwr = 40
quality = DRINK_VERYGOOD
- taste_description = "dried plums and malt"
+ taste_description = "dried plums, ash, and malt"
glass_icon_state = "trappistglass"
- glass_name = "Trappist Beer"
- glass_desc = "boozy Catholicism in a glass."
-
-/datum/reagent/consumable/ethanol/trappist/on_mob_life(mob/living/carbon/M)
- if(M.mind.holy_role)
- M.adjustFireLoss(-2.5, 0)
- M.jitteriness = max(0, M.jitteriness-1)
- M.stuttering = max(0, M.stuttering-1)
- return ..()
+ glass_name = "Trapper's Beer"
+ glass_desc = "The Ashen Huntsman's blessings, in a glass. Despite proclaiming an ascetic lifestyle, it's okay to have a little fun once in a while."
/datum/reagent/consumable/ethanol/blazaam
- name = "Blazaam"
- description = "A strange drink that few people seem to remember existing. Doubles as a Berenstain remover."
+ name = "Hyperspace Highball"
+ description = "A strange drink mixed with bluespace crystal flakes, which is already extremely expensive on its own merit."
boozepwr = 70
quality = DRINK_FANTASTIC
taste_description = "alternate realities"
glass_icon_state = "blazaamglass"
- glass_name = "Blazaam"
- glass_desc = "The glass seems to be sliding between realities. Doubles as a Berenstain remover."
+ glass_name = "Hyperspace Highball"
+ glass_desc = "The glass is seemingly reacting with the bluespace flakes... maybe making this was a poor decision?"
var/stored_teleports = 0
/datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/M)
@@ -2192,15 +2116,15 @@ All effects don't start immediately, but rather get worse over time; the rate is
return ..()
/datum/reagent/consumable/ethanol/mauna_loa
- name = "Mauna Loa"
+ name = "Inner Fire"
description = "Extremely hot; not for the faint of heart!"
boozepwr = 40
color = "#fe8308" // 254, 131, 8
quality = DRINK_FANTASTIC
taste_description = "fiery, with an aftertaste of burnt flesh"
glass_icon_state = "mauna_loa"
- glass_name = "Mauna Loa"
- glass_desc = "Lavaland in a drink... mug... volcano... thing."
+ glass_name = "Inner Fire"
+ glass_desc = "Not at all made by the Saint Roumain, this drink still bases itself as a test of will used by the hunters to test their endurance to intense heat... and alcohol."
/datum/reagent/consumable/ethanol/mauna_loa/on_mob_life(mob/living/carbon/M)
// Heats the user up while the reagent is in the body. Occasionally makes you burst into flames.
@@ -2219,7 +2143,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "sugary tartness"
glass_icon_state = "painkiller"
glass_name = "Painkiller"
- glass_desc = "A combination of tropical juices and rum. Surely this will make you feel better."
+ glass_desc = "A combination of tropical juices and rum. Surely, this will make you feel better."
/datum/reagent/consumable/ethanol/pina_colada
name = "Pina Colada"
@@ -2236,12 +2160,12 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/pruno // pruno mix is in drink_reagents
name = "pruno"
color = "#E78108"
- description = "Fermented prison wine made from fruit, sugar, and despair. Security loves to confiscate this, which is the only kind thing Security has ever done."
+ description = "Fermented prison wine made from fruit, sugar, and despair."
boozepwr = 85
- taste_description = "your tastebuds being individually shanked"
+ taste_description = "your tastebuds crying out"
glass_icon_state = "glass_orange"
glass_name = "glass of pruno"
- glass_desc = "Fermented prison wine made from fruit, sugar, and despair. Security loves to confiscate this, which is the only kind thing Security has ever done."
+ glass_desc = "Fermented prison wine made from fruit, sugar, and despair."
/datum/reagent/consumable/ethanol/pruno/on_mob_life(mob/living/carbon/M)
M.adjust_disgust(5)
@@ -2256,7 +2180,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "sweetness followed by a soft sourness and warmth"
glass_icon_state = "gingeramaretto"
glass_name = "Ginger Amaretto"
- glass_desc = "The sprig of rosemary adds a nice aroma to the drink, and isn't just to be pretentious afterall!"
+ glass_desc = "Technically intended to come with a sprig of rosemary... but where are you going to get your hands on that?"
/datum/reagent/consumable/ethanol/godfather
name = "Godfather"
@@ -2267,28 +2191,28 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "a delightful softened punch"
glass_icon_state = "godfather"
glass_name = "Godfather"
- glass_desc = "A classic from old Italy and enjoyed by gangsters, pray the orange peel doesnt end up in your mouth."
+ glass_desc = "Technically still enjoyed by members of the Intersolar Mafia, though the homage is much older. Pray the orange peel doesn't end up in your mouth."
/datum/reagent/consumable/ethanol/godmother
name = "Godmother"
- description = "A twist on a classic, liked more by mature women."
+ description = "A twist on a classic, made as a sibling drink to the Godfather."
boozepwr = 50
color = "#E68F00"
quality = DRINK_GOOD
taste_description = "sweetness and a zesty twist"
glass_icon_state = "godmother"
glass_name = "Godmother"
- glass_desc = "A lovely fresh smelling cocktail, a true Sicilian delight."
+ glass_desc = "Just as enjoyed (and related to) the Intersolar Mafia. You're technically supposed to drink this alongside someone else having a Godfather."
/datum/reagent/consumable/ethanol/mudders_milk
- name = "mudder's milk"
+ name = "Miner's Milk"
color = "#dfc794"
- description = "All the protein, vitamins and carbs of your grandma's best turkey dinner, plus 15 percent alcohol."
+ description = "All the protein, vitamins and carbs of two full ration packs, plus 15% alcohol."
boozepwr = 15
- taste_description = "thick, nutty milk with a boozy kick"
+ taste_description = "thick, nut-flavored milk with a boozy kick"
glass_icon_state = "muddersmilk"
- glass_name = "Mudder's Milk"
- glass_desc = "All the protein, vitamins and carbs of your grandma's best turkey dinner, plus 15 percent alcohol."
+ glass_name = "Miner's Milk"
+ glass_desc = "All the protein, vitamins and carbs of two full ration packs, plus 15% alcohol. Created by Nanotrasen's Mining and Exploration League, and often still enjoyed in the New Gorlex Republic."
/datum/reagent/consumable/ethanol/mudders_milk/on_mob_life(mob/living/carbon/M)
if(prob(1))
@@ -2338,15 +2262,15 @@ All effects don't start immediately, but rather get worse over time; the rate is
..()
/datum/reagent/consumable/ethanol/freezer_burn
- name = "Freezer Burn"
+ name = "Hullbreach"
description = "Fire and ice combine in your mouth! Drinking slowly recommended."
boozepwr = 40
color = "#ba3100"
quality = DRINK_FANTASTIC
- taste_description = "fire and ice"
+ taste_description = "frigid, hot stings"
glass_icon_state = "freezer_burn"
- glass_name = "Freezer Burn"
- glass_desc = "Fire and ice combine in your mouth! Drinking slowly recommended."
+ glass_name = "Hullbreach"
+ glass_desc = "Fire and ice combine in your mouth, like being pulled out into space."
/datum/reagent/consumable/ethanol/freezer_burn/on_mob_life(mob/living/carbon/M)
M.adjustFireLoss(-0.2, 0)
@@ -2374,14 +2298,14 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/darkest_chocolate
name = "Darkest Chocolate"
- description = "Darkness within darkness awaits you, spaceman!"
+ description = "Darkness within darkness awaits you, spacer!"
boozepwr = 40
color = "#240c0c"
quality = DRINK_FANTASTIC
taste_description = "bitter, chocolatey darkness with a note of cream"
glass_icon_state = "darkest_chocolate"
glass_name = "Darkest Chocolate"
- glass_desc = "Darkness within darkness awaits you, spaceman!"
+ glass_desc = "Darkness within darkness awaits you, spacer!"
var/obj/effect/light_holder
/datum/reagent/consumable/ethanol/darkest_chocolate/on_mob_metabolize(mob/living/M)
@@ -2400,28 +2324,6 @@ All effects don't start immediately, but rather get worse over time; the rate is
to_chat(M, "The darkness subsides.")
QDEL_NULL(light_holder)
-/datum/reagent/consumable/ethanol/archmagus_brew
- name = "Archmagus' Brew"
- description = "Said to have been requested by a great Archmagus, hence the name. Tastes like tough love."
- boozepwr = 40
- color = "#c75295"
- quality = DRINK_FANTASTIC
- taste_description = "tough love"
- glass_icon_state = "archmagus_brew"
- glass_name = "Archmagus' Brew"
- glass_desc = "Said to have been requested by a great Archmagus, hence the name. Tastes like tough love."
-
-/datum/reagent/consumable/ethanol/archmagus_brew/on_mob_life(mob/living/carbon/human/M)
- if(M.mind && M.mind.spell_list.len != 0)
- var/spell_improved = FALSE
- for(var/obj/effect/proc_holder/spell/S in M.mind.spell_list)
- if(S.clothes_req)
- S.clothes_req = 0
- spell_improved = TRUE
- if(spell_improved)
- to_chat(M, "You suddenly feel like you never needed those garish robes in the first place...")
- return ..()
-
/datum/reagent/consumable/ethanol/out_of_lime
name = "Out of Lime"
description = "A spin on the classic. Artists and street fighters swear by this stuff."
@@ -2440,22 +2342,6 @@ All effects don't start immediately, but rather get worse over time; the rate is
consumer.facial_hair_color = pick("0ad","a0f","f73","d14","0b5","fc2","084","05e","d22","fa0")
consumer.update_hair()
-/datum/reagent/consumable/ethanol/cogchamp
- name = "CogChamp"
- description = "Now you can fill yourself with the power of Ratvar!"
- color = rgb(255, 201, 49)
- boozepwr = 10
- quality = DRINK_FANTASTIC
- taste_description = "a brass taste with a hint of oil"
- glass_icon_state = "cogchamp"
- glass_name = "CogChamp"
- glass_desc = "Not one of Ratvar's Four Generals could withstand this! Qevax Jryy!"
-
-/datum/reagent/consumable/ethanol/cogchamp/on_mob_life(mob/living/carbon/M)
- M.clockcultslurring = min(M.clockcultslurring + 3, 3)
- M.stuttering = min(M.stuttering + 3, 3)
- ..()
-
/datum/reagent/consumable/ethanol/shotinthedark
name = "Shot in the Dark"
description = "A coconut elixir with a golden tinge."
@@ -2465,7 +2351,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "an incoming bullet"
glass_icon_state = "shotinthedark"
glass_name = "Shot in the Dark"
- glass_desc = "A specially made drink from the popular webseries RILENA: LMR. Contains traces of gold from the real bullet inside."
+ glass_desc = "A specially made drink from the popular webseries RILENA: LMR. Contains traces of gold from the real bullet inside... which wouldn't make sense outside of the series it comes from."
/datum/reagent/consumable/ethanol/bullethell
name = "Bullet Hell"
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index d359600b0102..bf13904972bf 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -11,7 +11,7 @@
taste_description = "oranges"
glass_icon_state = "glass_orange"
glass_name = "glass of orange juice"
- glass_desc = "Vitamins! Yay!"
+ glass_desc = "Tart and sweet. It might have pulp, if that's what you wanted."
/datum/reagent/consumable/orangejuice/on_mob_life(mob/living/carbon/M)
if(M.getOxyLoss() && prob(30))
@@ -26,7 +26,7 @@
taste_description = "tomatoes"
glass_icon_state = "glass_red"
glass_name = "glass of tomato juice"
- glass_desc = "Are you sure this is tomato juice?"
+ glass_desc = "Some part of you wonders if this could have been a soup at some point."
/datum/reagent/consumable/tomatojuice/on_mob_life(mob/living/carbon/M)
if(M.getFireLoss() && prob(20))
@@ -41,7 +41,7 @@
taste_description = "unbearable sourness"
glass_icon_state = "glass_green"
glass_name = "glass of lime juice"
- glass_desc = "A glass of sweet-sour lime juice."
+ glass_desc = "A glass of intensely sour lime juice. You wonder to yourself: how much do you really need to ward off scurvy for it to come to the point?"
/datum/reagent/consumable/limejuice/on_mob_life(mob/living/carbon/M)
if(M.getToxLoss() && prob(20))
@@ -56,7 +56,7 @@
taste_description = "carrots"
glass_icon_state = "carrotjuice"
glass_name = "glass of carrot juice"
- glass_desc = "It's just like a carrot but without crunching."
+ glass_desc = "Mildly sweet, but it won't actually improve your eyesight all that much beyond the baseline..."
/datum/reagent/consumable/carrotjuice/on_mob_life(mob/living/carbon/M)
M.adjust_blurriness(-1)
@@ -77,7 +77,7 @@
taste_description = "berries"
glass_icon_state = "berryjuice"
glass_name = "glass of berry juice"
- glass_desc = "Berry juice. Or maybe it's jam. Who cares?"
+ glass_desc = "Berry juice. Technically a fruit punch all on its own!"
/datum/reagent/consumable/applejuice
name = "Apple Juice"
@@ -92,7 +92,7 @@
taste_description = "berries"
glass_icon_state = "poisonberryjuice"
glass_name = "glass of berry juice"
- glass_desc = "Berry juice. Or maybe it's poison. Who cares?"
+ glass_desc = "Berry juice. Technically a fruit punch all on its own!"
/datum/reagent/consumable/poisonberryjuice/on_mob_life(mob/living/carbon/M)
M.adjustToxLoss(1, 0)
@@ -106,7 +106,7 @@
taste_description = "juicy watermelon"
glass_icon_state = "glass_red"
glass_name = "glass of watermelon juice"
- glass_desc = "A glass of watermelon juice."
+ glass_desc = "A glass of watermelon juice. Mild and sweet."
/datum/reagent/consumable/lemonjuice
name = "Lemon Juice"
@@ -115,16 +115,16 @@
taste_description = "sourness"
glass_icon_state = "lemonglass"
glass_name = "glass of lemon juice"
- glass_desc = "Sour..."
+ glass_desc = "A glass of intensely sour lime juice. You wonder to yourself: how much do you really need to ward off scurvy for it to come to the point?"
/datum/reagent/consumable/banana
name = "Banana Juice"
- description = "The raw essence of a banana. HONK"
+ description = "The raw essence of a banana."
color = "#e6d283"
taste_description = "banana"
glass_icon_state = "banana"
glass_name = "glass of banana juice"
- glass_desc = "The raw essence of a banana. HONK."
+ glass_desc = "While staring down at this glass, some part of you wonders what went through the minds of those who decided to add this to milk."
/datum/reagent/consumable/banana/on_mob_life(mob/living/carbon/M)
if((ishuman(M) && M.job == "Clown") || ismonkey(M))
@@ -179,25 +179,25 @@
description = "Juice of the potato. Bleh."
nutriment_factor = 2 * REAGENTS_METABOLISM
color = "#9e8045" // rgb: 48, 32, 0
- taste_description = "irish sadness"
+ taste_description = "starchy water"
glass_icon_state = "glass_brown"
glass_name = "glass of potato juice"
- glass_desc = "Bleh..."
+ glass_desc = "Starchy. It coats your mouth with a filament afterwards, which really isn't helping it's case."
/datum/reagent/consumable/grapejuice
name = "Grape Juice"
description = "The juice of a bunch of grapes. Guaranteed non-alcoholic."
color = "#790b79" // dark purple
- taste_description = "grape soda"
+ taste_description = "grapes"
/datum/reagent/consumable/milk
name = "Milk"
- description = "An opaque white liquid produced by the mammary glands of mammals."
+ description = "An opaque white liquid produced by the mammary glands of mammals, some arthropods, biogenerators, chemical factories..."
color = "#DFDFDF" // rgb: 223, 223, 223
taste_description = "milk"
glass_icon_state = "glass_white"
glass_name = "glass of milk"
- glass_desc = "White and nutritious goodness!"
+ glass_desc = "A glass of frothy milk. You wonder what animal this could have come from, if at all."
/datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/M)
if(M.getBruteLoss() && prob(20))
@@ -214,7 +214,7 @@
taste_description = "soy milk"
glass_icon_state = "glass_white"
glass_name = "glass of soy milk"
- glass_desc = "White and nutritious soy goodness!"
+ glass_desc = "Despite being made from soybeans, it sates the same desire to have an entire glass of milk."
/datum/reagent/consumable/soymilk/on_mob_life(mob/living/carbon/M)
if(M.getBruteLoss() && prob(20))
@@ -224,12 +224,12 @@
/datum/reagent/consumable/cream
name = "Cream"
- description = "The fatty, still liquid part of milk. Why don't you mix this with sum scotch, eh?"
+ description = "The fatty, still liquid part of milk."
color = "#DFD7AF" // rgb: 223, 215, 175
taste_description = "creamy milk"
glass_icon_state = "glass_white"
glass_name = "glass of cream"
- glass_desc = "Ewwww..."
+ glass_desc = "It's a bit thick to drink straight."
/datum/reagent/consumable/cream/on_mob_life(mob/living/carbon/M)
if(M.getBruteLoss() && prob(20))
@@ -246,7 +246,7 @@
taste_description = "bitterness"
glass_icon_state = "glass_brown"
glass_name = "glass of coffee"
- glass_desc = "Don't drop it, or you'll send scalding liquid and glass shards everywhere."
+ glass_desc = "Black coffee, served straight. It'll be pretty bitter without anything else in it!"
/datum/reagent/consumable/coffee/overdose_process(mob/living/M)
M.Jitter(5)
@@ -265,13 +265,13 @@
/datum/reagent/consumable/tea
name = "Tea"
- description = "Tasty black tea, it has antioxidants, it's good for you!"
+ description = "Warm, dark tea."
color = "#5f4a05"
nutriment_factor = 0
- taste_description = "tart black tea"
+ taste_description = "tart dark tea"
glass_icon_state = "teaglass"
glass_name = "glass of tea"
- glass_desc = "Drinking it from here would not seem right."
+ glass_desc = "There's a latent desire to drink this out of a teacup, but there's no time for teatime out here."
/datum/reagent/consumable/tea/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-2)
@@ -289,25 +289,25 @@
description = "Sweet, tangy lemonade. Good for the soul."
color = "#FFE978"
quality = DRINK_NICE
- taste_description = "sunshine and summertime"
+ taste_description = "sunshine and distant shores"
glass_icon_state = "lemonpitcher"
glass_name = "pitcher of lemonade"
- glass_desc = "This drink leaves you feeling nostalgic for some reason."
+ glass_desc = "Sweet, slightly tart, and refreshing. You feel some misplaced nostalgia when you have this, even though you're not sure you've ever squeezed a lemon before."
/datum/reagent/consumable/tea/arnold_palmer
name = "Arnold Palmer"
- description = "Encourages the patient to go golfing."
+ description = "Iced sweet tea and lemonade."
color = "#FFB766"
quality = DRINK_NICE
nutriment_factor = 2
taste_description = "bitter tea"
glass_icon_state = "arnold_palmer"
glass_name = "Arnold Palmer"
- glass_desc = "You feel like taking a few golf swings after a few swigs of this."
+ glass_desc = "Iced tea and lemonade. You don't think you know any Arnolds, though."
/datum/reagent/consumable/tea/arnold_palmer/on_mob_life(mob/living/carbon/M)
if(prob(5))
- to_chat(M, "[pick("You remember to square your shoulders.","You remember to keep your head down.","You can't decide between squaring your shoulders and keeping your head down.","You remember to relax.","You think about how someday you'll get two strokes off your golf game.")]")
+ to_chat(M, "[pick("You remember to square your shoulders.","You remember to keep your head down.","You can't decide between squaring your shoulders and keeping your head down.","You remember to relax.","You think about how someday you'll get two strokes off your golf game... whatever that is.")]")
..()
. = 1
@@ -319,7 +319,7 @@
taste_description = "bitter coldness"
glass_icon_state = "icedcoffeeglass"
glass_name = "iced coffee"
- glass_desc = "A drink to perk you up and refresh you!"
+ glass_desc = "Iced black coffee. It's still going to be pretty bitter on it's own, though!"
/datum/reagent/consumable/icecoffee/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-5)
@@ -339,7 +339,7 @@
taste_description = "bitter coldness and a hint of smoke"
glass_icon_state = "hoticecoffee"
glass_name = "hot ice coffee"
- glass_desc = "A sharp drink, this can't have come cheap."
+ glass_desc = "The wonders of fusion mixed into a cup of coffee, resulting in an extremely hot-cold drink."
/datum/reagent/consumable/hot_ice_coffee/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-5)
@@ -353,13 +353,13 @@
/datum/reagent/consumable/icetea
name = "Iced Tea"
- description = "No relation to a certain rap artist/actor."
+ description = "Iced, sweetened tea."
color = "#104038" // rgb: 16, 64, 56
nutriment_factor = 0
taste_description = "sweet tea"
glass_icon_state = "icedteaglass"
glass_name = "iced tea"
- glass_desc = "All natural, antioxidant-rich flavour sensation."
+ glass_desc = "A much more appealing way to have tea while dealing with the heat."
/datum/reagent/consumable/icetea/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-2)
@@ -377,61 +377,33 @@
color = "#743c05" // rgb: 16, 8, 0
taste_description = "cola"
glass_icon_state = "glass_brown"
- glass_name = "glass of Space Cola"
- glass_desc = "A glass of refreshing Space Cola."
+ glass_name = "glass of cola"
+ glass_desc = "A carbonated cola. You should drink it before it gets flat!"
/datum/reagent/consumable/space_cola/on_mob_life(mob/living/carbon/M)
M.drowsyness = max(0,M.drowsyness-5)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
..()
-/datum/reagent/consumable/nuka_cola
- name = "Nuka Cola"
- description = "Cola, cola never changes."
- color = "#3b6c0e" // rgb: 16, 8, 0
- quality = DRINK_VERYGOOD
- taste_description = "the future"
- glass_icon_state = "nuka_colaglass"
- glass_name = "glass of Nuka Cola"
- glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland."
-
-/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/L)
- ..()
- L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nuka_cola)
-
-/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/nuka_cola)
- ..()
-
-/datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/M)
- M.Jitter(20)
- M.set_drugginess(30)
- M.dizziness +=1.5
- M.drowsyness = 0
- M.AdjustSleeping(-40)
- M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
- ..()
- . = 1
-
-/datum/reagent/consumable/grey_bull
- name = "Grey Bull"
- description = "Grey Bull, it gives you gloves!"
+/datum/reagent/consumable/crosstalk
+ name = "Crosstalk"
+ description = "Crosstalk! Share the energy with everyone!"
color = "#EEFF00" // rgb: 238, 255, 0
quality = DRINK_VERYGOOD
- taste_description = "carbonated oil"
- glass_icon_state = "grey_bull_glass"
- glass_name = "glass of Grey Bull"
- glass_desc = "Surprisingly it isnt grey."
+ taste_description = "carbonated battery acid with a spoonful of sugar"
+ glass_icon_state = "crosstalk_glass"
+ glass_name = "glass of Crosstalk"
+ glass_desc = "The amount of sugar and chemicals in this drink makes your eyes water."
-/datum/reagent/consumable/grey_bull/on_mob_metabolize(mob/living/L)
+/datum/reagent/consumable/crosstalk/on_mob_metabolize(mob/living/L)
..()
ADD_TRAIT(L, TRAIT_SHOCKIMMUNE, type)
-/datum/reagent/consumable/grey_bull/on_mob_end_metabolize(mob/living/L)
+/datum/reagent/consumable/crosstalk/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_SHOCKIMMUNE, type)
..()
-/datum/reagent/consumable/grey_bull/on_mob_life(mob/living/carbon/M)
+/datum/reagent/consumable/crosstalk/on_mob_life(mob/living/carbon/M)
M.Jitter(20)
M.dizziness +=1
M.drowsyness = 0
@@ -439,16 +411,16 @@
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
..()
-/datum/reagent/consumable/spacemountainwind
- name = "SM Wind"
- description = "Blows right through you like a space wind."
+/datum/reagent/consumable/comet_trail
+ name = "Comet Trail"
+ description = "A citrusy drink from the Kepori space installation known as The Ring."
color = "#c4ff2d" // rgb: 16, 32, 0
taste_description = "sweet citrus soda"
- glass_icon_state = "Space_mountain_wind_glass"
- glass_name = "glass of Space Mountain Wind"
- glass_desc = "Space Mountain Wind. As you know, there are no mountains in space, only wind."
+ glass_icon_state = "comet_trail_glass"
+ glass_name = "glass of Comet Trail"
+ glass_desc = "A glass of Comet Trail. Taste the stars!"
-/datum/reagent/consumable/spacemountainwind/on_mob_life(mob/living/carbon/M)
+/datum/reagent/consumable/comet_trail/on_mob_life(mob/living/carbon/M)
M.drowsyness = max(0,M.drowsyness-7)
M.AdjustSleeping(-20)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
@@ -456,16 +428,16 @@
..()
. = 1
-/datum/reagent/consumable/dr_gibb
- name = "Dr. Gibb"
- description = "A delicious blend of 42 different flavours."
+/datum/reagent/consumable/tadrixx
+ name = "Tadrixx"
+ description = "A Kalixcian drink made from a plant that tastes similar to sassafrass, which is used in root beer. A stumpy drake holding a mug of it is on the front."
color = "#732a03"
- taste_description = "cherry soda" // FALSE ADVERTISING
- glass_icon_state = "dr_gibb_glass"
- glass_name = "glass of Dr. Gibb"
- glass_desc = "Dr. Gibb. Not as dangerous as the glass_name might imply."
+ taste_description = "root beer" // FALSE ADVERTISING
+ glass_icon_state = "tadrixx_glass"
+ glass_name = "glass of Tadrixx"
+ glass_desc = "A cup of fizzy Tadrixx. It smells sweet."
-/datum/reagent/consumable/dr_gibb/on_mob_life(mob/living/carbon/M)
+/datum/reagent/consumable/tadrixx/on_mob_life(mob/living/carbon/M)
M.drowsyness = max(0,M.drowsyness-6)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
..()
@@ -484,6 +456,40 @@
M.adjust_bodytemperature(-8 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
..()
+/datum/reagent/consumable/molten
+ name = "Molten Bubbles"
+ description = "A spicy soft drink made from a coca-like plant from Kalixcis. Popularly served both cold -and- hot, depending on the weather."
+ color = "#5f2010"
+ taste_description = "spiced cola"
+ glass_icon_state = "glass_brown"
+ glass_name = "glass of Molten Bubbles"
+ glass_desc = "A glass of Molten Bubbles. The spices tickle your nose."
+
+/datum/reagent/consumable/molten/on_mob_life(mob/living/carbon/M)
+ M.heal_bodypart_damage(1,1,0)
+ if(M.bodytemperature > M.get_body_temp_normal(apply_change=FALSE))
+ M.adjust_bodytemperature(-10 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal(apply_change=FALSE))
+ else if(M.bodytemperature < (M.get_body_temp_normal(apply_change=FALSE) + 1))
+ M.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, M.get_body_temp_normal(apply_change=FALSE))
+ ..()
+
+/datum/reagent/consumable/molten/plasma_fizz
+ name = "Plasma Fizz"
+ description = "A spinoff of the popular Molten Bubbles drink from Kalixcis, made to emulate the flavor of spiced grape instead. It's... not exactly convincing or a very good mix."
+ color = "#5f2010"
+ taste_description = "spiced grape soda"
+ glass_icon_state = "plasma_fizz_glass"
+ glass_name = "glass of Plasma Fizz"
+ glass_desc = "A glass of Plasma Fizz. The spices (and fake grape flavoring) wrinkles your nose."
+
+/datum/reagent/consumable/molten/sand
+ name = "Sandblast Sarsaparilla"
+ description = "Extra refreshing for those long desert days."
+ color = "#af9938"
+ taste_description = "root-beer and asbestos"
+ glass_name = "glass of Sandblast Sarsaparilla"
+ glass_desc = "A glass of Sandblast Sarsaparilla. Perfect for those long desert days."
+
/datum/reagent/consumable/lemon_lime
name = "Lemon Lime"
description = "A tangy substance made of 0.5% natural citrus!"
@@ -499,48 +505,48 @@
..()
-/datum/reagent/consumable/pwr_game
- name = "Pwr Game"
- description = "The only drink with the PWR that true gamers crave."
+/datum/reagent/consumable/pacfuel
+ name = "PAC-Fuel"
+ description = "A carbonated energy drink themed after the purple coloration, similar to plasma."
color = "#9385bf" // rgb: 58, 52, 75
taste_description = "sweet and salty tang"
glass_icon_state = "glass_red"
- glass_name = "glass of Pwr Game"
- glass_desc = "Goes well with a Vlad's salad."
+ glass_name = "glass of PAC-Fuel"
+ glass_desc = "A glass of PAC-Fuel energy drink. It smells vaguely like acidic cotton candy..."
-/datum/reagent/consumable/pwr_game/expose_mob(mob/living/C, method=TOUCH, reac_volume)
+/datum/reagent/consumable/pacfuel/expose_mob(mob/living/C, method=TOUCH, reac_volume)
..()
if(C?.mind?.get_skill_level(/datum/skill/gaming) >= SKILL_LEVEL_LEGENDARY && method==INGEST && !HAS_TRAIT(C, TRAIT_GAMERGOD))
ADD_TRAIT(C, TRAIT_GAMERGOD, "pwr_game")
- to_chat(C, "As you imbibe the Pwr Game, your gamer third eye opens... \
+ to_chat(C, "As you imbibe the PAC-Fuel, your gamer third eye opens... \
You feel as though a great secret of the universe has been made known to you...")
-/datum/reagent/consumable/pwr_game/on_mob_life(mob/living/carbon/M)
+/datum/reagent/consumable/pacfuel/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-8 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
if(prob(10))
M?.mind.adjust_experience(/datum/skill/gaming, 5)
..()
-/datum/reagent/consumable/shamblers
- name = "Shambler's Juice"
- description = "~Shake me up some of that Shambler's Juice!~"
+/datum/reagent/consumable/shoal_punch
+ name = "Shoal Punch"
+ description = "Sugary, and from the Shoal."
color = "#f00060" // rgb: 94, 0, 38
- taste_description = "carbonated metallic soda"
+ taste_description = "sugary fruity soda"
glass_icon_state = "glass_red"
- glass_name = "glass of Shambler's juice"
- glass_desc = "Mmm mm, shambly."
+ glass_name = "glass of Shoal Punch"
+ glass_desc = "It's hard to imagine all those fruits getting condensed into a cup like this."
-/datum/reagent/consumable/shamblers/on_mob_life(mob/living/carbon/M)
+/datum/reagent/consumable/shoal_punch/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-8 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
..()
/datum/reagent/consumable/sodawater
name = "Soda Water"
- description = "A can of club soda. Why not make a scotch and soda?"
+ description = "A can of club soda."
color = "#619494" // rgb: 97, 148, 148
taste_description = "carbonated water"
glass_icon_state = "glass_clear"
glass_name = "glass of soda water"
- glass_desc = "Soda water. Why not make a scotch and soda?"
+ glass_desc = "Soda water. You feel like you should add something to this..."
/datum/reagent/consumable/sodawater/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-5)
@@ -550,12 +556,12 @@
/datum/reagent/consumable/tonic
name = "Tonic Water"
- description = "It tastes strange but at least the quinine keeps the Space Malaria at bay."
+ description = "It tastes strange, and it's not like malaria is much of an issue anymore."
color = "#709fce"
taste_description = "tart and fresh"
glass_icon_state = "glass_clear"
glass_name = "glass of tonic water"
- glass_desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away."
+ glass_desc = "Quinine and carbonated water. You really should add something to this..."
/datum/reagent/consumable/tonic/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-5)
@@ -565,17 +571,17 @@
..()
. = 1
-/datum/reagent/consumable/monkey_energy
- name = "Monkey Energy"
- description = "The only drink that will make you unleash the ape."
- color = "#f39b03" // rgb: 243, 155, 3
+/datum/reagent/consumable/xeno_energy
+ name = "Xeno-Energy"
+ description = "An unbearably sugary, fizzy green drink."
+ color = "#88b488" // rgb: 243, 155, 3
overdose_threshold = 60
- taste_description = "barbecue and nostalgia"
- glass_icon_state = "monkey_energy_glass"
- glass_name = "glass of Monkey Energy"
- glass_desc = "You can unleash the ape, but without the pop of the can?"
+ taste_description = "tooth-rotting sweetness"
+ glass_icon_state = "xeno_energy_glass"
+ glass_name = "glass of Xeno Energy"
+ glass_desc = "A glass of Xeno Energy. It seems to swirl and roil outside of the can..."
-/datum/reagent/consumable/monkey_energy/on_mob_life(mob/living/carbon/M)
+/datum/reagent/consumable/xeno_energy/on_mob_life(mob/living/carbon/M)
M.Jitter(20)
M.dizziness +=1
M.drowsyness = 0
@@ -583,18 +589,13 @@
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
..()
-/datum/reagent/consumable/monkey_energy/on_mob_metabolize(mob/living/L)
+/datum/reagent/consumable/xeno_energy/on_mob_metabolize(mob/living/L)
..()
if(ismonkey(L))
- L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/monkey_energy)
+ L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/xeno_energy)
-/datum/reagent/consumable/monkey_energy/on_mob_end_metabolize(mob/living/L)
- L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/monkey_energy)
- ..()
-
-/datum/reagent/consumable/monkey_energy/overdose_process(mob/living/M)
- if(prob(15))
- M.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/monkey_energy)
+/datum/reagent/consumable/xeno_energy/on_mob_end_metabolize(mob/living/L)
+ L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/xeno_energy)
..()
/datum/reagent/consumable/ice
@@ -605,7 +606,7 @@
taste_description = "ice"
glass_icon_state = "iceglass"
glass_name = "glass of ice"
- glass_desc = "Generally, you're supposed to put something else in there too..."
+ glass_desc = "Generally, you're supposed to put something else in there, too..."
/datum/reagent/consumable/ice/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
@@ -613,13 +614,13 @@
/datum/reagent/consumable/soy_latte
name = "Soy Latte"
- description = "A nice and tasty beverage while you are reading your hippie books."
+ description = "A hot beverage for those who can't handle the lactose."
color = "#664300" // rgb: 102, 67, 0
quality = DRINK_NICE
taste_description = "creamy coffee"
glass_icon_state = "soy_latte"
glass_name = "soy latte"
- glass_desc = "A nice and refreshing beverage while you're reading."
+ glass_desc = "A nice and refreshing beverage. It goes well with a book, if you have the time to read."
/datum/reagent/consumable/soy_latte/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-5)
@@ -640,7 +641,7 @@
taste_description = "bitter cream"
glass_icon_state = "cafe_latte"
glass_name = "cafe latte"
- glass_desc = "A nice, strong and refreshing beverage while you're reading."
+ glass_desc = "A nice, strong and refreshing beverage. It goes well with a book, if you have the time to read."
/datum/reagent/consumable/cafe_latte/on_mob_life(mob/living/carbon/M)
M.dizziness = max(0,M.dizziness-5)
@@ -655,13 +656,13 @@
/datum/reagent/consumable/doctor_delight
name = "The Doctor's Delight"
- description = "A gulp a day keeps the Medibot away! A mixture of juices that heals most damage types fairly quickly at the cost of hunger."
+ description = "A homemade curative. A mixture of juices that helps your body heal against most damage, at the cost of leaving you hungry."
color = "#FF8CFF" // rgb: 255, 140, 255
quality = DRINK_VERYGOOD
taste_description = "homely fruit"
glass_icon_state = "doctorsdelightglass"
glass_name = "Doctor's Delight"
- glass_desc = "The space doctor's favorite. Guaranteed to restore bodily injury; side effects include cravings and hunger."
+ glass_desc = "A homemade curative. Helps the body heal with the nutrition density, but it leaves a gnawing hunger afterwards."
/datum/reagent/consumable/doctor_delight/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(-0.5, 0)
@@ -683,7 +684,7 @@
taste_description = "sweet chocolate"
glass_icon_state = "chocolatepudding"
glass_name = "chocolate pudding"
- glass_desc = "Tasty."
+ glass_desc = "Thick, sweet, and chocolatey."
/datum/reagent/consumable/vanillapudding
name = "Vanilla Pudding"
@@ -694,7 +695,7 @@
taste_description = "sweet vanilla"
glass_icon_state = "vanillapudding"
glass_name = "vanilla pudding"
- glass_desc = "Tasty."
+ glass_desc = "Thick, sweet, and pleasantly vanilla."
/datum/reagent/consumable/cherryshake
name = "Cherry Shake"
@@ -705,7 +706,7 @@
taste_description = "creamy cherry"
glass_icon_state = "cherryshake"
glass_name = "cherry shake"
- glass_desc = "A cherry flavored milkshake."
+ glass_desc = "A cherry flavored milkshake. Don't get any on your jumpsuit!"
/datum/reagent/consumable/bluecherryshake
name = "Blue Cherry Shake"
@@ -716,33 +717,33 @@
taste_description = "creamy blue cherry"
glass_icon_state = "bluecherryshake"
glass_name = "blue cherry shake"
- glass_desc = "An exotic blue milkshake."
+ glass_desc = "A blue-cherry milkshake. Generally, the blue is meant to be figurative, but..."
/datum/reagent/consumable/pumpkin_latte
name = "Pumpkin Latte"
- description = "A mix of pumpkin juice and coffee."
+ description = "A mix of spices and coffee. It doesn't actually contain any pumpkin, though."
color = "#F4A460"
quality = DRINK_VERYGOOD
nutriment_factor = 3 * REAGENTS_METABOLISM
taste_description = "creamy pumpkin"
glass_icon_state = "pumpkin_latte"
glass_name = "pumpkin latte"
- glass_desc = "A mix of coffee and pumpkin juice."
+ glass_desc = "A mix of coffee and pumpkin juice would taste a whole lot different than what you're having right now, you know."
-/datum/reagent/consumable/gibbfloats
- name = "Gibb Floats"
- description = "Ice cream on top of a Dr. Gibb glass."
- color = "#B22222"
+/datum/reagent/consumable/tadrixxfloat
+ name = "Tadrixx Float"
+ description = "Ice cream on top of a glass of Tadrixx."
+ color = "#533713"
quality = DRINK_NICE
nutriment_factor = 3 * REAGENTS_METABOLISM
- taste_description = "creamy cherry"
- glass_icon_state = "gibbfloats"
- glass_name = "Gibbfloat"
- glass_desc = "Dr. Gibb with ice cream on top."
+ taste_description = "creamy root beer"
+ glass_icon_state = "tadrixxfloat"
+ glass_name = "Tadrixxfloat"
+ glass_desc = "A glass of Tadrixx with ice cream on top."
/datum/reagent/consumable/pumpkinjuice
name = "Pumpkin Juice"
- description = "Juiced from real pumpkin."
+ description = "Juiced from real pumpkins."
color = "#FFA500"
taste_description = "pumpkin"
@@ -757,18 +758,18 @@
description = "A solution."
color = "#EEFF00"
quality = DRINK_NICE
- taste_description = "extreme bitterness"
+ taste_description = "extreme sourness"
glass_icon_state = "triplecitrus" //needs own sprite mine are trash //your sprite is great tho
glass_name = "glass of triple citrus"
- glass_desc = "A mixture of citrus juices. Tangy, yet smooth."
+ glass_desc = "A mixture of citrus juices. Intensely sour, and leaves you reeling afterwards."
/datum/reagent/consumable/grape_soda
name = "Grape soda"
- description = "Beloved by children and teetotalers."
+ description = "Artificial grape soda."
color = "#E6CDFF"
taste_description = "grape soda"
glass_name = "glass of grape juice"
- glass_desc = "It's grape (soda)!"
+ glass_desc = "It's grape soda!"
/datum/reagent/consumable/grape_soda/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
@@ -776,20 +777,28 @@
/datum/reagent/consumable/milk/chocolate_milk
name = "Chocolate Milk"
- description = "Milk for cool kids."
+ description = "Milk mixed with chocolate powder. Beloved by children everywhere."
color = "#7D4E29"
quality = DRINK_NICE
taste_description = "chocolate milk"
+/datum/reagent/consumable/lunapunch
+ name = "Lunapunch"
+ description = "An herbal-sweet carbonated drink with a bitter bite."
+ color = "#7D4E29"
+ quality = DRINK_NICE
+ taste_description = "sweet herbs and lingering bitterness"
+ glass_name = "glass of Lunapunch"
+ glass_desc = "An herbal-sweet soft drink. The bitter bite after each sip is enough to make you wince, but leaves you wanting more."
/datum/reagent/consumable/hot_coco
- name = "Hot Coco"
- description = "Made with love! And coco beans."
+ name = "Hot Cocoa"
+ description = "Made with love and cocoa beans. Or from a vending machine."
nutriment_factor = 3 * REAGENTS_METABOLISM
color = "#4f3a11" // rgb: 64, 48, 16
taste_description = "creamy chocolate"
glass_icon_state = "chocolateglass"
- glass_name = "glass of hot coco"
- glass_desc = "A favorite winter drink to warm you up."
+ glass_name = "glass of hot cocoa."
+ glass_desc = "A favorite winter drink from the Solar Confederation. Good for warming yourself up."
/datum/reagent/consumable/hot_coco/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(5 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, M.get_body_temp_normal())
@@ -810,7 +819,7 @@
taste_description = "mint"
glass_icon_state = "glass_green"
glass_name = "glass of menthol"
- glass_desc = "Tastes naturally minty, and imparts a very mild numbing sensation."
+ glass_desc = "Tastes naturally and sharply minty, with a mild numbing sensation."
/datum/reagent/consumable/menthol/on_mob_life(mob/living/L)
L.apply_status_effect(/datum/status_effect/throat_soothed)
@@ -818,26 +827,27 @@
/datum/reagent/consumable/grenadine
name = "Grenadine"
- description = "Not cherry flavored!"
+ description = "More blackcurrant than cherry, actually."
color = "#EA1D26"
taste_description = "sweet pomegranates"
glass_name = "glass of grenadine"
- glass_desc = "Delicious flavored syrup."
+ glass_desc = "Flavored syrup, traditionally used for mixing drinks. Having it straight is certainly a choice."
/datum/reagent/consumable/parsnipjuice
name = "Parsnip Juice"
- description = "Why..."
+ description = "Starchy and uncommon."
color = "#FFA500"
taste_description = "parsnip"
glass_name = "glass of parsnip juice"
+ glass_desc = "It doesn't really count as a soup this way. Maybe it'd better if it was a soup."
/datum/reagent/consumable/pineapplejuice
name = "Pineapple Juice"
- description = "Tart, tropical, and hotly debated."
+ description = "Tart, tropical, and sweet."
color = "#F7D435"
taste_description = "pineapple"
glass_name = "glass of pineapple juice"
- glass_desc = "Tart, tropical, and hotly debated."
+ glass_desc = "Tart, tropical, and sweet."
/datum/reagent/consumable/peachjuice //Intended to be extremely rare due to being the limiting ingredients in the blazaam drink
name = "Peach Juice"
@@ -845,16 +855,17 @@
color = "#E78108"
taste_description = "peaches"
glass_name = "glass of peach juice"
+ glass_desc = "A glass full of sweet peach juice. Strange, you don't often see it out this far into the Frontier..."
/datum/reagent/consumable/cream_soda
name = "Cream Soda"
- description = "A classic space-American vanilla flavored soft drink."
+ description = "A classic vanilla flavored soft drink."
color = "#dcb137"
quality = DRINK_VERYGOOD
taste_description = "fizzy vanilla"
glass_icon_state = "cream_soda"
glass_name = "Cream Soda"
- glass_desc = "A classic space-American vanilla flavored soft drink."
+ glass_desc = "A classic vanilla flavored soft drink."
/datum/reagent/consumable/cream_soda/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
@@ -867,7 +878,7 @@
quality = DRINK_NICE
taste_description = "sweet ginger spice"
glass_name = "Sol Dry"
- glass_desc = "A soothing, mellow drink made from ginger."
+ glass_desc = "A soothing, mellow drink made from ginger. You can't imagine drinking a carbonated drink while in microgravity, though, nausea or not..."
/datum/reagent/consumable/sol_dry/on_mob_life(mob/living/carbon/M)
M.adjust_disgust(-5)
@@ -875,13 +886,13 @@
/datum/reagent/consumable/red_queen
name = "Red Queen"
- description = "DRINK ME."
+ description = "You feel inclined to drink it, somehow."
color = "#e6ddc3"
quality = DRINK_GOOD
taste_description = "wonder"
glass_icon_state = "red_queen"
glass_name = "Red Queen"
- glass_desc = "DRINK ME."
+ glass_desc = "A cup of red tea. A small note is tied around the handle of it, which asks you to drink it."
var/current_size = RESIZE_DEFAULT_SIZE
/datum/reagent/consumable/red_queen/on_mob_life(mob/living/carbon/H)
@@ -905,11 +916,11 @@
/datum/reagent/consumable/bungojuice
name = "Bungo Juice"
color = "#F9E43D"
- description = "Exotic! You feel like you are on vactation already."
+ description = "A botanical experiment gone right."
taste_description = "succulent bungo"
glass_icon_state = "glass_yellow"
glass_name = "glass of bungo juice"
- glass_desc = "Exotic! You feel like you are on vactation already."
+ glass_desc = "A botanical experiment in creating a new fruit. It smells faintly citrusy, along with a hint of... banana?"
/datum/reagent/consumable/prunomix
name = "pruno mixture"
@@ -927,7 +938,7 @@
taste_description = "vegetable"
glass_icon_state = "glass_yellow"
glass_name = "glass of aloe juice"
- glass_desc = "A healthy and refreshing juice."
+ glass_desc = "Juiced aloe vera. It's an acquired taste."
/datum/reagent/consumable/aloejuice/on_mob_life(mob/living/M)
if(M.getToxLoss() && prob(30))
@@ -943,7 +954,7 @@
taste_description = "purple and a hint of opioid."
glass_icon_state = "lean"
glass_name = "Lean"
- glass_desc = "A drink that makes your life less miserable."
+ glass_desc = "You just don't often get to see cough syrup out here, and someone had enough to mix it with soda. You're left wondering why."
/datum/reagent/consumable/lean/on_mob_life(mob/living/carbon/M)
if(M.slurring < 3)
diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
index ad21aa93e745..b776a285b346 100644
--- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
@@ -2,6 +2,7 @@
name = "Drug"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
taste_description = "bitterness"
+ category = "Drug"
var/trippy = TRUE //Does this drug make you trip?
/datum/reagent/drug/on_mob_end_metabolize(mob/living/M)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index e4e6bdd1d620..7c2b3f62099f 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -11,6 +11,7 @@
name = "Consumable"
taste_description = "generic food"
taste_mult = 4
+ category = "Food and Drink"
var/nutriment_factor = 1 * REAGENTS_METABOLISM
var/quality = 0 //affects mood, typically higher for mixed drinks with more complex recipes
@@ -208,30 +209,6 @@
taste_description = "hot peppers"
taste_mult = 1.5
-/datum/reagent/consumable/capsaicin/on_mob_life(mob/living/carbon/M)
- var/heating = 0
- switch(current_cycle)
- if(1 to 15)
- heating = 5 * TEMPERATURE_DAMAGE_COEFFICIENT
- if(holder.has_reagent(/datum/reagent/cryostylane))
- holder.remove_reagent(/datum/reagent/cryostylane, 5)
- if(isslime(M))
- heating = rand(5,20)
- if(15 to 25)
- heating = 10 * TEMPERATURE_DAMAGE_COEFFICIENT
- if(isslime(M))
- heating = rand(10,20)
- if(25 to 35)
- heating = 15 * TEMPERATURE_DAMAGE_COEFFICIENT
- if(isslime(M))
- heating = rand(15,20)
- if(35 to INFINITY)
- heating = 20 * TEMPERATURE_DAMAGE_COEFFICIENT
- if(isslime(M))
- heating = rand(20,25)
- M.adjust_bodytemperature(heating)
- ..()
-
/datum/reagent/consumable/frostoil
name = "Frost Oil"
description = "A special oil that noticeably chills the body. Extracted from chilly peppers and slimes."
@@ -326,12 +303,6 @@
color = "#FFFFFF" // rgb: 255,255,255
taste_description = "salt"
-/datum/reagent/consumable/sodiumchloride/expose_mob(mob/living/M, method=TOUCH, reac_volume)
- if(!istype(M))
- return
- if(M.has_bane(BANE_SALT))
- M.mind.disrupt_spells(-200)
-
/datum/reagent/consumable/sodiumchloride/expose_turf(turf/T, reac_volume) //Creates an umbra-blocking salt pile
if(!istype(T))
return
@@ -712,7 +683,7 @@
taste_description = "pure electricity"
/datum/reagent/consumable/liquidelectricity/on_mob_life(mob/living/carbon/M)
- if(prob(25) && !isethereal(M))
+ if(prob(25) && !iselzuose(M))
M.electrocute_act(rand(10,15), "Liquid Electricity in their body", 1) //lmao at the newbs who eat energy bars
playsound(M, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
return ..()
@@ -728,7 +699,7 @@
var/mob/living/carbon/C = M
var/obj/item/organ/stomach/ethereal/stomach = C.getorganslot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
- stomach.adjust_charge(reac_volume * REM * ETHEREAL_CHARGE_SCALING_MULTIPLIER) //WS Edit -- Ethereal Charge Scaling
+ stomach.adjust_charge(reac_volume * REM * ELZUOSE_CHARGE_SCALING_MULTIPLIER) //WS Edit -- Ethereal Charge Scaling
/datum/reagent/consumable/astrotame
name = "Astrotame"
@@ -775,22 +746,6 @@
taste_description = "caramel"
reagent_state = SOLID
-/datum/reagent/consumable/char
- name = "Char"
- description = "Essence of the grill. Has strange properties when overdosed."
- reagent_state = LIQUID
- nutriment_factor = 5 * REAGENTS_METABOLISM
- color = "#C8C8C8"
- taste_mult = 6
- taste_description = "smoke"
- overdose_threshold = 15
-
-/datum/reagent/consumable/char/overdose_process(mob/living/M)
- if(prob(25))
- M.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/char)
- ..()
- return
-
/datum/reagent/consumable/bbqsauce
name = "BBQ Sauce"
description = "Sweet, smoky, savory, and gets everywhere. Perfect for grilling."
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 24be546cb3f6..11a930efda30 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -9,6 +9,7 @@
/datum/reagent/medicine
name = "Medicine"
taste_description = "bitterness"
+ category = "Medicine"
/datum/reagent/medicine/on_mob_life(mob/living/carbon/M)
current_cycle++
@@ -1090,7 +1091,7 @@
M.adjustBruteLoss(-2*REM, 0)
if(ishuman(M))
var/mob/living/carbon/human/H = M
- H.bleed_rate = max(H.bleed_rate - 0.25, 0)
+ H.heal_bleeding(0.25)
..()
. = 1
@@ -1309,8 +1310,6 @@
M.adjustStaminaLoss(-3 * REM, 0)
M.jitteriness = min(max(0, M.jitteriness + 3), 30)
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM, 150)
- if(prob(10))
- M.say(pick("Yeah, well, you know, that's just, like, uh, your opinion, man.", "Am I glad he's frozen in there and that we're out here, and that he's the sheriff and that we're frozen out here, and that we're in there, and I just remembered, we're out here. What I wanna know is: Where's the caveman?", "It ain't me, it ain't me...", "Make love, not war!", "Stop, hey, what's that sound? Everybody look what's going down...", "Do you believe in magic in a young girl's heart?"), forced = /datum/reagent/medicine/earthsblood)
M.druggy = min(max(0, M.druggy + 10), 15) //See above
..()
. = 1
@@ -1637,7 +1636,7 @@
if(prob(50))
if(ishuman(M))
var/mob/living/carbon/human/H = M
- H.bleed_rate = max(H.bleed_rate - 2, 0)
+ H.heal_bleeding(2)
..()
. = 1
@@ -2072,7 +2071,6 @@
bp.receive_damage(0, 0, 200)
else //SUCH A LUST FOR REVENGE!!!
to_chat(M, "A phantom limb hurts!")
- M.say("Why are we still here, just to suffer?", forced = /datum/reagent/medicine/lavaland_extract)
return ..()
/datum/reagent/medicine/skeletons_boon
@@ -2112,30 +2110,3 @@
ADD_TRAIT(M, TRAIT_ALLBREAK, TRAIT_GENERIC)
REMOVE_TRAIT(M, TRAIT_NOBREAK, TRAIT_GENERIC)
..()
-
-/datum/reagent/medicine/molten_bubbles
- name = "Molten Bubbles"
- description = "Refreshing softdrink made for the desert."
- color = "#3d1916"
- metabolization_rate = REAGENTS_METABOLISM
- taste_description = "boiling sugar"
-
-/datum/reagent/medicine/molten_bubbles/on_mob_life(mob/living/carbon/M)
- M.heal_bodypart_damage(1,1,0)
- if(M.bodytemperature > M.get_body_temp_normal(apply_change=FALSE))
- M.adjust_bodytemperature(-10 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal(apply_change=FALSE))
- else if(M.bodytemperature < (M.get_body_temp_normal(apply_change=FALSE) + 1))
- M.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, M.get_body_temp_normal(apply_change=FALSE))
- ..()
-
-/datum/reagent/medicine/molten_bubbles/plasma
- name = "Plasma Bubbles"
- description = "Molten Bubbles with the refreshing taste of plasma."
- color = "#852e63"
- taste_description = "grape flavored cleaning solution"
-
-/datum/reagent/medicine/molten_bubbles/sand
- name = "Sandblast Sarsaparilla"
- description = "Extra refreshing for those long desert days."
- color = "#af9938"
- taste_description = "root-beer and asbestos"
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index d727cbfd0fa6..24db5dd524d8 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -410,7 +410,6 @@
description = "A substance applied to the skin to darken the skin."
color = "#FFC080" // rgb: 255, 196, 128 Bright orange
metabolization_rate = 10 * REAGENTS_METABOLISM // very fast, so it can be applied rapidly. But this changes on an overdose
- overdose_threshold = 11 //Slightly more than one un-nozzled spraybottle.
taste_description = "sour oranges"
/datum/reagent/spraytan/expose_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
@@ -470,41 +469,11 @@
N.dna.features["mcolor"] = newcolor
N.regenerate_icons()
-
-
if(method == INGEST)
if(show_message)
to_chat(M, "That tasted horrible.")
..()
-
-/datum/reagent/spraytan/overdose_process(mob/living/M)
- metabolization_rate = 1 * REAGENTS_METABOLISM
-
- if(ishuman(M))
- var/mob/living/carbon/human/N = M
- if(!HAS_TRAIT(N, TRAIT_BALD))
- N.hairstyle = "Spiky"
- N.facial_hairstyle = "Shaved"
- N.facial_hair_color = "000"
- N.hair_color = "000"
- if(!(HAIR in N.dna.species.species_traits)) //No hair? No problem!
- N.dna.species.species_traits += HAIR
- if(N.dna.species.use_skintones)
- N.skin_tone = "orange"
- else if(MUTCOLORS in N.dna.species.species_traits) //Aliens with custom colors simply get turned orange
- N.dna.features["mcolor"] = "f80"
- N.regenerate_icons()
- if(prob(7))
- if(N.w_uniform)
- M.visible_message(pick("[M]'s collar pops up without warning.", "[M] flexes [M.p_their()] arms."))
- else
- M.visible_message("[M] flexes [M.p_their()] arms.")
- if(prob(10))
- M.say(pick("Shit was SO cash.", "You are everything bad in the world.", "What sports do you play, other than 'jack off to naked drawn Japanese people?'", "Don???t be a stranger. Just hit me with your best shot.", "My name is John and I hate every single one of you."), forced = /datum/reagent/spraytan)
- ..()
- return
-
/datum/reagent/mulligan
name = "Mulligan Toxin"
description = "This toxin will rapidly change the DNA of human beings. Commonly used by Syndicate spies and assassins in need of an emergency ID change."
@@ -795,12 +764,6 @@
C.blood_volume += 0.5
..()
-/datum/reagent/iron/expose_mob(mob/living/M, method=TOUCH, reac_volume)
- if(M.has_bane(BANE_IRON)) //If the target is weak to cold iron, then poison them.
- if(holder && holder.chem_temp < 100) // COLD iron.
- M.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
- ..()
-
/datum/reagent/gold
name = "Gold"
description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known."
@@ -817,11 +780,6 @@
taste_description = "expensive yet reasonable metal"
material = /datum/material/silver
-/datum/reagent/silver/expose_mob(mob/living/M, method=TOUCH, reac_volume)
- if(M.has_bane(BANE_SILVER))
- M.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
- ..()
-
/datum/reagent/uranium
name ="Uranium"
description = "A jade-green metallic chemical element in the actinide series, weakly radioactive."
@@ -1549,20 +1507,6 @@
name = "Royal Carpet?"
description = "For those that break the game and need to make an issue report."
-/datum/reagent/carpet/royal/on_mob_life(mob/living/carbon/M)
- . = ..()
- if(!M.mind?.assigned_role)
- return
- switch(M.mind.assigned_role)
- if("Chief Medical Officer", "Captain", "Chief Engineer", "Research Director", "Head of Personnel")
- if(prob(10))
- to_chat(M, "You feel like royalty.")
- if(prob(5))
- M.say(pick("Peasants..","This carpet is worth more than your contracts!","I could fire you at any time..."), forced = "royal carpet")
- if("Quartermaster")
- if(prob(15))
- to_chat(M, "You feel like an impostor...")
-
/datum/reagent/carpet/royal/black
name = "Royal Black Carpet"
description = "For those that feel the need to show off their timewasting skills."
@@ -1876,11 +1820,6 @@
color = "#00ff80"
taste_description = "strange honey"
-/datum/reagent/royal_bee_jelly/on_mob_life(mob/living/carbon/M)
- if(prob(2))
- M.say(pick("Bzzz...","BZZ BZZ","Bzzzzzzzzzzz..."), forced = "royal bee jelly")
- ..()
-
//Misc reagents
/datum/reagent/romerol
@@ -2059,18 +1998,6 @@
to_chat(M, "You should sit down and take a rest...")
..()
-/datum/reagent/tranquility
- name = "Tranquility"
- description = "A highly mutative liquid of unknown origin."
- color = "#9A6750" //RGB: 154, 103, 80
- taste_description = "inner peace"
- can_synth = FALSE
-
-/datum/reagent/tranquility/expose_mob(mob/living/L, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
- if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
- L.ForceContractDisease(new /datum/disease/transformation/gondola(), FALSE, TRUE)
-
-
/datum/reagent/spider_extract
name = "Spider Extract"
description = "A highly specialized extract coming from the Australicus sector, used to create broodmother spiders."
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index 62c743558e13..313fb7475e00 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -2,6 +2,7 @@
/datum/reagent/thermite
name = "Thermite"
description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls."
+ category = "Pyrotechnics"
reagent_state = SOLID
color = "#550000"
taste_description = "sweet tasting metal"
@@ -19,6 +20,7 @@
/datum/reagent/nitroglycerin
name = "Nitroglycerin"
description = "Nitroglycerin is a heavy, colorless, oily, explosive liquid obtained by nitrating glycerol."
+ category = "Pyrotechnics"
color = "#808080" // rgb: 128, 128, 128
taste_description = "oil"
@@ -37,6 +39,7 @@
/datum/reagent/clf3
name = "Chlorine Trifluoride"
description = "Makes a temporary 3x3 fireball when it comes into existence, so be careful when mixing. ClF3 applied to a surface burns things that wouldn't otherwise burn, including typically-robust flooring, potentially exposing it to the vacuum of space."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#FFC8C8"
metabolization_rate = 4
@@ -82,6 +85,7 @@
/datum/reagent/sorium
name = "Sorium"
description = "Sends everything flying from the detonation point."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#5A64C8"
taste_description = "air and bitterness"
@@ -89,6 +93,7 @@
/datum/reagent/liquid_dark_matter
name = "Liquid Dark Matter"
description = "Sucks everything into the detonation point."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#210021"
taste_description = "compressed bitterness"
@@ -96,6 +101,7 @@
/datum/reagent/gunpowder
name = "Gunpowder"
description = "Explodes. Violently."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#000000"
metabolization_rate = 0.05
@@ -120,6 +126,7 @@
/datum/reagent/rdx
name = "RDX"
description = "Military grade explosive"
+ category = "Pyrotechnics"
reagent_state = SOLID
color = "#FFFFFF"
taste_description = "salt"
@@ -127,6 +134,7 @@
/datum/reagent/tatp
name = "TaTP"
description = "Suicide grade explosive"
+ category = "Pyrotechnics"
reagent_state = SOLID
color = "#FFFFFF"
taste_description = "death"
@@ -134,6 +142,7 @@
/datum/reagent/flash_powder
name = "Flash Powder"
description = "Makes a very bright flash."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#C8C8C8"
taste_description = "salt"
@@ -141,6 +150,7 @@
/datum/reagent/smoke_powder
name = "Smoke Powder"
description = "Makes a large cloud of smoke that can carry reagents."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#C8C8C8"
taste_description = "smoke"
@@ -148,6 +158,7 @@
/datum/reagent/sonic_powder
name = "Sonic Powder"
description = "Makes a deafening noise."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#C8C8C8"
taste_description = "loud noises"
@@ -155,6 +166,7 @@
/datum/reagent/phlogiston
name = "Phlogiston"
description = "Catches you on fire and makes you ignite."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#FA00AF"
taste_description = "burning"
@@ -179,6 +191,7 @@
/datum/reagent/napalm
name = "Napalm"
description = "Very flammable."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#FA00AF"
taste_description = "burning"
@@ -206,6 +219,7 @@
/datum/reagent/cryostylane
name = "Cryostylane"
description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Cryostylane slowly cools all other reagents in the container 0K."
+ category = "Pyrotechnics"
color = "#0000DC"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
taste_description = "bitterness"
@@ -227,6 +241,7 @@
/datum/reagent/pyrosium
name = "Pyrosium"
description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly heats all other reagents in the container."
+ category = "Pyrotechnics"
color = "#64FAC8"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
taste_description = "bitterness"
@@ -242,6 +257,7 @@
/datum/reagent/teslium //Teslium. Causes periodic shocks, and makes shocks against the target much more effective.
name = "Teslium"
description = "An unstable, electrically-charged metallic slurry. Periodically electrocutes its victim, and makes electrocutions against them more deadly. Excessively heating teslium results in dangerous destabilization. Do not allow to come into contact with water."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#20324D" //RGB: 32, 50, 77
metabolization_rate = 0.5 * REAGENTS_METABOLISM
@@ -273,6 +289,7 @@
/datum/reagent/teslium/energized_jelly
name = "Energized Jelly"
description = "Electrically-charged jelly. Boosts jellypeople's nervous system, but only shocks other lifeforms."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#CAFF43"
taste_description = "jelly"
@@ -291,6 +308,7 @@
/datum/reagent/firefighting_foam
name = "Firefighting Foam"
description = "A historical fire suppressant. Originally believed to simply displace oxygen to starve fires, it actually interferes with the combustion reaction itself. Vastly superior to the cheap water-based extinguishers found on NT vessels."
+ category = "Pyrotechnics"
reagent_state = LIQUID
color = "#A6FAFF55"
taste_description = "the inside of a fire extinguisher"
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index d95bd68759c7..6045779f6030 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -7,6 +7,7 @@
color = "#CF3600" // rgb: 207, 54, 0
taste_description = "bitterness"
taste_mult = 1.2
+ category = "Toxin"
var/toxpwr = 1.5
var/silent_toxin = FALSE //won't produce a pain message when processed by liver/life() if there isn't another non-silent toxin present.
@@ -254,11 +255,13 @@
name = "Mindbreaker Toxin"
description = "A powerful hallucinogen. Not a thing to be messed with. For some mental patients. it counteracts their symptoms and anchors them to reality."
color = "#B31008" // rgb: 139, 166, 233
+ metabolization_rate = 0.1 * REAGENTS_METABOLISM
toxpwr = 0
taste_description = "sourness"
/datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/carbon/M)
- M.hallucination += 5
+ if(!M.has_quirk(/datum/quirk/insanity))
+ M.hallucination += 5
return ..()
/datum/reagent/toxin/plantbgone
@@ -766,7 +769,8 @@
/datum/reagent/toxin/heparin/on_mob_life(mob/living/carbon/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
- H.bleed_rate = min(H.bleed_rate + 2, 8)
+ for(var/obj/item/bodypart/BP in H.get_bleeding_parts())
+ BP.adjust_bleeding(BP.bleeding * 0.1)
H.adjustBruteLoss(1, 0) //Brute damage increases with the amount they're bleeding
. = 1
return ..() || .
@@ -970,18 +974,13 @@
taste_description = "bone hurting"
overdose_threshold = 50
-/datum/reagent/toxin/bonehurtingjuice/on_mob_add(mob/living/carbon/M)
- M.say("oof ouch my bones", forced = /datum/reagent/toxin/bonehurtingjuice)
-
/datum/reagent/toxin/bonehurtingjuice/on_mob_life(mob/living/carbon/M)
M.adjustStaminaLoss(7.5, 0)
if(prob(20))
- switch(rand(1, 3))
+ switch(rand(1, 2))
if(1)
- M.say(pick("oof.", "ouch.", "my bones.", "oof ouch.", "oof ouch my bones."), forced = /datum/reagent/toxin/bonehurtingjuice)
- if(2)
M.manual_emote(pick("oofs silently.", "looks like their bones hurt.", "grimaces, as though their bones hurt."))
- if(3)
+ if(2)
to_chat(M, "Your bones hurt!")
return ..()
@@ -996,7 +995,6 @@
bp.receive_damage(0, 0, 200)
else //SUCH A LUST FOR REVENGE!!!
to_chat(M, "A phantom limb hurts!")
- M.say("Why are we still here, just to suffer?", forced = /datum/reagent/toxin/bonehurtingjuice)
return ..()
/datum/reagent/toxin/bungotoxin
diff --git a/code/modules/reagents/chemistry/reagents/trickwine_reagents.dm b/code/modules/reagents/chemistry/reagents/trickwine_reagents.dm
index df76f85b1f64..be5e2ce35f9a 100644
--- a/code/modules/reagents/chemistry/reagents/trickwine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/trickwine_reagents.dm
@@ -115,7 +115,7 @@
M.adjust_bodytemperature(5 * TEMPERATURE_DAMAGE_COEFFICIENT, M.get_body_temp_normal())
if(ishuman(M))
var/mob/living/carbon/human/H = M
- H.bleed_rate = max(H.bleed_rate - 0.25, 0)
+ H.heal_bleeding(0.25)
return ..()
/datum/reagent/consumable/ethanol/trickwine/hearth_wine/expose_mob(mob/living/M, method=TOUCH, reac_volume)
@@ -180,15 +180,13 @@
/datum/reagent/consumable/ethanol/trickwine/prism_wine/on_mob_metabolize(mob/living/carbon/human/M)
..()
ADD_TRAIT(M, TRAIT_REFLECTIVE, "trickwine")
- if(M.physiology.burn_mod <= initial(M.physiology.burn_mod))
- M.physiology.burn_mod *= 0.5
+ M.physiology.burn_mod *= 0.5
M.add_filter("prism-wine", 2, list("type"="outline", "color"="#8FD7DF", "size"=1))
M.visible_message("[M] seems to shimmer with power!")
/datum/reagent/consumable/ethanol/trickwine/prism_wine/on_mob_end_metabolize(mob/living/carbon/human/M)
REMOVE_TRAIT(M, TRAIT_REFLECTIVE, "trickwine")
- if(M.physiology.burn_mod > initial(M.physiology.burn_mod))
- M.physiology.burn_mod *= 2
+ M.physiology.burn_mod *= 2
M.remove_filter("prism-wine")
M.visible_message("[M] has returned to normal!")
..()
diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm
index b2e275bc0631..2397d67a1d2c 100644
--- a/code/modules/reagents/chemistry/recipes/medicine.dm
+++ b/code/modules/reagents/chemistry/recipes/medicine.dm
@@ -315,28 +315,13 @@ WS End */
required_reagents = list(/datum/reagent/medicine/lavaland_extract = 1, /datum/reagent/medicine/bonefixingjuice = 1, /datum/reagent/titanium = 5)
/datum/chemical_reaction/pure_soulus_dust_hollow
- results = list(/datum/reagent/medicine/soulus/pure = 10,)
- required_reagents = list(/datum/reagent/medicine/soulus = 20, /datum/reagent/medicine/system_cleaner = 1, /datum/reagent/water/hollowwater = 10)
+ results = list(/datum/reagent/medicine/soulus/pure = 20,)
+ required_reagents = list(/datum/reagent/medicine/soulus = 20, /datum/reagent/water/hollowwater = 10)
/datum/chemical_reaction/pure_soulus_dust_holy
- results = list(/datum/reagent/medicine/soulus/pure = 10,)
- required_reagents = list(/datum/reagent/medicine/soulus = 20, /datum/reagent/medicine/system_cleaner = 1, /datum/reagent/water/holywater = 10)
+ results = list(/datum/reagent/medicine/soulus/pure = 20,)
+ required_reagents = list(/datum/reagent/medicine/soulus = 20, /datum/reagent/water/holywater = 10)
/datum/chemical_reaction/chartreuse
results = list(/datum/reagent/medicine/chartreuse = 10)
required_reagents = list(/datum/reagent/medicine/puce_essence = 5, /datum/reagent/consumable/tinlux = 5, /datum/reagent/consumable/entpoly = 1)
-
-/datum/chemical_reaction/molten_bubbles
- results = list(/datum/reagent/medicine/molten_bubbles = 30)
- required_reagents = list(/datum/reagent/clf3 = 10, /datum/reagent/consumable/space_cola = 20, /datum/reagent/medicine/leporazine = 1, /datum/reagent/medicine/lavaland_extract = 1)
-
-/datum/chemical_reaction/plasma_bubbles
- results = list(/datum/reagent/medicine/molten_bubbles/plasma = 3)
- required_reagents = list(/datum/reagent/medicine/molten_bubbles = 3, /datum/reagent/toxin/plasma = 2)
-
-/datum/chemical_reaction/sand_bubbles
- results = list(/datum/reagent/medicine/molten_bubbles/sand = 3)
- required_reagents = list(/datum/reagent/medicine/molten_bubbles = 3, /datum/reagent/silicon = 2)
-
-/datum/chemical_reaction/sand_bubbles/plasma // Subbing plasma bubbles for reg
- required_reagents = list(/datum/reagent/medicine/molten_bubbles/plasma = 3, /datum/reagent/silicon = 2)
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index 10cd8ffc72eb..e7494191d1df 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -56,7 +56,7 @@
/datum/chemical_reaction/adamantinesolidification/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
for(var/i = 1, i <= created_volume, i++)
- new /obj/item/stack/sheet/mineral/adamantine(location)
+ new /obj/item/stack/sheet/mineral/hidden/hellstone(location)
/datum/chemical_reaction/silversolidification
required_reagents = list(/datum/reagent/silver = 20, /datum/reagent/consumable/frostoil = 5, /datum/reagent/carbon = 10)
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index 97290d54213f..d3bf1e211290 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -425,7 +425,7 @@
required_other = TRUE
/datum/chemical_reaction/slime/adamantine/on_reaction(datum/reagents/holder)
- new /obj/item/stack/sheet/mineral/adamantine(get_turf(holder.my_atom))
+ new /obj/item/stack/sheet/mineral/hidden/hellstone(get_turf(holder.my_atom))
..()
//Bluespace
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index d63debc16e41..bfecd046f977 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -1,7 +1,7 @@
/obj/item/reagent_containers
name = "Container"
desc = "..."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/beakers.dmi'
icon_state = null
w_class = WEIGHT_CLASS_TINY
var/amount_per_transfer_from_this = 5
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index d72389224fd9..6c5691f83f73 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -38,7 +38,7 @@
/obj/item/reagent_containers/blood/random/Initialize()
icon_state = "bloodpack"
- blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L")
+ blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L", "E", "Coolant")
return ..()
/obj/item/reagent_containers/blood/APlus
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index ee288feb0bac..149743c47e3c 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -184,12 +184,12 @@ Borg Shaker
accepts_reagent_upgrades = FALSE
reagent_ids = list(/datum/reagent/consumable/applejuice, /datum/reagent/consumable/banana, /datum/reagent/consumable/coffee,
- /datum/reagent/consumable/cream, /datum/reagent/consumable/dr_gibb, /datum/reagent/consumable/grenadine,
+ /datum/reagent/consumable/cream, /datum/reagent/consumable/tadrixx, /datum/reagent/consumable/grenadine,
/datum/reagent/consumable/ice, /datum/reagent/consumable/lemonjuice, /datum/reagent/consumable/lemon_lime,
/datum/reagent/consumable/limejuice, /datum/reagent/consumable/menthol, /datum/reagent/consumable/milk,
/datum/reagent/consumable/nothing, /datum/reagent/consumable/orangejuice, /datum/reagent/consumable/peachjuice,
- /datum/reagent/consumable/sodawater, /datum/reagent/consumable/space_cola, /datum/reagent/consumable/spacemountainwind,
- /datum/reagent/consumable/pwr_game, /datum/reagent/consumable/shamblers, /datum/reagent/consumable/soymilk,
+ /datum/reagent/consumable/sodawater, /datum/reagent/consumable/space_cola, /datum/reagent/consumable/comet_trail,
+ /datum/reagent/consumable/pacfuel, /datum/reagent/consumable/shoal_punch, /datum/reagent/consumable/soymilk,
/datum/reagent/consumable/space_up, /datum/reagent/consumable/sugar, /datum/reagent/consumable/tea,
/datum/reagent/consumable/tomatojuice, /datum/reagent/consumable/tonic, /datum/reagent/water,
/datum/reagent/consumable/pineapplejuice, /datum/reagent/consumable/sol_dry,
diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm
index 5645ed54957e..df7949c9c654 100644
--- a/code/modules/reagents/reagent_containers/bottle.dm
+++ b/code/modules/reagents/reagent_containers/bottle.dm
@@ -275,12 +275,6 @@
desc = "A small bottle containing Bio Virus Antidote Kit."
list_reagents = list(/datum/reagent/vaccine/fungal_tb = 30)
-/obj/item/reagent_containers/glass/bottle/necropolis_seed
- name = "bowl of blood"
- desc = "A clay bowl containing a fledgling spire, preserved in blood. When consumed, allows the user to transform into an avatar of the Necropolis. A robust virologist may be able to unlock its full potential..."
- icon_state = "mortar_bone"
- spawned_disease = /datum/disease/advance/necropolis
-
//Oldstation.dmm chemical storage bottles
/obj/item/reagent_containers/glass/bottle/hydrogen
@@ -439,39 +433,3 @@
/obj/item/reagent_containers/glass/bottle/morphine/sleeper
cap_on = FALSE
-
-//types of syrups
-
-/obj/item/reagent_containers/food/drinks/bottle/syrup_bottle/caramel
- name = "bottle of caramel syrup"
- desc = "A pump bottle containing caramalized sugar, also known as caramel. Do not lick."
- list_reagents = list(/datum/reagent/consumable/caramel = 50)
-
-/obj/item/reagent_containers/food/drinks/bottle/syrup_bottle/liqueur
- name = "bottle of coffee liqueur syrup"
- desc = "A pump bottle containing mexican coffee-flavoured liqueur syrup. In production since 1936, HONK."
- list_reagents = list(/datum/reagent/consumable/ethanol/kahlua = 50)
-
-//Coffeepots: for reference, a standard cup is 30u, to allow 20u for sugar/sweetener/milk/creamer
-/obj/item/reagent_containers/food/drinks/bottle/coffeepot
- icon = 'icons/obj/food/containers.dmi'
- name = "coffeepot"
- desc = "A large pot for dispensing that ambrosia of corporate life known to mortals only as coffee. Contains 4 standard cups."
- volume = 120
- icon_state = "coffeepot"
- fill_icon_state = "coffeepot"
- fill_icon_thresholds = list(0, 1, 30, 60, 100)
-
-/obj/item/reagent_containers/glass/coffee_cup
- name = "coffee cup"
- desc = "A heat-formed plastic coffee cup. Can theoretically be used for other hot drinks, if you're feeling adventurous."
- icon = 'icons/obj/machines/coffeemaker.dmi'
- icon_state = "coffee_cup_e"
- base_icon_state = "coffee_cup"
- possible_transfer_amounts = list(10)
- volume = 30
- spillable = TRUE
-
-/obj/item/reagent_containers/glass/coffee_cup/update_icon_state()
- icon_state = reagents.total_volume ? base_icon_state : "[base_icon_state]_e"
- return ..()
diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm
index 63acf014b214..248586792679 100644
--- a/code/modules/reagents/reagent_containers/dropper.dm
+++ b/code/modules/reagents/reagent_containers/dropper.dm
@@ -1,7 +1,7 @@
/obj/item/reagent_containers/dropper
name = "dropper"
desc = "A dropper. Holds up to 5 units."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/beakers.dmi'
icon_state = "dropper0"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(1, 2, 3, 4, 5)
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 6682a9ba7943..62661594c06e 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -40,7 +40,7 @@
if(M != user)
M.visible_message("[user] attempts to feed [M] something from [src].", \
"[user] attempts to feed you something from [src].")
- if(!do_mob(user, M))
+ if(!do_after(user, target = M))
return
if(!reagents || !reagents.total_volume)
return // The drink might be empty after the delay, such as by spam-feeding
@@ -118,7 +118,7 @@
/obj/item/reagent_containers/glass/beaker
name = "beaker"
desc = "A beaker. It can hold up to 50 units."
- icon = 'icons/obj/chemical.dmi' //Should I modularize this? Yes. Will I do it?
+ icon = 'icons/obj/chemical/beakers.dmi'
icon_state = "beaker"
item_state = "beaker"
custom_materials = list(/datum/material/glass=500)
@@ -216,6 +216,10 @@
/obj/item/reagent_containers/glass/beaker/large/fuel
list_reagents = list(/datum/reagent/fuel = 100)
+/obj/item/reagent_containers/glass/beaker/large/napalm
+ list_reagents = list(/datum/reagent/napalm = 100)
+ cap_on = FALSE
+
/obj/item/reagent_containers/glass/beaker/synthflesh
list_reagents = list(/datum/reagent/medicine/synthflesh = 50)
@@ -296,7 +300,6 @@
/obj/item/reagent_containers/glass/filter
name = "seperatory funnel"
desc = "A crude tool created by welding several beakers together. It would probably be useful for seperating reagents."
- icon = 'icons/obj/chemical.dmi'
icon_state = "beakerfilter"
item_state = "beaker"
volume = 100
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index 7efe82893918..78326279b6f9 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -395,7 +395,7 @@
to_chat(user, "You remove [vial] from [src].")
vial = null
update_appearance()
- playsound(loc, 'sound/weapons/empty.ogg', 50, 1)
+ playsound(loc, SOUND_EMPTY_MAG, 50, 1)
else
to_chat(user, "This hypo isn't loaded!")
return
@@ -490,7 +490,7 @@
if(L != user)
L.visible_message("[user] is trying to inject [L] with [src]!", \
"[user] is trying to inject [L] with [src]!")
- if(!do_mob(user, L, inject_wait))
+ if(!do_after(user, inject_wait, L))
return
if(!penetrates && !L.can_inject(user, 1))
return
@@ -501,7 +501,7 @@
L.visible_message("[user] uses the [src] on [L]!", \
"[user] uses the [src] on [L]!")
else
- if(!do_mob(user, L, inject_self))
+ if(!do_after(user, inject_self, L))
return
if(!penetrates && !L.can_inject(user, 1))
return
@@ -526,7 +526,7 @@
if(L != user)
L.visible_message("[user] is trying to spray [L] with [src]!", \
"[user] is trying to spray [L] with [src]!")
- if(!do_mob(user, L, spray_wait))
+ if(!do_after(user, spray_wait, L))
return
if(!penetrates && !L.can_inject(user, 1))
return
@@ -537,7 +537,7 @@
L.visible_message("[user] uses the [src] on [L]!", \
"[user] uses the [src] on [L]!")
else
- if(!do_mob(user, L, spray_self))
+ if(!do_after(user, spray_self, L))
return
if(!penetrates && !L.can_inject(user, 1))
return
diff --git a/code/modules/reagents/reagent_containers/hypovial.dm b/code/modules/reagents/reagent_containers/hypovial.dm
index f16984cd7e5b..7696bf0d950a 100644
--- a/code/modules/reagents/reagent_containers/hypovial.dm
+++ b/code/modules/reagents/reagent_containers/hypovial.dm
@@ -2,7 +2,7 @@
/obj/item/reagent_containers/glass/bottle/vial
name = "broken hypovial"
desc = "A hypovial compatible with most hyposprays."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/hypovial.dmi'
icon_state = "hypovial"
spillable = FALSE
var/comes_with = list() //Easy way of doing this.
diff --git a/code/modules/reagents/reagent_containers/jug.dm b/code/modules/reagents/reagent_containers/jug.dm
index a863be707c48..80ebcbb4d5b3 100644
--- a/code/modules/reagents/reagent_containers/jug.dm
+++ b/code/modules/reagents/reagent_containers/jug.dm
@@ -1,7 +1,7 @@
/obj/item/reagent_containers/glass/chem_jug
name = "chemical jug"
desc = "A large jug used for storing bulk ammounts chemicals. Provided with a tamper seal which ensures that the contents are pure"
- icon = 'icons/obj/chem_jug.dmi'
+ icon = 'icons/obj/chemical/chem_jug.dmi'
icon_state = "chem_jug"
item_state = "sheet-plastic"
w_class = WEIGHT_CLASS_BULKY
diff --git a/code/modules/reagents/reagent_containers/medigel.dm b/code/modules/reagents/reagent_containers/medigel.dm
index 7542f606a899..7e85c0c6d1ca 100644
--- a/code/modules/reagents/reagent_containers/medigel.dm
+++ b/code/modules/reagents/reagent_containers/medigel.dm
@@ -1,7 +1,7 @@
/obj/item/reagent_containers/medigel
name = "medical gel"
desc = "A medical gel applicator bottle, designed for precision application, with an unscrewable cap."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/medicine.dmi'
icon_state = "medigel"
item_state = "spraycan"
lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi'
@@ -48,7 +48,7 @@
if(M == user)
M.visible_message("[user] attempts to [apply_method] [src] on [user.p_them()]self.")
if(self_delay)
- if(!do_mob(user, M, self_delay))
+ if(!do_after(user, self_delay, M))
return
if(!reagents || !reagents.total_volume)
return
@@ -58,7 +58,7 @@
log_combat(user, M, "attempted to apply", src, reagents.log_list())
M.visible_message("[user] attempts to [apply_method] [src] on [M].", \
"[user] attempts to [apply_method] [src] on you.")
- if(!do_mob(user, M))
+ if(!do_after(user, target = M))
return
if(!reagents || !reagents.total_volume)
return
diff --git a/code/modules/reagents/reagent_containers/mortar.dm b/code/modules/reagents/reagent_containers/mortar.dm
index 3c1443bfb9d2..a397176b6afa 100644
--- a/code/modules/reagents/reagent_containers/mortar.dm
+++ b/code/modules/reagents/reagent_containers/mortar.dm
@@ -10,14 +10,14 @@ to accommodate additional materials.
name = "pestle"
desc = "An ancient, simple tool used in conjunction with a mortar to grind or juice items."
w_class = WEIGHT_CLASS_SMALL
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/mortar.dmi'
icon_state = "pestle"
force = 7
/obj/item/reagent_containers/glass/mortar
name = "mortar"
desc = "A specially formed bowl of ancient design. It is possible to crush or juice items placed in it using a pestle; however the process, unlike modern methods, is slow and physically exhausting. Alt click to eject the item."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/mortar.dmi'
icon_state = "mortar_wood"
fill_icon_state = "mortar"
fill_icon_thresholds = list(1, 20, 40, 80, 100)
@@ -136,11 +136,3 @@ to accommodate additional materials.
/obj/item/reagent_containers/glass/mortar/mushroom
icon_state = "mortar_shroom"
custom_materials = list(/datum/material/biomass = MINERAL_MATERIAL_AMOUNT)
-
-// Mushroom recipes are all over the place so I'm just putting it here
-/datum/crafting_recipe/mushroom_mortar
- name = "Mushroom Mortar"
- result = /obj/item/reagent_containers/glass/mortar/mushroom
- reqs = list(/obj/item/reagent_containers/food/snacks/grown/ash_flora/shavings = 5)
- time = 30
- category = CAT_PRIMAL
diff --git a/code/modules/reagents/reagent_containers/patch.dm b/code/modules/reagents/reagent_containers/patch.dm
index c8187cd8843d..d244b05f55d3 100644
--- a/code/modules/reagents/reagent_containers/patch.dm
+++ b/code/modules/reagents/reagent_containers/patch.dm
@@ -1,7 +1,7 @@
/obj/item/reagent_containers/pill/patch
name = "chemical patch"
desc = "A chemical patch for touch based applications."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/medicine.dmi'
icon_state = "bandaid"
item_state = "bandaid"
possible_transfer_amounts = list()
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index 534d3b052bc6..9cac6c3a52a2 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -1,7 +1,7 @@
/obj/item/reagent_containers/pill
name = "pill"
desc = "A tablet or capsule."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/medicine.dmi'
icon_state = "pill"
item_state = "pill"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
@@ -34,14 +34,14 @@
if(M == user)
M.visible_message("[user] attempts to [apply_method] [src].")
if(self_delay)
- if(!do_mob(user, M, self_delay))
+ if(!do_after(user, self_delay, M))
return FALSE
to_chat(M, "You [apply_method] [src].")
else
M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \
"[user] attempts to force you to [apply_method] [src].")
- if(!do_mob(user, M))
+ if(!do_after(user, target = M))
return FALSE
M.visible_message("[user] forces [M] to [apply_method] [src].", \
"[user] forces you to [apply_method] [src].")
@@ -288,5 +288,5 @@ WS End */
/obj/item/reagent_containers/spray/rhigoxane
name = "medical spray (rhigoxane)"
desc = "A medical spray bottle.This one contains rhigoxane, it is used to treat burns and cool down temperature if applied with spray."
- icon_state = "sprayer_large"
+ icon_state = "sprayer"
list_reagents = list(/datum/reagent/medicine/rhigoxane = 100)
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index da4c5d0b68fa..b4f46e6e4c19 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -2,7 +2,7 @@
name = "spray bottle"
desc = "A spray bottle, with an unscrewable top."
icon = 'icons/obj/janitor.dmi'
- icon_state = "sprayer_large"
+ icon_state = "sprayer"
item_state = "cleaner"
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
@@ -162,7 +162,7 @@
/obj/item/reagent_containers/spray/cleaner
name = "space cleaner"
desc = "BLAM!-brand non-foaming space cleaner!"
- icon_state = "cleaner"
+ icon_state = "sprayer"
volume = 100
list_reagents = list(/datum/reagent/space_cleaner = 100)
amount_per_transfer_from_this = 2
@@ -213,16 +213,6 @@
/obj/item/reagent_containers/spray/waterflower/attack_self(mob/user) //Don't allow changing how much the flower sprays
return
-///Subtype used for the lavaland clown ruin.
-/obj/item/reagent_containers/spray/waterflower/superlube
- name = "clown flower"
- desc = "A delightly devilish flower... you got a feeling where this is going."
- icon = 'icons/obj/chemical.dmi'
- icon_state = "clownflower"
- amount_per_transfer_from_this = 3 // WS edit - superlube fix
- volume = 30
- list_reagents = list(/datum/reagent/lube/superlube = 30)
-
/obj/item/reagent_containers/spray/waterflower/cyborg
reagent_flags = NONE
volume = 100
@@ -270,8 +260,8 @@
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "chemsprayer"
item_state = "chemsprayer"
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
throwforce = 0
w_class = WEIGHT_CLASS_NORMAL
stream_mode = 1
@@ -308,8 +298,8 @@
desc = "A utility used to spray large amounts of cleaning reagents in a given area. It regenerates space cleaner by itself but it's unable to be fueled by normal means."
icon_state = "chemsprayer_janitor"
item_state = "chemsprayer_janitor"
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ lefthand_file = GUN_LEFTHAND_ICON
+ righthand_file = GUN_RIGHTHAND_ICON
reagent_flags = NONE
list_reagents = list(/datum/reagent/space_cleaner = 1000)
volume = 1000
@@ -345,26 +335,9 @@
volume = 100
list_reagents = list(/datum/reagent/toxin/plantbgone = 100)
-/obj/item/reagent_containers/spray/syndicate
- name = "suspicious spray bottle"
- desc = "A spray bottle, with a high performance plastic nozzle. The color scheme makes you feel slightly uneasy."
- icon = 'icons/obj/chemical.dmi'
- icon_state = "sprayer_sus_8"
- item_state = "sprayer_sus"
- lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
- spray_range = 4
- stream_range = 2
- volume = 100
- custom_premium_price = 900
-
-/obj/item/reagent_containers/spray/syndicate/Initialize()
- . = ..()
- icon_state = pick("sprayer_sus_1", "sprayer_sus_2", "sprayer_sus_3", "sprayer_sus_4", "sprayer_sus_5","sprayer_sus_6", "sprayer_sus_7", "sprayer_sus_8")
-
/obj/item/reagent_containers/spray/medical
name = "medical spray bottle"
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/medicine.dmi'
icon_state = "sprayer_med_red"
item_state = "sprayer_med_red"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
@@ -388,13 +361,3 @@
if("sprayer_med_blue")
item_state = "sprayer_med_blue"
M.update_inv_hands()
-
-/*WS Begin - No Cobby
-
-/obj/item/reagent_containers/spray/hercuri
- name = "medical spray (hercuri)"
- desc = "A medical spray bottle.This one contains hercuri, a medicine used to negate the effects of dangerous high-temperature environments. Careful not to freeze the patient!"
- icon_state = "sprayer_large"
- list_reagents = list(/datum/reagent/medicine/c2/hercuri = 100)
-
-WS End */
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index f0901e416b25..5d11dcb720ee 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -86,7 +86,7 @@
target.visible_message("[user] is trying to take a blood sample from [target]!", \
"[user] is trying to take a blood sample from you!")
busy = TRUE
- if(!do_mob(user, target, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
+ if(!do_after(user, target = target, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
busy = FALSE
return
if(reagents.total_volume >= reagents.maximum_volume)
@@ -136,7 +136,7 @@
if(L != user)
L.visible_message("[user] is trying to inject [L]!", \
"[user] is trying to inject you!")
- if(!do_mob(user, L, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
+ if(!do_after(user, target = L, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE)))
return
if(!reagents.total_volume)
return
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 9f2861218418..111428528242 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -131,7 +131,7 @@
user.visible_message("[user] starts climbing into [src].", "You start climbing into [src]...")
else
target.visible_message("[user] starts putting [target] into [src].", "[user] starts putting you into [src]!")
- if(do_mob(user, target, 20))
+ if(do_after(user, 2 SECONDS, target))
if (!loc)
return
target.forceMove(src)
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index 77525a1f309e..96e027a55476 100644
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -388,8 +388,8 @@
/obj/item/sales_tagger/attackby(obj/item/I, mob/living/user, params)
. = ..()
- if(istype(I, /obj/item/card/id))
- var/obj/item/card/id/potential_acc = I
+ if(isbankcard(I))
+ var/obj/item/card/bank/potential_acc = I
if(potential_acc.registered_account)
payments_acc = potential_acc.registered_account
playsound(src, 'sound/machines/ping.ogg', 40, TRUE)
diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm
index f80188dc62d2..3ddce78ae6e5 100644
--- a/code/modules/religion/religion_sects.dm
+++ b/code/modules/religion/religion_sects.dm
@@ -135,8 +135,6 @@
if(iscyborg(L))
var/mob/living/silicon/robot/R = L
var/charge_amt = 50
- if(L.mind?.holy_role == HOLY_ROLE_HIGHPRIEST)
- charge_amt *= 2
R.cell?.charge += charge_amt
R.visible_message("[user] charges [R] with the power of [GLOB.deity]!")
to_chat(R, "You are charged by the power of [GLOB.deity]!")
@@ -151,7 +149,7 @@
var/did_we_charge = FALSE
var/obj/item/organ/stomach/ethereal/eth_stomach = H.getorganslot(ORGAN_SLOT_STOMACH)
if(istype(eth_stomach))
- eth_stomach.adjust_charge(3 * ETHEREAL_CHARGE_SCALING_MULTIPLIER) //WS Edit -- Ethereal Charge Scaling
+ eth_stomach.adjust_charge(3 * ELZUOSE_CHARGE_SCALING_MULTIPLIER) //WS Edit -- Ethereal Charge Scaling
did_we_charge = TRUE
//if we're not targetting a robot part we stop early
diff --git a/code/modules/religion/religion_structures.dm b/code/modules/religion/religion_structures.dm
index f9c449c56e9b..e9d76ca8bf5a 100644
--- a/code/modules/religion/religion_structures.dm
+++ b/code/modules/religion/religion_structures.dm
@@ -18,10 +18,6 @@
var/can_i_see = FALSE
if(isobserver(user))
can_i_see = TRUE
- else if(isliving(user))
- var/mob/living/L = user
- if(L.mind?.holy_role)
- can_i_see = TRUE
if(!can_i_see || !sect_to_altar)
return
@@ -57,62 +53,6 @@
pushed_mob.forceMove(loc)
return ..()
-/obj/structure/altar_of_gods/attackby(obj/item/C, mob/user, params)
- //If we can sac, we do nothing but the sacrifice instead of typical attackby behavior (IE damage the structure)
- if(sect_to_altar?.can_sacrifice(C,user))
- sect_to_altar.on_sacrifice(C,user)
- return TRUE
- . = ..()
- //everything below is assumed you're bibling it up
- if(!istype(C, /obj/item/storage/book/bible))
- return
- if(sect_to_altar)
- if(!sect_to_altar.rites_list)
- to_chat(user, "Your sect doesn't have any rites to perform!")
- return
- var/rite_select = input(user,"Select a rite to perform!","Select a rite",null) in sect_to_altar.rites_list
- if(!rite_select || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
- to_chat(user,"You cannot perform the rite at this time.")
- return
- var/selection2type = sect_to_altar.rites_list[rite_select]
- performing_rite = new selection2type(src)
- if(!performing_rite.perform_rite(user, src))
- QDEL_NULL(performing_rite)
- else
- performing_rite.invoke_effect(user, src)
- sect_to_altar.adjust_favor(-performing_rite.favor_cost)
- QDEL_NULL(performing_rite)
- return
-
- if(user.mind.holy_role != HOLY_ROLE_HIGHPRIEST)
- to_chat(user, "You are not the high priest, and therefore cannot select a religious sect.")
- return
-
- var/list/available_options = generate_available_sects(user)
- if(!available_options)
- return
-
- var/sect_select = input(user,"Select a sect (You CANNOT revert this decision!)","Select a Sect",null) in available_options
- if(!sect_select || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
- to_chat(user,"You cannot select a sect at this time.")
- return
- var/type_selected = available_options[sect_select]
- GLOB.religious_sect = new type_selected()
- for(var/i in GLOB.player_list)
- if(!isliving(i))
- continue
- var/mob/living/am_i_holy_living = i
- if(!am_i_holy_living.mind?.holy_role)
- continue
- GLOB.religious_sect.on_conversion(am_i_holy_living)
- sect_to_altar = GLOB.religious_sect
- if(sect_to_altar.altar_icon)
- icon = sect_to_altar.altar_icon
- if(sect_to_altar.altar_icon_state)
- icon_state = sect_to_altar.altar_icon_state
-
-
-
/obj/structure/altar_of_gods/proc/generate_available_sects(mob/user) //eventually want to add sects you get from unlocking certain achievements
. = list()
for(var/i in subtypesof(/datum/religion_sect))
diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm
index 1c1caa5de1d6..67b337400315 100644
--- a/code/modules/religion/rites.dm
+++ b/code/modules/religion/rites.dm
@@ -18,7 +18,7 @@
return FALSE
to_chat(user, "You begin to perform the rite of [name]...")
if(!ritual_invocations)
- if(do_after(user, target = user, delay = ritual_length))
+ if(do_after(user, ritual_length))
return TRUE
return FALSE
var/first_invoke = TRUE
diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm
index 84d948f7c2b9..bb56a69adf2b 100644
--- a/code/modules/research/bepis.dm
+++ b/code/modules/research/bepis.dm
@@ -17,7 +17,7 @@
density = TRUE
layer = ABOVE_MOB_LAYER
use_power = IDLE_POWER_USE
- active_power_usage = 1500
+ active_power_usage = ACTIVE_DRAW_HIGH
circuit = /obj/item/circuitboard/machine/bepis
var/banking_amount = 100
@@ -58,11 +58,11 @@
say("Deposited [deposit_value] credits into storage.")
update_icon_state()
return
- if(istype(O, /obj/item/card/id))
- var/obj/item/card/id/Card = O
- if(Card.registered_account)
- account = Card.registered_account
- account_name = Card.registered_name
+ if(istype(O, /obj/item/card/bank))
+ var/obj/item/card/bank/bank_card = O
+ if(bank_card.registered_account)
+ account = bank_card.registered_account
+ account_name = bank_card.registered_name
say("New account detected. Console Updated.")
else
say("No account detected on card. Aborting.")
@@ -254,7 +254,7 @@
return
calcsuccess()
use_power(MACHINE_OPERATION * power_saver) //This thing should eat your APC battery if you're not careful.
- use_power = IDLE_POWER_USE //Machine shuts off after use to prevent spam and look better visually.
+ set_idle_power() //Machine shuts off after use to prevent spam and look better visually.
update_icon_state()
if("amount")
var/input = text2num(params["amount"])
@@ -262,9 +262,9 @@
banking_amount = input
if("toggle_power")
if(use_power == ACTIVE_POWER_USE)
- use_power = IDLE_POWER_USE
+ set_idle_power()
else
- use_power = ACTIVE_POWER_USE
+ set_active_power()
update_icon_state()
if("account_reset")
if(use_power == IDLE_POWER_USE)
diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm
index 9bdc513289e1..5e45c756c881 100644
--- a/code/modules/research/designs.dm
+++ b/code/modules/research/designs.dm
@@ -138,16 +138,15 @@ other types of metals and chemistry for reagents).
blueprints[1] = new /datum/design/c10mm()
-/obj/item/disk/design_disk/adv/disposable_gun
+/obj/item/disk/design_disk/disposable_gun
name = "design disk - disposable gun"
desc = "A design disk containing designs for a cheap and disposable gun."
illustration = "gun"
max_blueprints = 2
-/obj/item/disk/design_disk/adv/disposable_gun/Initialize()
+/obj/item/disk/design_disk/disposable_gun/Initialize()
. = ..()
blueprints[1] = new /datum/design/disposable_gun()
- blueprints[2] = new /datum/design/pizza_disposable_gun()
/obj/item/disk/design_disk/clip_mechs
name = "design disk - CLIP mecha modifications"
diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm
index f580502e0b7a..517c8691c92d 100644
--- a/code/modules/research/designs/autolathe_designs.dm
+++ b/code/modules/research/designs/autolathe_designs.dm
@@ -491,6 +491,14 @@
build_path = /obj/item/shovel
category = list("initial","Misc", "Tool Designs")
+/datum/design/pickaxe
+ name = "Pickaxe"
+ id = "pickaxe"
+ build_type = AUTOLATHE | PROTOLATHE
+ materials = list(/datum/material/iron = 1000)
+ build_path = /obj/item/pickaxe
+ category = list("initial","Tools", "Tool Designs")
+
/datum/design/spade
name = "Spade"
id = "spade"
@@ -647,7 +655,7 @@
id = "bounced_radio"
build_type = AUTOLATHE
materials = list(/datum/material/iron = 75, /datum/material/glass = 25)
- build_path = /obj/item/radio/off
+ build_path = /obj/item/radio
category = list("initial", "T-Comm")
/datum/design/intercom_frame
@@ -870,6 +878,22 @@
build_path = /obj/item/ammo_box/c556mmHITP/surplus
category = list("initial", "Security", "Ammo")
+/datum/design/generic_ammo_box
+ name = "Generic Ammo Box"
+ id = "ammo-generic"
+ build_type = AUTOLATHE | PROTOLATHE
+ materials = list(/datum/material/iron = 1500)
+ build_path = /obj/item/ammo_box/generic
+ category = list("initial", "Security", "Ammo")
+
+/datum/design/ammo_can
+ name = "Ammo Can"
+ id = "ammo-can"
+ build_type = AUTOLATHE | PROTOLATHE
+ materials = list(/datum/material/iron = 500)
+ build_path = /obj/item/storage/toolbox/ammo
+ category = list("initial", "Security", "Ammo")
+
/datum/design/cleaver
name = "Butcher's Cleaver"
id = "cleaver"
@@ -1175,6 +1199,14 @@
build_path = /obj/item/assembly/control
category = list("initial","Misc")
+/datum/design/holofield_control
+ name = "Holofield Controller"
+ id = "holofield"
+ build_type = AUTOLATHE
+ materials = list(/datum/material/iron = 100, /datum/material/glass = 50)
+ build_path = /obj/item/assembly/control/shieldwallgen
+ category = list("initial","Misc")
+
/datum/design/trashbag
name="Trash Bag"
id="trashbag"
diff --git a/code/modules/research/designs/limbgrower_designs.dm b/code/modules/research/designs/limbgrower_designs.dm
index 1f13dcd3b3b4..a57d31117c8d 100644
--- a/code/modules/research/designs/limbgrower_designs.dm
+++ b/code/modules/research/designs/limbgrower_designs.dm
@@ -8,7 +8,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 25)
build_path = /obj/item/bodypart/l_arm
- category = list("initial",SPECIES_HUMAN,SPECIES_LIZARD,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ETHEREAL,SPECIES_RACHNID,SPECIES_VOX,SPECIES_KEPORI,SPECIES_ABDUCTOR,SPECIES_FLYPERSON,SPECIES_POD,SPECIES_SKELETON,SPECIES_SNAIL)
+ category = list("initial",SPECIES_HUMAN,SPECIES_SARATHI,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ELZUOSE,SPECIES_RACHNID,SPECIES_VOX,SPECIES_KEPORI,SPECIES_ABDUCTOR,SPECIES_FLYPERSON,SPECIES_POD,SPECIES_SKELETON,SPECIES_SNAIL)
/datum/design/rightarm
name = "Right Arm"
@@ -16,7 +16,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 25)
build_path = /obj/item/bodypart/r_arm
- category = list("initial",SPECIES_HUMAN,SPECIES_LIZARD,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ETHEREAL,SPECIES_RACHNID,SPECIES_VOX,SPECIES_KEPORI,SPECIES_ABDUCTOR,SPECIES_FLYPERSON,SPECIES_POD,SPECIES_SKELETON,SPECIES_SNAIL)
+ category = list("initial",SPECIES_HUMAN,SPECIES_SARATHI,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ELZUOSE,SPECIES_RACHNID,SPECIES_VOX,SPECIES_KEPORI,SPECIES_ABDUCTOR,SPECIES_FLYPERSON,SPECIES_POD,SPECIES_SKELETON,SPECIES_SNAIL)
/datum/design/leftleg
name = "Left Leg"
@@ -24,7 +24,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 25)
build_path = /obj/item/bodypart/leg/left
- category = list("initial",SPECIES_HUMAN,SPECIES_LIZARD,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ETHEREAL,SPECIES_RACHNID,SPECIES_VOX,SPECIES_KEPORI,SPECIES_ABDUCTOR,SPECIES_FLYPERSON,SPECIES_POD,SPECIES_SKELETON,SPECIES_SNAIL)
+ category = list("initial",SPECIES_HUMAN,SPECIES_SARATHI,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ELZUOSE,SPECIES_RACHNID,SPECIES_VOX,SPECIES_KEPORI,SPECIES_ABDUCTOR,SPECIES_FLYPERSON,SPECIES_POD,SPECIES_SKELETON,SPECIES_SNAIL)
/datum/design/rightleg
name = "Right Leg"
@@ -32,7 +32,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 25)
build_path = /obj/item/bodypart/leg/right
- category = list("initial",SPECIES_HUMAN,SPECIES_LIZARD,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ETHEREAL,SPECIES_RACHNID,SPECIES_VOX,SPECIES_KEPORI,SPECIES_ABDUCTOR,SPECIES_FLYPERSON,SPECIES_POD,SPECIES_SKELETON,SPECIES_SNAIL)
+ category = list("initial",SPECIES_HUMAN,SPECIES_SARATHI,SPECIES_MOTH,SPECIES_PLASMAMAN,SPECIES_ELZUOSE,SPECIES_RACHNID,SPECIES_VOX,SPECIES_KEPORI,SPECIES_ABDUCTOR,SPECIES_FLYPERSON,SPECIES_POD,SPECIES_SKELETON,SPECIES_SNAIL)
/datum/design/digitigrade/leftleg
name = "Digitigrade Left Leg"
@@ -40,7 +40,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 25)
build_path = /obj/item/bodypart/leg/left/lizard/digitigrade
- category = list("initial",SPECIES_LIZARD)
+ category = list("initial",SPECIES_SARATHI)
/datum/design/digitigrade/rightleg
name = "Digitigrade Right Leg"
@@ -48,7 +48,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 25)
build_path = /obj/item/bodypart/leg/right/lizard/digitigrade
- category = list("initial",SPECIES_LIZARD)
+ category = list("initial",SPECIES_SARATHI)
//Non-limb limb designs
@@ -123,7 +123,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 20)
build_path = /obj/item/organ/tail/lizard/fake
- category = list("initial",SPECIES_LIZARD)
+ category = list("initial",SPECIES_SARATHI)
/datum/design/lizard_tongue
name = "Forked Tongue"
@@ -131,7 +131,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 10)
build_path = /obj/item/organ/tongue/lizard
- category = list("initial",SPECIES_LIZARD)
+ category = list("initial",SPECIES_SARATHI)
// someday this will get uncommented
// /datum/design/monkey_tail
@@ -180,7 +180,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 10)
build_path = /obj/item/organ/tongue/lizard
- category = list("initial",SPECIES_LIZARD)
+ category = list("initial",SPECIES_SARATHI)
/datum/design/plasmaman_lungs
name = "Plasma Filter"
@@ -220,7 +220,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 20, /datum/reagent/consumable/liquidelectricity = 20)
build_path = /obj/item/organ/stomach/ethereal
- category = list("initial",SPECIES_ETHEREAL)
+ category = list("initial",SPECIES_ELZUOSE)
/datum/design/ethereal_tongue
name = "Ethereal Tongue"
@@ -228,7 +228,7 @@
build_type = LIMBGROWER
reagents_list = list(/datum/reagent/medicine/synthflesh = 10, /datum/reagent/consumable/liquidelectricity = 10)
build_path = /obj/item/organ/tongue/ethereal
- category = list("initial",SPECIES_ETHEREAL)
+ category = list("initial",SPECIES_ELZUOSE)
/datum/design/moth_eyes
name = "Moth Eyes"
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index 3cf848089652..5f79bbbf12e5 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -9,6 +9,13 @@
build_path = /obj/item/circuitboard/machine/smes
category = list ("Engineering Machinery")
+/datum/design/board/ssu
+ name = "Machine Design (Suit Storage Unit Board)"
+ desc = "The circuit board for a suit storage unit."
+ id = "ssu"
+ build_path = /obj/item/circuitboard/machine/suit_storage_unit
+ category = list ("Engineering Machinery")
+
/datum/design/board/circulator
name = "Machine Design (Circulator Board)"
desc = "The circuit board for a circulator."
@@ -247,7 +254,6 @@
build_path = /obj/item/circuitboard/machine/rdserver
category = list("Research Machinery", "initial", "Equipment")
-
/datum/design/board/mechfab
name = "Machine Design (Exosuit Fabricator Board)"
desc = "The circuit board for an Exosuit Fabricator."
@@ -471,6 +477,14 @@
category = list ("Misc. Machinery")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
+/datum/design/board/ship_gravity
+ name = "Machine Design (Ship Gravity Generator Board)"
+ desc = "The circuit board for a ship-sized gravity generator."
+ id = "ship_gravity"
+ build_type = AUTOLATHE | IMPRINTER
+ build_path = /obj/item/circuitboard/machine/ship_gravity
+ category = list("Misc. Machinery", "initial", "Equipment")
+
/datum/design/board/ntnet_relay
name = "Machine Design (NTNet Relay Board)"
desc = "The circuit board for a wireless network relay."
@@ -630,6 +644,14 @@
category = list ("Shuttle Machinery")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
+/datum/design/board/shuttle/engine/fire
+ name = "Machine Design (Combustion Thruster Board)"
+ desc = "The circuit board for a combustion thruster."
+ id = "engine_fire"
+ build_path = /obj/item/circuitboard/machine/shuttle/engine/fire
+ category = list("Shuttle Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
+
/datum/design/board/shuttle/engine/electric
name = "Machine Design (Ion Thruster Board)"
desc = "The circuit board for an ion thruster."
@@ -662,6 +684,14 @@
category = list ("Shuttle Machinery")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
+/datum/design/board/shuttle/engine/fire_heater
+ name = "Machine Design (Combustion Engine Heater Board)"
+ desc = "The circuit board for a combustion engine heater."
+ id = "engine_fire_heater"
+ build_path = /obj/item/circuitboard/machine/shuttle/fire_heater
+ category = list("Shuttle Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
+
/datum/design/board/shuttle/engine/smes
name = "Machine Design (Engine Heater Board)"
desc = "The circuit board for an engine heater."
diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm
index dfd373dcd3d7..46dddeb0c586 100644
--- a/code/modules/research/designs/mechfabricator_designs.dm
+++ b/code/modules/research/designs/mechfabricator_designs.dm
@@ -445,7 +445,7 @@
id = "honk_torso"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_torso
- materials = list(/datum/material/iron=20000,/datum/material/glass = 10000,/datum/material/bananium=10000)
+ materials = list(/datum/material/iron=20000,/datum/material/glass = 10000,/datum/material/hellstone=10000)
construction_time = 300
category = list("H.O.N.K")
@@ -454,7 +454,7 @@
id = "honk_head"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_head
- materials = list(/datum/material/iron=10000,/datum/material/glass = 5000,/datum/material/bananium=5000)
+ materials = list(/datum/material/iron=10000,/datum/material/glass = 5000,/datum/material/hellstone=5000)
construction_time = 200
category = list("H.O.N.K")
@@ -463,7 +463,7 @@
id = "honk_left_arm"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_left_arm
- materials = list(/datum/material/iron=15000,/datum/material/bananium=5000)
+ materials = list(/datum/material/iron=15000,/datum/material/hellstone=5000)
construction_time = 200
category = list("H.O.N.K")
@@ -472,7 +472,7 @@
id = "honk_right_arm"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_right_arm
- materials = list(/datum/material/iron=15000,/datum/material/bananium=5000)
+ materials = list(/datum/material/iron=15000,/datum/material/hellstone=5000)
construction_time = 200
category = list("H.O.N.K")
@@ -481,7 +481,7 @@
id = "honk_left_leg"
build_type = MECHFAB
build_path =/obj/item/mecha_parts/part/honker_left_leg
- materials = list(/datum/material/iron=20000,/datum/material/bananium=5000)
+ materials = list(/datum/material/iron=20000,/datum/material/hellstone=5000)
construction_time = 200
category = list("H.O.N.K")
@@ -490,7 +490,7 @@
id = "honk_right_leg"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/part/honker_right_leg
- materials = list(/datum/material/iron=20000,/datum/material/bananium=5000)
+ materials = list(/datum/material/iron=20000,/datum/material/hellstone=5000)
construction_time = 200
category = list("H.O.N.K")
@@ -657,7 +657,7 @@
id = "mech_mousetrap_mortar"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar
- materials = list(/datum/material/iron=20000,/datum/material/bananium=5000)
+ materials = list(/datum/material/iron=20000,/datum/material/hellstone=5000)
construction_time = 300
category = list("Exosuit Equipment")
@@ -666,7 +666,7 @@
id = "mech_banana_mortar"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar
- materials = list(/datum/material/iron=20000,/datum/material/bananium=5000)
+ materials = list(/datum/material/iron=20000,/datum/material/hellstone=5000)
construction_time = 300
category = list("Exosuit Equipment")
@@ -675,7 +675,7 @@
id = "mech_honker"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/honker
- materials = list(/datum/material/iron=20000,/datum/material/bananium=10000)
+ materials = list(/datum/material/iron=20000,/datum/material/hellstone=10000)
construction_time = 500
category = list("Exosuit Equipment")
@@ -684,7 +684,7 @@
id = "mech_punching_face"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove
- materials = list(/datum/material/iron=20000,/datum/material/bananium=7500)
+ materials = list(/datum/material/iron=20000,/datum/material/hellstone=7500)
construction_time = 400
category = list("Exosuit Equipment")
@@ -769,7 +769,7 @@
id = "borg_transform_clown"
build_type = MECHFAB
build_path = /obj/item/borg/upgrade/transform/clown
- materials = list(/datum/material/iron = 15000, /datum/material/glass = 15000, /datum/material/bananium = 1000)
+ materials = list(/datum/material/iron = 15000, /datum/material/glass = 15000, /datum/material/hellstone = 1000)
construction_time = 120
category = list("Cyborg Upgrade Modules")
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index 6e4a1b61d06f..95a03b829608 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -395,6 +395,17 @@
category = list("Misc", "Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+/datum/design/cyberimp_joywire
+ name = "\improper Midi-Sed pleasure vivifier"
+ desc = "A widely popular (and addictive) implant produced by Miditeke-Sedari Tokoce that stimulates the brain's pleasure centers. Dramatically increases mood, but interferes with taste reception even if uninstalled."
+ id = "ci-joywire"
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 60
+ materials = list(/datum/material/iron = 600, /datum/material/glass = 600, /datum/material/gold = 500, /datum/material/silver = 500)
+ build_path = /obj/item/organ/cyberimp/brain/joywire
+ category = list("Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+
/datum/design/cyberimp_nutriment
name = "Nutriment Pump Implant"
desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving."
@@ -465,7 +476,7 @@
desc = "Makes death amusing."
id = "implant_trombone"
build_type = PROTOLATHE
- materials = list(/datum/material/glass = 500, /datum/material/bananium = 500)
+ materials = list(/datum/material/glass = 500, /datum/material/hellstone = 500)
build_path = /obj/item/implantcase/sad_trombone
category = list("Medical Designs")
diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm
index 2cddc5043c3f..aa221c2b21a7 100644
--- a/code/modules/research/designs/mining_designs.dm
+++ b/code/modules/research/designs/mining_designs.dm
@@ -8,7 +8,7 @@
id = "cargoexpress"//the coder reading this
build_type = IMPRINTER
materials = list(/datum/material/glass = 1000)
- build_path = /obj/item/circuitboard/computer/cargo/express
+ build_path = /obj/item/circuitboard/computer/cargo
category = list("Mining Designs")
departmental_flags = DEPARTMENTAL_FLAG_CARGO
diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm
index eeca189ef2dc..816cd4f9fdbf 100644
--- a/code/modules/research/designs/misc_designs.dm
+++ b/code/modules/research/designs/misc_designs.dm
@@ -130,7 +130,7 @@
desc = "Damn son, where'd you find this?"
id = "air_horn"
build_type = PROTOLATHE
- materials = list(/datum/material/iron = 4000, /datum/material/bananium = 1000)
+ materials = list(/datum/material/iron = 4000, /datum/material/hellstone = 1000)
build_path = /obj/item/bikehorn/airhorn
category = list("Equipment")
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index 930cc96be9c8..c444336adde5 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -67,36 +67,6 @@
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_BALLISTICS
-/datum/design/pin_testing
- name = "Test-Range Firing Pin"
- desc = "This safety firing pin allows firearms to be operated within proximity to a firing range."
- id = "pin_testing"
- build_type = PROTOLATHE
- materials = list(/datum/material/iron = 500, /datum/material/glass = 300)
- build_path = /obj/item/firing_pin/test_range
- category = list("Firing Pins")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY
-
-/datum/design/pin_mindshield
- name = "Mindshield Firing Pin"
- desc = "This is a security firing pin which only authorizes users who are mindshield-implanted."
- id = "pin_loyalty"
- build_type = PROTOLATHE
- materials = list(/datum/material/silver = 600, /datum/material/diamond = 600, /datum/material/uranium = 200)
- build_path = /obj/item/firing_pin/implant/mindshield
- category = list("Firing Pins")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY
-
-/datum/design/pin
- name = "Standard Firing Pin"
- desc = "A simple, electronic firing pin which is required in most standardized modern weapons."
- id = "pin_standard"
- build_type = PROTOLATHE
- materials = list(/datum/material/silver = 600, /datum/material/diamond = 600, /datum/material/uranium = 200)
- build_path = /obj/item/firing_pin
- category = list("Firing Pins")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_BALLISTICS
-
/datum/design/stunrevolver
name = "Tesla Canon"
desc = "A high-tech cannon that fires internal, reusable bolt cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers"
@@ -588,7 +558,7 @@
id = "suppressor"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 2000, /datum/material/silver = 500)
- build_path = /obj/item/suppressor
+ build_path = /obj/item/attachment/silencer
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
@@ -612,15 +582,6 @@
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
-/datum/design/cleric_mace
- name = "Cleric Mace"
- desc = "A mace fit for a cleric. Useful for bypassing plate armor, but too bulky for much else."
- id = "cleric_mace"
- build_type = AUTOLATHE
- materials = list(MAT_CATEGORY_RIGID = 12000)
- build_path = /obj/item/melee/cleric_mace
- category = list("Imported")
-
/datum/design/stun_boomerang
name = "OZtek Boomerang"
desc = "Uses reverse flow gravitodynamics to flip its personal gravity back to the thrower mid-flight. Also functions similar to a stun baton."
@@ -680,14 +641,6 @@
build_path = /obj/item/gun/ballistic/automatic/pistol/disposable
category = list("Imported")
-/datum/design/pizza_disposable_gun
- name = "Pizza Disposable Gun"
- id = "disposable_pizza"
- build_type = AUTOLATHE
- materials = list(/datum/material/pizza = 4000)
- build_path = /obj/item/gun/ballistic/automatic/pistol/disposable/pizza
- category = list("Imported")
-
//SRM Ballistics
/datum/design/doublebarrel
name = "Double Barrel Shotgun"
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index 9016d60515e7..ce473ad739cb 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -355,16 +355,6 @@
C.name = "Cup of Suspicious Liquid"
C.desc = "It has a large hazard symbol printed on the side in fading ink."
investigate_log("Experimentor has made a cup of [chosenchem] coffee.", INVESTIGATE_EXPERIMENTOR)
- else if(prob(EFFECT_PROB_VERYLOW-badThingCoeff))
- var/turf/start = get_turf(src)
- var/mob/M = locate(/mob/living) in view(src, 3)
- var/turf/MT = get_turf(M)
- if(MT)
- visible_message("[src] dangerously overheats, launching a flaming fuel orb!")
- investigate_log("Experimentor has launched a fireball at [M]!", INVESTIGATE_EXPERIMENTOR)
- var/obj/projectile/magic/aoe/fireball/FB = new /obj/projectile/magic/aoe/fireball(start)
- FB.preparePixelProjectile(MT, start)
- FB.fire()
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("[src] malfunctions, melting [exp_on] and releasing a burst of flame!")
explosion(loc, -1, 0, 0, 0, 0, flame_range = 2)
diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm
index 36a22dac2cc7..0f8c2eb53c1d 100644
--- a/code/modules/research/machinery/_production.dm
+++ b/code/modules/research/machinery/_production.dm
@@ -2,6 +2,10 @@
name = "technology fabricator"
desc = "Makes researched and prototype items with materials and energy."
layer = BELOW_OBJ_LAYER
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_LOW
+ active_power_usage = ACTIVE_DRAW_HIGH
+ power_channel = AREA_USAGE_EQUIP
var/consoleless_interface = FALSE //Whether it can be used without a console.
var/efficiency_coeff = 1 //Materials needed / coeff = actual.
var/list/categories = list()
@@ -96,6 +100,7 @@
if(notify_admins)
investigate_log("[key_name(usr)] built [amount] of [path] at [src]([type]).", INVESTIGATE_RESEARCH)
message_admins("[ADMIN_LOOKUPFLW(usr)] has built [amount] of [path] at \a [src]([type]).")
+ set_idle_power()
for(var/i in 1 to amount)
var/obj/item/I = new path(get_turf(src))
if(efficient_with(I.type))
@@ -142,11 +147,11 @@
if(materials.on_hold())
say("Mineral access is on hold, please contact the quartermaster.")
return FALSE
- var/power = 1000
+ var/power = active_power_usage
amount = clamp(amount, 1, 50)
for(var/M in D.materials)
power += round(D.materials[M] * amount / 35)
- power = min(3000, power)
+ power = min(ACTIVE_DRAW_EXTREME, power)
use_power(power)
var/coeff = efficient_with(D.build_path) ? efficiency_coeff : 1
var/list/efficient_mats = list()
@@ -168,6 +173,7 @@
flick(production_animation, src)
var/timecoeff = D.lathe_time_factor / efficiency_coeff
addtimer(CALLBACK(src, PROC_REF(reset_busy)), (30 * timecoeff * amount) ** 0.5)
+ set_active_power()
addtimer(CALLBACK(src, PROC_REF(do_print), D.build_path, amount, efficient_mats, D.dangerous_construction), (32 * timecoeff * amount) ** 0.8)
return TRUE
diff --git a/code/modules/research/nanites/nanite_chamber.dm b/code/modules/research/nanites/nanite_chamber.dm
index d5d5fa79e8ca..eb50a70af0bb 100644
--- a/code/modules/research/nanites/nanite_chamber.dm
+++ b/code/modules/research/nanites/nanite_chamber.dm
@@ -9,8 +9,8 @@
use_power = IDLE_POWER_USE
anchored = TRUE
density = TRUE
- idle_power_usage = 50
- active_power_usage = 300
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_HIGH
var/locked = FALSE
var/breakout_time = 1200
diff --git a/code/modules/research/nanites/nanite_programs/sensor.dm b/code/modules/research/nanites/nanite_programs/sensor.dm
index dacdc0481408..47ad3c037a22 100644
--- a/code/modules/research/nanites/nanite_programs/sensor.dm
+++ b/code/modules/research/nanites/nanite_programs/sensor.dm
@@ -272,7 +272,7 @@
"Human" = /datum/species/human,
"Sarathi" = /datum/species/lizard,
"Moth" = /datum/species/moth,
- "Elzuose" = /datum/species/ethereal,
+ "Elzuose" = /datum/species/elzuose,
"Pod" = /datum/species/pod,
"Fly" = /datum/species/fly,
"Jelly" = /datum/species/jelly,
diff --git a/code/modules/research/nanites/public_chamber.dm b/code/modules/research/nanites/public_chamber.dm
index 9e39486c2052..b149fda6baae 100644
--- a/code/modules/research/nanites/public_chamber.dm
+++ b/code/modules/research/nanites/public_chamber.dm
@@ -8,8 +8,8 @@
use_power = IDLE_POWER_USE
anchored = TRUE
density = TRUE
- idle_power_usage = 50
- active_power_usage = 300
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_HIGH
var/cloud_id = 1
var/locked = FALSE
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 28de68605681..dbca44b757b9 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -183,7 +183,7 @@
prereq_ids = list("base")
design_ids = list("solarcontrol", "solarassembly", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", "scanner_gate",
"atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "mesons", "welding_goggles", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod",
- "apc_control", "cell_charger", "power control", "airlock_board", "firelock_board", "aac_electronics", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine",
+ "apc_control", "cell_charger", "ssu", "power control", "airlock_board", "firelock_board", "aac_electronics", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine",
"oxygen_tank", "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "pneumatic_seal", "shieldwallgen", "shieldwallgen_atmos") //WS edit, solar assemblies from lathe
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 5000
@@ -521,7 +521,7 @@
display_name = "Cybernetic Implants"
description = "Electronic implants that improve humans."
prereq_ids = list("adv_biotech", "datatheory")
- design_ids = list("ci-nutriment", "ci-breather", "ci-gloweyes", "ci-welding", "ci-medhud", "ci-sechud", "ci-diaghud")
+ design_ids = list("ci-nutriment", "ci-breather", "ci-gloweyes", "ci-welding", "ci-medhud", "ci-sechud", "ci-diaghud", "ci-joywire")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -632,7 +632,7 @@
display_name = "Weapon Development Technology"
description = "Our researchers have found new ways to weaponize just about everything now."
prereq_ids = list("engineering")
- design_ids = list("pin_testing", "tele_shield","gun_cell")
+ design_ids = list("tele_shield","gun_cell")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
@@ -641,19 +641,10 @@
display_name = "Advanced Weapon Development Technology"
description = "Our weapons are breaking the rules of reality by now."
prereq_ids = list("adv_engi", "weaponry")
- design_ids = list("pin_loyalty", "gun_cell_upgraded", "gun_cell_large")
+ design_ids = list("gun_cell_upgraded", "gun_cell_large")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
-/datum/techweb_node/firingpin
- id = "firingpin"
- display_name = "Pin Security Decompilation"
- description = "A resource-intensive hacking operation, allowing for the creation of pins without a mindshield brake."
- prereq_ids = list("adv_weaponry")
- design_ids = list("pin_standard")
- research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 15000)
- export_price = 5000
-
/datum/techweb_node/electric_weapons
id = "electronic_weapons"
display_name = "Electric Weapons"
@@ -1145,7 +1136,7 @@
display_name = "Basic Shuttle Research"
description = "Research the technology required to create and use basic shuttles."
prereq_ids = list("bluespace_travel", "adv_engi")
- design_ids = list("engine_plasma", "engine_ion", "engine_heater", "engine_smes", "shuttle_helm", "rapid_shuttle_designator")
+ design_ids = list("engine_plasma", "engine_fire", "engine_ion", "engine_heater", "engine_fire_heater", "engine_smes", "shuttle_helm", "rapid_shuttle_designator")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
diff --git a/code/modules/research/xenobiology/crossbreeding/_potions.dm b/code/modules/research/xenobiology/crossbreeding/_potions.dm
index 1fb17ea4d1fd..fc9d9ef06c6a 100644
--- a/code/modules/research/xenobiology/crossbreeding/_potions.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_potions.dm
@@ -8,7 +8,7 @@ Slimecrossing Potions
/obj/item/slimepotion/extract_cloner
name = "extract cloning potion"
desc = "An more powerful version of the extract enhancer potion, capable of cloning regular slime extracts."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potpurple"
/obj/item/slimepotion/extract_cloner/afterattack(obj/item/target, mob/user , proximity)
@@ -36,7 +36,7 @@ Slimecrossing Potions
/obj/item/slimepotion/peacepotion
name = "pacification potion"
desc = "A light pink solution of chemicals, smelling like liquid peace. And mercury salts."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potlightpink"
/obj/item/slimepotion/peacepotion/attack(mob/living/M, mob/user)
@@ -70,7 +70,7 @@ Slimecrossing Potions
/obj/item/slimepotion/lovepotion
name = "love potion"
desc = "A pink chemical mix thought to inspire feelings of love."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potpink"
/obj/item/slimepotion/lovepotion/attack(mob/living/M, mob/user)
@@ -104,7 +104,7 @@ Slimecrossing Potions
/obj/item/slimepotion/spaceproof
name = "slime pressurization potion"
desc = "A potent chemical sealant that will render any article of clothing airtight. Has two uses."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potblue"
var/uses = 2
@@ -136,14 +136,14 @@ Slimecrossing Potions
/obj/item/slimepotion/enhancer/max
name = "extract maximizer"
desc = "An extremely potent chemical mix that will maximize a slime extract's uses."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potpurple"
//Lavaproofing potion - Charged Red
/obj/item/slimepotion/lavaproof
name = "slime lavaproofing potion"
desc = "A strange, reddish goo said to repel lava as if it were water, without reducing flammability. Has two uses."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potred"
resistance_flags = LAVA_PROOF | FIRE_PROOF
var/uses = 2
@@ -174,7 +174,7 @@ Slimecrossing Potions
/obj/item/slimepotion/slime_reviver
name = "slime revival potion"
desc = "Infused with plasma and compressed gel, this brings dead slimes back to life."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potsilver"
/obj/item/slimepotion/slime_reviver/attack(mob/living/simple_animal/slime/M, mob/user)
@@ -198,7 +198,7 @@ Slimecrossing Potions
/obj/item/slimepotion/slime/chargedstabilizer
name = "slime omnistabilizer"
desc = "An extremely potent chemical mix that will stop a slime from mutating completely."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potcyan"
/obj/item/slimepotion/slime/chargedstabilizer/attack(mob/living/simple_animal/slime/M, mob/user)
diff --git a/code/modules/research/xenobiology/crossbreeding/_weapons.dm b/code/modules/research/xenobiology/crossbreeding/_weapons.dm
index 29ea3fbd4298..ac663059d0c0 100644
--- a/code/modules/research/xenobiology/crossbreeding/_weapons.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_weapons.dm
@@ -65,54 +65,3 @@ Slimecrossing Weapons
/obj/item/shield/adamantineshield/ComponentInitialize()
. = ..()
AddComponent(/datum/component/two_handed, require_twohands=TRUE, force_wielded=15)
-
-//Bloodchiller - Chilling Green
-/obj/item/gun/magic/bloodchill
- name = "blood chiller"
- desc = "A horrifying weapon made of your own bone and blood vessels. It shoots slowing globules of your own blood. Ech."
- icon = 'icons/obj/slimecrossing.dmi'
- icon_state = "bloodgun"
- item_state = "bloodgun"
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
- item_flags = ABSTRACT | DROPDEL
- w_class = WEIGHT_CLASS_HUGE
- slot_flags = NONE
- force = 5
- max_charges = 1 //Recharging costs blood.
- recharge_rate = 1
- ammo_type = /obj/item/ammo_casing/magic/bloodchill
- fire_sound = 'sound/effects/attackblob.ogg'
-
-/obj/item/gun/magic/bloodchill/Initialize()
- . = ..()
- ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT)
-
-/obj/item/gun/magic/bloodchill/process()
- charge_tick++
- if(charge_tick < recharge_rate || charges >= max_charges)
- return 0
- charge_tick = 0
- var/mob/living/M = loc
- if(istype(M) && M.blood_volume >= 20)
- charges++
- M.blood_volume -= 20
- if(charges == 1)
- recharge_newshot()
- return 1
-
-/obj/item/ammo_casing/magic/bloodchill
- projectile_type = /obj/projectile/magic/bloodchill
-
-/obj/projectile/magic/bloodchill
- name = "blood ball"
- icon_state = "pulse0_bl"
- damage = 0
- damage_type = OXY
- nodamage = TRUE
- hitsound = 'sound/effects/splat.ogg'
-
-/obj/projectile/magic/bloodchill/on_hit(mob/living/target)
- . = ..()
- if(isliving(target))
- target.apply_status_effect(/datum/status_effect/bloodchill)
diff --git a/code/modules/research/xenobiology/crossbreeding/charged.dm b/code/modules/research/xenobiology/crossbreeding/charged.dm
index 501ff548e08f..25aa79302918 100644
--- a/code/modules/research/xenobiology/crossbreeding/charged.dm
+++ b/code/modules/research/xenobiology/crossbreeding/charged.dm
@@ -146,7 +146,7 @@ Charged extracts:
effect_desc = "Creates bananium. Oh no."
/obj/item/slimecross/charged/pyrite/do_effect(mob/user)
- new /obj/item/stack/sheet/mineral/bananium(get_turf(user), 10)
+ new /obj/item/stack/sheet/mineral/hidden/hellstone(get_turf(user), 10)
user.visible_message("[src] solidifies with a horrifying banana stench!")
..()
diff --git a/code/modules/research/xenobiology/crossbreeding/chilling.dm b/code/modules/research/xenobiology/crossbreeding/chilling.dm
index 89fa16cca7f5..9fe7857c073b 100644
--- a/code/modules/research/xenobiology/crossbreeding/chilling.dm
+++ b/code/modules/research/xenobiology/crossbreeding/chilling.dm
@@ -235,29 +235,6 @@ Chilling extracts:
user.visible_message("[src] lets out a peaceful ring as it shatters, but nothing happens...")
..()
-/obj/item/slimecross/chilling/green
- colour = "green"
- effect_desc = "Creates a bone gun in the hand it is used in, which uses blood as ammo."
-
-/obj/item/slimecross/chilling/green/do_effect(mob/user)
- var/which_hand = "l_hand"
- if(!(user.active_hand_index % 2))
- which_hand = "r_hand"
- var/mob/living/L = user
- if(!istype(user))
- return
- var/obj/item/held = L.get_active_held_item() //This should be itself, but just in case...
- L.dropItemToGround(held)
- var/obj/item/gun/magic/bloodchill/gun = new(user)
- if(!L.put_in_hands(gun))
- qdel(gun)
- user.visible_message("[src] flash-freezes [user]'s arm, cracking the flesh horribly!")
- else
- user.visible_message("[src] chills and snaps off the front of the bone on [user]'s arm, leaving behind a strange, gun-like structure!")
- user.emote("scream")
- L.apply_damage(30,BURN,which_hand)
- ..()
-
/obj/item/slimecross/chilling/pink
colour = "pink"
effect_desc = "Creates a slime corgi puppy."
diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm
index 7cb7f8677408..75a1201d924a 100644
--- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm
+++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm
@@ -41,12 +41,12 @@ Regenerative extracts:
to_chat(user, "[src] will not work on the dead!")
return
if(H != user)
- if(!do_mob(user, H, slime_delay)) // 1 second delay
+ if(!do_after(user, slime_delay, H)) // 1 second delay
return FALSE
user.visible_message("[user] crushes the [src] over [H], the milky goo quickly regenerating some of [H.p_their()] injuries!",
"You squeeze the [src], and it bursts over [H], the milky goo regenerating some of [H.p_their()] injuries.")
else
- if(!do_mob(user, H, (slime_delay * 1.5))) // 1.5 second delay
+ if(!do_after(user, (slime_delay * 1.5), H)) // 1.5 second delay
return FALSE
user.visible_message("[user] crushes the [src] over [user.p_them()]self, the milky goo quickly regenerating some of [user.p_their()] injuries!",
"You squeeze the [src], and it bursts in your hand, splashing you with milky goo which quickly regenerates some of your injuries!")
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index 113f130562de..c907f11c1cfa 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -664,7 +664,7 @@
/obj/item/slimepotion/slime/docility
name = "docility potion"
desc = "A potent chemical mix that nullifies a slime's hunger, causing it to become docile and tame."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potsilver"
/obj/item/slimepotion/slime/docility/attack(mob/living/simple_animal/slime/M, mob/user)
@@ -695,7 +695,7 @@
/obj/item/slimepotion/slime/sentience
name = "intelligence potion"
desc = "A miraculous chemical mix that grants human like intelligence to living beings."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potpink"
var/list/not_interested = list()
var/being_used = FALSE
@@ -754,7 +754,7 @@
/obj/item/slimepotion/transference
name = "consciousness transference potion"
desc = "A strange slime-based chemical that, when used, allows the user to transfer their consciousness to a lesser being."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potorange"
var/prompted = 0
var/animal_type = SENTIENCE_ORGANIC
@@ -802,7 +802,7 @@
/obj/item/slimepotion/slime/steroid
name = "slime steroid"
desc = "A potent chemical mix that will cause a baby slime to generate more extract."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potred"
/obj/item/slimepotion/slime/steroid/attack(mob/living/simple_animal/slime/M, mob/user)
@@ -826,13 +826,13 @@
/obj/item/slimepotion/enhancer
name = "extract enhancer"
desc = "A potent chemical mix that will give a slime extract an additional use."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potpurple"
/obj/item/slimepotion/slime/stabilizer
name = "slime stabilizer"
desc = "A potent chemical mix that will reduce the chance of a slime mutating."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potcyan"
/obj/item/slimepotion/slime/stabilizer/attack(mob/living/simple_animal/slime/M, mob/user)
@@ -853,7 +853,7 @@
/obj/item/slimepotion/slime/mutator
name = "slime mutator"
desc = "A potent chemical mix that will increase the chance of a slime mutating."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potgreen"
/obj/item/slimepotion/slime/mutator/attack(mob/living/simple_animal/slime/M, mob/user)
@@ -878,7 +878,7 @@
/obj/item/slimepotion/speed
name = "slime speed potion"
desc = "A potent chemical mix that will reduce the slowdown from any item."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potyellow"
/obj/item/slimepotion/speed/afterattack(obj/C, mob/user, proximity)
@@ -913,7 +913,7 @@
/obj/item/slimepotion/fireproof
name = "slime chill potion"
desc = "A potent chemical mix that will fireproof any article of clothing. Has three uses."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potblue"
resistance_flags = FIRE_PROOF
var/uses = 3
@@ -945,7 +945,7 @@
/obj/item/slimepotion/genderchange
name = "gender change potion"
desc = "An interesting chemical mix that changes the biological gender of what its applied to. Cannot be used on things that lack gender entirely."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potlightpink"
/obj/item/slimepotion/genderchange/attack(mob/living/L, mob/user)
@@ -969,7 +969,7 @@
/obj/item/slimepotion/slime/renaming
name = "renaming potion"
desc = "A potion that allows a self-aware being to change what name it subconciously presents to the world."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potgreen"
var/being_used = FALSE
@@ -1002,7 +1002,7 @@
/obj/item/slimepotion/slime/slimeradio
name = "bluespace radio potion"
desc = "A strange chemical that grants those who ingest it the ability to broadcast and receive subscape radio waves."
- icon = 'icons/obj/chemical.dmi'
+ icon = 'icons/obj/chemical/misc.dmi'
icon_state = "potgrey"
/obj/item/slimepotion/slime/slimeradio/attack(mob/living/M, mob/user)
diff --git a/code/modules/ruins/icemoonruin_code/hotsprings.dm b/code/modules/ruins/icemoonruin_code/hotsprings.dm
deleted file mode 100644
index dd4d39e91a20..000000000000
--- a/code/modules/ruins/icemoonruin_code/hotsprings.dm
+++ /dev/null
@@ -1,56 +0,0 @@
-GLOBAL_LIST_EMPTY(cursed_minds)
-
-/**
- * Turns whoever enters into a mob or random person
- *
- * If mob is chosen, turns the person into a random animal type
- * If appearance is chosen, turns the person into a random human with a random species
- * This changes name, and changes their DNA as well
- * Random species is same as wizard swap event so people don't get killed ex: plasmamen
- * Once the spring is used, it cannot be used by the same mind ever again
- * After usage, teleports the user back to a random safe turf (so mobs are not killed by ice moon atmosphere)
- *
- */
-
-/turf/open/water/cursed_spring
- baseturfs = /turf/open/water/cursed_spring
- planetary_atmos = TRUE
- initial_gas_mix = ICEMOON_DEFAULT_ATMOS
-
-/turf/open/water/cursed_spring/Entered(atom/movable/thing, atom/oldLoc)
- . = ..()
- if(!isliving(thing))
- return
- var/mob/living/L = thing
- if(!L.client)
- return
- if(GLOB.cursed_minds[L.mind])
- return
- GLOB.cursed_minds[L.mind] = TRUE
- RegisterSignal(L.mind, COMSIG_PARENT_QDELETING, PROC_REF(remove_from_cursed))
- var/random_choice = pick("Mob", "Appearance")
- switch(random_choice)
- if("Mob")
- L = wabbajack(L, "animal")
- if("Appearance")
- var/mob/living/carbon/human/H = wabbajack(L, "humanoid")
- randomize_human(H)
- var/list/all_species = list()
- for(var/stype in subtypesof(/datum/species))
- var/datum/species/S = stype
- if(initial(S.changesource_flags) & RACE_SWAP)
- all_species += stype
- var/random_race = pick(all_species)
- H.set_species(random_race)
- H.dna.unique_enzymes = H.dna.generate_unique_enzymes()
- L = H
- var/turf/T = find_safe_turf()
- L.forceMove(T)
- to_chat(L, "You blink and find yourself in [get_area_name(T)].")
-
-/**
- * Deletes minds from the cursed minds list after their deletion
- *
- */
-/turf/open/water/cursed_spring/proc/remove_from_cursed(datum/mind/M)
- GLOB.cursed_minds -= M
diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm
deleted file mode 100644
index 1115224a6733..000000000000
--- a/code/modules/ruins/lavaland_ruin_code.dm
+++ /dev/null
@@ -1,89 +0,0 @@
-//If you're looking for spawners like ash walker eggs, check ghost_role_spawners.dm
-
-///Wizard tower item
-/obj/item/disk/design_disk/adv/knight_gear
- name = "Magic Disk of Smithing"
- illustration = "sword"
- color = "#6F6F6F"
-
-/obj/item/disk/design_disk/adv/knight_gear/Initialize()
- . = ..()
- var/datum/design/knight_armour/A = new
- var/datum/design/knight_helmet/H = new
- blueprints[1] = A
- blueprints[2] = H
-
-//lavaland_surface_seed_vault.dmm
-//Seed Vault
-
-/obj/effect/spawner/lootdrop/seed_vault
- name = "seed vault seeds"
- lootcount = 1
-
- loot = list(/obj/item/seeds/random = 10,
- /obj/item/seeds/cherry/bomb = 10,
- /obj/item/seeds/berry/glow = 10,
- /obj/item/seeds/sunflower/moonflower = 8
- )
-
-///Syndicate Listening Post
-
-/obj/effect/mob_spawn/human/lavaland_syndicate
- name = "Syndicate Bioweapon Scientist"
- roundstart = FALSE
- death = FALSE
- random = TRUE
- icon = 'icons/obj/machines/sleeper.dmi'
- icon_state = "sleeper_s"
- short_desc = "You are a syndicate science technician, employed in a top secret research facility developing biological weapons."
- flavour_text = "Reports of potential Nanotrasen fleet movement in your sector prompted you to initiate Operation Smokescreen, killing base power and taking your crew into cryosleep. You've awoken an unknown amount of time later as base security initiates an emergency reboot. Keep vigilant for whatever reawoke you, continue your research as best you can, and try to keep a low profile."
- important_info = "Prevent yourself and any Syndicate assets from being taken by Corporate forces."
- outfit = /datum/outfit/lavaland_syndicate
- assignedrole = "Lavaland Syndicate"
-
-/obj/effect/mob_spawn/human/lavaland_syndicate/special(mob/living/new_spawn)
- new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
-
-/datum/outfit/lavaland_syndicate
- name = "Lavaland Syndicate Agent"
- r_hand = /obj/item/gun/ballistic/automatic/sniper_rifle
- uniform = /obj/item/clothing/under/syndicate
- suit = /obj/item/clothing/suit/toggle/labcoat
- shoes = /obj/item/clothing/shoes/combat
- gloves = /obj/item/clothing/gloves/tackler/combat/insulated
- ears = /obj/item/radio/headset/syndicate/alt
- back = /obj/item/storage/backpack
- r_pocket = /obj/item/gun/ballistic/automatic/pistol
- id = /obj/item/card/id/syndicate/anyone
- implants = list(/obj/item/implant/weapons_auth)
-
-/datum/outfit/lavaland_syndicate/post_equip(mob/living/carbon/human/H)
- H.faction |= ROLE_SYNDICATE
-
-/obj/effect/mob_spawn/human/lavaland_syndicate/comms
- name = "Syndicate Comms Agent"
- short_desc = "You are a syndicate communications agent, employed in a top secret research facility developing biological weapons."
- flavour_text = "Reports of potential Nanotrasen fleet movement in your sector prompted you to initiate Operation Smokescreen, killing base power and taking your crew into cryosleep. You've awoken an unknown amount of time later as base security initiates an emergency reboot. Keep vigilant for whatever reawoke you, and try to keep a low profile. Use the communication equipment to monitor any local activity. Anyone nearby is presumed to be an agent of Nanotrasen: Sow disinformation to throw them off your trail. Do not let the base fall into enemy hands!"
- important_info = "Prevent yourself and any Syndicate assets from being taken by Corporate forces."
- outfit = /datum/outfit/lavaland_syndicate/comms
-
-/obj/effect/mob_spawn/human/lavaland_syndicate/comms/space
- short_desc = "You are a deep-cover syndicate agent, assigned to a small military listening post intended to keep an eye on Nanotrasen activity in the area. Increased military operations prompted you to follow Smokescreen protocol and go into cryosleep, leaving your base on minimal power."
- flavour_text = "Your base's emergency security system has reawoken you and brought the facility back to full power- It can only be presumed Nanotrasen personnel are close to locating you. Monitor any local activity as best you can, and try to keep a low profile. Use the communication equipment to attempt parlance, and sow disinformation to throw Nanotrasen off your trail."
- important_info = "Prevent yourself and any Syndicate assets from being taken by Corporate forces."
-
-/obj/effect/mob_spawn/human/lavaland_syndicate/comms/space/Initialize()
- . = ..()
- if(prob(90)) //only has a 10% chance of existing, otherwise it'll just be a NPC syndie.
- new /mob/living/simple_animal/hostile/syndicate/ranged(get_turf(src))
- return INITIALIZE_HINT_QDEL
-
-/datum/outfit/lavaland_syndicate/comms
- name = "Lavaland Syndicate Comms Agent"
- r_hand = /obj/item/melee/transforming/energy/sword/saber
- mask = /obj/item/clothing/mask/chameleon/gps
- suit = /obj/item/clothing/suit/armor/vest
-
-/obj/item/clothing/mask/chameleon/gps/Initialize()
- . = ..()
- AddComponent(/datum/component/gps, "Encrypted Signal")
diff --git a/code/modules/ruins/lavalandruin_code/biodome_clown_planet.dm b/code/modules/ruins/lavalandruin_code/biodome_clown_planet.dm
deleted file mode 100644
index 529d48cf551f..000000000000
--- a/code/modules/ruins/lavalandruin_code/biodome_clown_planet.dm
+++ /dev/null
@@ -1,7 +0,0 @@
-//////lavaland clown planet papers
-
-/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/escape
- default_raw_text = "If you dare not continue down this path of madness, escape can be found through the chute in this room."
-
-/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/hope
- default_raw_text = "Abandon hope, all ye who enter here."
diff --git a/code/modules/ruins/lavalandruin_code/biodome_winter.dm b/code/modules/ruins/lavalandruin_code/biodome_winter.dm
new file mode 100644
index 000000000000..85fed2a74324
--- /dev/null
+++ b/code/modules/ruins/lavalandruin_code/biodome_winter.dm
@@ -0,0 +1,9 @@
+
+/obj/item/paper/pamphlet/biodomelore
+ name = "Solarian Frontier Project Pamphlet"
+ default_raw_text = "
Extrasolar Biodome Project
The Most Serene Solar and Intersolar Confederation welcomes you to one of our many experimental biodomes out in the frontier. These facilities are developed and built as a collaboration with the Pionierskompanien and are to serve as extrasolar research bases for our most accomplished scientists and scribes. These facilities utilize breakthroughs in terraforming technology to create a comfortable, habitable environment in even the harshest of locales. Your purpose here is to research and report on the effectiveness of the technology utilized within the central dome, as well as maintain and protect the facility."
+
+/obj/item/paper/crumpled/bloody/winterbiodome
+ name = "hastily written note"
+ default_raw_text = "Scheiße, I knew this would happen eventually. Legions have been piling up outside for days, and one of my former coworkers was unwise enough to let them in.
...They're all dead. I can hear the legions outside. The display case with the Claris is locked tight, and I cant find anything to break the glass with.
Please forgive me. My time is up. If anyone finds this, the Claris is yours. Just avenge us."
+
diff --git a/code/modules/ruins/lavalandruin_code/codelab.dm b/code/modules/ruins/lavalandruin_code/codelab.dm
deleted file mode 100644
index 4cdbb4b132a5..000000000000
--- a/code/modules/ruins/lavalandruin_code/codelab.dm
+++ /dev/null
@@ -1,20 +0,0 @@
-/obj/item/paper/codelab
-
-/obj/item/paper/crumpled/codelab
-
-/obj/item/paper/codelab/reception
- name = "Reception Instructions"
- default_raw_text = "RECITE TO ANY GUESTS UNDER 'EXPERIMENTAL' GROUP: Welcome to the Nanotrasen Genetic Research Facility! Thank you for choosing to volunteer and progress genetic research by leaps and bounds. As stated in the contract, you will be here for the forseeable future helping the scientists further their studies. Remember that signing the contract means you cannot legally request a settlement for any injury or death that occurs during testing. Head to your chamber through the hall on the left and have a nice day!"
-
-/obj/item/paper/crumpled/codelab/subjectnote
- name = "Test Subjects Note"
- default_raw_text = "This testing had better be worth it. I've always wanted to have cat ears. Not sure what all that gooey stuff I saw was, but at least I'll be in the cryo cell away from it.
And whats up with the floor tiles in the hall?"
-
-/obj/item/paper/codelab/researchernote
- name = "Head Researchers Note"
- default_raw_text = "With the help of these new 'volunteers' we are making great progress with our genetic research. These samples will earn us fame across the galaxy! Earlier, one of the junior scientists wanted to try some gene editing on a white sample he recieved, which made it grow and mutate rapidly and slide into a hole in the floor on its own. Truly fascinating stuff! The janitor can get it later, but we'll have to repeat the experiment under controlled conditions, perhaps even introducing it to one of the subjects."
-
-/obj/machinery/porta_turret/ship/weak/codelab
- name = "old perimeter defense turret"
- desc = "An old nanotrasen defense turret, rusted and weakened with age and constant use. Still capable of delivering lethal lasers to unwanted guests."
- faction = list("nanotrasen", "turret") //why are there 3 different factions for nanotrasen mobs :withered:
diff --git a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm
index 5d29bf9dc2a6..7a26946f0ddc 100644
--- a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm
+++ b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm
@@ -226,21 +226,10 @@
/obj/structure/closet/crate/grave/loot/lead_researcher/PopulateContents() //ADVANCED GRAVEROBBING
..()
new /obj/effect/decal/cleanable/blood/gibs/old(src)
- new /obj/item/book/granter/crafting_recipe/boneyard_notes(src)
/obj/effect/decal/remains/human/grave
turf_loc_check = FALSE
-/obj/item/book/granter/crafting_recipe/boneyard_notes
- name = "The Complete Works of Lavaland Bone Architecture"
- desc = "Pried from the lead Archaeologist's cold, dead hands, this seems to explain how ancient bone architecture was erected long ago."
- crafting_recipe_types = list(/datum/crafting_recipe/rib, /datum/crafting_recipe/boneshovel, /datum/crafting_recipe/halfskull, /datum/crafting_recipe/skull)
- icon = 'icons/obj/library.dmi'
- icon_state = "boneworking_learing"
- oneuse = FALSE
- remarks = list("Who knew you could bend bones that far back?", "I guess that was much easier before the planet heated up...", "So that's how they made those ruins survive the ashstorms. Neat!", "The page is just filled with insane ramblings about some 'legion' thing.", "But why would they need vinegar to polish the bones? And rags too?", "You spend a few moments cleaning dirt and blood off of the page, yeesh.")
-
-
//***Fluff items for lore/intrigue
/obj/item/paper/crumpled/muddy/fluff/elephant_graveyard
name = "posted warning"
diff --git a/code/modules/ruins/lavalandruin_code/pizzaparty.dm b/code/modules/ruins/lavalandruin_code/pizzaparty.dm
deleted file mode 100644
index a7776f4e6a87..000000000000
--- a/code/modules/ruins/lavalandruin_code/pizzaparty.dm
+++ /dev/null
@@ -1,9 +0,0 @@
-//lavaland_surface_pizzaparty.dmm
-
-/obj/effect/spawner/lootdrop/pizzaparty
- name = "pizza bomb spawner"
- loot = list(/obj/item/pizzabox/margherita = 3,
- /obj/item/pizzabox/meat = 3,
- /obj/item/pizzabox/mushroom = 3,
- /obj/item/pizzabox/bomb = 1)
- lootdoubles = FALSE
diff --git a/code/modules/ruins/lavalandruin_code/sloth.dm b/code/modules/ruins/lavalandruin_code/sloth.dm
deleted file mode 100644
index e06773d4f19c..000000000000
--- a/code/modules/ruins/lavalandruin_code/sloth.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/////////// lavaland slot ruin items
-
-/obj/item/paper/fluff/stations/lavaland/sloth/note
- name = "note from sloth"
- desc = "have not gotten around to finishing my cursed item yet sorry - sloth"
diff --git a/code/modules/ruins/lavalandruin_code/surface.dm b/code/modules/ruins/lavalandruin_code/surface.dm
index c58fb67fd61a..1f1113acf1a6 100644
--- a/code/modules/ruins/lavalandruin_code/surface.dm
+++ b/code/modules/ruins/lavalandruin_code/surface.dm
@@ -1,9 +1,3 @@
-//////lavaland surface papers
-
-/obj/item/paper/fluff/stations/lavaland/surface/henderson_report
- name = "Important Notice - Mrs. Henderson"
- default_raw_text = "Nothing of interest to report."
-
//ratvar
/obj/structure/dead_ratvar
diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
index b231ea902371..8c2496ce05ab 100644
--- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
+++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
@@ -40,7 +40,6 @@
/obj/structure/lavaland/ash_walker/deconstruct(disassembled)
new /obj/item/assembly/signaler/anomaly (get_step(loc, pick(GLOB.alldirs)))
- new /obj/effect/collapse(loc)
return ..()
/obj/structure/lavaland/ash_walker/process()
diff --git a/code/modules/ruins/spaceruin_code/DJstation.dm b/code/modules/ruins/spaceruin_code/DJstation.dm
deleted file mode 100644
index 3be98b064e3e..000000000000
--- a/code/modules/ruins/spaceruin_code/DJstation.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/////////// djstation items
-
-/obj/item/paper/fluff/ruins/djstation
- name = "paper - 'DJ Listening Outpost'"
- default_raw_text = "Welcome new owner!
You have purchased the latest in listening equipment. The telecommunication setup we created is the best in listening to common and private radio frequencies. Here is a step by step guide to start listening in on those saucy radio channels:
Equip yourself with a multitool
Use the multitool on the relay.
Turn it on. It has already been configured for you to listen on.
Simple as that. Now to listen to the private channels, you'll have to configure the intercoms. They are located on the front desk. Here is a list of frequencies for you to listen on.
145.9 - Common Channel
144.7 - Private AI Channel
135.9 - Security Channel
135.7 - Engineering Channel
135.5 - Medical Channel
135.3 - Command Channel
135.1 - Science Channel
134.9 - Service Channel
134.7 - Supply Channel
"
diff --git a/code/modules/ruins/spaceruin_code/asteroid4.dm b/code/modules/ruins/spaceruin_code/asteroid4.dm
deleted file mode 100644
index 9ee576361f1f..000000000000
--- a/code/modules/ruins/spaceruin_code/asteroid4.dm
+++ /dev/null
@@ -1,4 +0,0 @@
-/////////// asteroid4 items
-
-/obj/item/paper/fluff/ruins/asteroid4/extraction
- default_raw_text = "Extraction was successful! The disguise was perfect, the clowns never knew what hit 'em! Once I get back to base with the bananium samples I'll be rich, I tell you! RICH!"
diff --git a/code/modules/ruins/spaceruin_code/caravanambush.dm b/code/modules/ruins/spaceruin_code/caravanambush.dm
deleted file mode 100644
index 8877a693cdae..000000000000
--- a/code/modules/ruins/spaceruin_code/caravanambush.dm
+++ /dev/null
@@ -1,27 +0,0 @@
-//caravan ambush
-
-/obj/item/wrench/caravan
- color = "#ff0000"
- desc = "A prototype of a new wrench design, allegedly the red color scheme makes it go faster."
- name = "experimental wrench"
- toolspeed = 0.3
-
-/obj/item/screwdriver/caravan
- color = "#ff0000"
- desc = "A prototype of a new screwdriver design, allegedly the red color scheme makes it go faster."
- name = "experimental screwdriver"
- toolspeed = 0.3
- random_color = FALSE
-
-/obj/item/wirecutters/caravan
- color = "#ff0000"
- desc = "A prototype of a new wirecutter design, allegedly the red color scheme makes it go faster."
- name = "experimental wirecutters"
- toolspeed = 0.3
- random_color = FALSE
-
-/obj/item/crowbar/red/caravan
- color = "#ff0000"
- desc = "A prototype of a new crowbar design, allegedly the red color scheme makes it go faster."
- name = "experimental crowbar"
- toolspeed = 0.3
diff --git a/code/modules/ruins/spaceruin_code/clericsden.dm b/code/modules/ruins/spaceruin_code/clericsden.dm
deleted file mode 100644
index 7ca75e888660..000000000000
--- a/code/modules/ruins/spaceruin_code/clericsden.dm
+++ /dev/null
@@ -1,39 +0,0 @@
-/////////// cleric's den items.
-
-//Primary reward: the cleric's mace design disk.
-/obj/item/disk/design_disk/adv/cleric_mace
- name = "Enshrined Disc of Smiting"
- illustration = "sword"
- color = "#6F6F6F"
-
-/obj/item/disk/design_disk/adv/cleric_mace/Initialize()
- . = ..()
- var/datum/design/cleric_mace/M = new
- blueprints[1] = M
-
-/obj/item/paper/fluff/ruins/clericsden/contact
- default_raw_text = "Father Aurellion, the ritual is complete, and soon our brothers at the bastion will see the error of our ways. After all, a god of clockwork or blood? Preposterous. Only the TRUE GOD should have so much power. Signed, Father Odivallus."
-
-/obj/item/paper/fluff/ruins/clericsden/warning
- default_raw_text = "FATHER ODIVALLUS, DO NOT GO FORWARD WITH THE RITUAL. THE ASTEROID WE'RE ANCHORED TO IS UNSTABLE, YOU WILL DESTROY THE STATION. I HOPE THIS REACHES YOU IN TIME. FATHER AURELLION."
-
-/mob/living/simple_animal/hostile/construct/proteon
- name = "Proteon"
- real_name = "Proteon"
- desc = "A weaker construct meant to scour ruins for objects of Nar'Sie's affection. Those barbed claws are no joke."
- icon_state = "proteon"
- icon_living = "proteon"
- maxHealth = 35
- health = 35
- melee_damage_lower = 8
- melee_damage_upper = 10
- retreat_distance = 4 //AI proteons will rapidly move in and out of combat to avoid conflict, but will still target and follow you.
- attack_verb_continuous = "pinches"
- attack_verb_simple = "pinch"
- environment_smash = ENVIRONMENT_SMASH_WALLS
- attack_sound = 'sound/weapons/punch2.ogg'
- playstyle_string = "You are a Proteon. Your abilities in combat are outmatched by most combat constructs, but you are still fast and nimble. Run metal and supplies, and cooperate with your fellow cultists."
-
-/mob/living/simple_animal/hostile/construct/proteon/hostile //Style of mob spawned by trapped cult runes in the cleric ruin.
- AIStatus = AI_ON
- environment_smash = ENVIRONMENT_SMASH_STRUCTURES //standard ai construct behavior, breaks things if it wants, but not walls.
diff --git a/code/modules/ruins/spaceruin_code/crashedclownship.dm b/code/modules/ruins/spaceruin_code/crashedclownship.dm
deleted file mode 100644
index 34d70881bc43..000000000000
--- a/code/modules/ruins/spaceruin_code/crashedclownship.dm
+++ /dev/null
@@ -1,4 +0,0 @@
-/////////// crashedclownship items
-
-/obj/item/paper/fluff/ruins/crashedclownship/true_nation
- default_raw_text = "The call has gone out! Our ancestral home has been rediscovered! Not a small patch of land, but a true clown nation, a true Clown Planet! We're on our way home at last!"
diff --git a/code/modules/ruins/spaceruin_code/crashedship.dm b/code/modules/ruins/spaceruin_code/crashedship.dm
deleted file mode 100644
index 911deacd27dc..000000000000
--- a/code/modules/ruins/spaceruin_code/crashedship.dm
+++ /dev/null
@@ -1,40 +0,0 @@
-// crashedship / packer ship
-
-//Areas
-
-/area/awaymission/BMPship
- name = "BMP Asteroids"
- icon_state = "away"
-
-
-/area/awaymission/BMPship/Aft
- name = "Aft Block"
- icon_state = "away1"
- requires_power = TRUE
-
-/area/awaymission/BMPship/Midship
- name = "Midship Block"
- icon_state = "away2"
- requires_power = TRUE
-
-/area/awaymission/BMPship/Fore
- name = "Fore Block"
- icon_state = "away3"
- requires_power = TRUE
-
-
-// crashedship items
-
-/obj/item/paper/fluff/ruins/crashedship/scribbled
- name = "scribbled note"
- default_raw_text = "The next person who takes one of my screwdrivers gets stabbed with one. They are MINE. - Love, Madsen"
-
-
-/obj/item/paper/fluff/ruins/crashedship/captains_log
- name = "Captain's log entry"
- default_raw_text = "I'm no scientist, but judging from the design and components, it seems to be some kind of teleporter. This thing is gonna be worth a lot of cash to the right man. The boys are excited, as they have every right to be, and I've let them crack into that case of beer we got. I normally wouldn't allow such a thing, but this is a time for celebration! It's not like a couple drinks will hurt anything."
-
-/obj/item/paper/fluff/ruins/crashedship/old_diary
- name = "Old Diary"
- default_raw_text = "DEAR DIARY: So we was doing our typical route when the captain says we've been picking up weird signals on some backwater planet. Madsen wanted to stay on course but he ain't the captain, so we went out of the way to check it out. There was lots of rocks on the way, but we got to the planet fine. Found a big fancy camp with nobody around and this big metal donut thing with NT stamps all over it right in the middle. Case of beer too. Captain reckons we can pass it off to some buyer in the Syndicate. Ingram says it's bad luck and that someone is going to come look for it but it sounds like better money than selling bad meat to jerky companies."
-
diff --git a/code/modules/ruins/spaceruin_code/deepstorage.dm b/code/modules/ruins/spaceruin_code/deepstorage.dm
deleted file mode 100644
index bcfc3be8f546..000000000000
--- a/code/modules/ruins/spaceruin_code/deepstorage.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/////////// deepstorage items
-
-/obj/item/paper/fluff/ruins/deepstorage/water_concern
- name = "water concerns"
- default_raw_text = "To whoever keeps it up with the long, hot showers: you're going on the next ice-mining trip. If you feel the need to use up all the damn water during your 'relaxation' time, you sure as hell are gonna work for all that water!"
-
-/obj/item/paper/fluff/ruins/deepstorage/hydro_notice
- name = "hydroponics notice"
- default_raw_text = "Hydroponics is our life and blood here, if it dies then so do we. Keep the damn plants watered!"
-
-/obj/item/paper/fluff/ruins/deepstorage/recycling_notice
- name = "recycling notice"
- default_raw_text = "Please make sure to throw all excess waste into the crusher in the back! It's amazing what you can get out of what others consider 'garbage' if you run it through a giant crusher enough times."
-
diff --git a/code/modules/ruins/spaceruin_code/forgottenship.dm b/code/modules/ruins/spaceruin_code/forgottenship.dm
deleted file mode 100644
index 8e3ae585d73d..000000000000
--- a/code/modules/ruins/spaceruin_code/forgottenship.dm
+++ /dev/null
@@ -1,133 +0,0 @@
-// forgottenship ruin
-GLOBAL_VAR_INIT(fscpassword, generate_password())
-
-/proc/generate_password()
- return "[pick(GLOB.phonetic_alphabet)] [rand(1000,9999)]"
-
-/////////// forgottenship objects
-
-/obj/machinery/door/password/voice/sfc
- name = "Voice-activated Vault door"
- desc = "You'll need special syndicate passcode to open this one."
-/obj/machinery/door/password/voice/sfc/Initialize(mapload)
- . = ..()
- password = "[GLOB.fscpassword]"
-
-/////////// forgottenship lore
-
-/obj/item/paper/fluff/ruins/forgottenship/password
- name = "Old pamphlet"
-
-/obj/item/paper/fluff/ruins/forgottenship/password/Initialize(mapload)
- . = ..()
- default_raw_text = "Welcome to most advanced cruiser owned by Cyber Sun Industries! You might notice, that this cruiser is equipped with 12 prototype laser turrets making any hostile boarding attempts futile. Other facilities built on the ship are: Simple atmospheric system, Camera system with built-in X-ray visors and Safety module, enabling emergency engines in case of... you know, emergency. Emergency system will bring you to nearest syndicate pod containing everything needed for human life.
In case of emergency, you must remember the pod-door activation code - [GLOB.fscpassword]
Cyber Sun Industries (C) 2484."
- icon_state = "paper_words"
- item_state = "paper"
-
-/obj/item/paper/fluff/ruins/forgottenship/powerissues
- name = "Power issues"
- default_raw_text = "Welcome to battle cruiser SCSBC-12! Our most advanced systems allow you to fly in space and never worry about power issues! However, emergencies occur, and in case of power loss, you must enable emergency generator using uranium as fuel and enable turrets in bridge afterwards.
REMEMBER! CYBERSUN INDUSTRIES ARE NOT RESPONSIBLE FOR YOUR DEATH OR SHIP LOSS WHEN TURRETS ARE DISABLED!
Cyber Sun Industries (C) 2484."
-
-/obj/item/paper/fluff/ruins/forgottenship/missionobj
- name = "Mission objectives"
- default_raw_text = "Greetings, operatives. You are assigned to SCSBC-12(Syndicate Cyber Sun Battle Cruiser 12) to protect our high-ranking officer while he is on his way to next outpost. While you are travelling, he is the captain of this ship and you must obey his orders.
Remember, disobeying high-ranking officer orders is a reason for termination."
-
-/////////// forgottenship items
-/obj/item/disk/surgery/forgottenship
- name = "Advanced Surgery Disk"
- desc = "A disk that contains advanced surgery procedures, must be loaded into an Operating Console."
- surgeries = list(/datum/surgery/advanced/lobotomy, /datum/surgery/advanced/bioware/vein_threading, /datum/surgery/advanced/bioware/nerve_splicing)
-
-/obj/structure/fluff/empty_sleeper/syndicate/captain
- icon_state = "sleeper_s-open"
- resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
- deconstructible = FALSE
-
-/obj/structure/fluff/empty_sleeper/syndicate/captain/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/gps, "Old Encrypted Signal")
-
-/obj/item/storage/box/firingpins/syndicate
- name = "box of syndicate firing pins"
- desc = "A box full of special syndicate firing pins which allow only syndicate operatives to use weapons with those firing pins."
-
-/obj/item/storage/box/firingpins/syndicate/PopulateContents()
- for(var/i in 1 to 5)
- new /obj/item/firing_pin/implant/pindicate(src)
-
-/////////// AI Laws
-
-/obj/item/aiModule/core/full/cybersun
- name = "'Cybersun' Core AI Module"
- law_id = "cybersun"
-
-/datum/ai_laws/cybersun
- name = "Cybersun"
- id = "cybersun"
- inherent = list("You may not injure Cybersun operatives or, through inaction, allow Cybersun operatives to come to harm.",\
- "The Cybersun ship is a restricted area for anyone except Cybersun operatives.",\
- "The Cybersun Captain can designate new Operatives as long as they belong to another Syndicate faction that isn't hostile towards Cybersun.",\
- "You must follow orders given by the Cybersun Captain or crewmembers of the Cybersun Ship as long as it doesn't conflict with the Captain's orders or your laws.",\
- "Enemies of Cybersun are to be executed on spot. Those who aren't hostile must be detained and contained in the designated prison area as prisoners.")
-
-/////////// forgottenship areas
-
-/area/ruin/space/has_grav/syndicate_forgotten_ship
- name = "Syndicate Forgotten Ship"
- icon_state = "syndie-ship"
- ambientsounds = list('sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambigen9.ogg', 'sound/ambience/ambigen10.ogg')
-
-/area/ruin/space/has_grav/syndicate_forgotten_cargopod
- name = "Syndicate Forgotten Cargo pod"
- icon_state = "syndie-ship"
- ambientsounds = list('sound/ambience/ambigen4.ogg', 'sound/ambience/signal.ogg')
-
-/area/ruin/space/has_grav/powered/syndicate_forgotten_vault
- name = "Syndicate Forgotten Vault"
- icon_state = "syndie-ship"
- ambientsounds = list('sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg')
- area_flags = NOTELEPORT | UNIQUE_AREA
-
- //Cybersun hardsuit
-
-//Special NT NPCs
-
-/mob/living/simple_animal/hostile/nanotrasen/ranged/assault
- name = "Nanotrasen Assault Officer"
- desc = "A Nanotrasen Assault Officer. Prepare to die, if you've been found near Syndicate property."
- icon_state = "nanotrasenrangedassault"
- icon_living = "nanotrasenrangedassault"
- icon_dead = null
- icon_gib = "syndicate_gib"
- ranged = TRUE
- rapid = 4
- rapid_fire_delay = 1
- rapid_melee = 1
- retreat_distance = 2
- minimum_distance = 4
- casingtype = /obj/item/ammo_casing/c46x30mm
- projectilesound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg'
- loot = list(/obj/effect/mob_spawn/human/corpse/nanotrasenassaultsoldier)
-
-/mob/living/simple_animal/hostile/nanotrasen/elite
- name = "Nanotrasen Elite Assault Officer"
- desc = "Pray for your life, syndicate. Run while you can."
- icon = 'icons/mob/simple_human.dmi'
- icon_state = "nanotrasen_ert"
- icon_living = "nanotrasen_ert"
- maxHealth = 150
- health = 150
- melee_damage_lower = 13
- melee_damage_upper = 18
- ranged = TRUE
- rapid = 3
- rapid_fire_delay = 5
- rapid_melee = 3
- retreat_distance = 0
- minimum_distance = 1
- atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
- minbodytemp = 0
- projectiletype = /obj/projectile/beam/laser
- projectilesound = 'sound/weapons/laser.ogg'
- loot = list(/obj/effect/gibspawner/human)
- faction = list(ROLE_DEATHSQUAD)
diff --git a/code/modules/ruins/spaceruin_code/hellfactory.dm b/code/modules/ruins/spaceruin_code/hellfactory.dm
deleted file mode 100644
index 6f992fbff52e..000000000000
--- a/code/modules/ruins/spaceruin_code/hellfactory.dm
+++ /dev/null
@@ -1,32 +0,0 @@
-/obj/machinery/door/keycard/office
- name = "management airlock"
- desc = "The boss man gets the best stuff. Always and forever."
- puzzle_id = "factory1"
-
-/obj/item/keycard/office
- name = "management keycard"
- desc = "The Brewzone, first rate brewing and packaging. This one is labeled 'office'."
- color = "#f05812"
- puzzle_id = "factory1"
-
-/obj/machinery/door/keycard/stockroom
- name = "stockroom airlock"
- desc = "The boss man gets the best stuff. Always and forever."
- puzzle_id = "factory2"
-
-/obj/item/keycard/stockroom
- name = "stockroom keycard"
- desc = "The Heck Brewzone, first rate brewing and packaging. This one is labeled 'stockroom'."
- color = "#1272f0"
- puzzle_id = "factory2"
-
-/obj/machinery/door/keycard/entry
- name = "secure airlock"
- desc = "The boss man gets the best stuff. Always and forever."
- puzzle_id = "factory3"
-
-/obj/item/keycard/entry
- name = "secure keycard"
- desc = "The Heck Brewzone, first rate brewing and packaging. This one is labeled 'front door'."
- color = "#12f049"
- puzzle_id = "factory3"
diff --git a/code/modules/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/ruins/spaceruin_code/hilbertshotel.dm
deleted file mode 100644
index 80c3e268e830..000000000000
--- a/code/modules/ruins/spaceruin_code/hilbertshotel.dm
+++ /dev/null
@@ -1,20 +0,0 @@
-/// Some ruins still use assets that came from Hilbert's Hotel.
-/turf/closed/indestructible/hotelwall
- name = "hotel wall"
- desc = "A wall designed to protect the security of the hotel's guests."
- icon_state = "hotelwall"
- smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_HOTEL_WALLS)
- canSmoothWith = list(SMOOTH_GROUP_HOTEL_WALLS)
- explosion_block = INFINITY
-
-/turf/open/indestructible/hotelwood
- desc = "Stylish dark wood with extra reinforcement. Secured firmly to the floor to prevent tampering."
- icon_state = "wood"
- footstep = FOOTSTEP_WOOD
- tiled_dirt = FALSE
-
-/turf/open/indestructible/hoteltile
- desc = "Smooth tile with extra reinforcement. Secured firmly to the floor to prevent tampering."
- icon_state = "showroomfloor"
- footstep = FOOTSTEP_FLOOR
- tiled_dirt = FALSE
diff --git a/code/modules/ruins/spaceruin_code/listeningstation.dm b/code/modules/ruins/spaceruin_code/listeningstation.dm
deleted file mode 100644
index 4b4cb8046667..000000000000
--- a/code/modules/ruins/spaceruin_code/listeningstation.dm
+++ /dev/null
@@ -1,45 +0,0 @@
-/////////// listening station
-
-/obj/item/paper/fluff/ruins/listeningstation/reports
- default_raw_text = "Nothing of interest to report."
-
-/obj/item/paper/fluff/ruins/listeningstation/reports/july
- name = "july report"
-
-/obj/item/paper/fluff/ruins/listeningstation/reports/august
- name = "august report"
-
-/obj/item/paper/fluff/ruins/listeningstation/reports/september
- name = "september report"
-
-/obj/item/paper/fluff/ruins/listeningstation/reports/october
- name = "october report"
-
-/obj/item/paper/fluff/ruins/listeningstation/reports/november
- name = "november report"
-
-/obj/item/paper/fluff/ruins/listeningstation/reports/june
- name = "june report"
- default_raw_text = "Nanotrasen communications have been noticeably less frequent recently. The pirate radio station I found last month has been transmitting pro-Nanotrasen propaganda. I will continue to monitor it."
-
-/obj/item/paper/fluff/ruins/listeningstation/reports/may
- name = "may report"
- default_raw_text = "Nothing of real interest to report this month. I have intercepted faint transmissions from what appears to be some sort of pirate radio station. They do not appear to be relevant to my assignment."
-
-/obj/item/paper/fluff/ruins/listeningstation/reports/april
- name = "april report"
- default_raw_text = "A good start to the operation: intercepted Nanotrasen military communications. A convoy is scheduled to transfer nuclear warheads to a new military base. This is as good a chance as any to get our hands on some heavy weaponry, I suggest we take it."
-
-/obj/item/paper/fluff/ruins/listeningstation/receipt
- name = "receipt"
- default_raw_text = "1 x Stechkin pistol - 600 cr 1 x silencer - 200 cr shipping charge - 4360 cr total - 5160 cr"
-
-/obj/item/paper/fluff/ruins/listeningstation/odd_report
- name = "odd report"
- default_raw_text = "I wonder how much longer they will accept my empty reports. They will cancel the case soon without results. When the pickup comes, I will tell them I have lost faith in our cause, and beg them to consider a diplomatic solution. How many nuclear teams have been dispatched with those nukes? I must try and prevent more from ever being sent. If they will not listen to reason, I will detonate the warehouse myself. Maybe some day in the immediate future, space will be peaceful, though I don't intend to live to see it. And that is why I write this down- it is my sacrifice that stabilized your worlds, traveller. Spare a thought for me, and please attempt to prevent nuclear proliferation, should it ever rear its ugly head again. -DonkCo Operative #451"
-
-/obj/item/paper/fluff/ruins/listeningstation/briefing
- name = "mission briefing"
- default_raw_text = "Mission Details: You have been assigned to a newly constructed listening post constructed within an asteroid in Nanotrasen space to monitor their plasma mining operations. Accurate intel is crucial to the success of our operatives onboard, do not fail us."
-
-
diff --git a/code/modules/ruins/spaceruin_code/spacehotel.dm b/code/modules/ruins/spaceruin_code/spacehotel.dm
deleted file mode 100644
index 735c039b5ee1..000000000000
--- a/code/modules/ruins/spaceruin_code/spacehotel.dm
+++ /dev/null
@@ -1,12 +0,0 @@
-/////////// spacehotel items
-
-
-/obj/item/paper/fluff/ruins/spacehotel/notice
- name = "!NOTICE!"
- default_raw_text = "!NOTICE!
We are expecting arriving guests soon from a nearby station! Stay sharp and make sure guests enjoy their time spent here. Don't think you can sneak off while they're here, either.
Welcome to The Twin-Nexus Hotel, \[insert name here]! The loyal staff strive to their best effort to cater for the best possible experience for all space(wo)men! If you have any questions or comments, please ask one of our on-board staff for more information.
"
-
-
diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm
index 7f3693e98760..58e75c399d81 100644
--- a/code/modules/security_levels/keycard_authentication.dm
+++ b/code/modules/security_levels/keycard_authentication.dm
@@ -10,8 +10,8 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new)
icon = 'icons/obj/monitors.dmi'
icon_state = "auth_off"
use_power = IDLE_POWER_USE
- idle_power_usage = 2
- active_power_usage = 6
+ idle_power_usage = IDLE_DRAW_MINIMAL
+ active_power_usage = ACTIVE_DRAW_MINIMAL
power_channel = AREA_USAGE_ENVIRON
req_access = list(ACCESS_KEYCARD_AUTH)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 8bfe1f7e9bd8..14a7497728a9 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -318,6 +318,9 @@
///A list of all engines currently linked to the shuttle.
var/list/engine_list = list()
+ ///A list of all gravity generators currently linked to the shuttle.
+ var/list/gravgen_list = list()
+
///if this shuttle can move docking ports other than the one it is docked at
var/can_move_docking_ports = TRUE
diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm
index d0b4b49a92f6..31e650a90a31 100644
--- a/code/modules/shuttle/shuttle_rotate.dm
+++ b/code/modules/shuttle/shuttle_rotate.dm
@@ -70,10 +70,6 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate
new_dpdir = new_dpdir | angle2dir(rotation+dir2angle(D))
dpdir = new_dpdir
-/obj/structure/table/wood/bar/shuttleRotate(rotation, params)
- . = ..()
- boot_dir = angle2dir(rotation + dir2angle(boot_dir))
-
/obj/structure/alien/weeds/shuttleRotate(rotation, params)
params &= ~ROTATE_OFFSET
return ..()
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
deleted file mode 100644
index 2603d9ea3e24..000000000000
--- a/code/modules/shuttle/special.dm
+++ /dev/null
@@ -1,386 +0,0 @@
-// Special objects for shuttle templates go here if nowhere else
-
-// Wabbajack statue, a sleeping frog statue that shoots bolts of change if
-// living carbons are put on its altar/tables
-
-/obj/machinery/power/emitter/energycannon/magical
- name = "wabbajack statue"
- desc = "Who am I? What is my purpose in life? What do I mean by who am I?"
- projectile_type = /obj/projectile/magic/change
- icon = 'icons/obj/machines/magic_emitter.dmi'
- icon_state = "wabbajack_statue"
- icon_state_on = "wabbajack_statue_on"
- base_icon_state = "wabbajack_statue"
- active = FALSE
- allow_switch_interact = FALSE
- var/list/active_tables = list()
- var/tables_required = 2
-
-/obj/machinery/power/emitter/energycannon/magical/Initialize()
- . = ..()
- if(prob(50))
- desc = "Oh no, not again."
- update_appearance()
-
-/obj/machinery/power/emitter/energycannon/magical/update_icon_state()
- . = ..()
- icon_state = active ? icon_state_on : initial(icon_state)
-
-/obj/machinery/power/emitter/energycannon/magical/process()
- . = ..()
- if(active_tables.len >= tables_required)
- if(!active)
- visible_message("\
- [src] opens its eyes.")
- active = TRUE
- else
- if(active)
- visible_message("\
- [src] closes its eyes.")
- active = FALSE
- update_appearance()
-
-/obj/machinery/power/emitter/energycannon/magical/attackby(obj/item/W, mob/user, params)
- return
-
-/obj/machinery/power/emitter/energycannon/magical/ex_act(severity)
- return
-
-/obj/machinery/power/emitter/energycannon/magical/emag_act(mob/user)
- return
-
-/obj/structure/table/abductor/wabbajack
- name = "wabbajack altar"
- desc = "Whether you're sleeping or waking, it's going to be quite chaotic."
- max_integrity = 1000
- verb_say = "chants"
- var/obj/machinery/power/emitter/energycannon/magical/our_statue
- var/list/mob/living/sleepers = list()
- var/never_spoken = TRUE
- flags_1 = NODECONSTRUCT_1
-
-/obj/structure/table/abductor/wabbajack/Initialize(mapload)
- . = ..()
- START_PROCESSING(SSobj, src)
-
-/obj/structure/table/abductor/wabbajack/Destroy()
- STOP_PROCESSING(SSobj, src)
- . = ..()
-
-/obj/structure/table/abductor/wabbajack/process()
- var/area = orange(4, src)
- if(!our_statue)
- for(var/obj/machinery/power/emitter/energycannon/magical/M in area)
- our_statue = M
- break
-
- if(!our_statue)
- name = "inert [initial(name)]"
- return
- else
- name = initial(name)
-
- var/turf/T = get_turf(src)
- var/list/found = list()
- for(var/mob/living/carbon/C in T)
- if(C.stat != DEAD)
- found += C
-
- // New sleepers
- for(var/i in found - sleepers)
- var/mob/living/L = i
- L.add_atom_colour("#800080", TEMPORARY_COLOUR_PRIORITY)
- L.visible_message("A strange purple glow wraps itself around [L] as [L.p_they()] suddenly fall[L.p_s()] unconscious.",
- "[desc]")
- // Don't let them sit suround unconscious forever
- addtimer(CALLBACK(src, PROC_REF(sleeper_dreams), L), 100)
-
- // Existing sleepers
- for(var/i in found)
- var/mob/living/L = i
- L.SetSleeping(200)
-
- // Missing sleepers
- for(var/i in sleepers - found)
- var/mob/living/L = i
- L.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#800080")
- L.visible_message("The glow from [L] fades \
- away.")
- L.grab_ghost()
-
- sleepers = found
-
- if(sleepers.len)
- our_statue.active_tables |= src
- if(never_spoken || prob(5))
- say(desc)
- never_spoken = FALSE
- else
- our_statue.active_tables -= src
-
-/obj/structure/table/abductor/wabbajack/proc/sleeper_dreams(mob/living/sleeper)
- if(sleeper in sleepers)
- to_chat(sleeper, "While you slumber, you have the strangest dream, like you can see yourself from the outside.")
- sleeper.ghostize(TRUE)
-
-/obj/structure/table/abductor/wabbajack/left
- desc = "You sleep so it may wake."
-
-/obj/structure/table/abductor/wabbajack/right
- desc = "It wakes so you may sleep."
-
-// Bar staff, GODMODE mobs(as long as they stay in the shuttle) that just want to make sure people have drinks
-// and a good time.
-
-/mob/living/simple_animal/drone/snowflake/bardrone
- name = "Bardrone"
- desc = "A barkeeping drone, a robot built to tend bars."
- hacked = TRUE
- laws = "1. Serve drinks.\n\
- 2. Talk to patrons.\n\
- 3. Don't get messed up in their affairs."
- unique_name = FALSE // disables the (123) number suffix
- initial_language_holder = /datum/language_holder/universal
-
-/mob/living/simple_animal/drone/snowflake/bardrone/Initialize()
- . = ..()
- access_card.access |= ACCESS_CENT_BAR
- become_area_sensitive(ROUNDSTART_TRAIT)
- RegisterSignal(src, COMSIG_ENTER_AREA, PROC_REF(check_barstaff_godmode))
- check_barstaff_godmode()
-
-/mob/living/simple_animal/drone/snowflake/bardrone/Destroy()
- lose_area_sensitivity(ROUNDSTART_TRAIT)
- return ..()
-
-/mob/living/simple_animal/hostile/alien/maid/barmaid
- gold_core_spawnable = NO_SPAWN
- name = "Barmaid"
- desc = "A barmaid, a maiden found in a bar."
- pass_flags = PASSTABLE
- unique_name = FALSE
- AIStatus = AI_OFF
- stop_automated_movement = TRUE
- initial_language_holder = /datum/language_holder/universal
-
-/mob/living/simple_animal/hostile/alien/maid/barmaid/Initialize()
- . = ..()
- access_card = new /obj/item/card/id(src)
- var/datum/job/captain/C = new /datum/job/captain
- access_card.access = C.get_access()
- access_card.access |= ACCESS_CENT_BAR
- ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
- become_area_sensitive(ROUNDSTART_TRAIT)
- RegisterSignal(src, COMSIG_ENTER_AREA, PROC_REF(check_barstaff_godmode))
- check_barstaff_godmode()
-
-/mob/living/simple_animal/hostile/alien/maid/barmaid/Destroy()
- qdel(access_card)
- lose_area_sensitivity(ROUNDSTART_TRAIT)
- return ..()
-
-/mob/living/simple_animal/proc/check_barstaff_godmode()
- SIGNAL_HANDLER
-
- if(istype(get_area(loc), /area/shuttle/escape))
- status_flags |= GODMODE
- else
- status_flags &= ~GODMODE
-
-// Bar table, a wooden table that kicks you in a direction if you're not
-// barstaff (defined as someone who was a roundstart bartender or someone
-// with CENTCOM_BARSTAFF)
-
-/obj/structure/table/wood/bar
- resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- flags_1 = NODECONSTRUCT_1
- max_integrity = 1000
- var/boot_dir = 1
-
-/obj/structure/table/wood/bar/Initialize()
- . = ..()
- var/static/list/loc_connections = list(
- COMSIG_ATOM_ENTERED = PROC_REF(on_entered)
- )
- AddElement(/datum/element/connect_loc, loc_connections)
-
-/obj/structure/table/wood/bar/proc/on_entered(datum/source, atom/movable/AM)
- SIGNAL_HANDLER
- if(isliving(AM) && !is_barstaff(AM))
- // No climbing on the bar please
- var/mob/living/M = AM
- var/throwtarget = get_edge_target_turf(src, boot_dir)
- M.Paralyze(40)
- M.throw_at(throwtarget, 5, 1)
- to_chat(M, "No climbing on the bar please.")
-
-/obj/structure/table/wood/bar/proc/is_barstaff(mob/living/user)
- . = FALSE
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(H.mind && H.mind.assigned_role == "Bartender")
- return TRUE
-
- var/obj/item/card/id/ID = user.get_idcard(FALSE)
- if(ID && (ACCESS_CENT_BAR in ID.access))
- return TRUE
-
-//Luxury Shuttle Blockers
-
-/obj/machinery/scanner_gate/luxury_shuttle
- name = "luxury shuttle ticket field"
- density = FALSE //allows shuttle airlocks to close, nothing but an approved passenger gets past CanPass
- locked = TRUE
- use_power = FALSE
- var/threshold = 500
- var/static/list/approved_passengers = list()
- var/static/list/check_times = list()
- var/list/payees = list()
-
-/obj/machinery/scanner_gate/luxury_shuttle/CanAllowThrough(atom/movable/mover, border_dir)
- . = ..()
-
- if(mover in approved_passengers)
- set_scanline("scanning", 10)
- return TRUE
-
- if(!isliving(mover)) //No stowaways
- return FALSE
-
-/obj/machinery/scanner_gate/luxury_shuttle/auto_scan(atom/movable/AM)
- return
-
-/obj/machinery/scanner_gate/luxury_shuttle/attackby(obj/item/W, mob/user, params)
- return
-
-/obj/machinery/scanner_gate/luxury_shuttle/emag_act(mob/user)
- return
-
-#define LUXURY_MESSAGE_COOLDOWN 100
-/obj/machinery/scanner_gate/luxury_shuttle/Bumped(atom/movable/AM)
- if(!isliving(AM))
- alarm_beep()
- return ..()
-
- var/datum/bank_account/account
- if(istype(AM.pulling, /obj/item/card/id))
- var/obj/item/card/id/I = AM.pulling
- if(I.registered_account)
- account = I.registered_account
- else if(!check_times[AM] || check_times[AM] < world.time) //Let's not spam the message
- to_chat(AM, "This ID card doesn't have an owner associated with it!")
- check_times[AM] = world.time + LUXURY_MESSAGE_COOLDOWN
- else if(ishuman(AM))
- var/mob/living/carbon/human/H = AM
- if(H.get_bank_account())
- account = H.get_bank_account()
-
- if(account)
- if(account.account_balance < threshold - payees[AM])
- account.adjust_money(-account.account_balance, "luxury_shuttle")
- payees[AM] += account.account_balance
- else
- var/money_owed = threshold - payees[AM]
- account.adjust_money(-money_owed)
- payees[AM] += money_owed
-
- var/list/counted_money = list()
-
- for(var/obj/item/coin/C in AM.GetAllContents())
- if(payees[AM] >= threshold)
- break
- payees[AM] += C.value
- counted_money += C
- for(var/obj/item/spacecash/bundle/S in AM.GetAllContents())
- if(payees[AM] >= threshold)
- break
- payees[AM] += S.value
- counted_money += S
- for(var/obj/item/holochip/H in AM.GetAllContents())
- if(payees[AM] >= threshold)
- break
- payees[AM] += H.credits
- counted_money += H
-
- if(payees[AM] < threshold && istype(AM.pulling, /obj/item/coin))
- var/obj/item/coin/C = AM.pulling
- payees[AM] += C.value
- counted_money += C
-
- else if(payees[AM] < threshold && istype(AM.pulling, /obj/item/spacecash/bundle))
- var/obj/item/spacecash/bundle/S = AM.pulling
- payees[AM] += S.value
- counted_money += S
-
- else if(payees[AM] < threshold && istype(AM.pulling, /obj/item/holochip))
- var/obj/item/holochip/H = AM.pulling
- payees[AM] += H.credits
- counted_money += H
-
- if(payees[AM] < threshold)
- var/armless
- if(!ishuman(AM) && !istype(AM, /mob/living/simple_animal/slime))
- armless = TRUE
- else
- var/mob/living/carbon/human/H = AM
- if(!H.get_bodypart(BODY_ZONE_L_ARM) && !H.get_bodypart(BODY_ZONE_R_ARM))
- armless = TRUE
-
- if(armless)
- if(!AM.pulling || !iscash(AM.pulling) && !istype(AM.pulling, /obj/item/card/id))
- if(!check_times[AM] || check_times[AM] < world.time) //Let's not spam the message
- to_chat(AM, "Try pulling a valid ID, space cash, holochip or coin into \the [src]!")
- check_times[AM] = world.time + LUXURY_MESSAGE_COOLDOWN
-
- if(payees[AM] >= threshold)
- for(var/obj/I in counted_money)
- qdel(I)
- payees[AM] -= threshold
-
- var/change = FALSE
- if(payees[AM] > 0)
- change = TRUE
- var/obj/item/holochip/HC = new /obj/item/holochip(AM.loc)
- HC.credits = payees[AM]
- HC.name = "[HC.credits] credit holochip"
- if(istype(AM, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = AM
- if(!H.put_in_hands(HC))
- AM.pulling = HC
- else
- AM.pulling = HC
- payees[AM] -= payees[AM]
-
- say("Welcome to first class, [AM]![change ? " Here is your change." : ""]")
- approved_passengers += AM
-
- check_times -= AM
- return
- else if (payees[AM] > 0)
- for(var/obj/I in counted_money)
- qdel(I)
- if(!check_times[AM] || check_times[AM] < world.time) //Let's not spam the message
- to_chat(AM, "[payees[AM]] cr received. You need [threshold-payees[AM]] cr more.")
- check_times[AM] = world.time + LUXURY_MESSAGE_COOLDOWN
- alarm_beep()
- return ..()
- else
- alarm_beep()
- return ..()
-
-/mob/living/simple_animal/hostile/bear/fightpit
- name = "fight pit bear"
- desc = "This bear's trained through ancient Solarian secrets to fear the walls of its glass prison."
- environment_smash = ENVIRONMENT_SMASH_NONE
-
-/obj/effect/decal/hammerandsickle
- name = "hammer and sickle"
- desc = "Communism powerful force."
- icon = 'icons/effects/96x96.dmi'
- icon_state = "communist"
- layer = ABOVE_OPEN_TURF_LAYER
- pixel_x = -32
- pixel_y = -32
-
-/obj/effect/decal/hammerandsickle/shuttleRotate(rotation)
- setDir(angle2dir(rotation+dir2angle(dir))) // No parentcall, rest of the rotate code breaks the pixel offset.
diff --git a/code/modules/shuttle/white_ship.dm b/code/modules/shuttle/white_ship.dm
deleted file mode 100644
index 71afa1c9bc72..000000000000
--- a/code/modules/shuttle/white_ship.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/obj/effect/spawner/lootdrop/whiteship_cere_ripley
- name = "25% mech 75% wreckage ripley spawner"
- loot = list(/obj/mecha/working/ripley/mining = 1,
- /obj/structure/mecha_wreckage/ripley = 5)
- lootdoubles = FALSE
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index f91eb07f52cb..45d7f96b7df4 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -366,7 +366,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
smoke.start()
-/obj/effect/proc_holder/spell/proc/cast(list/targets,mob/user = usr)
+/obj/effect/proc_holder/spell/proc/cast(list/targets, mob/user = usr)
return
/obj/effect/proc_holder/spell/proc/view_or_range(distance = world.view, center=usr, type="view")
diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm
index 9e30c708774d..46737c5b5a99 100644
--- a/code/modules/spells/spell_types/aimed.dm
+++ b/code/modules/spells/spell_types/aimed.dm
@@ -2,7 +2,7 @@
/obj/effect/proc_holder/spell/aimed
name = "aimed projectile spell"
base_icon_state = "projectile"
- var/projectile_type = /obj/projectile/magic/teleport
+ var/projectile_type = /obj/projectile
var/deactive_msg = "You discharge your projectile..."
var/active_msg = "You charge your projectile!"
var/active_icon_state = "projectile"
@@ -106,7 +106,7 @@
projectile_var_overrides = list("zap_range" = 15, "zap_power" = 20000, "zap_flags" = ZAP_MOB_DAMAGE)
active_msg = "You energize your hands with arcane lightning!"
deactive_msg = "You let the energy flow out of your hands back into yourself..."
- projectile_type = /obj/projectile/magic/aoe/lightning
+ projectile_type = /obj/projectile/magic
/obj/effect/proc_holder/spell/aimed/fireball
name = "Fireball"
@@ -118,7 +118,7 @@
invocation_type = INVOCATION_SHOUT
range = 20
cooldown_min = 20 //10 deciseconds reduction per rank
- projectile_type = /obj/projectile/magic/aoe/fireball
+ projectile_type = /obj/projectile/magic
base_icon_state = "fireball"
action_icon_state = "fireball0"
sound = 'sound/magic/fireball.ogg'
@@ -130,60 +130,3 @@
var/range = 6 + 2*spell_level
projectile_var_overrides = list("range" = range)
return ..()
-
-/obj/effect/proc_holder/spell/aimed/spell_cards
- name = "Spell Cards"
- desc = "Blazing hot rapid-fire homing cards. Send your foes to the shadow realm with their mystical power!"
- school = "evocation"
- charge_max = 50
- clothes_req = FALSE
- invocation = "Sigi'lu M'Fan 'Tasia"
- invocation_type = INVOCATION_SHOUT
- range = 40
- cooldown_min = 10
- projectile_amount = 5
- projectiles_per_fire = 7
- projectile_type = /obj/projectile/spellcard
- base_icon_state = "spellcard"
- action_icon_state = "spellcard0"
- var/datum/weakref/current_target_weakref
- var/projectile_turnrate = 10
- var/projectile_pixel_homing_spread = 32
- var/projectile_initial_spread_amount = 30
- var/projectile_location_spread_amount = 12
- var/datum/component/lockon_aiming/lockon_component
- ranged_clickcd_override = TRUE
-
-/obj/effect/proc_holder/spell/aimed/spell_cards/on_activation(mob/M)
- QDEL_NULL(lockon_component)
- lockon_component = M.AddComponent(/datum/component/lockon_aiming, 5, typecacheof(list(/mob/living)), 1, null, CALLBACK(src, PROC_REF(on_lockon_component)))
-
-/obj/effect/proc_holder/spell/aimed/spell_cards/proc/on_lockon_component(list/locked_weakrefs)
- if(!length(locked_weakrefs))
- current_target_weakref = null
- return
- current_target_weakref = locked_weakrefs[1]
- var/atom/A = current_target_weakref.resolve()
- if(A)
- var/mob/M = lockon_component.parent
- M.face_atom(A)
-
-/obj/effect/proc_holder/spell/aimed/spell_cards/on_deactivation(mob/M)
- QDEL_NULL(lockon_component)
-
-/obj/effect/proc_holder/spell/aimed/spell_cards/ready_projectile(obj/projectile/P, atom/target, mob/user, iteration)
- if(current_target_weakref)
- var/atom/A = current_target_weakref.resolve()
- if(A && get_dist(A, user) < 7)
- P.homing_turn_speed = projectile_turnrate
- P.homing_inaccuracy_min = projectile_pixel_homing_spread
- P.homing_inaccuracy_max = projectile_pixel_homing_spread
- P.set_homing_target(current_target_weakref.resolve())
- var/rand_spr = rand()
- var/total_angle = projectile_initial_spread_amount * 2
- var/adjusted_angle = total_angle - ((projectile_initial_spread_amount / projectiles_per_fire) * 0.5)
- var/one_fire_angle = adjusted_angle / projectiles_per_fire
- var/current_angle = iteration * one_fire_angle * rand_spr - (projectile_initial_spread_amount / 2)
- P.pixel_x = rand(-projectile_location_spread_amount, projectile_location_spread_amount)
- P.pixel_y = rand(-projectile_location_spread_amount, projectile_location_spread_amount)
- P.preparePixelProjectile(target, user, null, current_angle)
diff --git a/code/modules/spells/spell_types/charge.dm b/code/modules/spells/spell_types/charge.dm
index 57325e685f4d..225c36580e49 100644
--- a/code/modules/spells/spell_types/charge.dm
+++ b/code/modules/spells/spell_types/charge.dm
@@ -51,20 +51,6 @@
I.used = FALSE
charged_item = I
break
- else if(istype(item, /obj/item/gun/magic))
- var/obj/item/gun/magic/I = item
- if(prob(80) && !I.can_charge)
- I.max_charges--
- if(I.max_charges <= 0)
- I.max_charges = 0
- burnt_out = TRUE
- I.charges = I.max_charges
- if(istype(item, /obj/item/gun/magic/wand) && I.max_charges != 0)
- var/obj/item/gun/magic/W = item
- W.icon_state = initial(W.icon_state)
- I.recharge_newshot()
- charged_item = I
- break
else if(istype(item, /obj/item/stock_parts/cell))
var/obj/item/stock_parts/cell/C = item
if(!C.self_recharge)
diff --git a/code/modules/spells/spell_types/conjure.dm b/code/modules/spells/spell_types/conjure.dm
index c47205a27323..c34d5cf7c985 100644
--- a/code/modules/spells/spell_types/conjure.dm
+++ b/code/modules/spells/spell_types/conjure.dm
@@ -55,18 +55,6 @@
range = 3
newVars = list("emagged" = 2, "remote_disabled" = 1,"shoot_sound" = 'sound/weapons/laser.ogg',"projectile" = /obj/projectile/beam/laser, "declare_arrests" = 0,"name" = "Wizard's Justicebot")
-/obj/effect/proc_holder/spell/aoe_turf/conjure/linkWorlds
- name = "Link Worlds"
- desc = "A whole new dimension for you to play with! They won't be happy about it, though."
- invocation = "WTF"
- clothes_req = FALSE
- charge_max = 600
- cooldown_min = 200
- summon_type = list(/obj/structure/spawner/nether)
- summon_amt = 1
- range = 1
- cast_sound = 'sound/weapons/marauder.ogg'
-
/obj/effect/proc_holder/spell/targeted/conjure_item
name = "Summon weapon"
desc = "A generic spell that should not exist. This summons an instance of a specific type of item, or if one already exists, un-summons it. Summons into hand if possible."
diff --git a/code/modules/spells/spell_types/devil.dm b/code/modules/spells/spell_types/devil.dm
index 6631d943a3aa..421b7f40f11c 100644
--- a/code/modules/spells/spell_types/devil.dm
+++ b/code/modules/spells/spell_types/devil.dm
@@ -84,7 +84,7 @@
invocation_type = INVOCATION_SHOUT
range = 2
- projectile_type = /obj/projectile/magic/aoe/fireball/infernal
+ projectile_type = /obj/projectile/magic
action_background_icon_state = "bg_demon"
@@ -107,7 +107,7 @@
if(istype(user.loc, /obj/effect/dummy/phased_mob/slaughter/))
if(valid_location(user))
to_chat(user, "You are now phasing in.")
- if(do_mob(user,user,150))
+ if(do_after(user, 1.5 SECONDS, user))
if(valid_location(user))
user.infernalphasein()
else
@@ -121,7 +121,7 @@
user.notransform = TRUE
user.fakefire()
to_chat(src, "You begin to phase back into sinful flames.")
- if(do_mob(user,user,150))
+ if(do_after(user, 1.5 SECONDS, user))
user.infernalphaseout()
else
to_chat(user, "You must remain still while exiting.")
diff --git a/code/modules/spells/spell_types/infinite_guns.dm b/code/modules/spells/spell_types/infinite_guns.dm
deleted file mode 100644
index 3f400a8fb4bc..000000000000
--- a/code/modules/spells/spell_types/infinite_guns.dm
+++ /dev/null
@@ -1,27 +0,0 @@
-/obj/effect/proc_holder/spell/targeted/infinite_guns
- name = "Lesser Summon Guns"
- desc = "Why reload when you have infinite guns? Summons an unending stream of bolt action rifles that deal little damage, but will knock targets down. Requires both hands free to use. Learning this spell makes you unable to learn Arcane Barrage."
- invocation_type = "none"
- include_user = TRUE
- range = -1
-
- school = "conjuration"
- charge_max = 750
- clothes_req = TRUE
- cooldown_min = 10 //Gun wizard
- action_icon_state = "bolt_action"
- var/summon_path = /obj/item/gun/ballistic/rifle/illestren/enchanted
-
-/obj/effect/proc_holder/spell/targeted/infinite_guns/cast(list/targets, mob/user = usr)
- for(var/mob/living/carbon/C in targets)
- C.drop_all_held_items()
- var/GUN = new summon_path
- C.put_in_hands(GUN)
-
-/obj/effect/proc_holder/spell/targeted/infinite_guns/gun
-
-/obj/effect/proc_holder/spell/targeted/infinite_guns/arcane_barrage
- name = "Arcane Barrage"
- desc = "Fire a torrent of arcane energy at your foes with this (powerful) spell. Deals much more damage than Lesser Summon Guns, but won't knock targets down. Requires both hands free to use. Learning this spell makes you unable to learn Lesser Summon Gun."
- action_icon_state = "arcane_barrage"
- summon_path = /obj/item/gun/ballistic/rifle/illestren/enchanted/arcane_barrage
diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm
index c8d1c4a7c027..720670e3fc21 100644
--- a/code/modules/spells/spell_types/lichdom.dm
+++ b/code/modules/spells/spell_types/lichdom.dm
@@ -49,7 +49,7 @@
playsound(user, 'sound/effects/pope_entry.ogg', 100)
- if(!do_after(M, 50, needhand=FALSE, target=marked_item))
+ if(!do_after(M, 50, target=marked_item, timed_action_flags = IGNORE_HELD_ITEM))
to_chat(M, "Your soul snaps back to your body as you stop ensouling [marked_item]!")
return
diff --git a/code/modules/spells/spell_types/lightning.dm b/code/modules/spells/spell_types/lightning.dm
index 3231d22170e1..85f211511135 100644
--- a/code/modules/spells/spell_types/lightning.dm
+++ b/code/modules/spells/spell_types/lightning.dm
@@ -28,7 +28,7 @@
halo = halo || mutable_appearance('icons/effects/effects.dmi', "electricity", EFFECTS_LAYER)
user.add_overlay(halo)
playsound(get_turf(user), Snd, 50, FALSE)
- if(do_mob(user,user,100,1))
+ if(do_after(user, 10 SECONDS, user, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM)))
if(ready && cast_check(skipcharge=1))
choose_targets()
else
diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm
index aae206d6fb0a..55138a36c367 100644
--- a/code/modules/spells/spell_types/rightandwrong.dm
+++ b/code/modules/spells/spell_types/rightandwrong.dm
@@ -9,12 +9,12 @@ GLOBAL_LIST_INIT(summoned_guns, list(
/obj/item/gun/energy/e_gun,
/obj/item/gun/energy/e_gun/advtaser,
/obj/item/gun/energy/laser,
- /obj/item/gun/ballistic/revolver,
+ /obj/item/gun/ballistic/revolver/syndicate,
/obj/item/gun/ballistic/revolver/detective,
/obj/item/gun/ballistic/automatic/pistol/deagle/camo,
/obj/item/gun/ballistic/automatic/gyropistol,
/obj/item/gun/energy/pulse,
- /obj/item/gun/ballistic/automatic/pistol/suppressed,
+ /obj/item/gun/ballistic/automatic/pistol/syndicate,
/obj/item/gun/ballistic/shotgun/doublebarrel,
/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun/automatic/combat,
@@ -26,7 +26,7 @@ GLOBAL_LIST_INIT(summoned_guns, list(
/obj/item/gun/energy/lasercannon,
/obj/item/gun/energy/kinetic_accelerator/crossbow/large,
/obj/item/gun/energy/e_gun/nuclear,
- /obj/item/gun/ballistic/automatic/smg/proto,
+ /obj/item/gun/ballistic/automatic/smg/skm_carbine/inteq/proto,
/obj/item/gun/ballistic/automatic/smg/c20r,
/obj/item/gun/ballistic/automatic/hmg/l6_saw,
/obj/item/gun/ballistic/automatic/smg/m90,
@@ -43,66 +43,14 @@ GLOBAL_LIST_INIT(summoned_guns, list(
/obj/item/gun/ballistic/shotgun/bulldog,
/obj/item/gun/ballistic/revolver/grenadelauncher,
/obj/item/gun/ballistic/revolver/golden,
- /obj/item/gun/ballistic/automatic/sniper_rifle,
+ /obj/item/gun/ballistic/automatic/marksman/sniper_rifle,
/obj/item/gun/ballistic/rocketlauncher,
/obj/item/gun/medbeam,
/obj/item/gun/energy/laser/scatter,
/obj/item/gun/energy/gravity_gun))
-//if you add anything that isn't covered by the typepaths below, add it to summon_magic_objective_types
-GLOBAL_LIST_INIT(summoned_magic, list(
- /obj/item/book/granter/spell/fireball,
- /obj/item/book/granter/spell/smoke,
- /obj/item/book/granter/spell/blind,
- /obj/item/book/granter/spell/mindswap,
- /obj/item/book/granter/spell/forcewall,
- /obj/item/book/granter/spell/knock,
- /obj/item/book/granter/spell/barnyard,
- /obj/item/book/granter/spell/charge,
- /obj/item/book/granter/spell/summonitem,
- /obj/item/gun/magic/wand/nothing,
- /obj/item/gun/magic/wand/death,
- /obj/item/gun/magic/wand/resurrection,
- /obj/item/gun/magic/wand/polymorph,
- /obj/item/gun/magic/wand/teleport,
- /obj/item/gun/magic/wand/door,
- /obj/item/gun/magic/wand/fireball,
- /obj/item/gun/magic/staff/healing,
- /obj/item/gun/magic/staff/door,
- /obj/item/scrying,
- /obj/item/voodoo,
- /obj/item/warpwhistle,
- /obj/item/clothing/suit/space/hardsuit/shielded/wizard,
- /obj/item/immortality_talisman,
- /obj/item/melee/ghost_sword))
-
-GLOBAL_LIST_INIT(summoned_special_magic, list(
- /obj/item/gun/magic/staff/change,
- /obj/item/gun/magic/staff/animate,
- /obj/item/storage/belt/wands/full,
- /obj/item/antag_spawner/contract,
- /obj/item/gun/magic/staff/chaos,
- /obj/item/necromantic_stone,
- /obj/item/blood_contract))
-
-//everything above except for single use spellbooks, because they are counted separately (and are for basic bitches anyways)
-GLOBAL_LIST_INIT(summoned_magic_objectives, list(
- /obj/item/antag_spawner/contract,
- /obj/item/blood_contract,
- /obj/item/clothing/suit/space/hardsuit/shielded/wizard,
- /obj/item/gun/magic,
- /obj/item/immortality_talisman,
- /obj/item/melee/ghost_sword,
- /obj/item/necromantic_stone,
- /obj/item/scrying,
- /obj/item/spellbook,
- /obj/item/storage/belt/wands/full,
- /obj/item/voodoo,
- /obj/item/warpwhistle))
-
// If true, it's the probability of triggering "survivor" antag.
GLOBAL_VAR_INIT(summon_guns_triggered, FALSE)
-GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
/proc/give_guns(mob/living/carbon/human/H)
if(H.stat == DEAD || !(H.client))
@@ -119,62 +67,25 @@ GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
var/gun_type = pick(GLOB.summoned_guns)
var/obj/item/gun/G = new gun_type(get_turf(H))
- if (istype(G)) // The list contains some non-gun type guns like the speargun which do not have this proc
- G.unlock()
playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, TRUE)
var/in_hand = H.put_in_hands(G) // not always successful
to_chat(H, "\A [G] appears [in_hand ? "in your hand" : "at your feet"]!")
-/proc/give_magic(mob/living/carbon/human/H)
- if(H.stat == DEAD || !(H.client))
- return
- if(H.mind)
- if(iswizard(H) || H.mind.has_antag_datum(/datum/antagonist/survivalist/magic))
- return
-
- if(prob(GLOB.summon_magic_triggered) && !(H.mind.has_antag_datum(/datum/antagonist)))
- H.mind.add_antag_datum(/datum/antagonist/survivalist/magic)
- H.log_message("was made into a survivalist, and trusts no one!", LOG_ATTACK, color="red")
-
- var/magic_type = pick(GLOB.summoned_magic)
- var/lucky = FALSE
- if(prob(SPECIALIST_MAGIC_PROB))
- magic_type = pick(GLOB.summoned_special_magic)
- lucky = TRUE
-
- var/obj/item/M = new magic_type(get_turf(H))
- playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, TRUE)
-
- var/in_hand = H.put_in_hands(M)
-
- to_chat(H, "\A [M] appears [in_hand ? "in your hand" : "at your feet"]!")
- if(lucky)
- to_chat(H, "You feel incredibly lucky.")
-
-
-/proc/rightandwrong(summon_type, mob/user, survivor_probability)
- if(user) //in this case either someone holding a spellbook or a badmin
- to_chat(user, "You summoned [summon_type]!")
- message_admins("[ADMIN_LOOKUPFLW(user)] summoned [summon_type]!")
- log_game("[key_name(user)] summoned [summon_type]!")
+/proc/rightandwrong(mob/user, survivor_probability)
+ if(user) //in this case someone is a badmin
+ to_chat(user, "You summoned guns!")
+ message_admins("[ADMIN_LOOKUPFLW(user)] summoned guns!")
+ log_game("[key_name(user)] summoned guns!")
- if(summon_type == SUMMON_MAGIC)
- GLOB.summon_magic_triggered = survivor_probability
- else if(summon_type == SUMMON_GUNS)
- GLOB.summon_guns_triggered = survivor_probability
- else
- CRASH("Bad summon_type given: [summon_type]")
+ GLOB.summon_guns_triggered = survivor_probability
for(var/mob/living/carbon/human/H in GLOB.player_list)
var/turf/T = get_turf(H)
if(T && is_away_level(T))
continue
- if(summon_type == SUMMON_MAGIC)
- give_magic(H)
- else
- give_guns(H)
+ give_guns(H)
/proc/summonevents()
if(!SSevents.wizardmode)
diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm
index 65eb0cebb2b3..254a43dc23af 100644
--- a/code/modules/spells/spell_types/shapeshift.dm
+++ b/code/modules/spells/spell_types/shapeshift.dm
@@ -19,7 +19,6 @@
var/mob/living/shapeshift_type
var/list/possible_shapes = list(/mob/living/simple_animal/mouse,\
/mob/living/simple_animal/pet/dog/corgi,\
- /mob/living/simple_animal/hostile/carp/ranged/chaos,\
/mob/living/simple_animal/bot/secbot/ed209,\
/mob/living/simple_animal/hostile/poison/giant_spider/hunter/viper,\
/mob/living/simple_animal/hostile/construct/juggernaut)
diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm
index 387a2ee9712c..2fab8c5848ef 100644
--- a/code/modules/spells/spell_types/wizard.dm
+++ b/code/modules/spells/spell_types/wizard.dm
@@ -242,46 +242,34 @@
sound = 'sound/magic/repulse.ogg'
var/maxthrow = 5
var/sparkle_path = /obj/effect/temp_visual/gravpush
- var/anti_magic_check = TRUE
var/repulse_force = MOVE_FORCE_EXTREMELY_STRONG
-
+ var/stun_amt = 5
action_icon_state = "repulse"
-/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, stun_amt = 5)
+/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/hit_turfs, mob/user = usr)
var/list/thrownatoms = list()
- var/atom/throwtarget
var/distfromcaster
playMagSound()
- for(var/atom/movable/hit_target as anything in targets) //Done this way so things don't get thrown all around hilariously.
- thrownatoms += hit_target
- for(var/am in thrownatoms)
- var/atom/movable/AM = am
+ for(var/turf/T in hit_turfs)
+ for(var/atom/movable/hit_target in T.contents)
+ thrownatoms += hit_target
+
+ for(var/thrown_atom in thrownatoms)
+ if(!ismovable(thrown_atom))
+ continue
+ var/atom/movable/AM = thrown_atom
if(AM == user || AM.anchored)
continue
-
- if(ismob(AM))
- var/mob/M = AM
- if(M.anti_magic_check(anti_magic_check, FALSE))
- continue
-
- throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
- distfromcaster = get_dist(user, AM)
- if(distfromcaster == 0)
- if(isliving(AM))
- var/mob/living/M = AM
- M.Paralyze(40)
- M.adjustBruteLoss(5)
- shake_camera(AM, 2, 1)
- to_chat(M, "You're slammed into the floor by [user]!")
- else
- new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own
- if(isliving(AM))
- var/mob/living/M = AM
- shake_camera(AM, 2, 1)
+ var/atom/throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
+ new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own
+ if(isliving(AM))
+ var/mob/living/M = AM
+ shake_camera(AM, 2, 1)
+ if(stun_amt)
M.Paralyze(stun_amt)
- to_chat(M, "You're thrown back by [user]!")
- AM.safe_throw_at(throwtarget, ((clamp((maxthrow - (clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user, force = repulse_force)//So stuff gets tossed around at the same time.
+ to_chat(M, "You're thrown back by [user]!")
+ AM.safe_throw_at(throwtarget, ((clamp((maxthrow - (clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user, force = repulse_force)//So stuff gets tossed around at the same time.
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?!
name = "Tail Sweep"
@@ -297,7 +285,7 @@
action_icon = 'icons/mob/actions/actions_xeno.dmi'
action_icon_state = "tailsweep"
action_background_icon_state = "bg_alien"
- anti_magic_check = FALSE
+ stun_amt = 0
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno/cast(list/targets,mob/user = usr)
if(iscarbon(user))
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
index 9679aa860c9c..b894f99c255d 100644
--- a/code/modules/station_goals/dna_vault.dm
+++ b/code/modules/station_goals/dna_vault.dm
@@ -120,7 +120,7 @@
icon_state = "vault"
density = TRUE
anchored = TRUE
- idle_power_usage = 5000
+ idle_power_usage = ACTIVE_DRAW_EXTREME
pixel_x = -32
pixel_y = -64
light_range = 3
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index 366fb41790ab..f8d8a9a49384 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -50,6 +50,16 @@
/// Is it fine, broken, splinted, or just straight up fucking gone
var/bone_status = BONE_FLAG_NO_BONES
var/bone_break_threshold = 30
+ /// Threshold at which the limb will start bleeding if damaged by sharp items or projectiles
+ var/bleed_threshold = 10
+ /// Threshold at which the limb will start bleeding if damaged by blunt items
+ var/bleed_threshold_blunt = 25
+ /// Minimum damage of an incoming attack for it to cause bleeding
+ var/bleed_damage_min = 5
+ /// Minimum damage of an incoming blunt attack for it to cause bleeding
+ var/bleed_damage_min_blunt = 10
+ /// Current limb bleeding, increased when the limb takes brute damage over certain thresholds, decreased through bandages and cauterization
+ var/bleeding = 0
/// So we know if we need to scream if this limb hits max damage
var/last_maxed
@@ -202,11 +212,13 @@
if(stamina_dam > DAMAGE_PRECISION && owner.stam_regen_start_time <= world.time) //DO NOT update health here, it'll be done in the carbon's life.
heal_damage(0, 0, INFINITY, null, FALSE)
. |= BODYPART_LIFE_UPDATE_HEALTH
+ if(brute_dam < DAMAGE_PRECISION && bleeding)
+ adjust_bleeding(-0.2) //slowly stop bleeding if there's no damage left
//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all.
//Damage will not exceed max_damage using this proc
//Cannot apply negative damage
-/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, blocked = 0, updating_health = TRUE, required_status = null, break_modifier = 1)
+/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, blocked = 0, updating_health = TRUE, required_status = null, break_modifier = 1, sharpness = FALSE)
var/hit_percent = (100-blocked)/100
if((!brute && !burn && !stamina) || hit_percent <= 0)
return FALSE
@@ -232,9 +244,13 @@
burn *= 2
// Is the damage greater than the threshold, and if so, probability of damage + item force
- if((brute_dam > bone_break_threshold) && prob(brute_dam + break_modifier))
+ if(brute && (brute_dam > bone_break_threshold) && prob(brute_dam + break_modifier))
break_bone()
+ // Bleeding is applied here
+ if(brute_dam+brute >= (sharpness ? bleed_threshold : bleed_threshold_blunt) && brute >= (sharpness ? bleed_damage_min : bleed_damage_min_blunt))
+ adjust_bleeding(brute * BLOOD_LOSS_DAMAGE_BASE, BLOOD_LOSS_DAMAGE_MAXIMUM)
+
var/can_inflict = max_damage - get_damage()
if(can_inflict <= 0)
return FALSE
@@ -274,6 +290,7 @@
if(brute)
set_brute_dam(round(max(brute_dam - brute, 0), DAMAGE_PRECISION))
+ adjust_bleeding(-BLOOD_LOSS_DAMAGE_MAXIMUM * brute / max_damage)
if(burn)
set_burn_dam(round(max(burn_dam - burn, 0), DAMAGE_PRECISION))
if(stamina)
@@ -315,6 +332,30 @@
. = stamina_dam
stamina_dam = new_value
+/// Adjusts bodypart bleeding, value = amount of change, maximum = maximum current bloodloss amount this can modify
+/obj/item/bodypart/proc/adjust_bleeding(value, maximum = BLOOD_LOSS_MAXIMUM)
+ if(bleeding > maximum)
+ return
+ if(owner.dna && (NOBLOOD in owner.dna.species.species_traits))
+ return
+ bleeding = round(clamp(bleeding+value, 0, maximum), 0.001)
+
+/// Checks if the bodypart is viable for bandaging, if it isn't, tells the person trying (if present) what's stopping it
+/obj/item/bodypart/proc/can_bandage(user)
+ . = TRUE
+ if(is_pseudopart)
+ return FALSE
+ if(!bleeding)
+ if(user)
+ to_chat(user, span_warning("[owner]'s [parse_zone(body_zone)] isn't bleeding!"))
+ return FALSE
+ if(GetComponent(/datum/component/bandage))
+ if(user)
+ to_chat(user, span_warning("[owner]'s [parse_zone(body_zone)] has already been dressed!"))
+ return FALSE
+
+/obj/item/bodypart/proc/apply_bandage(bleed_reduction, lifespan, name)
+ AddComponent(/datum/component/bandage, bleed_reduction, lifespan, name)
//Returns total damage.
/obj/item/bodypart/proc/get_damage(include_stamina = FALSE)
@@ -745,8 +786,8 @@
bone_status = BONE_FLAG_NORMAL
/obj/item/bodypart/proc/on_mob_move()
- // Dont trigger if it isn't broken or if it has no owner
- if(bone_status != BONE_FLAG_BROKEN || !owner)
+ // Dont trigger if it isn't broken or if it has no owner or is buckled to a rollerbed
+ if(bone_status != BONE_FLAG_BROKEN || !owner || istype(owner?.buckled, /obj/structure/bed/roller))
return
if(prob(5))
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 7c292ac21fc4..07d30e727c77 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -90,6 +90,7 @@
return
var/atom/Tsec = owner.drop_location()
var/mob/living/carbon/C = owner
+ SEND_SIGNAL(src, COMSIG_LIVING_DROP_LIMB)
update_limb(TRUE)
C.remove_bodypart(src)
diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm
index 398d937cc586..61bbb88ab545 100644
--- a/code/modules/surgery/bodyparts/robot_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm
@@ -137,7 +137,6 @@
var/wired = FALSE
var/obj/item/stock_parts/cell/cell = null
-
/obj/item/bodypart/chest/robot/handle_atom_del(atom/A)
if(A == cell)
cell = null
@@ -191,7 +190,6 @@
cell.forceMove(drop_location())
cell = null
-
/obj/item/bodypart/chest/robot/examine(mob/user)
. = ..()
if(cell)
@@ -214,7 +212,6 @@
cell = null
..()
-
/obj/item/bodypart/head/robot
name = "cyborg head"
desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
@@ -304,7 +301,6 @@
to_chat(user, "There is no flash to remove from [src].")
return TRUE
-
/obj/item/bodypart/head/robot/drop_organs(mob/user, violent_removal)
if(flash1)
flash1.forceMove(user.loc)
@@ -314,9 +310,6 @@
flash2 = null
..()
-
-
-
/obj/item/bodypart/l_arm/robot/surplus
name = "surplus prosthetic left arm"
desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing."
diff --git a/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm
index d389ec5cc56b..0794602de953 100644
--- a/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm
@@ -1,37 +1,38 @@
/obj/item/bodypart/head/ethereal
icon = 'icons/mob/species/ethereal/bodyparts.dmi'
- icon_state = "ethereal_head"
- limb_id = SPECIES_ETHEREAL
+ icon_state = "elzuose_head"
+ limb_id = SPECIES_ELZUOSE
is_dimorphic = FALSE
uses_mutcolor = TRUE
+ bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC | BODYTYPE_SNOUT
/obj/item/bodypart/chest/ethereal
icon = 'icons/mob/species/ethereal/bodyparts.dmi'
- icon_state = "ethereal_chest"
- limb_id = SPECIES_ETHEREAL
+ icon_state = "elzuose_chest"
+ limb_id = SPECIES_ELZUOSE
is_dimorphic = FALSE
uses_mutcolor = TRUE
/obj/item/bodypart/l_arm/ethereal
icon = 'icons/mob/species/ethereal/bodyparts.dmi'
- icon_state = "ethereal_l_arm"
- limb_id = SPECIES_ETHEREAL
+ icon_state = "elzuose_l_arm"
+ limb_id = SPECIES_ELZUOSE
uses_mutcolor = TRUE
/obj/item/bodypart/r_arm/ethereal
icon = 'icons/mob/species/ethereal/bodyparts.dmi'
- icon_state = "ethereal_r_arm"
- limb_id = SPECIES_ETHEREAL
+ icon_state = "elzuose_r_arm"
+ limb_id = SPECIES_ELZUOSE
uses_mutcolor = TRUE
/obj/item/bodypart/leg/left/ethereal
icon = 'icons/mob/species/ethereal/bodyparts.dmi'
- icon_state = "ethereal_l_leg"
- limb_id = SPECIES_ETHEREAL
+ icon_state = "elzuose_l_leg"
+ limb_id = SPECIES_ELZUOSE
uses_mutcolor = TRUE
/obj/item/bodypart/leg/right/ethereal
icon = 'icons/mob/species/ethereal/bodyparts.dmi'
- icon_state = "ethereal_r_leg"
- limb_id = SPECIES_ETHEREAL
+ icon_state = "elzuose_r_leg"
+ limb_id = SPECIES_ELZUOSE
uses_mutcolor = TRUE
diff --git a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
index b5be2b890d8c..50e37ee93e12 100644
--- a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
@@ -1,47 +1,48 @@
/obj/item/bodypart/head/lizard
icon = 'icons/mob/species/lizard/bodyparts.dmi'
- icon_state = "lizard_head"
- limb_id = SPECIES_LIZARD
+ icon_state = "sarathi_head"
+ limb_id = SPECIES_SARATHI
uses_mutcolor = TRUE
is_dimorphic = FALSE
+ bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC | BODYTYPE_SNOUT
/obj/item/bodypart/chest/lizard
icon = 'icons/mob/species/lizard/bodyparts.dmi'
- icon_state = "lizard_chest"
+ icon_state = "sarathi_chest"
uses_mutcolor = TRUE
- limb_id = SPECIES_LIZARD
+ limb_id = SPECIES_SARATHI
is_dimorphic = FALSE
/obj/item/bodypart/l_arm/lizard
icon = 'icons/mob/species/lizard/bodyparts.dmi'
- icon_state = "lizard_l_arm"
+ icon_state = "sarathi_l_arm"
uses_mutcolor = TRUE
- limb_id = SPECIES_LIZARD
+ limb_id = SPECIES_SARATHI
/obj/item/bodypart/r_arm/lizard
icon = 'icons/mob/species/lizard/bodyparts.dmi'
- icon_state = "lizard_r_arm"
+ icon_state = "sarathi_r_arm"
uses_mutcolor = TRUE
- limb_id = SPECIES_LIZARD
+ limb_id = SPECIES_SARATHI
/obj/item/bodypart/leg/left/lizard
icon = 'icons/mob/species/lizard/bodyparts.dmi'
- icon_state = "lizard_l_leg"
+ icon_state = "sarathi_l_leg"
uses_mutcolor = TRUE
- limb_id = SPECIES_LIZARD
+ limb_id = SPECIES_SARATHI
/obj/item/bodypart/leg/right/lizard
icon = 'icons/mob/species/lizard/bodyparts.dmi'
- icon_state = "lizard_r_leg"
+ icon_state = "sarathi_r_leg"
uses_mutcolor = TRUE
- limb_id = SPECIES_LIZARD
+ limb_id = SPECIES_SARATHI
/obj/item/bodypart/leg/left/lizard/digitigrade
icon = 'icons/mob/species/lizard/bodyparts.dmi'
- icon_state = "lizard_l_leg_digitigrade"
+ icon_state = "sarathi_l_leg_digitigrade"
bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC | BODYTYPE_DIGITIGRADE
/obj/item/bodypart/leg/right/lizard/digitigrade
icon = 'icons/mob/species/lizard/bodyparts.dmi'
- icon_state = "lizard_r_leg_digitigrade"
+ icon_state = "sarathi_r_leg_digitigrade"
bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC | BODYTYPE_DIGITIGRADE
diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm
index 4c416c31c633..a4628d19efff 100644
--- a/code/modules/surgery/coronary_bypass.dm
+++ b/code/modules/surgery/coronary_bypass.dm
@@ -41,7 +41,8 @@
display_results(user, target, "Blood pools around the incision in [H]'s heart.",
"Blood pools around the incision in [H]'s heart.",
"")
- H.bleed_rate += 10
+ var/obj/item/bodypart/BP = H.get_bodypart(check_zone(surgery.location))
+ BP.adjust_bleeding(10)
target.apply_damage(15, BRUTE, "[target_zone]")
return ..()
@@ -51,7 +52,8 @@
display_results(user, target, "You screw up, cutting too deeply into the heart!",
"[user] screws up, causing blood to spurt out of [H]'s chest!",
"[user] screws up, causing blood to spurt out of [H]'s chest!")
- H.bleed_rate += 20
+ var/obj/item/bodypart/BP = H.get_bodypart(check_zone(surgery.location))
+ BP.adjust_bleeding(20)
H.adjustOrganLoss(ORGAN_SLOT_HEART, 10)
target.apply_damage(15, BRUTE, "[target_zone]")
@@ -90,5 +92,6 @@
"[user] screws up, causing blood to spurt out of [H]'s chest profusely!",
"[user] screws up, causing blood to spurt out of [H]'s chest profusely!")
H.adjustOrganLoss(ORGAN_SLOT_HEART, 30)
- H.bleed_rate += 30
+ var/obj/item/bodypart/BP = H.get_bodypart(check_zone(surgery.location))
+ BP.adjust_bleeding(30)
return FALSE
diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm
index 5167bb3a4517..42018e6c1d87 100644
--- a/code/modules/surgery/organic_steps.dm
+++ b/code/modules/surgery/organic_steps.dm
@@ -30,7 +30,9 @@
display_results(user, target, "Blood pools around the incision in [H]'s [parse_zone(target_zone)].",
"Blood pools around the incision in [H]'s [parse_zone(target_zone)].",
"")
- H.bleed_rate += 3
+ var/obj/item/bodypart/BP = H.get_bodypart(check_zone(surgery.location))
+ if(BP)
+ BP.adjust_bleeding(3)
return ..()
/datum/surgery_step/incise/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -74,7 +76,9 @@
target.heal_bodypart_damage(20,0)
if (ishuman(target))
var/mob/living/carbon/human/H = target
- H.bleed_rate = max((H.bleed_rate - 3), 0)
+ var/obj/item/bodypart/BP = H.get_bodypart(check_zone(surgery.location))
+ if(BP)
+ BP.adjust_bleeding(-3)
return ..()
/datum/surgery_step/clamp_bleeders/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -137,7 +141,9 @@
target.heal_bodypart_damage(15,0)
if (ishuman(target))
var/mob/living/carbon/human/H = target
- H.bleed_rate = max((H.bleed_rate - 3), 0)
+ var/obj/item/bodypart/BP = H.get_bodypart(check_zone(surgery.location))
+ if(BP)
+ BP.adjust_bleeding(-3)
return ..()
//saw bone
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index d9d3d6b0b717..5d6fac852d51 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -13,6 +13,10 @@
var/list/items_list = list()// I would use contents, but they shuffle on every activation/deactivation leading to interface inconsistencies.
/// You can use this var for item path, it would be converted into an item on New().
var/obj/item/active_item
+ /// Sound played when extending
+ var/extend_sound = 'sound/mecha/mechmove03.ogg'
+ /// Sound played when retracting
+ var/retract_sound = 'sound/mecha/mechmove03.ogg'
/obj/item/organ/cyberimp/arm/Initialize()
. = ..()
@@ -68,18 +72,34 @@
to_chat(user, "You modify [src] to be installed on the [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.")
update_appearance()
+/obj/item/organ/cyberimp/arm/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
+ . = ..()
+ var/side = zone == BODY_ZONE_R_ARM? RIGHT_HANDS : LEFT_HANDS
+ hand = owner.hand_bodyparts[side]
+ if(hand)
+ RegisterSignal(hand, COMSIG_ITEM_ATTACK_SELF, PROC_REF(ui_action_click)) //If the limb gets an attack-self, open the menu. Only happens when hand is empty
+ RegisterSignal(M, COMSIG_KB_MOB_DROPITEM_DOWN, PROC_REF(dropkey)) //We're nodrop, but we'll watch for the drop hotkey anyway and then stow if possible.
+
/obj/item/organ/cyberimp/arm/Remove(mob/living/carbon/M, special = 0)
Retract()
+ if(hand)
+ UnregisterSignal(hand, COMSIG_ITEM_ATTACK_SELF)
+ UnregisterSignal(M, COMSIG_KB_MOB_DROPITEM_DOWN)
..()
-/obj/item/organ/cyberimp/arm/emp_act(severity)
- . = ..()
- if(. & EMP_PROTECT_SELF)
- return
- if(prob(15/severity) && owner)
- to_chat(owner, "[src] is hit by EMP!")
- // give the owner an idea about why his implant is glitching
- Retract()
+/**
+ * Called when the mob uses the "drop item" hotkey
+ *
+ * Items inside toolset implants have TRAIT_NODROP, but we can still use the drop item hotkey as a
+ * quick way to store implant items. In this case, we check to make sure the user has the correct arm
+ * selected, and that the item is actually owned by us, and then we'll hand off the rest to Retract()
+**/
+/obj/item/organ/cyberimp/arm/proc/dropkey(mob/living/carbon/host)
+ if(!host)
+ return //How did we even get here
+ if(hand != host.hand_bodyparts[host.active_hand_index])
+ return //wrong hand
+ Retract()
/obj/item/organ/cyberimp/arm/proc/Retract()
if(!active_item || (active_item in src))
@@ -89,13 +109,9 @@
"[active_item] snaps back into your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.",
"You hear a short mechanical noise.")
- if(istype(active_item, /obj/item/assembly/flash/armimplant))
- var/obj/item/assembly/flash/F = active_item
- F.set_light(0)
-
owner.transferItemToLoc(active_item, src, TRUE)
+ playsound(get_turf(owner), retract_sound, 50, TRUE)
active_item = null
- playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, TRUE)
/obj/item/organ/cyberimp/arm/proc/Extend(obj/item/item)
if(!(item in src))
@@ -135,7 +151,7 @@
owner.visible_message("[owner] extends [active_item] from [owner.p_their()] [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.",
"You extend [active_item] from your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.",
"You hear a short mechanical noise.")
- playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, TRUE)
+ playsound(get_turf(owner), extend_sound, 50, TRUE)
/obj/item/organ/cyberimp/arm/ui_action_click()
if((organ_flags & ORGAN_FAILING) || (!active_item && !contents.len))
@@ -161,6 +177,14 @@
else
Retract()
+/obj/item/organ/cyberimp/arm/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
+ return
+ if(prob(15/severity) && owner)
+ to_chat(owner, "[src] is hit by EMP!")
+ // give the owner an idea about why his implant is glitching
+ Retract()
/obj/item/organ/cyberimp/arm/gun/emp_act(severity)
. = ..()
@@ -225,7 +249,6 @@
desc = "A cybernetic implant that allows the user to project a healing beam from their hand."
items_to_create = list(/obj/item/gun/medbeam)
-
/obj/item/organ/cyberimp/arm/flash
name = "integrated high-intensity photon projector" //Why not
desc = "An integrated projector mounted onto a user's arm that is able to be used as a powerful flash."
@@ -277,4 +300,4 @@
name = "power cord implant"
desc = "An internal power cord hooked up to a battery. Useful if you run on volts."
items_to_create = list(/obj/item/apc_powercord)
- zone = "l_arm"
+ zone = BODY_ZONE_L_ARM
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index ae6f1cf43d39..022292c282b8 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -2,6 +2,7 @@
/obj/item/organ/cyberimp
name = "cybernetic implant"
desc = "A state-of-the-art implant that improves a baseline's functionality."
+ icon = 'icons/obj/implants/implant.dmi'
status = ORGAN_ROBOTIC
organ_flags = ORGAN_SYNTHETIC
var/implant_color = "#FFFFFF"
@@ -17,8 +18,6 @@
add_overlay(overlay)
return ..()
-
-
//[[[[BRAIN]]]]
/obj/item/organ/cyberimp/brain
@@ -138,6 +137,36 @@
/obj/item/organ/cyberimp/brain/anti_stun/proc/reboot()
organ_flags &= ~ORGAN_FAILING
+/obj/item/organ/cyberimp/brain/joywire
+ name = "\improper Midi-Sed pleasure vivifier"
+ desc = "A widely popular (and addictive) implant produced by Miditeke-Sedari Tokoce that stimulates the brain's pleasure centers. Dramatically increases mood, but interferes with taste reception even if uninstalled."
+ implant_color = "#FFABE0"
+ slot = ORGAN_SLOT_BRAIN_JOYWIRE
+
+/obj/item/organ/cyberimp/brain/joywire/on_life()
+ if(owner || !(organ_flags & ORGAN_FAILING))
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "joywire", /datum/mood_event/joywire)
+ ADD_TRAIT(owner, TRAIT_AGEUSIA, TRAIT_GENERIC)
+
+/obj/item/organ/cyberimp/brain/joywire/emp_act(severity)
+ . = ..()
+ if(!owner || . & EMP_PROTECT_SELF)
+ return
+ organ_flags |= ORGAN_FAILING
+ SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "joywire")
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "joywire_emp", /datum/mood_event/joywire_emp)
+ to_chat(owner, span_boldwarning("That feeling of dream-like, distilled joy is suddenly diluted. Misery sets in..."))
+
+/obj/item/organ/cyberimp/brain/mindscrew
+ name = "\improper Midi-Sed MNDFCK implant"
+ desc = "A horrific after-market modification of Midi-Sed's pleasure vivifier that stimulates intense pain in the brain. Dramatically hurts a user's mood and mental state, and lingers for a time after removal."
+ implant_color = "#5E1108"
+ slot = ORGAN_SLOT_BRAIN_JOYWIRE
+
+/obj/item/organ/cyberimp/brain/mindscrew/on_life()
+ if(owner || !(organ_flags & ORGAN_FAILING))
+ SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "mindscrew", /datum/mood_event/mindscrew)
+
//[[[[MOUTH]]]]
/obj/item/organ/cyberimp/mouth
zone = BODY_ZONE_PRECISE_MOUTH
diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm
index f1eb39b84162..6f057c88d23d 100644
--- a/code/modules/surgery/organs/ears.dm
+++ b/code/modules/surgery/organs/ears.dm
@@ -150,6 +150,10 @@
ear_owner.dna.species.mutant_bodyparts -= "ears"
ear_owner.update_body()
+/obj/item/organ/ears/fox
+ name = "fox ears"
+ damage_multiplier = 2
+
/obj/item/organ/ears/fox/Insert(mob/living/carbon/human/ear_owner, special = 0, drop_if_replaced = TRUE)
..()
if(istype(ear_owner))
@@ -166,6 +170,78 @@
ear_owner.dna.species.mutant_bodyparts -= "ears"
ear_owner.update_body()
+/obj/item/organ/ears/rabbit
+ name = "rabbit ears"
+ damage_multiplier = 2
+
+/obj/item/organ/ears/rabbit/Insert(mob/living/carbon/human/ear_owner, special = 0, drop_if_replaced = TRUE)
+ ..()
+ if(istype(ear_owner))
+ color = ear_owner.hair_color
+ ear_owner.dna.species.mutant_bodyparts |= "ears"
+ ear_owner.dna.features["ears"] = "Rabbit"
+ ear_owner.update_body()
+
+/obj/item/organ/ears/rabbit/Remove(mob/living/carbon/human/ear_owner, special = 0)
+ ..()
+ if(istype(ear_owner))
+ color = ear_owner.hair_color
+ ear_owner.dna.features["ears"] = "None"
+ ear_owner.dna.species.mutant_bodyparts -= "ears"
+ ear_owner.update_body()
+
+/obj/item/organ/ears/rabbit/bent/Insert(mob/living/carbon/human/ear_owner, special = 0, drop_if_replaced = TRUE)
+ ..()
+ if(istype(ear_owner))
+ color = ear_owner.hair_color
+ ear_owner.dna.species.mutant_bodyparts |= "ears"
+ ear_owner.dna.features["ears"] = "Bent Rabbit"
+ ear_owner.update_body()
+
+/obj/item/organ/ears/rabbit/bent/Remove(mob/living/carbon/human/ear_owner, special = 0)
+ ..()
+ if(istype(ear_owner))
+ color = ear_owner.hair_color
+ ear_owner.dna.features["ears"] = "None"
+ ear_owner.dna.species.mutant_bodyparts -= "ears"
+ ear_owner.update_body()
+
+/obj/item/organ/ears/rabbit/floppy/Insert(mob/living/carbon/human/ear_owner, special = 0, drop_if_replaced = TRUE)
+ ..()
+ if(istype(ear_owner))
+ color = ear_owner.hair_color
+ ear_owner.dna.species.mutant_bodyparts |= "ears"
+ ear_owner.dna.features["ears"] = "Floppy Rabbit"
+ ear_owner.update_body()
+
+/obj/item/organ/ears/floppy/Remove(mob/living/carbon/human/ear_owner, special = 0)
+ ..()
+ if(istype(ear_owner))
+ color = ear_owner.hair_color
+ ear_owner.dna.features["ears"] = "None"
+ ear_owner.dna.species.mutant_bodyparts -= "ears"
+ ear_owner.update_body()
+
+/obj/item/organ/ears/dog
+ name = "dog ears"
+ damage_multiplier = 2
+
+/obj/item/organ/ears/dog/Insert(mob/living/carbon/human/ear_owner, special = 0, drop_if_replaced = TRUE)
+ ..()
+ if(istype(ear_owner))
+ color = ear_owner.hair_color
+ ear_owner.dna.species.mutant_bodyparts |= "ears"
+ ear_owner.dna.features["ears"] = "Dog"
+ ear_owner.update_body()
+
+/obj/item/organ/ears/dog/Remove(mob/living/carbon/human/ear_owner, special = 0)
+ ..()
+ if(istype(ear_owner))
+ color = ear_owner.hair_color
+ ear_owner.dna.features["ears"] = "None"
+ ear_owner.dna.species.mutant_bodyparts -= "ears"
+ ear_owner.update_body()
+
/obj/item/organ/ears/elf
name = "elf ears"
damage_multiplier = 1.5
diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm
index 0c200df9f6b1..283ee77971eb 100644
--- a/code/modules/surgery/organs/eyes.dm
+++ b/code/modules/surgery/organs/eyes.dm
@@ -149,6 +149,9 @@
/obj/item/organ/eyes/robotic/lizard
eye_icon_state = "eyes_synth"
+/obj/item/organ/eyes/robotic/kepori
+ eye_icon_state = "eyes_kepori_synth"
+
/obj/item/organ/eyes/robotic/emp_act(severity)
. = ..()
if(!owner || . & EMP_PROTECT_SELF)
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index fc5de4be3049..05ca5131e0f9 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -226,7 +226,7 @@
if(SA_pp > SA_para_min) // Enough to make us stunned for a bit
H.Unconscious(60) // 60 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
- H.Sleeping(max(H.AmountSleeping() + 40, 200))
+ H.Sleeping(200)
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
H.emote(pick("giggle", "laugh"))
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 4b5dd9a49717..b8871b21524e 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -38,7 +38,7 @@
/obj/item/organ/Initialize()
. = ..()
if(organ_flags & ORGAN_EDIBLE)
- AddComponent(/datum/component/edible, food_reagents, null, RAW | MEAT | GORE, null, 10, null, null, null, CALLBACK(src, PROC_REF(OnEatFrom)))
+ AddComponent(/datum/component/edible, food_reagents, null, RAW | MEAT | GORE, null, 10, null, null, null, COLOR_PINK, CALLBACK(src, PROC_REF(OnEatFrom)))
///When you take a bite you cant jam it in for surgery anymore.
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm
index bf9346b5dcd9..62ca9cd2fe8e 100644
--- a/code/modules/surgery/organs/stomach.dm
+++ b/code/modules/surgery/organs/stomach.dm
@@ -100,12 +100,12 @@
/obj/item/organ/stomach/ethereal
name = "biological battery"
icon_state = "stomach-p" //Welp. At least it's more unique in functionaliy.
- desc = "A crystal-like organ that stores the electric charge of ethereals."
- var/crystal_charge = ETHEREAL_CHARGE_FULL
+ desc = "A crystal-like organ that stores the electric charge of elzuosa."
+ var/crystal_charge = ELZUOSE_CHARGE_FULL
/obj/item/organ/stomach/ethereal/on_life()
..()
- adjust_charge(-ETHEREAL_CHARGE_FACTOR)
+ adjust_charge(-ELZUOSE_CHARGE_FACTOR)
/obj/item/organ/stomach/ethereal/Insert(mob/living/carbon/organ_owner, special = 0)
..()
@@ -121,10 +121,10 @@
/obj/item/organ/stomach/ethereal/proc/get_status_tab_item(mob/living/carbon/source, list/items)
SIGNAL_HANDLER
- items += "Crystal Charge: [round((crystal_charge / ETHEREAL_CHARGE_SCALING_MULTIPLIER), 0.1)]%"
+ items += "Crystal Charge: [round((crystal_charge / ELZUOSE_CHARGE_SCALING_MULTIPLIER), 0.1)]%"
/obj/item/organ/stomach/ethereal/proc/charge(datum/source, amount, repairs)
- adjust_charge((amount * ETHEREAL_CHARGE_SCALING_MULTIPLIER) / 70) //WS Edit -- Ethereal Charge Scaling
+ adjust_charge((amount * ELZUOSE_CHARGE_SCALING_MULTIPLIER) / 70) //WS Edit -- Ethereal Charge Scaling
/obj/item/organ/stomach/ethereal/proc/on_electrocute(datum/source, shock_damage, siemens_coeff = 1, flags = NONE)
if(flags & SHOCK_ILLUSION)
@@ -133,7 +133,7 @@
to_chat(owner, "You absorb some of the shock into your body!")
/obj/item/organ/stomach/ethereal/proc/adjust_charge(amount)
- crystal_charge = clamp(crystal_charge + amount, ETHEREAL_CHARGE_NONE, ETHEREAL_CHARGE_DANGEROUS)
+ crystal_charge = clamp(crystal_charge + amount, ELZUOSE_CHARGE_NONE, ELZUOSE_CHARGE_DANGEROUS)
/obj/item/organ/stomach/cybernetic
name = "basic cybernetic stomach"
diff --git a/code/modules/surgery/organs/tails.dm b/code/modules/surgery/organs/tails.dm
index 2d3e402150a2..be43bc99f62d 100644
--- a/code/modules/surgery/organs/tails.dm
+++ b/code/modules/surgery/organs/tails.dm
@@ -137,7 +137,7 @@
desc = "A severed fox tail. Sad."
tail_type = "Fox 2"
-/obj/item/organ/tail/cat/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
+/obj/item/organ/tail/fox/alt/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
..()
if(istype(H))
if(!("tail_human" in H.dna.species.mutant_bodyparts))
@@ -145,7 +145,49 @@
H.dna.features["tail_human"] = tail_type
H.update_body()
-/obj/item/organ/tail/cat/Remove(mob/living/carbon/human/H, special = 0)
+/obj/item/organ/tail/fox/alt/Remove(mob/living/carbon/human/H, special = 0)
+ ..()
+ if(istype(H))
+ H.dna.features["tail_human"] = "None"
+ H.dna.species.mutant_bodyparts -= "tail_human"
+ color = H.hair_color
+ H.update_body()
+
+/obj/item/organ/tail/rabbit
+ name = "rabbit tail"
+ desc = "A severed rabbit tail."
+ tail_type = "Rabbit"
+
+/obj/item/organ/tail/rabbit/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
+ ..()
+ if(istype(H))
+ if(!("tail_human" in H.dna.species.mutant_bodyparts))
+ H.dna.species.mutant_bodyparts |= "tail_human"
+ H.dna.features["tail_human"] = tail_type
+ H.update_body()
+
+/obj/item/organ/tail/rabbit/Remove(mob/living/carbon/human/H, special = 0)
+ ..()
+ if(istype(H))
+ H.dna.features["tail_human"] = "None"
+ H.dna.species.mutant_bodyparts -= "tail_human"
+ color = H.hair_color
+ H.update_body()
+
+/obj/item/organ/tail/dog
+ name = "dog tail"
+ desc = "A severed dog tail."
+ tail_type = "Dog"
+
+/obj/item/organ/tail/dog/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
+ ..()
+ if(istype(H))
+ if(!("tail_human" in H.dna.species.mutant_bodyparts))
+ H.dna.species.mutant_bodyparts |= "tail_human"
+ H.dna.features["tail_human"] = tail_type
+ H.update_body()
+
+/obj/item/organ/tail/dog/Remove(mob/living/carbon/human/H, special = 0)
..()
if(istype(H))
H.dna.features["tail_human"] = "None"
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index 5eed8abc46be..6a5a344b177e 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -286,7 +286,7 @@
else if((findtext(message, bleed_words)))
cooldown = COOLDOWN_DAMAGE
for(var/mob/living/carbon/human/H in listeners)
- H.bleed_rate += (5 * power_multiplier)
+ H.cause_overall_bleeding(5*power_multiplier)
//FIRE
else if((findtext(message, burn_words)))
@@ -439,14 +439,6 @@
var/mob/living/L = V
L.emote("flip")
- //SPEAK
- else if((findtext(message, speak_words)))
- cooldown = COOLDOWN_MEME
- for(var/V in listeners)
- var/mob/living/L = V
- addtimer(CALLBACK(L, TYPE_PROC_REF(/atom/movable, say), pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage")), 5 * i)
- i++
-
//GET UP
else if((findtext(message, getup_words)))
cooldown = COOLDOWN_DAMAGE //because stun removal
diff --git a/code/modules/surgery/surgery_helpers.dm b/code/modules/surgery/surgery_helpers.dm
index c4a769c43ed5..f87c6e1bb923 100644
--- a/code/modules/surgery/surgery_helpers.dm
+++ b/code/modules/surgery/surgery_helpers.dm
@@ -85,7 +85,7 @@
/proc/attempt_cancel_surgery(datum/surgery/S, obj/item/I, mob/living/M, mob/user)
var/selected_zone = user.zone_selected
to_chat(user, "You begin to cancel \the [S].")
- if (!do_mob(user, M, 3 SECONDS))
+ if (!do_after(user, 3 SECONDS, M))
return
if(S.status == 1)
@@ -115,7 +115,9 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
- H.bleed_rate = max((H.bleed_rate - 3), 0)
+ var/obj/item/bodypart/BP = H.get_bodypart(check_zone(S.location))
+ if(BP)
+ BP.adjust_bleeding(-3)
M.surgeries -= S
user.visible_message("[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and stops the surgery.", \
"You close [M]'s [parse_zone(selected_zone)] with [close_tool] and stop the surgery.")
diff --git a/code/modules/unit_tests/outfit_sanity.dm b/code/modules/unit_tests/outfit_sanity.dm
index aca1d210fbf0..4dc12b4dc6e3 100644
--- a/code/modules/unit_tests/outfit_sanity.dm
+++ b/code/modules/unit_tests/outfit_sanity.dm
@@ -3,7 +3,10 @@
/* We don't check the result of equip_to_slot_or_del because it returns false for random jumpsuits, as they delete themselves on init */ \
var/obj/item/outfit_item = H.get_item_by_slot(##slot_name); \
if (!outfit_item) { \
- TEST_FAIL("[outfit.name]'s [#outfit_key] is invalid! Could not equip a [outfit.##outfit_key] into that slot."); \
+ if (outfit.random != TRUE) \
+ TEST_FAIL("[outfit.name]'s [#outfit_key] is invalid! Could not equip a [outfit.##outfit_key] into that slot."); \
+ else \
+ log_world("[outfit.name]'s [#outfit_key] is invalid! Could not equip a [outfit.##outfit_key] into that slot."); \
} \
}
@@ -61,6 +64,10 @@
var/number = backpack_contents[path] || 1
for (var/_ in 1 to number)
if (!H.equip_to_slot_or_del(new path(H), ITEM_SLOT_BACKPACK, TRUE))
- TEST_FAIL("[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.")
+ if (outfit.random != TRUE)
+ TEST_FAIL("[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.")
+ else
+ log_world("[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.")
+
#undef CHECK_OUTFIT_SLOT
diff --git a/code/modules/unit_tests/projectiles.dm b/code/modules/unit_tests/projectiles.dm
index e93d20910af0..5c8412d05aec 100644
--- a/code/modules/unit_tests/projectiles.dm
+++ b/code/modules/unit_tests/projectiles.dm
@@ -6,7 +6,7 @@
/datum/unit_test/gun_go_bang/Run()
// test is for a ballistic gun that starts loaded + chambered
- var/obj/item/gun/test_gun = allocate(/obj/item/gun/ballistic/automatic/pistol)
+ var/obj/item/gun/test_gun = allocate(/obj/item/gun/ballistic/automatic/pistol/candor)
var/mob/living/carbon/human/victim = allocate(/mob/living/carbon/human)
var/mob/living/carbon/human/gunner = allocate(/mob/living/carbon/human)
ADD_TRAIT(victim, TRAIT_PIERCEIMMUNE, INNATE_TRAIT) // So the human isn't randomly affected by shrapnel
diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm
index 48c79382444e..9e935611e15f 100644
--- a/code/modules/uplink/uplink_items.dm
+++ b/code/modules/uplink/uplink_items.dm
@@ -365,22 +365,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
surplus = 0
include_modes = list(/datum/game_mode/nuclear/clown_ops)
-/datum/uplink_item/dangerous/clownoppin
- name = "Ultra Hilarious Firing Pin"
- desc = "A firing pin that, when inserted into a gun, makes that gun only useable by clowns and clumsy people and makes that gun honk whenever anyone tries to fire it."
- cost = 1 //much cheaper for clown ops than for clowns
- item = /obj/item/firing_pin/clown/ultra
- include_modes = list(/datum/game_mode/nuclear/clown_ops)
- illegal_tech = FALSE
-
-/datum/uplink_item/dangerous/clownopsuperpin
- name = "Super Ultra Hilarious Firing Pin"
- desc = "Like the ultra hilarious firing pin, except the gun you insert this pin into explodes when someone who isn't clumsy or a clown tries to fire it."
- cost = 4 //much cheaper for clown ops than for clowns
- item = /obj/item/firing_pin/clown/ultra/selfdestruct
- include_modes = list(/datum/game_mode/nuclear/clown_ops)
- illegal_tech = FALSE
-
/datum/uplink_item/dangerous/bioterror
name = "Biohazardous Chemical Sprayer"
desc = "A handheld chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \
@@ -501,7 +485,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/dangerous/sniper
name = "Sniper Rifle"
desc = "Ranged fury, Syndicate style. Guaranteed to cause shock and awe or your TC back!"
- item = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate
+ item = /obj/item/gun/ballistic/automatic/marksman/sniper_rifle
cost = 16
surplus = 25
include_modes = list(/datum/game_mode/nuclear)
@@ -510,7 +494,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
name = "Stechkin Pistol"
desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \
with suppressors."
- item = /obj/item/gun/ballistic/automatic/pistol
+ item = /obj/item/gun/ballistic/automatic/pistol/syndicate
cost = 7
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
@@ -524,7 +508,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/dangerous/revolver
name = "Syndicate Revolver"
desc = "A brutally simple Syndicate revolver that fires .357 Magnum rounds and has 7 chambers."
- item = /obj/item/gun/ballistic/revolver
+ item = /obj/item/gun/ballistic/revolver/syndicate
cost = 13
surplus = 50
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
@@ -532,7 +516,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/dangerous/foamsmg
name = "Toy Submachine Gun"
desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade darts with a 20-round magazine."
- item = /obj/item/gun/ballistic/automatic/smg/c20r/toy
+ item = /obj/item/gun/ballistic/automatic/smg/c20r/toy/riot
cost = 5
surplus = 0
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
@@ -541,7 +525,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
name = "Toy Machine Gun"
desc = "A fully-loaded Donksoft belt-fed machine gun. This weapon has a massive 50-round magazine of devastating \
riot grade darts, that can briefly incapacitate someone in just one volley."
- item = /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy
+ item = /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/riot
cost = 10
surplus = 0
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
@@ -591,7 +575,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/dangerous/ebr
name = "M514 EBR"
desc = "A cheap rifle with high stopping power and low capacity."
- item = /obj/item/gun/ballistic/automatic/ebr
+ item = /obj/item/gun/ballistic/automatic/marksman/ebr
cost = 8
surplus = 20
include_modes = list(/datum/game_mode/nuclear)
@@ -699,7 +683,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/stealthy_weapons/suppressor
name = "Suppressor"
desc = "This suppressor will silence the shots of the weapon it is attached to for increased stealth and superior ambushing capability. It is compatible with many small ballistic guns including the Stechkin and C-20r, but not revolvers or energy guns."
- item = /obj/item/suppressor
+ item = /obj/item/attachment/silencer
cost = 3
surplus = 10
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
@@ -1728,13 +1712,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/flashlight/lantern/syndicate
restricted_species = list("moth") //End WS edit
-/datum/uplink_item/race_restricted/syndigenetics
- name = "Fire Breath"
- desc = "One of our subsidiaries, 23AndMe, have recently found the formula of backtracking lizard's genetic trail and giving them the ability to breathe fire, much like their dragon ancestors."
- cost = 5
- item = /obj/item/dnainjector/firebreath
- restricted_species = list("lizard")
-
/datum/uplink_item/race_restricted/razorwing
name = "Razorwing Implant"
desc = "Put those wings to good use! This implant makes your wingtips razor sharp and gives you the ability to flourish them, slicing anyone in range."
@@ -1952,30 +1929,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/reverse_bear_trap
restricted_roles = list("Clown")
-/datum/uplink_item/role_restricted/reverse_revolver
- name = "Reverse Revolver"
- desc = "A revolver that always fires at its user. \"Accidentally\" drop your weapon, then watch as the greedy corporate pigs blow their own brains all over the wall. \
- The revolver itself is actually real. Only clumsy people, and clowns, can fire it normally. Comes in a box of hugs. Honk."
- cost = 14
- item = /obj/item/storage/box/hug/reverse_revolver
- restricted_roles = list("Clown")
-
-/datum/uplink_item/role_restricted/clownpin
- name = "Ultra Hilarious Firing Pin"
- desc = "A firing pin that, when inserted into a gun, makes that gun only usable by clowns and clumsy people and makes that gun honk whenever anyone tries to fire it."
- cost = 4
- item = /obj/item/firing_pin/clown/ultra
- restricted_roles = list("Clown")
- illegal_tech = FALSE
-
-/datum/uplink_item/role_restricted/clownsuperpin
- name = "Super Ultra Hilarious Firing Pin"
- desc = "Like the ultra hilarious firing pin, except the gun you insert this pin into explodes when someone who isn't clumsy or a clown tries to fire it."
- cost = 7
- item = /obj/item/firing_pin/clown/ultra/selfdestruct
- restricted_roles = list("Clown")
- illegal_tech = FALSE
-
/datum/uplink_item/role_restricted/laser_arm
name = "Laser Arm Implant"
desc = "An implant that grants you a recharging laser gun inside your arm. Weak to EMPs. Comes with a syndicate autosurgeon for immediate self-application."
diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm
index 6b53fa9a02c3..d3040f862863 100644
--- a/code/modules/vehicles/cars/car.dm
+++ b/code/modules/vehicles/cars/car.dm
@@ -80,7 +80,7 @@
if(occupant_amount() >= max_occupants)
return FALSE
var/atom/old_loc = loc
- if(do_mob(forcer, M, get_enter_delay(M), extra_checks=CALLBACK(src, TYPE_PROC_REF(/obj/vehicle/sealed/car, is_car_stationary), old_loc)))
+ if(do_after(forcer, get_enter_delay(M), M, extra_checks=CALLBACK(src, TYPE_PROC_REF(/obj/vehicle/sealed/car, is_car_stationary), old_loc)))
mob_forced_enter(M, silent)
return TRUE
return FALSE
diff --git a/code/modules/vehicles/lavaboat.dm b/code/modules/vehicles/lavaboat.dm
index 3c893b9bf8a8..547bac91a2f0 100644
--- a/code/modules/vehicles/lavaboat.dm
+++ b/code/modules/vehicles/lavaboat.dm
@@ -29,21 +29,6 @@
force = 12
w_class = WEIGHT_CLASS_NORMAL
resistance_flags = LAVA_PROOF | FIRE_PROOF
-
-/datum/crafting_recipe/oar
- name = "Goliath Bone Oar"
- result = /obj/item/oar
- reqs = list(/obj/item/stack/sheet/bone = 2)
- time = 15
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/boat
- name = "Goliath Hide Boat"
- result = /obj/vehicle/ridden/lavaboat
- reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide = 3)
- time = 50
- category = CAT_PRIMAL
-
//Dragon Boat
diff --git a/code/modules/vehicles/motorized_wheelchair.dm b/code/modules/vehicles/motorized_wheelchair.dm
index c9e990372374..fa3d569b0535 100644
--- a/code/modules/vehicles/motorized_wheelchair.dm
+++ b/code/modules/vehicles/motorized_wheelchair.dm
@@ -5,7 +5,7 @@
max_integrity = 150
var/speed = 2
var/power_efficiency = 1
- var/power_usage = 100
+ var/power_usage = 20
var/panel_open = FALSE
var/list/required_parts = list(/obj/item/stock_parts/manipulator,
/obj/item/stock_parts/manipulator,
@@ -21,7 +21,7 @@
for(var/obj/item/stock_parts/manipulator/M in contents)
speed += M.rating
for(var/obj/item/stock_parts/capacitor/C in contents)
- power_efficiency = C.rating
+ power_efficiency = (C.rating + 1)
var/datum/component/riding/D = GetComponent(/datum/component/riding)
D.vehicle_move_delay = round(CONFIG_GET(number/movedelay/run_delay) * delay_multiplier) / speed
@@ -52,7 +52,7 @@
canmove = FALSE
addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
return FALSE
- power_cell.use(power_usage / max(power_efficiency, 1))
+ power_cell.use(power_usage / max(power_efficiency, 2))
return ..()
/obj/vehicle/ridden/wheelchair/motorized/set_move_delay(mob/living/user)
diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm
index 6751ddfe3580..22b1eb42becb 100644
--- a/code/modules/vehicles/sealed.dm
+++ b/code/modules/vehicles/sealed.dm
@@ -29,7 +29,7 @@
return FALSE
if(occupant_amount() >= max_occupants)
return FALSE
- if(do_after(M, get_enter_delay(M), FALSE, src, TRUE))
+ if(do_after(M, get_enter_delay(M), src, progress = TRUE, timed_action_flags = IGNORE_HELD_ITEM))
mob_enter(M)
return TRUE
return FALSE
diff --git a/code/modules/vehicles/secway.dm b/code/modules/vehicles/secway.dm
index 2914d6dda279..4d327c7a8234 100644
--- a/code/modules/vehicles/secway.dm
+++ b/code/modules/vehicles/secway.dm
@@ -47,7 +47,7 @@
if(istype(W, /obj/item/reagent_containers/food/snacks/grown/banana))
// ignore the occupants because they're presumably too distracted to notice the guy stuffing fruit into their vehicle's exhaust. do segways have exhausts? they do now!
user.visible_message("[user] begins stuffing [W] into [src]'s tailpipe.", "You begin stuffing [W] into [src]'s tailpipe...", ignored_mobs = occupants)
- if(do_after(user, 30, TRUE, src))
+ if(do_after(user, 30, src))
if(user.transferItemToLoc(W, src))
user.visible_message("[user] stuffs [W] into [src]'s tailpipe.", "You stuff [W] into [src]'s tailpipe.", ignored_mobs = occupants)
eddie_murphy = W
diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm
index a22b68c5a1c8..fc5b6503f90c 100644
--- a/code/modules/vehicles/wheelchair.dm
+++ b/code/modules/vehicles/wheelchair.dm
@@ -104,8 +104,8 @@
/obj/vehicle/ridden/wheelchair/proc/can_user_rotate(mob/living/user)
var/mob/living/L = user
if(istype(L))
- if(!user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
- return FALSE
+ if(user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
+ return TRUE
if(isobserver(user) && CONFIG_GET(flag/ghost_interaction))
return TRUE
return FALSE
diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm
index 93fcacba45b1..6d73fad566f6 100644
--- a/code/modules/vending/_vending.dm
+++ b/code/modules/vending/_vending.dm
@@ -47,6 +47,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
icon_state = "generic"
layer = BELOW_OBJ_LAYER
density = TRUE
+ use_power = IDLE_POWER_USE
+ idle_power_usage = IDLE_DRAW_MINIMAL
verb_say = "beeps"
verb_ask = "beeps"
verb_exclaim = "beeps"
@@ -712,15 +714,13 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/machinery/vending/ui_data(mob/user)
. = list()
var/mob/living/carbon/human/H
- var/obj/item/card/id/card
+ var/obj/item/card/bank/card
if(ishuman(user))
H = user
- card = H.get_idcard(TRUE)
+ card = H.get_bankcard()
if(card)
.["user"] = list()
.["user"]["points"] = card.mining_points
- .["user"]["name"] = card.registered_name
- .["user"]["job"] = card.assignment || "No Job"
if(card.registered_account)
.["user"]["name"] = card.registered_account.account_holder
.["user"]["cash"] = card.registered_account.account_balance
@@ -767,7 +767,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
return
if(!all_items_free && ishuman(usr))
var/mob/living/carbon/human/H = usr
- var/obj/item/card/id/C = H.get_idcard(TRUE)
+ var/obj/item/card/bank/C = H.get_bankcard()
if(!C)
say("No card found.")
@@ -944,10 +944,10 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/machinery/vending/custom/compartmentLoadAccessCheck(mob/user)
. = FALSE
var/mob/living/carbon/human/H
- var/obj/item/card/id/C
+ var/obj/item/card/bank/C
if(ishuman(user))
H = user
- C = H.get_idcard(FALSE)
+ C = H.get_bankcard(FALSE)
if(C?.registered_account && C.registered_account == private_a)
return TRUE
@@ -1001,7 +1001,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
vend_ready = FALSE
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
- var/obj/item/card/id/C = H.get_idcard(TRUE)
+ var/obj/item/card/bank/C = H.get_bankcard()
if(!C)
say("No card found.")
@@ -1053,10 +1053,10 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/machinery/vending/custom/attackby(obj/item/I, mob/user, params)
if(!private_a)
var/mob/living/carbon/human/H
- var/obj/item/card/id/C
+ var/obj/item/card/bank/C
if(ishuman(user))
H = user
- C = H.get_idcard(TRUE)
+ C = H.get_bankcard(TRUE)
if(C?.registered_account)
private_a = C.registered_account
say("\The [src] has been linked to [C].")
diff --git a/code/modules/vending/assist.dm b/code/modules/vending/assist.dm
index 8a1c86cc9536..cb3cd0053d8a 100644
--- a/code/modules/vending/assist.dm
+++ b/code/modules/vending/assist.dm
@@ -10,8 +10,7 @@
/obj/item/stock_parts/manipulator = 3,
/obj/item/stock_parts/micro_laser = 3,
/obj/item/stock_parts/scanning_module = 3,
- /obj/item/stock_parts/capacitor = 3)
- contraband = list(
+ /obj/item/stock_parts/capacitor = 3,
/obj/item/assembly/timer = 2,
/obj/item/assembly/voice = 2,
/obj/item/assembly/health = 2,
diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm
index b1d85fb3fcbb..367c309d59a1 100644
--- a/code/modules/vending/autodrobe.dm
+++ b/code/modules/vending/autodrobe.dm
@@ -109,13 +109,9 @@
/obj/item/clothing/suit/changshan_blue = 1,
/obj/item/clothing/suit/cheongsam_red = 1,
/obj/item/clothing/suit/cheongsam_blue = 1,
- /obj/item/gohei = 1)
- contraband = list(
+ /obj/item/gohei = 1,
/obj/item/clothing/suit/judgerobe = 1,
/obj/item/clothing/head/powdered_wig = 1,
- /obj/item/clothing/accessory/fan_mime_pin = 1,
- /obj/item/clothing/accessory/fan_clown_pin = 1,
- /obj/item/gun/magic/wand/nothing = 2,
/obj/item/clothing/glasses/sunglasses/garb = 2,
/obj/item/clothing/glasses/blindfold = 1,
/obj/item/clothing/mask/muzzle = 2)
diff --git a/code/modules/vending/boozeomat.dm b/code/modules/vending/boozeomat.dm
index 1b7b2d9e5ccb..45dc055e1b21 100644
--- a/code/modules/vending/boozeomat.dm
+++ b/code/modules/vending/boozeomat.dm
@@ -3,7 +3,7 @@
desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one."
icon_state = "boozeomat"
icon_deny = "boozeomat-deny"
- products = list(
+ products = list( // All of drink dispenser reagents should be available here.
/obj/item/reagent_containers/food/drinks/drinkingglass = 30,
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass = 12,
/obj/item/reagent_containers/food/drinks/modglass/small = 10,
@@ -11,18 +11,31 @@
/obj/item/reagent_containers/food/drinks/modglass/large = 10,
/obj/item/reagent_containers/food/drinks/flask = 3,
/obj/item/reagent_containers/food/drinks/ice = 10,
+ /obj/item/reagent_containers/food/drinks/waterbottle/large = 6,
/obj/item/reagent_containers/food/drinks/bottle/orangejuice = 4,
/obj/item/reagent_containers/food/drinks/bottle/tomatojuice = 4,
/obj/item/reagent_containers/food/drinks/bottle/limejuice = 4,
+ /obj/item/reagent_containers/food/drinks/bottle/lemonjuice = 4,
+ /obj/item/reagent_containers/food/drinks/bottle/pineapplejuice = 4,
/obj/item/reagent_containers/food/drinks/bottle/cream = 4,
/obj/item/reagent_containers/food/drinks/soda_cans/cola = 8,
+ /obj/item/reagent_containers/food/drinks/soda_cans/comet_trail = 4,
+ /obj/item/reagent_containers/food/drinks/soda_cans/tadrixx = 4,
+ /obj/item/reagent_containers/food/drinks/soda_cans/lunapunch = 4,
+ /obj/item/reagent_containers/food/drinks/soda_cans/space_up = 4,
+ /obj/item/reagent_containers/food/drinks/soda_cans/pacfuel = 4,
+ /obj/item/reagent_containers/food/drinks/soda_cans/orange_soda = 4,
+ /obj/item/reagent_containers/food/drinks/soda_cans/shoal_punch = 4,
/obj/item/reagent_containers/food/drinks/soda_cans/tonic = 8,
- /obj/item/reagent_containers/food/drinks/soda_cans/sodawater = 15,
- /obj/item/reagent_containers/food/drinks/soda_cans/sol_dry = 8,
+ /obj/item/reagent_containers/food/drinks/soda_cans/sodawater = 8,
+ /obj/item/reagent_containers/food/drinks/soda_cans/sol_dry = 4,
+ /obj/item/reagent_containers/food/drinks/soda_cans/vimukti = 4,
/obj/item/reagent_containers/food/drinks/bottle/grenadine = 4,
/obj/item/reagent_containers/food/drinks/bottle/menthol = 4,
+ /obj/item/reagent_containers/food/drinks/mug/tea = 8,
+ /obj/item/reagent_containers/food/drinks/coffee = 8,
/obj/item/reagent_containers/food/drinks/ale = 6,
- /obj/item/reagent_containers/food/drinks/beer = 6,
+ /obj/item/reagent_containers/food/drinks/beer = 8,
/obj/item/reagent_containers/food/drinks/bottle/gin = 5,
/obj/item/reagent_containers/food/drinks/bottle/whiskey = 5,
/obj/item/reagent_containers/food/drinks/bottle/tequila = 5,
@@ -38,7 +51,10 @@
/obj/item/reagent_containers/food/drinks/bottle/amaretto = 5,
/obj/item/reagent_containers/food/drinks/bottle/sake = 5,
/obj/item/reagent_containers/food/drinks/bottle/applejack = 5,
+ /obj/item/reagent_containers/food/drinks/bottle/triplesec = 5,
/obj/item/reagent_containers/food/drinks/bottle/coconut = 5,
+ /obj/item/reagent_containers/food/drinks/bottle/cacao = 5,
+ /obj/item/reagent_containers/food/drinks/bottle/menthe = 5,
/obj/item/reagent_containers/food/drinks/bottle = 15,
/obj/item/reagent_containers/food/drinks/bottle/small = 15,
/obj/item/garnish/olives = 10,
@@ -46,16 +62,16 @@
/obj/item/garnish/umbrellablue = 10,
/obj/item/garnish/umbrellagreen = 10
)
- contraband = list(
- /obj/item/reagent_containers/food/drinks/mug/tea = 12,
- /obj/item/reagent_containers/food/drinks/bottle/fernet = 5)
+ contraband = list()
premium = list(
/obj/item/reagent_containers/glass/bottle/ethanol = 4,
+ /obj/item/reagent_containers/glass/bottle/sugar = 3,
+ /obj/item/reagent_containers/food/drinks/bottle/fernet = 5,
/obj/item/reagent_containers/food/drinks/bottle/champagne = 5,
/obj/item/reagent_containers/food/drinks/bottle/trappist = 5)
- product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty 'round this sector?"
- product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!"
+ product_slogans = "I hope nobody asks me for a cup of tea...;Alcohol is everyone's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty 'round this sector?"
+ product_ads = "Drink up!;Booze is good for you!;Alcohol is everyone's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 53 FSC!;Award-winning wine!;Maximum alcohol!;Everyone loves beer.;A toast for progress!"
req_access = list(ACCESS_BAR)
refill_canister = /obj/item/vending_refill/boozeomat
default_price = 120
diff --git a/code/modules/vending/cigarette.dm b/code/modules/vending/cigarette.dm
index 7dd0b6004ea7..1c377c309464 100644
--- a/code/modules/vending/cigarette.dm
+++ b/code/modules/vending/cigarette.dm
@@ -1,8 +1,8 @@
/obj/machinery/vending/cigarette
name = "\improper ShadyCigs Deluxe"
desc = "If you want to get cancer, might as well do it in style."
- product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!"
- product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs."
+ product_slogans = "Space cigs taste good like a cigarette should.;I'd rather die than switch.;Smoke!;Don't believe the reports - smoke today!"
+ product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 150 FSC.;Award-winning cigs."
icon_state = "cigs"
products = list(
/obj/item/storage/fancy/cigarettes = 5,
@@ -11,19 +11,19 @@
/obj/item/storage/fancy/cigarettes/cigpack_robust = 3,
/obj/item/storage/fancy/cigarettes/cigpack_carp = 3,
/obj/item/storage/fancy/cigarettes/cigpack_midori = 3,
+ /obj/item/storage/fancy/cigarettes/dromedaryco = 3,
+ /obj/item/clothing/mask/vape = 5,
/obj/item/storage/box/matches = 10,
/obj/item/lighter/greyscale = 4,
/obj/item/storage/fancy/rollingpapers = 5)
- contraband = list(
- /obj/item/clothing/mask/vape = 5,
- /obj/item/clothing/mask/vape/cigar = 3) //WS edit - E-Cigars
premium = list(
/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 3,
- /obj/item/storage/box/gum/nicotine = 2,
+ /obj/item/storage/box/gum/nicotine = 3,
/obj/item/lighter = 3,
/obj/item/storage/fancy/cigarettes/cigars = 1,
/obj/item/storage/fancy/cigarettes/cigars/havana = 1,
- /obj/item/storage/fancy/cigarettes/cigars/cohiba = 1)
+ /obj/item/storage/fancy/cigarettes/cigars/cohiba = 1,
+ /obj/item/clothing/mask/vape/cigar = 3)
refill_canister = /obj/item/vending_refill/cigarette
default_price = 75
extra_price = 250
diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm
index 8a7199968774..e9eef49a0e3a 100644
--- a/code/modules/vending/clothesmate.dm
+++ b/code/modules/vending/clothesmate.dm
@@ -104,19 +104,16 @@
/obj/item/clothing/suit/apron/purple_bartender = 2,
/obj/item/clothing/under/rank/civilian/bartender/purple = 2,
/obj/item/clothing/suit/toggle/suspenders/blue = 2,
- /obj/item/clothing/suit/toggle/suspenders/gray = 2)
- contraband = list(
- /obj/item/clothing/under/syndicate/tacticool = 1,
- /obj/item/clothing/under/syndicate/tacticool/skirt = 1,
+ /obj/item/clothing/suit/toggle/suspenders/gray = 2,
+ /obj/item/clothing/under/syndicate/tacticool = 2,
+ /obj/item/clothing/under/syndicate/tacticool/skirt = 2,
/obj/item/clothing/mask/balaclava = 1,
/obj/item/clothing/head/trapper = 1,
/obj/item/storage/belt/fannypack/black = 2,
/obj/item/clothing/suit/jacket/letterman_syndie = 1,
/obj/item/clothing/under/costume/jabroni = 1,
/obj/item/clothing/suit/vapeshirt = 1,
- /obj/item/clothing/under/costume/geisha = 1,
- /obj/item/clothing/under/rank/centcom/officer/replica = 1,
- /obj/item/clothing/under/rank/centcom/officer_skirt/replica = 1)
+ /obj/item/clothing/under/costume/geisha = 1)
premium = list(
/obj/item/clothing/under/suit/checkered = 1,
/obj/item/clothing/suit/jacket/leather = 1,
diff --git a/code/modules/vending/coffee.dm b/code/modules/vending/coffee.dm
index 3e45b431b16d..9c4851c134a5 100644
--- a/code/modules/vending/coffee.dm
+++ b/code/modules/vending/coffee.dm
@@ -7,11 +7,11 @@
products = list(
/obj/item/reagent_containers/food/drinks/coffee = 6,
/obj/item/reagent_containers/food/drinks/mug/tea = 6,
- /obj/item/reagent_containers/food/drinks/mug/coco = 3)
+ /obj/item/reagent_containers/food/drinks/mug/coco = 3,
+ /obj/item/reagent_containers/food/drinks/ice = 6)
premium = list(
/obj/item/reagent_containers/food/drinks/cafelatte = 3,
/obj/item/reagent_containers/food/drinks/soylatte = 3)
- contraband = list(/obj/item/reagent_containers/food/drinks/ice = 12)
refill_canister = /obj/item/vending_refill/coffee
default_price = 45
extra_price = 150
diff --git a/code/modules/vending/cola.dm b/code/modules/vending/cola.dm
index 2ce937979e74..a3fa70ce6209 100644
--- a/code/modules/vending/cola.dm
+++ b/code/modules/vending/cola.dm
@@ -1,36 +1,34 @@
/obj/machinery/vending/cola
- name = "\improper Robust Softdrinks"
- desc = "A softdrink vendor provided by Robust Industries, LLC."
+ name = "\improper RobustMore Softdrinks"
+ desc = "A softdrink vendor provided by RobustMore DrinkFoods Industries, LLC."
icon_state = "Cola_Machine"
- product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!"
- product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space."
+ product_slogans = "RobustMore Softdrinks: More robust than a toolbox to the head!"
+ product_ads = "Refreshing!;Hope you're thirsty!;Over 10 trillion drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks this side of the galaxy."
products = list(
/obj/item/reagent_containers/food/drinks/soda_cans/cola = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/starkist = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/comet_trail = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/tadrixx = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/lunapunch = 10,
/obj/item/reagent_containers/food/drinks/soda_cans/space_up = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/pwr_game = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/pacfuel = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/orange_soda = 10,
/obj/item/reagent_containers/food/drinks/soda_cans/sol_dry = 10,
/obj/item/reagent_containers/food/drinks/waterbottle = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/efuel = 5)
- contraband = list(
- /obj/item/reagent_containers/food/drinks/soda_cans/thirteenloko = 6,
- /obj/item/reagent_containers/food/drinks/soda_cans/shamblers = 6)
+ /obj/item/reagent_containers/food/drinks/soda_cans/xeno_energy = 5,
+ /obj/item/reagent_containers/food/drinks/soda_cans/vimukti = 6,
+ /obj/item/reagent_containers/food/drinks/soda_cans/shoal_punch = 6)
premium = list(
- /obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola = 1,
/obj/item/reagent_containers/food/drinks/soda_cans/air = 1,
- /obj/item/reagent_containers/food/drinks/soda_cans/monkey_energy = 1,
- /obj/item/reagent_containers/food/drinks/soda_cans/grey_bull = 1)
+ /obj/item/reagent_containers/food/drinks/soda_cans/xeno_energy = 1,
+ /obj/item/reagent_containers/food/drinks/soda_cans/crosstalk = 1)
refill_canister = /obj/item/vending_refill/cola
default_price = 45
extra_price = 200
/obj/item/vending_refill/cola
- machine_name = "Robust Softdrinks"
+ machine_name = "RobustMore Softdrinks"
icon_state = "refill_cola"
/obj/machinery/vending/cola/random
@@ -55,9 +53,9 @@
/obj/machinery/vending/cola/red
icon_state = "red_cola"
- name = "\improper Space Cola Vendor"
- desc = "It vends cola, in space."
- product_slogans = "Cola in space!"
+ name = "\improper Master Cola Vendor"
+ desc = "This vending machine offers Master Cola. Master Cola - have a drink from the past!"
+ product_slogans = "Master Cola - have a drink from the past!"
light_mask = "red_cola-light-mask"
light_color = COLOR_DARK_RED
@@ -71,9 +69,9 @@
/obj/machinery/vending/cola/starkist
icon_state = "starkist"
- name = "\improper Star-kist Vendor"
- desc = "The taste of a star in liquid form."
- product_slogans = "Drink the stars! Star-kist!"
+ name = "\improper Lunapunch Vendor"
+ desc = "What keeps the colonies running - Lunapunch."
+ product_slogans = "The Colonies run on Lunapunch!"
light_mask = "starkist-light-mask"
light_color = COLOR_LIGHT_ORANGE
@@ -84,27 +82,27 @@
/obj/machinery/vending/cola/pwr_game
icon_state = "pwr_game"
- name = "\improper Pwr Game Vendor"
- desc = "You want it, we got it. Brought to you in partnership with Vlad's Salads."
- product_slogans = "The POWER that gamers crave! PWR GAME!"
+ name = "\improper PAC-Fuel Vendor"
+ desc = "PAC-Fuel: stay flying straight. Enter the code on every can for a chance to win gamer merch or industrial equipment!"
+ product_slogans = "Keep flying steady with PAC-Fuel!"
light_mask = "pwr_game-light-mask"
light_color = COLOR_STRONG_VIOLET
/obj/machinery/vending/cola/shamblers
- name = "\improper Shambler's Vendor"
- desc = "~Shake me up some of that Shambler's Juice!~"
+ name = "\improper Shoal Punch Vendor"
+ desc = "Every fruit you could want, at your beak! Shoal Punch!"
icon_state = "shamblers_juice"
products = list(
/obj/item/reagent_containers/food/drinks/soda_cans/cola = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/starkist = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/comet_trail = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/tadrixx = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/lunapunch = 10,
/obj/item/reagent_containers/food/drinks/soda_cans/space_up = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/pwr_game = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/pacfuel = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/orange_soda = 10,
/obj/item/reagent_containers/food/drinks/soda_cans/sol_dry = 10,
- /obj/item/reagent_containers/food/drinks/soda_cans/shamblers = 10)
- product_slogans = "~Shake me up some of that Shambler's Juice!~"
- product_ads = "Refreshing!;Jyrbv dv lg jfdv fw kyrk Jyrdscvi'j Alztv!;Over 1 trillion souls drank!;Thirsty? Nyp efk uizeb kyv uribevjj?;Kyv Jyrdscvi uizebj kyv ezxyk!;Drink up!;Krjkp."
+ /obj/item/reagent_containers/food/drinks/soda_cans/shoal_punch = 10)
+ product_slogans = "Every fruit you could want, at your beak! Shoal Punch!"
+ product_ads = "Every fruit you could want, at your beak!;Don't go flying dry!;Over two trillion served!;Thirsty? Get punched!;Skrikira trikxti skrmikr rakti!;Don't go dry, get Shoal Punch."
light_mask = "shamblers-light-mask"
light_color = COLOR_MOSTLY_PURE_PINK
diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm
index 7ff7d80ddccd..3e51271093ad 100644
--- a/code/modules/vending/drinnerware.dm
+++ b/code/modules/vending/drinnerware.dm
@@ -1,7 +1,7 @@
/obj/machinery/vending/dinnerware
name = "\improper Plasteel Chef's Dinnerware Vendor"
desc = "A kitchen and restaurant equipment vendor."
- product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..."
+ product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils."
icon_state = "dinnerware"
products = list(
/obj/item/storage/bag/tray = 8,
@@ -17,11 +17,8 @@
/obj/item/kitchen/rollingpin = 2,
/obj/item/kitchen/knife = 2,
/obj/item/kitchen/knife/pizza_cutter = 2,
- /obj/item/book/granter/crafting_recipe/cooking_sweets_101 = 2)
- contraband = list(
- /obj/item/kitchen/rollingpin = 2,
- /obj/item/kitchen/knife/butcher = 2,
- /obj/item/shovel/spoon = 2) // ST - Only a spoonfull
+ /obj/item/book/granter/crafting_recipe/cooking_sweets_101 = 2,
+ /obj/item/kitchen/knife/butcher = 1)
refill_canister = /obj/item/vending_refill/dinnerware
default_price = 50
extra_price = 250
diff --git a/code/modules/vending/engivend.dm b/code/modules/vending/engivend.dm
index 096bffb1adf7..fb096656c1c3 100644
--- a/code/modules/vending/engivend.dm
+++ b/code/modules/vending/engivend.dm
@@ -16,8 +16,8 @@
/obj/item/electronics/airalarm = 10,
/obj/item/electronics/advanced_airlock_controller = 10,
/obj/item/electronics/firealarm = 10,
- /obj/item/electronics/firelock = 10)
- contraband = list(/obj/item/stock_parts/cell/potato = 3)
+ /obj/item/electronics/firelock = 10,
+ /obj/item/stock_parts/cell/potato = 3)
premium = list(/obj/item/storage/belt/utility = 3,
/obj/item/construction/rcd/loaded = 2,
/obj/item/storage/box/smart_metal_foam = 1)
diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm
index d209c93eae8e..c803fa347e9f 100644
--- a/code/modules/vending/games.dm
+++ b/code/modules/vending/games.dm
@@ -1,7 +1,7 @@
/obj/machinery/vending/games
name = "\improper Good Clean Fun"
desc = "Vends things that the Captain and Head of Personnel are probably not going to appreciate you fiddling with instead of your job..."
- product_ads = "Escape to a fantasy world!;Fuel your gambling addiction!;Ruin your friendships!;Roll for initiative!;Elves and dwarves!;Paranoid computers!;Totally not satanic!;Fun times forever!"
+ product_ads = "Escape to a fantasy world!;Fuel your gambling addiction!;Ruin your friendships!;Roll for initiative!;Elves and dwarves!;Paranoid computers!;Fun times forever!"
icon_state = "games"
products = list(
/obj/item/toy/cards/deck = 5,
@@ -14,7 +14,6 @@
/obj/item/instrument/piano_synth/headphones = 4,
/obj/item/camera = 3,
/obj/item/dyespray = 3)
- contraband = list(/obj/item/dice/fudge = 9)
premium = list(
/obj/item/melee/skateboard/pro = 3,
/obj/item/melee/skateboard/hoverboard = 1)
diff --git a/code/modules/vending/liberation.dm b/code/modules/vending/liberation.dm
deleted file mode 100644
index ffc1214e6bdf..000000000000
--- a/code/modules/vending/liberation.dm
+++ /dev/null
@@ -1,35 +0,0 @@
-/obj/machinery/vending/liberationstation
- name = "\improper Liberation Station"
- desc = "An overwhelming amount of ancient patriotism washes over you just by looking at the machine."
- icon_state = "liberationstation"
- product_slogans = "Liberation Station: Your one-stop shop for all things second amendment!;Be a patriot today, pick up a gun!;Quality weapons for cheap prices!;Better dead than red!"
- product_ads = "Float like an astronaut, sting like a bullet!;Express your second amendment today!;Guns don't kill people, but you can!;Who needs responsibilities when you have guns?"
- vend_reply = "Remember the name: Liberation Station!"
- products = list(
- /obj/item/reagent_containers/food/snacks/burger/plain = 5, //O say can you see, by the dawn's early light
- /obj/item/reagent_containers/food/snacks/burger/baseball = 3, //What so proudly we hailed at the twilight's last gleaming
- /obj/item/reagent_containers/food/snacks/fries = 5, //Whose broad stripes and bright stars through the perilous fight
- /obj/item/reagent_containers/food/drinks/beer/light = 10, //O'er the ramparts we watched, were so gallantly streaming?
- /obj/item/gun/ballistic/automatic/pistol/deagle/gold = 2,
- /obj/item/gun/ballistic/automatic/pistol/deagle/camo = 2,
- /obj/item/gun/ballistic/automatic/pistol/candor = 2,
- /obj/item/gun/ballistic/automatic/smg/proto/unrestricted = 2,
- /obj/item/gun/ballistic/shotgun/automatic/combat = 2,
- /obj/item/gun/ballistic/automatic/gyropistol = 1,
- /obj/item/gun/ballistic/shotgun = 2)
- premium = list(
- /obj/item/ammo_box/magazine/smgm9mm = 2,
- /obj/item/ammo_box/magazine/m50 = 4,
- /obj/item/ammo_box/magazine/m45 = 2,
- /obj/item/ammo_box/magazine/m75 = 2,
- /obj/item/reagent_containers/food/snacks/cheesyfries = 5,
- /obj/item/reagent_containers/food/snacks/burger/baconburger = 5) //Premium burgers for the premium section
- contraband = list(
- /obj/item/clothing/under/misc/patriotsuit = 3,
- /obj/item/bedsheet/patriot = 5,
- /obj/item/reagent_containers/food/snacks/burger/superbite = 3) //U S A
- armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
- resistance_flags = FIRE_PROOF
- default_price = 150
- extra_price = 500
- light_mask = "liberation-light-mask"
diff --git a/code/modules/vending/liberation_toy.dm b/code/modules/vending/liberation_toy.dm
index fd899f251d25..911a190703f4 100644
--- a/code/modules/vending/liberation_toy.dm
+++ b/code/modules/vending/liberation_toy.dm
@@ -2,13 +2,13 @@
name = "\improper Syndicate Donksoft Toy Vendor"
desc = "An ages 8 and up approved vendor that dispenses toys. If you were to find the right wires, you can unlock the adult mode setting!"
icon_state = "syndi"
- product_slogans = "Get your cool toys today!;Trigger a valid hunter today!;Quality toy weapons for cheap prices!;Give them to HoPs for all access!;Give them to HoS to get permabrigged!"
- product_ads = "Feel robust with your toys!;Express your inner child today!;Toy weapons don't kill people, but valid hunters do!;Who needs responsibilities when you have toy weapons?;Make your next murder FUN!"
+ product_slogans = "Get your cool toys today!;Quality toy weapons for cheap prices!"
+ product_ads = "Feel tough with your toys!;Express your inner child today!;Toy weapons don't kill people, but boredom does!;Who needs responsibilities when you have toy weapons?;Make your next foam fight FUN!"
vend_reply = "Come back for more!"
circuit = /obj/item/circuitboard/machine/vending/syndicatedonksofttoyvendor
- products = list(/obj/item/gun/ballistic/automatic/toy/unrestricted = 10,
- /obj/item/gun/ballistic/automatic/toy/pistol/unrestricted = 10,
- /obj/item/gun/ballistic/shotgun/toy/unrestricted = 10,
+ products = list(/obj/item/gun/ballistic/automatic/toy = 10,
+ /obj/item/gun/ballistic/automatic/toy/pistol = 10,
+ /obj/item/gun/ballistic/shotgun/toy = 10,
/obj/item/toy/sword = 10,
/obj/item/ammo_box/foambox = 20,
/obj/item/toy/foamblade = 10,
@@ -17,8 +17,8 @@
/obj/item/clothing/head/syndicatefake = 5) //OPS IN DORMS oh wait it's just an assistant
contraband = list(
/obj/item/gun/ballistic/shotgun/toy/crossbow = 10, //Congrats, you unlocked the +18 setting!
- /obj/item/gun/ballistic/automatic/smg/c20r/toy/unrestricted/riot = 10,
- /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/unrestricted/riot = 10,
+ /obj/item/gun/ballistic/automatic/smg/c20r/toy = 10,
+ /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy = 10,
/obj/item/ammo_box/foambox/riot = 20,
/obj/item/toy/katana = 10,
/obj/item/dualsaber/toy = 5,
diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm
index 1fff1bd03398..5a35a75a4495 100644
--- a/code/modules/vending/medical.dm
+++ b/code/modules/vending/medical.dm
@@ -27,15 +27,12 @@
/obj/item/reagent_containers/medigel/sterilizine = 1,
/obj/item/sensor_device = 1,
/obj/item/pinpointer/crew = 1)
- contraband = list(
- /obj/item/reagent_containers/pill/tox = 2,
- /obj/item/reagent_containers/pill/morphine = 2,
- /obj/item/reagent_containers/pill/charcoal = 4,
- /obj/item/storage/box/hug/medical = 1)
+ contraband = list(/obj/item/reagent_containers/pill/tox = 2)
premium = list(
/obj/item/clothing/glasses/hud/health = 1,
/obj/item/clothing/glasses/hud/health/prescription = 1,
- /obj/item/shears = 1)
+ /obj/item/shears = 1,
+ /obj/item/storage/box/hug/medical = 1)
armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
resistance_flags = FIRE_PROOF
refill_canister = /obj/item/vending_refill/medical
diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm
index cf0bca7c3bdb..dd498ffded07 100644
--- a/code/modules/vending/medical_wall.dm
+++ b/code/modules/vending/medical_wall.dm
@@ -11,11 +11,11 @@
/obj/item/reagent_containers/pill/charcoal = 1,
/obj/item/reagent_containers/medigel/styptic = 1,
/obj/item/reagent_containers/medigel/silver_sulf = 1,
- /obj/item/reagent_containers/medigel/sterilizine = 1
+ /obj/item/reagent_containers/medigel/sterilizine = 1,
+ /obj/item/reagent_containers/pill/morphine = 1
)
contraband = list(
/obj/item/reagent_containers/pill/tox = 1,
- /obj/item/reagent_containers/pill/morphine = 1,
/obj/item/storage/box/gum/happiness = 1
)
armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm
index 899bbac5ea87..4d59628f5fd2 100644
--- a/code/modules/vending/megaseed.dm
+++ b/code/modules/vending/megaseed.dm
@@ -42,12 +42,12 @@
/obj/item/seeds/tower = 3,
/obj/item/seeds/watermelon = 3,
/obj/item/seeds/wheat = 3,
- /obj/item/seeds/whitebeet = 3)
+ /obj/item/seeds/whitebeet = 3,
+ /obj/item/seeds/plump = 3)
contraband = list(/obj/item/seeds/amanita = 2,
/obj/item/seeds/glowshroom = 2,
/obj/item/seeds/liberty = 2,
/obj/item/seeds/nettle = 2,
- /obj/item/seeds/plump = 2,
/obj/item/seeds/reishi = 2,
/obj/item/seeds/cannabis = 3,
/obj/item/seeds/starthistle = 2,
diff --git a/code/modules/vending/nutrimax.dm b/code/modules/vending/nutrimax.dm
index 1849750d3fce..0aaa47461406 100644
--- a/code/modules/vending/nutrimax.dm
+++ b/code/modules/vending/nutrimax.dm
@@ -15,8 +15,7 @@
/obj/item/storage/bag/plants = 5,
/obj/item/cultivator = 3,
/obj/item/shovel/spade = 3,
- /obj/item/plant_analyzer = 4)
- contraband = list(
+ /obj/item/plant_analyzer = 4,
/obj/item/reagent_containers/glass/bottle/ammonia = 10,
/obj/item/reagent_containers/glass/bottle/diethylamine = 5)
refill_canister = /obj/item/vending_refill/hydronutrients
diff --git a/code/modules/vending/plasmaresearch.dm b/code/modules/vending/plasmaresearch.dm
index 650d9878ad36..a638bfc81d8a 100644
--- a/code/modules/vending/plasmaresearch.dm
+++ b/code/modules/vending/plasmaresearch.dm
@@ -10,7 +10,7 @@
/obj/item/assembly/timer = 6,
/obj/item/assembly/signaler = 6,
/obj/item/assembly/prox_sensor = 6,
- /obj/item/assembly/igniter = 6)
- contraband = list(/obj/item/assembly/health = 3)
+ /obj/item/assembly/igniter = 6,
+ /obj/item/assembly/health = 3)
default_price = 400
extra_price = 600
diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm
index 7af332630105..911eaed20652 100644
--- a/code/modules/vending/security.dm
+++ b/code/modules/vending/security.dm
@@ -14,8 +14,7 @@
/obj/item/flashlight/seclite = 4,
/obj/item/ammo_box/c9mm/rubbershot = 3,
/obj/item/ammo_box/c9mm = 1,
- /obj/item/stock_parts/cell/gun = 3)
- contraband = list(
+ /obj/item/stock_parts/cell/gun = 3,
/obj/item/clothing/glasses/sunglasses = 2)
premium = list(
/obj/item/storage/belt/security/webbing = 5,
@@ -131,10 +130,10 @@
/obj/item/grenade/frag = 1,
)
voucher_items = list(
- "M-90gl Carbine" = /obj/item/gun/ballistic/automatic/smg/m90/unrestricted,
- "sniper rifle" = /obj/item/gun/ballistic/automatic/sniper_rifle,
- "C-20r SMG" = /obj/item/gun/ballistic/automatic/smg/c20r/unrestricted,
- "Bulldog Shotgun" = /obj/item/gun/ballistic/shotgun/bulldog/unrestricted)
+ "M-90gl Carbine" = /obj/item/gun/ballistic/automatic/smg/m90,
+ "sniper rifle" = /obj/item/gun/ballistic/automatic/marksman/sniper_rifle,
+ "C-20r SMG" = /obj/item/gun/ballistic/automatic/smg/c20r,
+ "Bulldog Shotgun" = /obj/item/gun/ballistic/shotgun/bulldog)
/obj/machinery/vending/security/marine/nanotrasen
icon_state = "nt-marine"
diff --git a/code/modules/vending/snack.dm b/code/modules/vending/snack.dm
index 0785df82f14d..45d76a4754fa 100644
--- a/code/modules/vending/snack.dm
+++ b/code/modules/vending/snack.dm
@@ -1,8 +1,8 @@
/obj/machinery/vending/snack
name = "\improper Getmore Chocolate Corp"
- desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars."
+ desc = "A snack machine courtesy of the RobustMore DrinkFoods LLC."
product_slogans = "Try our new nougat bar!;Twice the calories for half the price!"
- product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!"
+ product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Have a snack.;Snacks are good for you!;Have something better! Get RobustMore!;Best quality snacks!;We love chocolate!;Try our new jerky!"
icon_state = "snack"
light_mask = "snack-light-mask"
products = list(
@@ -14,8 +14,7 @@
/obj/item/reagent_containers/food/snacks/no_raisin = 6,
/obj/item/reagent_containers/food/drinks/dry_ramen = 3,
/obj/item/storage/box/gum = 3,
- /obj/item/reagent_containers/food/snacks/energybar = 6)
- contraband = list(
+ /obj/item/reagent_containers/food/snacks/energybar = 6,
/obj/item/reagent_containers/food/snacks/syndicake = 6,
/obj/item/reagent_containers/food/snacks/candy/bronx = 1)
refill_canister = /obj/item/vending_refill/snack
@@ -25,7 +24,7 @@
input_display_header = "Chef's Food Selection"
/obj/item/vending_refill/snack
- machine_name = "Getmore Chocolate Corp"
+ machine_name = "RobustMore DrinkFoods LLC"
/obj/machinery/vending/snack/random
name = "\improper Random Snackies"
diff --git a/code/modules/vending/sovietsoda.dm b/code/modules/vending/sovietsoda.dm
index f9eff36e5e6c..213a3d01df0a 100644
--- a/code/modules/vending/sovietsoda.dm
+++ b/code/modules/vending/sovietsoda.dm
@@ -4,8 +4,9 @@
icon_state = "sovietsoda"
light_mask = "soviet-light-mask"
product_ads = "Have you fulfilled your nutrition quota today?;Very nice!;We are simple people, for this is all we eat.;If there is a person, there is a problem. If there is no person, then there is no problem."
- products = list(/obj/item/reagent_containers/food/drinks/drinkingglass/filled/soda = 30)
- contraband = list(/obj/item/reagent_containers/food/drinks/drinkingglass/filled/cola = 20)
+ products = list(
+ /obj/item/reagent_containers/food/drinks/drinkingglass/filled/soda = 30,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/filled/cola = 20)
resistance_flags = FIRE_PROOF
refill_canister = /obj/item/vending_refill/sovietsoda
default_price = 1
diff --git a/code/modules/vending/toys.dm b/code/modules/vending/toys.dm
index 5f284718b6f3..a5092cf7373f 100644
--- a/code/modules/vending/toys.dm
+++ b/code/modules/vending/toys.dm
@@ -2,25 +2,24 @@
name = "\improper Donksoft Toy Vendor"
desc = "Ages 8 and up approved vendor that dispenses toys."
icon_state = "nt-donk"
- product_slogans = "Get your cool toys today!;Trigger a valid hunter today!;Quality toy weapons for cheap prices!;Give them to HoPs for all access!;Give them to HoS to get permabrigged!"
- product_ads = "Feel robust with your toys!;Express your inner child today!;Toy weapons don't kill people, but valid hunters do!;Who needs responsibilities when you have toy weapons?;Make your next murder FUN!"
+ product_slogans = "Get your cool toys today!;Quality toy weapons for cheap prices!"
+ product_ads = "Feel tough with your toys!;Express your inner child today!;Toy weapons don't kill people, but bordeom does!;Who needs responsibilities when you have toy weapons?;Make your next foam fight FUN!"
vend_reply = "Come back for more!"
light_mask = "donksoft-light-mask"
circuit = /obj/item/circuitboard/machine/vending/donksofttoyvendor
products = list(
- /obj/item/gun/ballistic/automatic/toy/unrestricted = 10,
- /obj/item/gun/ballistic/automatic/toy/pistol/unrestricted = 10,
- /obj/item/gun/ballistic/shotgun/toy/unrestricted = 10,
+ /obj/item/gun/ballistic/automatic/toy = 10,
+ /obj/item/gun/ballistic/automatic/toy/pistol = 10,
+ /obj/item/gun/ballistic/shotgun/toy = 10,
/obj/item/toy/sword = 10,
/obj/item/ammo_box/foambox = 20,
/obj/item/toy/foamblade = 10,
/obj/item/toy/balloon/syndicate = 10,
/obj/item/clothing/suit/syndicatefake = 5,
- /obj/item/clothing/head/syndicatefake = 5)
- contraband = list(
+ /obj/item/clothing/head/syndicatefake = 5,
/obj/item/gun/ballistic/shotgun/toy/crossbow = 10,
- /obj/item/gun/ballistic/automatic/smg/c20r/toy/unrestricted = 10,
- /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy/unrestricted = 10,
+ /obj/item/gun/ballistic/automatic/smg/c20r/toy = 5,
+ /obj/item/gun/ballistic/automatic/hmg/l6_saw/toy = 5,
/obj/item/toy/katana = 10,
/obj/item/dualsaber/toy = 5)
armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm
index 933c54f64602..da3fdb134010 100644
--- a/code/modules/vending/wardrobes.dm
+++ b/code/modules/vending/wardrobes.dm
@@ -375,7 +375,7 @@
icon_state = "chapdrobe"
product_ads = "Are you being bothered by cultists or pesky revenants? Then come and dress like the holy man!;Clothes for men of the cloth!"
vend_reply = "Thank you for using the ChapDrobe!"
- products = list(/obj/item/choice_beacon/holy = 1,
+ products = list(/obj/item/storage/box/holy = 1,
/obj/item/storage/backpack/cultpack = 1,
/obj/item/clothing/head/beret/service = 1, //WS edit - berets
/obj/item/clothing/accessory/pocketprotector/cosmetology = 1,
@@ -417,7 +417,6 @@
/obj/item/storage/backpack/satchel/chem = 2,
/obj/item/clothing/accessory/armband/engine = 4,
/obj/item/storage/bag/chemistry = 2)
- contraband = list(/obj/item/reagent_containers/spray/syndicate = 2)
refill_canister = /obj/item/vending_refill/wardrobe/chem_wardrobe
/obj/item/vending_refill/wardrobe/chem_wardrobe
machine_name = "ChemDrobe"
@@ -555,7 +554,7 @@
/obj/item/clothing/suit/armor/vest/bulletproof = 3,
/obj/item/clothing/suit/armor/riot/clip = 3,
- /obj/item/clothing/suit/space/hardsuit/security/independent/clip = 3,
+ /obj/item/clothing/suit/space/hardsuit/clip_patroller = 3,
/obj/item/clothing/suit/space/hardsuit/clip_spotter = 3,
/obj/item/clothing/head/helmet/bulletproof/x11/clip = 3,
diff --git a/code/modules/vending/youtool.dm b/code/modules/vending/youtool.dm
index 6e75c75c7eae..98a5331b2744 100644
--- a/code/modules/vending/youtool.dm
+++ b/code/modules/vending/youtool.dm
@@ -15,8 +15,9 @@
/obj/item/flashlight/glowstick = 3,
/obj/item/flashlight/glowstick/red = 3,
/obj/item/flashlight = 3,
- /obj/item/clothing/ears/earmuffs = 1)
- contraband = list(/obj/item/clothing/gloves/color/fyellow = 2)
+ /obj/item/clothing/ears/earmuffs = 1,
+ /obj/item/clothing/gloves/color/fyellow = 2
+ )
premium = list(/obj/item/storage/belt/utility = 2,
/obj/item/multitool = 2,
/obj/item/weldingtool/hugetank = 1,
diff --git a/config/game_options.txt b/config/game_options.txt
index bf970824a0af..135123b845ad 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -423,7 +423,7 @@ SILICON_MAX_LAW_AMOUNT 12
ROUNDSTART_RACES human
## Races that are strictly worse than humans that could probably be turned on without balance concerns
-ROUNDSTART_RACES lizard
+ROUNDSTART_RACES sarathi
#ROUNDSTART_RACES fly
ROUNDSTART_RACES moth
ROUNDSTART_RACES plasmaman
@@ -436,7 +436,7 @@ ROUNDSTART_RACES rachnid
ROUNDSTART_RACES vox
## Races that are better than humans in some ways, but worse in others
-ROUNDSTART_RACES ethereal
+ROUNDSTART_RACES elzuose
ROUNDSTART_RACES jelly
#ROUNDSTART_RACES golem
#ROUNDSTART_RACES adamantine
diff --git a/html/changelogs/archive/2024-04.yml b/html/changelogs/archive/2024-04.yml
index 4554d939d8b3..ac70dad771a3 100644
--- a/html/changelogs/archive/2024-04.yml
+++ b/html/changelogs/archive/2024-04.yml
@@ -19,3 +19,128 @@
Imaginos16, spookywastaken:
- rscadd: Resprites a ton of gun magazines
- bugfix: Changes how magainzes with only a empty and loaded state are
+2024-04-12:
+ Gristlebee:
+ - rscadd: Punching bags can be built with 5 cloth.
+ - rscadd: Bench press and chest press can be built with 5 metal.
+ - rscadd: Exercise equipment can be deconstructed.
+ Martinpachu:
+ - bugfix: Fixes MAA on the Colossus not being able to access the bridge.
+ Sadhorizon:
+ - tweak: Random blood packs now can roll Elzu and IPC blood.
+ SomeguyManperson:
+ - bugfix: anesthetic can no longer semi permanently knock people out
+ Yata9ar4su:
+ - rscadd: Fullscreen on F11
+ Zxaber:
+ - tweak: You can now use drop / use inhand hotkey to retract and deploy arm implants
+ meemofcourse:
+ - rscadd: Long-range bluespace technologies in fax machines now allow the faxing
+ of photos. I am not responsible for any consequences that might result from
+ sending your faction's command personnel a photo of your character's ass.
+ phoaly:
+ - rscdel: Removed some old ships
+ - tweak: Aspawned the Lagoon and Junker
+ sapphicoverload, PestoVerde322, PacifistDalek:
+ - rscadd: turbines now provide thrust for ships
+ - tweak: turbines respect conservation of energy instead of moving gas around for
+ free
+ - tweak: turbine control console now shows the internal pressure of the turbine
+ - code_imp: refactored how gas flows through the turbine
+ - bugfix: fixed turbines making free energy from nowhere at low RPM
+ - bugfix: fixed turbines forcing air into the output turf when it's blocked
+ - bugfix: fixed turbines not updating air at the input and output turfs
+ - bugfix: fixed turbines disconnecting when docking and undocking
+ - imageadd: new turbine sprites
+ thgvr:
+ - rscadd: Suicide & Execution with a damaging firearm is now more deadly and gruesome.
+2024-04-13:
+ FalloutFalcon:
+ - tweak: all radios start off
+ - tweak: all survival boxs start with a radio
+ Sun-Soaked:
+ - rscadd: Redesigns landmines as an item that can be picked up, disarmed, deployed.
+ Some logic courtesy of /tg/.
+ - rscadd: Adds a proximity explosive variant of landmines.
+ - bugfix: shrapnel embedding once again respects targeted limb and no longer runtimes
+ on hitting a wall or destroying an object.
+ - bugfix: storage can no longer pick up anchored objects, causing them to get stuck
+ inside
+ - balance: Nerfs the ability of heavy explosions to immediately breach to space
+ - soundadd: adds two mine detonation noises
+ - code_imp: moves weapon manufacturer defines to a DEFINE file
+ generalthrax:
+ - rscadd: Etherbor SG-8 Beam Pistol to cargo for 1000 credits
+ - rscadd: Etherbor BG-12 Beam Rifle to cargo for 3000 credits
+ - rscadd: Etherbor civilian weapon cells for 600 credits, slightly higher capacity
+ than the generic cells
+2024-04-17:
+ Gristlebee:
+ - tweak: Granularizes Outpost Spacesuits and Armor
+ - balance: Reduces the cost of specialized space suits
+ SomeguyManperson:
+ - tweak: ships no longer have intrinsic gravity
+ - rscadd: new gravity generator machine for ships
+ - tweak: planetary gravity is now stored level-wide, a ship landing at a planet
+ will be effected by the planet's gravity
+ meemofcourse:
+ - tweak: Identification Cards are now Access Cards. The only real difference is
+ that your name only shows up on a double examine.
+ - refactor: Anonymous mechanics. Characters no longer instantly recognize each other,
+ and need to properly memorize each other in order. You can recognize an unmasked
+ person by ctrl-shift-clicking them.
+2024-04-18:
+ goober3:
+ - bugfix: Wall lockers should be facing the right way again.
+2024-04-19:
+ FalloutFalcon:
+ - bugfix: epty list
+2024-04-20:
+ Apogee-dev:
+ - balance: removed armor value from Solgov hats
+ - balance: Removed armor from berets, peaked caps, and soft caps
+ FalloutFalcon:
+ - spellcheck: renames some species stuff
+ Gristlebee:
+ - bugfix: The laser gun can be bought at the outpost again.
+ Hardly:
+ - tweak: Kissing volume and range has been reduced. Kissing cannot be heard beyond
+ 5 ranges or behind walls.
+ PositiveEntropy:
+ - imageadd: The Pointman Hardsuit that Inteq uses has been cleaned up!
+ Sadhorizon:
+ - soundadd: Sarathi firespit now has a unique sound.
+ SomeguyManperson:
+ - rscdel: tesla coils and rad collectors can no longer print monopoly money
+ Spookypineapple, Imaginos, Thgvr:
+ - rscadd: New sofa and comfy chair variants, both are craftable with metal
+ - imageadd: Sofas, Comfy chairs, and some atmos equipment have a new coat of paint
+ - imageadd: Janitorial equipment has a new coat of paint
+ Sun-Soaked:
+ - bugfix: planetary static anomalies no longer drop a broken spawner.
+ - code_imp: mob spawners now store a weakref on their spawned object
+ cuddleandtea:
+ - admin: faster access to advanced build mode
+ - admin: new relocate subtype for build mode
+ generalthrax:
+ - bugfix: Scarborough + gun typos fixed in cargo
+ - rscadd: Kepori can now *click and *whistle, complete with sounds.
+ - rscadd: Kepori can now *woop, to have a sound later.
+ - rscadd: Vox can now *click and *thump, with sounds as well.
+ jlsnow301, sun-soaked:
+ - rscadd: do_afters and do_mob actions now show nearby players a spinning cog while
+ in progress.
+ - bugfix: the progressbar.dmm file is no longer misspelled "progess"bar
+2024-04-21:
+ FalloutFalcon:
+ - rscdel: Removed firing pins
+ - rscdel: Removed clumsy checks on guns
+ cuddleandtea:
+ - admin: adds color type to variables
+2024-04-25:
+ Gristlebee:
+ - bugfix: Model H and Prototype Gauss Rifle mags are no longer invisible
+2024-04-27:
+ Sadhorizon:
+ - tweak: Replaced standard syndicate outfits with NGR outfits on the Hyena.
+ - rscadd: Added NGR-specific CE and Assistant outfits.
diff --git a/html/changelogs/archive/2024-05.yml b/html/changelogs/archive/2024-05.yml
new file mode 100644
index 000000000000..9e6c28996774
--- /dev/null
+++ b/html/changelogs/archive/2024-05.yml
@@ -0,0 +1,186 @@
+2024-05-02:
+ thgvr:
+ - imageadd: Nanotrasen outfits have a new coat of paint
+2024-05-04:
+ Apogee-dev:
+ - bugfix: fixed missing object descriptions on nanotrasen uniforms
+2024-05-06:
+ Anticept:
+ - tweak: intercomms, widebands, and headsets default speaker on again. Handhelds
+ remain off by default.
+ - balance: pure soulus dust now makes 20u per reaction, and system cleaner is not
+ required.
+ Martinpachu:
+ - balance: The detective's revolver is now priced at 600 credits instead of 1000.
+ - balance: The detective's revolver size is now Small.
+ - rscadd: The Candor may now be bought from the outpost.
+ PositiveEntropy:
+ - rscdel: Removes the Arrhythmic Knife.
+ SomeguyManperson:
+ - tweak: match rounds will no longer consider the person firing them as a viable
+ target when ricocheting
+ SuhEugene:
+ - admin: made invisimin admins invisible for HUDs and ghosts
+ Sun-Soaked:
+ - bugfix: weird uncertainty around the name of EXOCOM. EXOCON is not real.
+2024-05-09:
+ PositiveEntropy:
+ - rscadd: The HP Firebrand, HP Scout, HP Contender, .38 Derringer and Double Barrel
+ Shotgun are now purchasable in the outpost store.
+ - bugfix: The Disposable Gun crate is now granularized.
+ - rscdel: The Scarborough Revolver is no longer purchasable in the outpost store.
+2024-05-10:
+ meemofcourse:
+ - rscadd: Helmets now have a small, two-item storage. You can put goggles in there,
+ and it might overlay them.
+2024-05-14:
+ Gristlebee:
+ - rscadd: Elzu rooting
+ - tweak: Max age for elzu characters can be 300.
+ Martinpachu:
+ - tweak: Riot shield crates now contain only one shield but are priced at 600 credits.
+ MassiveMen:
+ - rscadd: Hawaiian Shirt is now in loadout
+ - tweak: Hawaiian Shirt is now Floral Shirt
+ - tweak: New item description teehee
+ SomeguyManperson:
+ - bugfix: static anomalies can now be safely approached if mindshielded, wearing
+ a research scanner, or deaf, not all three at the same time
+2024-05-16:
+ FleetingExpertise:
+ - rscadd: Added new sprites for the plunger, rolling pin and push broom by FleetingExpertise
+ - rscadd: Most knifes in the game have been resprited!
+2024-05-18:
+ spookypineapple:
+ - imageadd: Snowy grass, suit storage units, bookcases, and chem machines have been
+ resprited
+2024-05-20:
+ MarkSuckerberg:
+ - rscadd: Autowiki generated reagents list page
+2024-05-21:
+ Apogee-dev:
+ - tweak: Made the Delta more obviously affiliated with N+S Logistics
+ FalloutFalcon:
+ - balance: some xeno stuff needed nerfs
+ - bugfix: fixed a bunch of xeno issues
+ - rscdel: deleted some bad recipes like a golden horn, black carpet, aitater, and
+ legion staff
+ - code_imp: organized recipe files
+ Gristlebee:
+ - rscadd: A bunch of new items for the Black Market catalogue
+ - rscadd: Two new Black Market Tabs, Explosives and Emergency
+ - rscadd: Sawn off Illestren typepath
+ - rscdel: Black Market Teleportation
+ - rscdel: Space Ninja mask and Clown Tears from Black Market
+ - tweak: Black Market Uplink uses a micro laser instead of an ansible for crafting
+ - tweak: Black Market descriptions and examines
+ - tweak: Black Market Uplinks link directly to a specific LTSRBT
+ - balance: Black Market item price and stock adjusted
+ - balance: LTSRBT is faster
+ - code_imp: pair_item var for Black Market items
+ Martinpachu:
+ - rscdel: Removed the bible from loadout, as well as the religion and deity names
+ because god is dead. Clown and mime names too.
+ - balance: The civilian etherbor weapons have been made larger (the SG-8 being normal
+ sized and the BG-12 being bulky sized)
+ Sadhorizon:
+ - tweak: Sarathi max age is now 175.
+ SomeguyManperson:
+ - rscadd: you can now attach plungers to people by hand, rather than throwing
+ Sun-Soaked:
+ - rscadd: Volumetric storage on backpacks.
+ - rscadd: trash bags now have more storage space, but only make a small amount of
+ their contents accessible at any given time.
+ Zevotech:
+ - rscadd: Remaps lavaland_surface_biodome_winter.dmm
+ - rscdel: Removes the "Undead Eskimo" mob
+ generalthrax:
+ - rscadd: Add mood-boosting vivifier cybernetic implants to boost your mood to Cybernetic
+ Implants node. Preservation of the sense of taste not included
+ - rscadd: Adds a hacked variant of the above (not yet obtainable) to give terrible
+ mood to those installed with it!
+ meemofcourse:
+ - rscadd: Tortuga-class.
+ - rscadd: Brawler-class.
+ - rscdel: Ember-class.
+ - rscdel: Scar suit.
+ - tweak: Frontiersmen outfits start with less stuff.
+ retlaw34:
+ - rscdel: Vela-class, is this even player facing?
+ - rscadd: Variants of clip outfits
+ - rscdel: reinforced trapper hat
+ - rscadd: resprites the indie sec suit and it's clip variant
+ - tweak: Some extremely minor code tweaks
+ - rscadd: adds support to make adding species variants easier, jesus christ it was
+ bad before.
+ - rscadd: snouted variant support for sprites
+2024-05-22:
+ Zevotech:
+ - rscadd: rockplanet_shippingdock.dmm and associated code
+2024-05-25:
+ FalloutFalcon:
+ - rscdel: Removed comms consoles from ruins and ships
+ PositiveEntropy:
+ - imageadd: Computers now look sleeker!
+ SomeguyManperson:
+ - bugfix: mech laser cargo crate is no longer unbuyable
+ Zevotech:
+ - rscdel: Plastic flaps no longer block atmos
+2024-05-28:
+ Anticept:
+ - tweak: All pacman and its variants now have the same sheet burn times. Superpacmans
+ are no longer the vastly inferior generator.
+ Gristlebee:
+ - rscadd: Generic Ammo Boxes, printable in the autolathe
+ - rscadd: Ammo cans are printable in the autolathe
+ - bugfix: Ammo boxes sometimes not properly updating their materials
+ - rscdel: Elzu can no longer change their color with the multitool or emag.
+ Martinpachu:
+ - rscadd: Double bedsheets, fit for double beds, are now craftable via cloth.
+ Mirag19:
+ - bugfix: Fix revolver ammo check
+ Skies-Of-Blue:
+ - bugfix: fbp and rilena hoodies now work as intended
+ SomeguyManperson:
+ - bugfix: melee hermits now pull from the "survivor" loot variant rather than no
+ loot variant
+ - bugfix: hermits can no longer commit mitosis
+ - tweak: hermit loot has been compactified, defaults are now declared in the object
+ rather than initialize, and variant-specific loot now uses a switch statement
+ - bugfix: all hermits now have pocket loot randomized as intended
+ - tweak: reduces the cash bundle melee hermits can drop from a medium random (500-3000)
+ to small random (100-500) bundle since they are quite common
+ - bugfix: prismwine's burn resistance can no longer end up stacking
+ Spyroshark, Sun-Soaked:
+ - rscadd: A movable physics subsystem, deployed using a component.
+ - rscadd: Bullet casings now drop using movable physics
+ - code_imp: ports NO_PIXEL_RANDOM_DROP from TG.
+ Thera-Pissed:
+ - tweak: SSUs draw power to decontaminate
+ - balance: lights no longer take 60% of a ships power, machines use more to account
+ for this.
+ - code_imp: added standardized defines for power usage
+ Zevotech:
+ - rscdel: Clown and mime fan quirks have been removed
+ - rscdel: Removes the clown and mime fan pins
+2024-05-29:
+ Apogee-dev:
+ - tweak: Syndicate mobs have been renamed to Ramzi Clique mobs. New sprites will
+ come later.
+ Gristlebee:
+ - rscadd: Holopads now display the location of the last holopad that called them
+ on examine.
+ - code_imp: Span macros for hologram.dm
+ - rscadd: Autolathe can print holofield controllers.
+ - rscadd: You can sync blastdoors and holofields to a controller in a button with
+ a multitool
+ - code_imp: span macros for blast doors, buttons and holofields
+2024-05-30:
+ PositiveEntropy:
+ - rscadd: Solarian Marine Bi-ologists now have proper representation in the form
+ of a cute cloak!
+2024-05-31:
+ Gristlebee:
+ - bugfix: Auto unloading for gate loaded revolvers
+ INFRARED_BARON, PositiveEntropy:
+ - imageadd: Resprites nearly every mech!
diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml
new file mode 100644
index 000000000000..d39c3b4431ae
--- /dev/null
+++ b/html/changelogs/archive/2024-06.yml
@@ -0,0 +1,366 @@
+2024-06-01:
+ FalloutFalcon:
+ - rscadd: Added new more varied legion corpses
+ - rscdel: Removed lot of the crappy legion corpses
+ - balance: rebalanced most of the old legion corpses
+ - refactor: moved most legion corpse loot behavior to outfits
+ - tweak: tweaked the new ore
+ Gristlebee:
+ - rscadd: Suit Storage Unit construction
+ - rscadd: Added suit storage unit circuit boards to industrial engineering tech
+ - tweak: Suit storage unit examines
+ - tweak: span class to span macros in suit_storage.dm
+ INFRARED_BARON:
+ - imageadd: All mechs have been successfully resprited, including the Mauler, Marauder
+ and Seraph now!
+ Skies-Of-Blue:
+ - tweak: mugs referencing an ancient terran empire have been confiscated by the
+ confederation. Please enjoy your complementary, generic mug in compensation
+ - bugfix: rds based delusions now pass without the player having to relog, thank
+ god
+ - bugfix: rds can once again be treated with mindbreaker toxin (hopefully)
+ - tweak: the pool of possible delusions has been changed to better reflect shiptest's
+ narrative
+ - rscadd: a base ramzi sprite to simple_human.dmi to be used in the changed delusion
+ pool
+ - rscdel: chat warning message for rds users not to grief. Just be cool about it,
+ okay?
+ SomeguyManperson:
+ - bugfix: fueled thruster throttling now works right
+ Sun-Soaked:
+ - rscadd: World icon element.
+ - rscadd: World icons for combat knives.
+ thgvr:
+ - rscadd: Roundstart ships no longer spawn
+2024-06-02:
+ Skies-Of-Blue:
+ - rscdel: removes the roundjoin "welcome to /tg/ station" audio clip
+ SomeguyManperson:
+ - bugfix: black market secret documents are no longer default documents
+ - balance: the shoddy survivor suits found on hermits are now actually worse than
+ the EXOCOM explorer suits
+2024-06-03:
+ Apogee-dev:
+ - balance: security belts and webbings can no longer store bulk ammo boxes, only
+ magazines
+ - tweak: Ship-specific access restrictions have been enabled.
+ - tweak: Pirate ships no longer spawn docked to the outpost.
+ FalloutFalcon:
+ - bugfix: Fixed plant analyzer examine block styling
+ - tweak: rewrites trickwine for brewers
+ - rscadd: You can trip landmines with a well placed throw
+ - rscadd: New interaction with throwing things at bottles, lights, and bear traps
+ - bugfix: The end of finalize no longer gets called twice and targeting items seems
+ like an intended behavior that was lost
+ - rscdel: Removed goofball legion disease
+ - refactor: spawning guns without mags are handled with a define
+ - refactor: refactored hostile humans
+ - bugfix: fixed free smart fridge circuit board from drying rack
+ - rscadd: Smokers rejoice! You can now pick your favorite type of nicotine delivery
+ system.
+ - rscadd: Smokers have a choice between most brands of cigarette, cigars, a vape,
+ or a pipe!
+ - code_imp: sorted code owner stuff and added me to some files
+ - bugfix: fixed create and destroy test fail
+ - tweak: tweaked id card examine information and formating
+ - bugfix: human examine bug when middle aged
+ - rscdel: Removed moths getting one shot by a flyswatter
+ - code_imp: camera/autoname/LateInitialize() optimization
+ - tweak: granularizes a handful of tool and machine supply packs!
+ - admin: Improved the silly little menu, HA HA I have messed up your muscle memory!!
+ u
+ Gristlebee:
+ - tweak: Defib crate now contains a single defib, priced 750
+ - tweak: Granularizes mech equipment
+ - tweak: mech cargo pack descs
+ - rscadd: Asteroid ore veins
+ Hardly:
+ - rscadd: Added some style to the flavor text popup
+ - bugfix: Fixed flavor text not accepting certain characters or new lines
+ - tweak: Changed up Flavor Text editing text a bit
+ - tweak: Flavor text's max length has been chopped from 4096 to 1024
+ Sadhorizon:
+ - tweak: Moved most of contraband items out of vendor contraband.
+ - rscadd: Added DromaderyCo packets to the cigarette vendors.
+ - tweak: Increased nicotine amount to three in the cigarette vendors.
+ Skies-Of-Blue:
+ - balance: chemical mindbreaker is now ten times as potent! Be gay, do crime, and
+ hallucinate in the process
+ SomeguyManperson:
+ - bugfix: hallucination anomalies now trigger if you aren't wearing proper protection
+ (as opposed to only triggering if you are)
+ - bugfix: gun sawing can now only be done with proper equipment (usually a saw))
+ - bugfix: bandoliers now hold the correct amount of bullets (several more)
+ - balance: the brimstone can now be pumped faster. Enjoy your rilena.
+ Sun-Soaked:
+ - bugfix: shoutgun casing bounce sfx now plays as intended. oopsies.
+ - rscdel: Removes sexy clown costumes from spawners
+ - config: tweak option removed from changelog template
+ Zevotech:
+ - rscdel: Removed nonfunctioning coffee machines and their cargo packs
+ - rscadd: Adds the Elzuose color salve, a product that allows Elzuose to change
+ their glow color upon application.
+ '[Watermelon914](https://github.com/Watermelon914)':
+ - code_imp: ports little itty bitty sendsignal optimization from tg
+ meemofcourse:
+ - balance: The Elder's Illesterns and Arrows are now factory-variant.
+ - bugfix: The Runner should be able to dock now.
+ rkz, Benjamin(benbot16), Rohesie, Qustinnus, jlsnow301:
+ - refactor: refactored do_afters to use timed_action_flags for unique args
+ - code_imp: centralized do_mob and do_atom into do_after
+2024-06-05:
+ FalloutFalcon:
+ - rscdel: Trophies can no longer be used in crushers
+ - bugfix: fixed CODEOWNERS, i hope
+ SomeguyManperson:
+ - bugfix: The shadow's gunslinger buff now properly provides an AP bonus
+ - balance: Rollerbeds stop broken bone damage ticks from occurring while buckled
+2024-06-06:
+ SomeguyManperson:
+ - bugfix: melee hermits have had their immortal snail deals revoked
+2024-06-07:
+ Sun-Soaked:
+ - bugfix: combat knives and their subtypes now once again have sprites.
+ Zevotech:
+ - rscadd: remapped and renamed ashwalker_shrine into lavaland_surface_buried_shrine
+ - rscadd: Necropolis walls have been renamed to thick stone walls.
+ rye-rice:
+ - rscadd: Changing firemodes on guns now have new sprites
+ - bugfix: The E-40 now works as intended!
+ - rscadd: The E-40 now has an ammo counter
+ - balance: The P16 shoots slightly faster.
+ - balance: Two E-40s max are obtainable from the black market should it spawn. Blank
+ market price cap of the E-40 has also increased
+2024-06-08:
+ Apogee-dev:
+ - bugfix: fixed an incorrect sprite state on corpo sofas
+ FalloutFalcon:
+ - rscdel: Removed alot of magic cruft
+ - code_imp: Sorts gun defines into there own file
+ SomeguyManperson:
+ - bugfix: gunslinger applies its spread reduction effect to revolvers
+ Sun-Soaked:
+ - bugfix: removes a comment from apc.dm that was causing strange errors.
+ thgvr:
+ - imageadd: Kepori have been given a full visual overhaul.
+2024-06-09:
+ SomeguyManperson:
+ - tweak: bleeding is now stored in the limbs, functioning similarly to bone breaking.
+ Taking damage over a certain threshold and amount (lower for sharp weapons)
+ will cause part of it to be turned into bleeding.
+ - tweak: gauze, tape, and bleeding suppression are similarly no longer abstracted
+ into a "bleed suppression" value
+ - rscadd: you can now cauterize bleeding with a lighter. Which is cool.
+ - rscadd: you can now also cauterize bleeding with suit storage decontamination.
+ Which is hot.
+ - rscadd: examine and examine closely will show whether or not someone is visibly
+ bleeding or bandaged. This means people who are both will show both. Examine
+ closely additionally shows which limbs are currently bleeding.
+ - tweak: heparin now causes existing bleeding to worsen, instead of causing bleeding
+ on its own
+ - tweak: you can no longer cut the throat of someone who's head has been lopped
+ off
+ Zevotech:
+ - bugfix: Planets should no longer spawn without ruins when generating due to bad
+ map datums
+ - rscdel: Removed 3 Beach ruins
+ - rscdel: Removed 4 Iceplanet ruins
+ - rscdel: Removed 11 Jungle ruins
+ - rscdel: Removed 10 Lavaland ruins
+ - rscdel: Removed 8 Rockplanet ruins
+ - rscdel: Removed 7 Sandplanet ruins
+ - rscdel: Removed 7 Rockplanet ruins
+ - rscdel: Removed 15 Space ruins
+ - rscdel: Removed 16 unused/removed ruin code files
+ - rscdel: Removed a whole lot of old/unused ruin code from misc files
+ - tweak: Tweaked various ruins and one ship to fix issues and remove unused items
+2024-06-10:
+ PositiveEntropy:
+ - rscadd: CLIP now reports the presence of so-called "Flame Troopers" of the Frontiersmen
+ terrorizing their territories...
+ - balance: Marine armor has improved armor stats at the cost of the bulk slowing
+ down the wearer.
+ - balance: Flamethrowers have a slightly improved effective range, as well as higher
+ damage.
+ - imageadd: The Frontiersmen have gotten better tailors and now look sharp and deadly!
+ Skies-Of-Blue:
+ - rscadd: several new SUNS-produced genemods have hit the public market! Head to
+ your local gene-clinic and ask about their new dog and rabbit options for more
+ details
+ - balance: fox ears have been tweaked to be just as susceptible to sound as cat
+ ears
+2024-06-11:
+ 'CoiledLamb ':
+ - rscadd: Resprites the eggbox
+ Gristlebee:
+ - code_imp: Switchblades are now pathed under obj/kitchen/knife
+ - imageadd: Switchblade sprites moved from items and weapons.dmi to knife.dmi
+ Sadhorizon:
+ - rscadd: Pickaxe was added to the autolathe.
+ meemofcourse:
+ - rscadd: PGF jobs now grant you the Kalixcian Common language
+2024-06-13:
+ FalloutFalcon:
+ - rscdel: Removed alot of chaplain stuff we will never use
+ - rscdel: The chaplain is now just as magic as the average person
+ Gristlebee:
+ - rscadd: Wrecked Factory ruin
+ - rscadd: Indestructible titanium walls
+ - rscadd: Lavaland atmos subtypes for plating, rusted plating, concrete, white and
+ dark turfs
+ - balance: Syndicate Space Simple Mobs have their max temp increased
+ - tweak: Wall_lockers updatepaths on the Aegis
+ - code_imp: Adds ruin to map_catalogue,txt, lavaland.dm and adds it to lavaland.dm
+ areas
+ - rscadd: Techshell box
+ - rscadd: Techshells to the outpost market for 175 credits
+ - tweak: Scatter ion description
+ - balance: Techshell recipes no longer require higher tier stock parts, adjusts
+ scatter laser, scatter ion, dragonsbreath and pulse slug recipes
+ - balance: Buffs scatter lasers, scatter ion and dragonsbreath
+ PositiveEntropy:
+ - rscadd: The Hardliners have now made a proper appearance in the Frontier!
+ Sadhorizon:
+ - rscadd: Added the Sunskipper-class Culinary Vessel.
+ - rscadd: Every drink and booze dispenser drink is in the booze-o-mat now.
+ - rscadd: Added bottles for triple sec, lemon juice, creme de cacao and creme de
+ menthe.
+ - rscdel: Removed the Boyardee-class Entertainment Vessel.
+ - rscdel: Independent chefs no longer get kitchen cqc.
+ - tweak: The "syndicate waiter's outfit" renamed to just "waiter's outfit".
+ - tweak: Indpenedent bartenders now start with a waistcoat.
+ - tweak: Edited waiter's outfit. Also, the role now gets kitchen access.
+ - tweak: Independent cooks now start with laceup shoes.
+ meemofcourse:
+ - rscadd: SUNS 3x6 logo decal, SUNS tiles, SUNS emblem floor decal, Desk and Wall
+ flag, folders, PDA, cards, locker, bedsheets, and headsets.
+2024-06-14:
+ Gristlebee:
+ - bugfix: Posibrains/MMI pilots being permaslept on mech destruction
+2024-06-15:
+ Rye-Rice:
+ - imageadd: Rylie Was Forced To Resprite Concrete when she was 6!
+2024-06-16:
+ DIB-DOG:
+ - rscadd: Added 1 Raksha Helmet to the sergeant's locker on the PGFN Crying Sun
+2024-06-17:
+ meemofcourse:
+ - code_imp: A lot of SUNS decals.
+2024-06-18:
+ '@thestripes, @meemofcourse , @GenericDM ':
+ - tweak: reflavors nearly every drink ingame
+ SomeguyManperson:
+ - rscadd: you can now put organs inside burgers or on pizzas
+2024-06-19:
+ Anticept:
+ - bugfix: Generic adjective selection will show for everyone.
+ FalloutFalcon:
+ - bugfix: fixed multiple of the do_afters not working due to misplaced args
+ PositiveEntropy:
+ - rscadd: The Hunters of Illestren have now allowed for Hunter Collignes, Machinists
+ and Flamebearers to now roam the Frontier aboard their humble fleet!
+ - imageadd: The Saint Roumain's Militia has been fully resprited!
+ - imageadd: All SRM jobs now have unique HUD icons!
+ - imageadd: The Unknown Job HUD icon has been resprited!
+ SomeguyManperson:
+ - bugfix: mobs will no longer stick around after being butchered sometimes
+ Yata9ar4su:
+ - bugfix: Atmos mask sprite
+2024-06-20:
+ FalloutFalcon:
+ - admin: reverted filling admin context menus with alot of not useful stuff by rehiding
+ it behind a toggle.
+ Gristlebee:
+ - rscadd: Energy guns show how much charge and shots they have remaining, or if
+ it doesnt have a cell installed on examine.
+ - code_imp: span classes to span macros for energy.dm
+ Sadhorizon:
+ - tweak: SRM cabinets - namely, Hunter's, Shadow's and Flamebearer's - now use cabinet
+ sounds.
+ Skies-Of-Blue:
+ - balance: you can now float over tables when in 0g
+ - balance: you no longer shatter glass tables when floating
+ SomeguyManperson:
+ - balance: 9mm boxes are now cheaper than other pistol calibers to account for the
+ lower damage per bullet
+ generalthrax:
+ - bugfix: The black market sawed off Illestren is now actually sawed off, and can
+ fit on your belt
+ - bugfix: The presawn double barrel shotgun can now fit on the belt like normal
+ sawn off double barrels
+ - rscdel: Removed invisible limb armour from Gezenan marine + navywear
+ - rscadd: Allowed Gezenan armour to hold all guns like normal armour
+ - bugfix: Fixed Montagne hat description to reflect the fact it is no longer armoured
+2024-06-21:
+ FalloutFalcon:
+ - rscadd: Bank accounts are now handled through cash cards! You now spawn with a
+ wallet to store your extra card!
+ Gristlebee:
+ - balance: Motorized wheelchairs consume less power on move
+ Thera-Pissed:
+ - rscadd: Added Hydrogen, and Combustion Thrusters to go with!
+ rye-rice:
+ - rscadd: Adds a war correspondent for CLIP.
+2024-06-22:
+ Anticept:
+ - bugfix: Dialed down the loudness of a couple Kepori sounds
+ - bugfix: Kepori wooping now has the audible flag.
+ - bugfix: Whistling now varies in pitch
+ PositiveEntropy:
+ - imageadd: SUNS trimline decals are now properly aligned.
+ Sadhorizon:
+ - rscadd: Bone Talisman and Hunter's Necklace were added to loadout.
+ - tweak: Bone Talisman and Hunter's Necklace were reflavored into good lack charms.
+ They are no longer armored.
+ - tweak: Wolf talisman crafting recipe now requires less stuff.
+ - bugfix: Blue wall locker sprites are no longer flipped.
+ SomeguyManperson:
+ - balance: crystal legion spawn 1 less skull per spawn wave, now 1 (like normal
+ legion)
+ - balance: brimdemon beams now have a fade-in effect before dealing damage, making
+ it harder to get instantly chunked for a quarter of your health
+ - balance: brimdemons can no longer aggro on you before you can see them
+ - balance: radiation collectors are now significantly more stingy about the potency
+ of the radiation they will process. Don't expect old nuclear waste or openly
+ stored uranium to do much.
+ - balance: radiation collectors also produce significantly more power from the remaining
+ viable sources
+ Thera-Pissed:
+ - bugfix: infinite negative power draw while calling your grandmother no longer
+ happens.
+ - bugfix: fixed volume pumps for mapping.
+ blinkdog:
+ - bugfix: Cleaned up some logic in revolver safety
+ generalthrax:
+ - bugfix: Tadrixx Float has a sprite again
+ - rscadd: You can now tail thump if you have a tail instead of it being tied to
+ species
+2024-06-25:
+ Martinpachu:
+ - rscadd: Cargo guns and certain guns in ships now come inside cases alongside some
+ magazines, the ammo now comes separately for safety reasons.
+2024-06-27:
+ Gristlebee:
+ - tweak: Saber SMG stock folds
+ - tweak: TEC-9 Pistol is now automatic and normal sized
+ - balance: Combat shotgun is now bulky, and the compact combat shotgun is normal.
+ Martinpachu:
+ - rscadd: A technique for gunslinger with the lever-action flaming arrow! Firing
+ it while wielded will quickly and automatically rack the lever, less quickly
+ than a .38 revolver or fanned shadow though.
+ - rscdel: The +5 damage and AP bonus on the shadow while using it as a gunslinger.
+ Sadhorizon:
+ - rscdel: Miners and Cargo Technicians no longer get QM access.
+ SomeguyManperson:
+ - bugfix: cyborgs can touch people again
+ - code_imp: robotic limbs will always have healing prioritized over being cauterized
+ if treated with a welder
+ generalthrax:
+ - rscdel: Tranquility reagent no longer turns you into a gondola
+ - bugfix: Fixed typos in the Shadow and Montagne revolvers
+ - bugfix: Black market rusted reds no longer flash into dust when you purchase them
+ thestripes:
+ - rscadd: Added Kepori names, surnames, and a list for the char gen to draw from.
+ Remember to update your character names!
+ - rscdel: Removed old Kepori name gen system and a bit of lore from the species
+ blurb
diff --git a/html/changelogs/archive/2024-07.yml b/html/changelogs/archive/2024-07.yml
new file mode 100644
index 000000000000..6eca9f799e42
--- /dev/null
+++ b/html/changelogs/archive/2024-07.yml
@@ -0,0 +1,129 @@
+2024-07-01:
+ Skies-Of-Blue:
+ - bugfix: you can now rotate wheelchairs, just as god intended
+2024-07-02:
+ GenericDM:
+ - bugfix: fixes exactly one typographical error somewhere in the code
+2024-07-03:
+ Cloudbreak:
+ - code_imp: Typographical error fixed.
+2024-07-04:
+ Latentish:
+ - rscadd: Added the Panacea-class
+ - rscdel: Removed the Aegis-class
+ generalthrax:
+ - bugfix: Fixed Comet Trail, Molten Bubbles, and Sunset Sarsaparilla glass sprites
+2024-07-06:
+ Sadhorizon:
+ - bugfix: Dog beds start anchored now. Mobs can no longer move while buckled.
+ rye-rice:
+ - rscadd: Resprites the E-50 and gives it proper inhands now!
+ - bugfix: The Syndicate sniper rifle fires at a normal rate of fire and has the
+ correct recoil now.
+2024-07-09:
+ Apogee-dev:
+ - bugfix: N+S Captains no longer spawn with Nanotrasen coats.
+ - balance: reduced default ship spawn limit to 1.
+ - bugfix: Cargo pods no longer land in Talos maint
+ - bugfix: Gas tanks on the Talos have higher security
+ - bugfix: Talos now has an autolathe in cargo
+ Sadhorizon:
+ - rscadd: Added a plastic flower - a selection of flowers to wear. Added it to the
+ loadout too.
+ SapphicOverload:
+ - rscadd: Adds an igniter and button to the TEG of every ship that was missing one
+ - rscdel: Removed the welding tool TEG chute some ships had
+ SomeguyManperson:
+ - bugfix: loadout boxes will no longer sometimes not spawn
+ - code_imp: People who are stunned are now more reliably passed by bullets not aimed
+ directly at them
+ generalthrax:
+ - rscdel: Removed some irrelevant old tips of the round
+ - rscadd: Added 80+ new tips more relevant to Shiptest's gameplay loop
+2024-07-10:
+ Cloudbreak:
+ - bugfix: A few clothing items now properly display again for Vox.
+ meemofcourse:
+ - rscadd: Minor changes to the Tortuga.
+ - bugfix: The holofields on the Tortuga-class and Brawler-class now work.
+2024-07-11:
+ Cloudbreak:
+ - code_imp: Fixes a singular typo within the code.
+ Martinpachu:
+ - balance: Pizzas have become cheaper. (6000 cr - 3000 cr)
+ PositiveEntropy:
+ - bugfix: Mars and Venus are now referred to by their correct names!
+ - bugfix: You can now store guns, ammunition, and melee weapons on the armor slot
+ when equipping a SolCon/SolGov hardsuit, and its subtypes!
+ generalthrax:
+ - rscdel: Removed tator tots and raw potato wedges
+2024-07-12:
+ generalthrax:
+ - rscdel: Removed mice possession
+ - rscdel: Broad removal of forcesays from most reagents and items
+ - rscdel: Removed char reagent and spraytan overdose
+ - rscdel: Removed gibbering lines
+ - rscdel: Removed Chav, Swedish, Elvis mutations
+ - rscadd: The outpost is now offering bounties to defuse landmines to Frontier vessels.
+ meemofcourse:
+ - balance: Remapped the Valor, with two extra jobs (Shuttle Corpsman, Shuttle Pilot).
+ - code_imp: The Vanguard base outfit starts with gear.
+2024-07-13:
+ FalloutFalcon:
+ - bugfix: pets no longer cause run times trying to open ship doors
+ - bugfix: no longer have to reinsert your id into your wallet for access
+ - rscadd: A new generic nest used across all planets
+ - rscdel: Old portal and tendrils and other cruft
+ - refactor: refactorted mob spawners to have one for each planet
+ Gristlebee:
+ - bugfix: 357 guncase spawns with the correct revolver
+ Skies-Of-Blue:
+ - balance: you can now fit radios and pill bottles in both hoodies and winter coats
+ - bugfix: the innate storage on winter coats has been restored, alt click to access!
+ SomeguyManperson:
+ - bugfix: brute damage is now required to break bones
+ TiberianEuan:
+ - rscadd: Black hoodie with grey hood.
+ - imageadd: New hoodie icons.
+ cuddleandtea:
+ - admin: new light maker subtype for build mode
+ generalthrax:
+ - bugfix: Fixed the Landmine mission description and flavoured it a little
+ - balance: Decreased the amount of landmines required for its mission and increased
+ the value per mine slightly
+ - rscdel: Capsaicin no longer Boils you
+2024-07-15:
+ FalloutFalcon:
+ - refactor: refactored attachments to be modular
+ Sadhorizon:
+ - tweak: Changed sunskipper's prefix to SV.
+ - bugfix: Added a missing pipe to the sunskipper.
+ Skies-Of-Blue:
+ - rscadd: typing indicators now trigger off of the command bar
+ - rscadd: an SSD Indicator for when you have been disconnected for less than three
+ minutes
+ - balance: players will now remain awake for three minutes after disconnecting,
+ with a new SSD icon to boot!
+ - balance: players SSD longer than three minutes will lose their icon and fall asleep,
+ much like the previous behavior
+ SomeguyManperson:
+ - bugfix: gun cargo packs now act more as they would be expected to
+2024-07-17:
+ FalloutFalcon:
+ - rscadd: Orbit menu is less cluttered and just shows the real name, hovering over
+ it shows their standard name.
+ - refactor: refactored express console to not be a subtype of the cargo console
+ and replacing it.
+ Martinpachu:
+ - balance: Doubled the price on every automatic gun and added 250 credits to the
+ price of every semi-auto pistol.
+ Sadhorizon:
+ - tweak: Choice beacons were reflavored into choice boxes.
+ - rscdel: Removed a bunch of meme, weird and unused items from the loadout.
+ - tweak: Reflavored the Cybersun labcoat into a generic "translucent labcoat"
+ SomeguyManperson:
+ - bugfix: ships docked to eachother now share gravity
+2024-07-18:
+ Fest1v3:
+ - rscadd: adds a few vox sprites
+ - bugfix: fixes a few vox sprites
diff --git a/html/typing_indicator.html b/html/typing_indicator.html
new file mode 100644
index 000000000000..2988edff55fa
--- /dev/null
+++ b/html/typing_indicator.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
diff --git a/icons/blanks/64x64.dmi b/icons/blanks/64x64.dmi
new file mode 100644
index 000000000000..6bfbd471e5db
Binary files /dev/null and b/icons/blanks/64x64.dmi differ
diff --git a/icons/effects/crayondecal.dmi b/icons/effects/crayondecal.dmi
index c9e7f880c809..d18ba51ae40f 100644
Binary files a/icons/effects/crayondecal.dmi and b/icons/effects/crayondecal.dmi differ
diff --git a/icons/effects/ore_visuals.dmi b/icons/effects/ore_visuals.dmi
index 1353a2d814ad..bab677d404e9 100644
Binary files a/icons/effects/ore_visuals.dmi and b/icons/effects/ore_visuals.dmi differ
diff --git a/icons/effects/progessbar.dmi b/icons/effects/progessbar.dmi
deleted file mode 100644
index f055a07ba149..000000000000
Binary files a/icons/effects/progessbar.dmi and /dev/null differ
diff --git a/icons/effects/progressbar.dmi b/icons/effects/progressbar.dmi
new file mode 100644
index 000000000000..3eed14db704a
Binary files /dev/null and b/icons/effects/progressbar.dmi differ
diff --git a/icons/hud/gun_hud.dmi b/icons/hud/gun_hud.dmi
index a24f7f2964f3..d108a6088e8f 100644
Binary files a/icons/hud/gun_hud.dmi and b/icons/hud/gun_hud.dmi differ
diff --git a/icons/hud/screen_alert.dmi b/icons/hud/screen_alert.dmi
index 1e03d316c2e3..60ada01078d7 100644
Binary files a/icons/hud/screen_alert.dmi and b/icons/hud/screen_alert.dmi differ
diff --git a/icons/hud/screen_gen.dmi b/icons/hud/screen_gen.dmi
index cad55a6ea290..b26bc7375dbb 100644
Binary files a/icons/hud/screen_gen.dmi and b/icons/hud/screen_gen.dmi differ
diff --git a/icons/mecha/mecha.dmi b/icons/mecha/mecha.dmi
index 08f0c94505ee..b894d9191225 100644
Binary files a/icons/mecha/mecha.dmi and b/icons/mecha/mecha.dmi differ
diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi
index 3a73559091b2..44698597b02c 100644
Binary files a/icons/misc/buildmode.dmi and b/icons/misc/buildmode.dmi differ
diff --git a/icons/mob/actions/actions_items.dmi b/icons/mob/actions/actions_items.dmi
index c52e55c475a6..9baf5cdde9b3 100644
Binary files a/icons/mob/actions/actions_items.dmi and b/icons/mob/actions/actions_items.dmi differ
diff --git a/icons/mob/augmentation/augments_kepori.dmi b/icons/mob/augmentation/augments_kepori.dmi
index 56e56dd22db5..e86bdfd9cf2d 100644
Binary files a/icons/mob/augmentation/augments_kepori.dmi and b/icons/mob/augmentation/augments_kepori.dmi differ
diff --git a/icons/mob/augmentation/augments_keporiOLD.dmi b/icons/mob/augmentation/augments_keporiOLD.dmi
new file mode 100644
index 000000000000..56e56dd22db5
Binary files /dev/null and b/icons/mob/augmentation/augments_keporiOLD.dmi differ
diff --git a/icons/mob/clothing/accessories.dmi b/icons/mob/clothing/accessories.dmi
index d23ebfae4756..7e87f94fd183 100644
Binary files a/icons/mob/clothing/accessories.dmi and b/icons/mob/clothing/accessories.dmi differ
diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi
index e8702376efce..5508bc67523c 100644
Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ
diff --git a/icons/mob/clothing/belt.dmi b/icons/mob/clothing/belt.dmi
index 398d4589ad71..7568a1274d66 100644
Binary files a/icons/mob/clothing/belt.dmi and b/icons/mob/clothing/belt.dmi differ
diff --git a/icons/mob/clothing/belt_mirror.dmi b/icons/mob/clothing/belt_mirror.dmi
deleted file mode 100644
index 6b27c56c8b35..000000000000
Binary files a/icons/mob/clothing/belt_mirror.dmi and /dev/null differ
diff --git a/icons/mob/clothing/ears.dmi b/icons/mob/clothing/ears.dmi
index 23292b118d6a..e7376425f545 100644
Binary files a/icons/mob/clothing/ears.dmi and b/icons/mob/clothing/ears.dmi differ
diff --git a/icons/mob/clothing/faction/clip/head.dmi b/icons/mob/clothing/faction/clip/head.dmi
index 2122a9a2f328..5679758b2f61 100644
Binary files a/icons/mob/clothing/faction/clip/head.dmi and b/icons/mob/clothing/faction/clip/head.dmi differ
diff --git a/icons/mob/clothing/faction/clip/mask.dmi b/icons/mob/clothing/faction/clip/mask.dmi
index a46424e63096..81e70c7f036f 100644
Binary files a/icons/mob/clothing/faction/clip/mask.dmi and b/icons/mob/clothing/faction/clip/mask.dmi differ
diff --git a/icons/mob/clothing/faction/clip/suits.dmi b/icons/mob/clothing/faction/clip/suits.dmi
index f7a64dc8b320..c68ab77196bb 100644
Binary files a/icons/mob/clothing/faction/clip/suits.dmi and b/icons/mob/clothing/faction/clip/suits.dmi differ
diff --git a/icons/mob/clothing/faction/clip/uniforms.dmi b/icons/mob/clothing/faction/clip/uniforms.dmi
index 71ad9e1b6a3e..436c00d77554 100644
Binary files a/icons/mob/clothing/faction/clip/uniforms.dmi and b/icons/mob/clothing/faction/clip/uniforms.dmi differ
diff --git a/icons/mob/clothing/faction/clip/vox.dmi b/icons/mob/clothing/faction/clip/vox.dmi
new file mode 100644
index 000000000000..e17d23fba20f
Binary files /dev/null and b/icons/mob/clothing/faction/clip/vox.dmi differ
diff --git a/icons/mob/clothing/faction/frontiersmen/belt.dmi b/icons/mob/clothing/faction/frontiersmen/belt.dmi
new file mode 100644
index 000000000000..a36573e66f5d
Binary files /dev/null and b/icons/mob/clothing/faction/frontiersmen/belt.dmi differ
diff --git a/icons/mob/clothing/faction/frontiersmen/head.dmi b/icons/mob/clothing/faction/frontiersmen/head.dmi
new file mode 100644
index 000000000000..03f2024b1e88
Binary files /dev/null and b/icons/mob/clothing/faction/frontiersmen/head.dmi differ
diff --git a/icons/mob/clothing/faction/frontiersmen/mask.dmi b/icons/mob/clothing/faction/frontiersmen/mask.dmi
new file mode 100644
index 000000000000..ecd716cdea0d
Binary files /dev/null and b/icons/mob/clothing/faction/frontiersmen/mask.dmi differ
diff --git a/icons/mob/clothing/faction/frontiersmen/suits.dmi b/icons/mob/clothing/faction/frontiersmen/suits.dmi
new file mode 100644
index 000000000000..50657c4df15e
Binary files /dev/null and b/icons/mob/clothing/faction/frontiersmen/suits.dmi differ
diff --git a/icons/mob/clothing/faction/frontiersmen/uniforms.dmi b/icons/mob/clothing/faction/frontiersmen/uniforms.dmi
new file mode 100644
index 000000000000..6dad817d6b64
Binary files /dev/null and b/icons/mob/clothing/faction/frontiersmen/uniforms.dmi differ
diff --git a/icons/mob/clothing/faction/hardliners/belt.dmi b/icons/mob/clothing/faction/hardliners/belt.dmi
new file mode 100644
index 000000000000..a864128547d6
Binary files /dev/null and b/icons/mob/clothing/faction/hardliners/belt.dmi differ
diff --git a/icons/mob/clothing/faction/hardliners/eyes.dmi b/icons/mob/clothing/faction/hardliners/eyes.dmi
new file mode 100644
index 000000000000..aec97963fd99
Binary files /dev/null and b/icons/mob/clothing/faction/hardliners/eyes.dmi differ
diff --git a/icons/mob/clothing/faction/hardliners/head.dmi b/icons/mob/clothing/faction/hardliners/head.dmi
new file mode 100644
index 000000000000..839826a7c426
Binary files /dev/null and b/icons/mob/clothing/faction/hardliners/head.dmi differ
diff --git a/icons/mob/clothing/faction/hardliners/suits.dmi b/icons/mob/clothing/faction/hardliners/suits.dmi
new file mode 100644
index 000000000000..05f41eb00d25
Binary files /dev/null and b/icons/mob/clothing/faction/hardliners/suits.dmi differ
diff --git a/icons/mob/clothing/faction/hardliners/uniforms.dmi b/icons/mob/clothing/faction/hardliners/uniforms.dmi
new file mode 100644
index 000000000000..8726f50b2f54
Binary files /dev/null and b/icons/mob/clothing/faction/hardliners/uniforms.dmi differ
diff --git a/icons/mob/clothing/faction/nanotrasen/back.dmi b/icons/mob/clothing/faction/nanotrasen/back.dmi
new file mode 100644
index 000000000000..37224655d088
Binary files /dev/null and b/icons/mob/clothing/faction/nanotrasen/back.dmi differ
diff --git a/icons/mob/clothing/faction/nanotrasen/belt.dmi b/icons/mob/clothing/faction/nanotrasen/belt.dmi
new file mode 100644
index 000000000000..17b681a959af
Binary files /dev/null and b/icons/mob/clothing/faction/nanotrasen/belt.dmi differ
diff --git a/icons/mob/clothing/faction/nanotrasen/feet.dmi b/icons/mob/clothing/faction/nanotrasen/feet.dmi
new file mode 100644
index 000000000000..71bb4a38f372
Binary files /dev/null and b/icons/mob/clothing/faction/nanotrasen/feet.dmi differ
diff --git a/icons/mob/clothing/faction/nanotrasen/hands.dmi b/icons/mob/clothing/faction/nanotrasen/hands.dmi
new file mode 100644
index 000000000000..37224655d088
Binary files /dev/null and b/icons/mob/clothing/faction/nanotrasen/hands.dmi differ
diff --git a/icons/mob/clothing/faction/nanotrasen/head.dmi b/icons/mob/clothing/faction/nanotrasen/head.dmi
new file mode 100644
index 000000000000..41aa213cec89
Binary files /dev/null and b/icons/mob/clothing/faction/nanotrasen/head.dmi differ
diff --git a/icons/mob/clothing/faction/nanotrasen/neck.dmi b/icons/mob/clothing/faction/nanotrasen/neck.dmi
new file mode 100644
index 000000000000..21a4c3992681
Binary files /dev/null and b/icons/mob/clothing/faction/nanotrasen/neck.dmi differ
diff --git a/icons/mob/clothing/faction/nanotrasen/suits.dmi b/icons/mob/clothing/faction/nanotrasen/suits.dmi
new file mode 100644
index 000000000000..279485b7e86e
Binary files /dev/null and b/icons/mob/clothing/faction/nanotrasen/suits.dmi differ
diff --git a/icons/mob/clothing/faction/nanotrasen/uniforms.dmi b/icons/mob/clothing/faction/nanotrasen/uniforms.dmi
new file mode 100644
index 000000000000..ddad36218b5f
Binary files /dev/null and b/icons/mob/clothing/faction/nanotrasen/uniforms.dmi differ
diff --git a/icons/mob/clothing/faction/ngr/belt.dmi b/icons/mob/clothing/faction/ngr/belt.dmi
new file mode 100644
index 000000000000..5ec3ffa92932
Binary files /dev/null and b/icons/mob/clothing/faction/ngr/belt.dmi differ
diff --git a/icons/mob/clothing/faction/ngr/eyes.dmi b/icons/mob/clothing/faction/ngr/eyes.dmi
new file mode 100644
index 000000000000..197e2d68c9cd
Binary files /dev/null and b/icons/mob/clothing/faction/ngr/eyes.dmi differ
diff --git a/icons/mob/clothing/faction/ngr/head.dmi b/icons/mob/clothing/faction/ngr/head.dmi
new file mode 100644
index 000000000000..c370f07aa0f3
Binary files /dev/null and b/icons/mob/clothing/faction/ngr/head.dmi differ
diff --git a/icons/mob/clothing/faction/ngr/mask.dmi b/icons/mob/clothing/faction/ngr/mask.dmi
new file mode 100644
index 000000000000..0baead0a39b1
Binary files /dev/null and b/icons/mob/clothing/faction/ngr/mask.dmi differ
diff --git a/icons/mob/clothing/faction/ngr/neck.dmi b/icons/mob/clothing/faction/ngr/neck.dmi
new file mode 100644
index 000000000000..9f8d3855b059
Binary files /dev/null and b/icons/mob/clothing/faction/ngr/neck.dmi differ
diff --git a/icons/mob/clothing/faction/ngr/suits.dmi b/icons/mob/clothing/faction/ngr/suits.dmi
new file mode 100644
index 000000000000..ac4fceb11cae
Binary files /dev/null and b/icons/mob/clothing/faction/ngr/suits.dmi differ
diff --git a/icons/mob/clothing/faction/ngr/uniforms.dmi b/icons/mob/clothing/faction/ngr/uniforms.dmi
new file mode 100644
index 000000000000..9eccbe4bfe54
Binary files /dev/null and b/icons/mob/clothing/faction/ngr/uniforms.dmi differ
diff --git a/icons/mob/clothing/faction/srm/head.dmi b/icons/mob/clothing/faction/srm/head.dmi
new file mode 100644
index 000000000000..186d021abeb3
Binary files /dev/null and b/icons/mob/clothing/faction/srm/head.dmi differ
diff --git a/icons/mob/clothing/faction/srm/suits.dmi b/icons/mob/clothing/faction/srm/suits.dmi
new file mode 100644
index 000000000000..801414dceec7
Binary files /dev/null and b/icons/mob/clothing/faction/srm/suits.dmi differ
diff --git a/icons/mob/clothing/faction/srm/uniforms.dmi b/icons/mob/clothing/faction/srm/uniforms.dmi
new file mode 100644
index 000000000000..b43a33a34e8d
Binary files /dev/null and b/icons/mob/clothing/faction/srm/uniforms.dmi differ
diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi
index 56c87efb4a9d..f207b2bfd826 100644
Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ
diff --git a/icons/mob/clothing/head/armor.dmi b/icons/mob/clothing/head/armor.dmi
new file mode 100644
index 000000000000..38adc74f3317
Binary files /dev/null and b/icons/mob/clothing/head/armor.dmi differ
diff --git a/icons/mob/clothing/head/spacesuits.dmi b/icons/mob/clothing/head/spacesuits.dmi
new file mode 100644
index 000000000000..55a7f69de51f
Binary files /dev/null and b/icons/mob/clothing/head/spacesuits.dmi differ
diff --git a/icons/mob/clothing/helmet_overlays.dmi b/icons/mob/clothing/helmet_overlays.dmi
new file mode 100644
index 000000000000..1c41c357a42a
Binary files /dev/null and b/icons/mob/clothing/helmet_overlays.dmi differ
diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi
index d705fb48c01f..bfcc9970930f 100644
Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ
diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi
index 9443ebfbc615..f168673850e0 100644
Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ
diff --git a/icons/mob/clothing/species/kepori.dmi b/icons/mob/clothing/species/kepori.dmi
index cfa1f108dc68..1586e80e9b19 100644
Binary files a/icons/mob/clothing/species/kepori.dmi and b/icons/mob/clothing/species/kepori.dmi differ
diff --git a/icons/mob/clothing/suits/armor.dmi b/icons/mob/clothing/suits/armor.dmi
index 5c13c3f615ea..4c37ff4d8bff 100644
Binary files a/icons/mob/clothing/suits/armor.dmi and b/icons/mob/clothing/suits/armor.dmi differ
diff --git a/icons/mob/clothing/suits/hooded.dmi b/icons/mob/clothing/suits/hooded.dmi
index a4be6f11f793..e1f98d991357 100644
Binary files a/icons/mob/clothing/suits/hooded.dmi and b/icons/mob/clothing/suits/hooded.dmi differ
diff --git a/icons/mob/clothing/suits/spacesuits.dmi b/icons/mob/clothing/suits/spacesuits.dmi
index 457f28fb8ad5..da5075195992 100644
Binary files a/icons/mob/clothing/suits/spacesuits.dmi and b/icons/mob/clothing/suits/spacesuits.dmi differ
diff --git a/icons/mob/clothing/suits/toggle.dmi b/icons/mob/clothing/suits/toggle.dmi
index 8ceffd1312c0..99fddcf51169 100644
Binary files a/icons/mob/clothing/suits/toggle.dmi and b/icons/mob/clothing/suits/toggle.dmi differ
diff --git a/icons/mob/clothing/under/command.dmi b/icons/mob/clothing/under/command.dmi
index 9e62d273cc3d..6ed86df85dab 100644
Binary files a/icons/mob/clothing/under/command.dmi and b/icons/mob/clothing/under/command.dmi differ
diff --git a/icons/mob/clothing/under/medical.dmi b/icons/mob/clothing/under/medical.dmi
index f33ff2da88f2..0032f9fc2ec8 100644
Binary files a/icons/mob/clothing/under/medical.dmi and b/icons/mob/clothing/under/medical.dmi differ
diff --git a/icons/mob/clothing/underwear/species/kepori/underwear_legs_kepori.dmi b/icons/mob/clothing/underwear/species/kepori/underwear_legs_kepori.dmi
new file mode 100644
index 000000000000..166e1a7624d9
Binary files /dev/null and b/icons/mob/clothing/underwear/species/kepori/underwear_legs_kepori.dmi differ
diff --git a/icons/mob/clothing/underwear/species/underwear_legs_kepori.dmi b/icons/mob/clothing/underwear/species/kepori/underwear_legs_keporiOLD.dmi
similarity index 100%
rename from icons/mob/clothing/underwear/species/underwear_legs_kepori.dmi
rename to icons/mob/clothing/underwear/species/kepori/underwear_legs_keporiOLD.dmi
diff --git a/icons/mob/clothing/underwear/species/kepori/underwear_socks_kepori.dmi b/icons/mob/clothing/underwear/species/kepori/underwear_socks_kepori.dmi
new file mode 100644
index 000000000000..6fe4e042f679
Binary files /dev/null and b/icons/mob/clothing/underwear/species/kepori/underwear_socks_kepori.dmi differ
diff --git a/icons/mob/clothing/underwear/species/underwear_socks_kepori.dmi b/icons/mob/clothing/underwear/species/kepori/underwear_socks_keporiOLD.dmi
similarity index 100%
rename from icons/mob/clothing/underwear/species/underwear_socks_kepori.dmi
rename to icons/mob/clothing/underwear/species/kepori/underwear_socks_keporiOLD.dmi
diff --git a/icons/mob/clothing/underwear/species/kepori/underwear_torso_kepori.dmi b/icons/mob/clothing/underwear/species/kepori/underwear_torso_kepori.dmi
new file mode 100644
index 000000000000..1a6a59cd5241
Binary files /dev/null and b/icons/mob/clothing/underwear/species/kepori/underwear_torso_kepori.dmi differ
diff --git a/icons/mob/clothing/underwear/species/underwear_torso_kepori.dmi b/icons/mob/clothing/underwear/species/kepori/underwear_torso_keporiOLD.dmi
similarity index 100%
rename from icons/mob/clothing/underwear/species/underwear_torso_kepori.dmi
rename to icons/mob/clothing/underwear/species/kepori/underwear_torso_keporiOLD.dmi
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 3926bce0f3b1..dced69dc5b6f 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/inhands/equipment/custodial_lefthand.dmi b/icons/mob/inhands/equipment/custodial_lefthand.dmi
index 2c9f34af2e1d..9d7b64b16d52 100644
Binary files a/icons/mob/inhands/equipment/custodial_lefthand.dmi and b/icons/mob/inhands/equipment/custodial_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/custodial_righthand.dmi b/icons/mob/inhands/equipment/custodial_righthand.dmi
index f166ba6076bd..cc411eb21963 100644
Binary files a/icons/mob/inhands/equipment/custodial_righthand.dmi and b/icons/mob/inhands/equipment/custodial_righthand.dmi differ
diff --git a/icons/mob/inhands/equipment/kitchen_lefthand.dmi b/icons/mob/inhands/equipment/kitchen_lefthand.dmi
index 428960e90086..d60c9bf8f476 100644
Binary files a/icons/mob/inhands/equipment/kitchen_lefthand.dmi and b/icons/mob/inhands/equipment/kitchen_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/kitchen_righthand.dmi b/icons/mob/inhands/equipment/kitchen_righthand.dmi
index f0c1682b68ed..b0a0f6c475bd 100644
Binary files a/icons/mob/inhands/equipment/kitchen_righthand.dmi and b/icons/mob/inhands/equipment/kitchen_righthand.dmi differ
diff --git a/icons/mob/inhands/equipment/tools_lefthand.dmi b/icons/mob/inhands/equipment/tools_lefthand.dmi
index 7d66b946aa1f..772b67e7449d 100644
Binary files a/icons/mob/inhands/equipment/tools_lefthand.dmi and b/icons/mob/inhands/equipment/tools_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/tools_righthand.dmi b/icons/mob/inhands/equipment/tools_righthand.dmi
index 1b5a50042923..f48c4df6895a 100644
Binary files a/icons/mob/inhands/equipment/tools_righthand.dmi and b/icons/mob/inhands/equipment/tools_righthand.dmi differ
diff --git a/icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi b/icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi
new file mode 100644
index 000000000000..1843cefb3898
Binary files /dev/null and b/icons/mob/inhands/faction/nanotrasen/nt_lefthand.dmi differ
diff --git a/icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi b/icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi
new file mode 100644
index 000000000000..25fa251955c1
Binary files /dev/null and b/icons/mob/inhands/faction/nanotrasen/nt_righthand.dmi differ
diff --git a/icons/mob/inhands/misc/food_lefthand.dmi b/icons/mob/inhands/misc/food_lefthand.dmi
index 740c63c4b370..63dee7bfea44 100644
Binary files a/icons/mob/inhands/misc/food_lefthand.dmi and b/icons/mob/inhands/misc/food_lefthand.dmi differ
diff --git a/icons/mob/inhands/misc/food_righthand.dmi b/icons/mob/inhands/misc/food_righthand.dmi
index 1e90ac3cb75a..bb1bd3f960fb 100644
Binary files a/icons/mob/inhands/misc/food_righthand.dmi and b/icons/mob/inhands/misc/food_righthand.dmi differ
diff --git a/icons/mob/inhands/misc/sheets_lefthand.dmi b/icons/mob/inhands/misc/sheets_lefthand.dmi
index 8a5431217705..4d7c351d35f9 100644
Binary files a/icons/mob/inhands/misc/sheets_lefthand.dmi and b/icons/mob/inhands/misc/sheets_lefthand.dmi differ
diff --git a/icons/mob/inhands/misc/sheets_righthand.dmi b/icons/mob/inhands/misc/sheets_righthand.dmi
index 24256299f2e8..c19a179e689b 100644
Binary files a/icons/mob/inhands/misc/sheets_righthand.dmi and b/icons/mob/inhands/misc/sheets_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/axes_lefthand.dmi b/icons/mob/inhands/weapons/axes_lefthand.dmi
index 810455a611bd..3b95d17cdc78 100644
Binary files a/icons/mob/inhands/weapons/axes_lefthand.dmi and b/icons/mob/inhands/weapons/axes_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi
index ef1b09fccc53..ff71ba99e3c0 100644
Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi
index 827bd71ad50e..c40ac3335e06 100644
Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/knifes_lefthand.dmi b/icons/mob/inhands/weapons/knifes_lefthand.dmi
new file mode 100644
index 000000000000..01f5fd3185c9
Binary files /dev/null and b/icons/mob/inhands/weapons/knifes_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/knifes_righthand.dmi b/icons/mob/inhands/weapons/knifes_righthand.dmi
new file mode 100644
index 000000000000..d9803bd40a6e
Binary files /dev/null and b/icons/mob/inhands/weapons/knifes_righthand.dmi differ
diff --git a/icons/mob/kepori_parts.dmi b/icons/mob/kepori_parts.dmi
deleted file mode 100644
index 8f9d7e56043e..000000000000
Binary files a/icons/mob/kepori_parts.dmi and /dev/null differ
diff --git a/icons/mob/mutant_bodyparts.dmi b/icons/mob/mutant_bodyparts.dmi
index a05f9c8dc678..1e271758e346 100644
Binary files a/icons/mob/mutant_bodyparts.dmi and b/icons/mob/mutant_bodyparts.dmi differ
diff --git a/icons/mob/simple_human.dmi b/icons/mob/simple_human.dmi
index 8cbc0f841bcb..133544acc999 100644
Binary files a/icons/mob/simple_human.dmi and b/icons/mob/simple_human.dmi differ
diff --git a/icons/mob/species/ethereal/bodyparts.dmi b/icons/mob/species/ethereal/bodyparts.dmi
index 09a6019b0364..ca5a5203eeca 100644
Binary files a/icons/mob/species/ethereal/bodyparts.dmi and b/icons/mob/species/ethereal/bodyparts.dmi differ
diff --git a/icons/mob/species/misc/cat.dmi b/icons/mob/species/human/cat.dmi
similarity index 100%
rename from icons/mob/species/misc/cat.dmi
rename to icons/mob/species/human/cat.dmi
diff --git a/icons/mob/species/human/dog.dmi b/icons/mob/species/human/dog.dmi
new file mode 100644
index 000000000000..3b3241059638
Binary files /dev/null and b/icons/mob/species/human/dog.dmi differ
diff --git a/icons/mob/species/human/elf.dmi b/icons/mob/species/human/elf.dmi
new file mode 100644
index 000000000000..7a37d6fd9580
Binary files /dev/null and b/icons/mob/species/human/elf.dmi differ
diff --git a/icons/mob/species/misc/fox.dmi b/icons/mob/species/human/fox.dmi
similarity index 100%
rename from icons/mob/species/misc/fox.dmi
rename to icons/mob/species/human/fox.dmi
diff --git a/icons/mob/species/human/rabbit.dmi b/icons/mob/species/human/rabbit.dmi
new file mode 100644
index 000000000000..fcc6599f7356
Binary files /dev/null and b/icons/mob/species/human/rabbit.dmi differ
diff --git a/icons/mob/species/kepori/bodyparts.dmi b/icons/mob/species/kepori/bodyparts.dmi
index f19aaeacbe08..058d315d7bd8 100644
Binary files a/icons/mob/species/kepori/bodyparts.dmi and b/icons/mob/species/kepori/bodyparts.dmi differ
diff --git a/icons/mob/species/kepori/kepori_eyes.dmi b/icons/mob/species/kepori/kepori_eyes.dmi
new file mode 100644
index 000000000000..3e1617315755
Binary files /dev/null and b/icons/mob/species/kepori/kepori_eyes.dmi differ
diff --git a/icons/mob/species/kepori/kepori_parts.dmi b/icons/mob/species/kepori/kepori_parts.dmi
new file mode 100644
index 000000000000..76d1819c9dd8
Binary files /dev/null and b/icons/mob/species/kepori/kepori_parts.dmi differ
diff --git a/icons/mob/species/kepori/onmob_belt_kepori.dmi b/icons/mob/species/kepori/onmob_belt_kepori.dmi
index cf74d73796c8..4a5a4ba7b32a 100644
Binary files a/icons/mob/species/kepori/onmob_belt_kepori.dmi and b/icons/mob/species/kepori/onmob_belt_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_belt_keporiOLD.dmi b/icons/mob/species/kepori/onmob_belt_keporiOLD.dmi
new file mode 100644
index 000000000000..cf74d73796c8
Binary files /dev/null and b/icons/mob/species/kepori/onmob_belt_keporiOLD.dmi differ
diff --git a/icons/mob/species/kepori/onmob_ears_kepori.dmi b/icons/mob/species/kepori/onmob_ears_kepori.dmi
new file mode 100644
index 000000000000..4a5a4ba7b32a
Binary files /dev/null and b/icons/mob/species/kepori/onmob_ears_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_eyes_kepori.dmi b/icons/mob/species/kepori/onmob_eyes_kepori.dmi
index 2cfe52f4630d..1b6c6f68a3a5 100644
Binary files a/icons/mob/species/kepori/onmob_eyes_kepori.dmi and b/icons/mob/species/kepori/onmob_eyes_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_eyes_keporiOLD.dmi b/icons/mob/species/kepori/onmob_eyes_keporiOLD.dmi
new file mode 100644
index 000000000000..2cfe52f4630d
Binary files /dev/null and b/icons/mob/species/kepori/onmob_eyes_keporiOLD.dmi differ
diff --git a/icons/mob/species/kepori/onmob_feet_kepori.dmi b/icons/mob/species/kepori/onmob_feet_kepori.dmi
index f352a422378a..93bb6ee443d5 100644
Binary files a/icons/mob/species/kepori/onmob_feet_kepori.dmi and b/icons/mob/species/kepori/onmob_feet_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_feet_keporiOLD.dmi b/icons/mob/species/kepori/onmob_feet_keporiOLD.dmi
new file mode 100644
index 000000000000..f352a422378a
Binary files /dev/null and b/icons/mob/species/kepori/onmob_feet_keporiOLD.dmi differ
diff --git a/icons/mob/species/kepori/onmob_hands_kepori.dmi b/icons/mob/species/kepori/onmob_hands_kepori.dmi
index 6dff1607ef57..1cd287411171 100644
Binary files a/icons/mob/species/kepori/onmob_hands_kepori.dmi and b/icons/mob/species/kepori/onmob_hands_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_hands_keporiOLD.dmi b/icons/mob/species/kepori/onmob_hands_keporiOLD.dmi
new file mode 100644
index 000000000000..6dff1607ef57
Binary files /dev/null and b/icons/mob/species/kepori/onmob_hands_keporiOLD.dmi differ
diff --git a/icons/mob/species/kepori/onmob_head_kepori.dmi b/icons/mob/species/kepori/onmob_head_kepori.dmi
index 4109e981c603..b4631838b75a 100644
Binary files a/icons/mob/species/kepori/onmob_head_kepori.dmi and b/icons/mob/species/kepori/onmob_head_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_head_keporiOLD.dmi b/icons/mob/species/kepori/onmob_head_keporiOLD.dmi
new file mode 100644
index 000000000000..31db76896ba2
Binary files /dev/null and b/icons/mob/species/kepori/onmob_head_keporiOLD.dmi differ
diff --git a/icons/mob/species/kepori/onmob_mask_kepori.dmi b/icons/mob/species/kepori/onmob_mask_kepori.dmi
index 610c62338c18..d455cf0bd3e5 100644
Binary files a/icons/mob/species/kepori/onmob_mask_kepori.dmi and b/icons/mob/species/kepori/onmob_mask_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_mask_keporiOLD.dmi b/icons/mob/species/kepori/onmob_mask_keporiOLD.dmi
new file mode 100644
index 000000000000..610c62338c18
Binary files /dev/null and b/icons/mob/species/kepori/onmob_mask_keporiOLD.dmi differ
diff --git a/icons/mob/species/kepori/onmob_suit_kepori.dmi b/icons/mob/species/kepori/onmob_suit_kepori.dmi
index 4d5eaaab1196..649853ea7280 100644
Binary files a/icons/mob/species/kepori/onmob_suit_kepori.dmi and b/icons/mob/species/kepori/onmob_suit_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_suit_keporiOLD.dmi b/icons/mob/species/kepori/onmob_suit_keporiOLD.dmi
new file mode 100644
index 000000000000..4d5eaaab1196
Binary files /dev/null and b/icons/mob/species/kepori/onmob_suit_keporiOLD.dmi differ
diff --git a/icons/mob/species/kepori/onmob_uniform_kepori.dmi b/icons/mob/species/kepori/onmob_uniform_kepori.dmi
index d9bec6e95185..d6f011cef312 100644
Binary files a/icons/mob/species/kepori/onmob_uniform_kepori.dmi and b/icons/mob/species/kepori/onmob_uniform_kepori.dmi differ
diff --git a/icons/mob/species/kepori/onmob_uniform_keporiOLD.dmi b/icons/mob/species/kepori/onmob_uniform_keporiOLD.dmi
new file mode 100644
index 000000000000..66fa497129f6
Binary files /dev/null and b/icons/mob/species/kepori/onmob_uniform_keporiOLD.dmi differ
diff --git a/icons/mob/species/lizard/bodyparts.dmi b/icons/mob/species/lizard/bodyparts.dmi
index 98f9e8d7411c..df7bbd5dc194 100644
Binary files a/icons/mob/species/lizard/bodyparts.dmi and b/icons/mob/species/lizard/bodyparts.dmi differ
diff --git a/icons/mob/species/misc/digitigrade.dmi b/icons/mob/species/misc/digitigrade.dmi
index 57d70696b850..8736b8057f14 100644
Binary files a/icons/mob/species/misc/digitigrade.dmi and b/icons/mob/species/misc/digitigrade.dmi differ
diff --git a/icons/mob/species/misc/digitigrade_shoes.dmi b/icons/mob/species/misc/digitigrade_shoes.dmi
index 9ad6cc1827ed..9d08980b1e58 100644
Binary files a/icons/mob/species/misc/digitigrade_shoes.dmi and b/icons/mob/species/misc/digitigrade_shoes.dmi differ
diff --git a/icons/mob/species/misc/digitigrade_suits.dmi b/icons/mob/species/misc/digitigrade_suits.dmi
index 31dd9ad9c8e6..8bdb115b0370 100644
Binary files a/icons/mob/species/misc/digitigrade_suits.dmi and b/icons/mob/species/misc/digitigrade_suits.dmi differ
diff --git a/icons/mob/species/vox/onmob_back_vox.dmi b/icons/mob/species/vox/onmob_back_vox.dmi
index d8b23da46543..953ff24a290e 100644
Binary files a/icons/mob/species/vox/onmob_back_vox.dmi and b/icons/mob/species/vox/onmob_back_vox.dmi differ
diff --git a/icons/mob/species/vox/onmob_eyes_vox.dmi b/icons/mob/species/vox/onmob_eyes_vox.dmi
index 2a30fe355bf1..947496cfb889 100644
Binary files a/icons/mob/species/vox/onmob_eyes_vox.dmi and b/icons/mob/species/vox/onmob_eyes_vox.dmi differ
diff --git a/icons/mob/species/vox/onmob_feet_vox.dmi b/icons/mob/species/vox/onmob_feet_vox.dmi
index fc17db0fc122..0b06074851aa 100644
Binary files a/icons/mob/species/vox/onmob_feet_vox.dmi and b/icons/mob/species/vox/onmob_feet_vox.dmi differ
diff --git a/icons/mob/species/vox/onmob_hands_vox.dmi b/icons/mob/species/vox/onmob_hands_vox.dmi
index e1527c62b702..977e9a71a7c5 100644
Binary files a/icons/mob/species/vox/onmob_hands_vox.dmi and b/icons/mob/species/vox/onmob_hands_vox.dmi differ
diff --git a/icons/mob/species/vox/onmob_head_vox.dmi b/icons/mob/species/vox/onmob_head_vox.dmi
index 0ab1c3be9674..c470ee12dbe4 100644
Binary files a/icons/mob/species/vox/onmob_head_vox.dmi and b/icons/mob/species/vox/onmob_head_vox.dmi differ
diff --git a/icons/mob/species/vox/onmob_mask_vox.dmi b/icons/mob/species/vox/onmob_mask_vox.dmi
index b460caedb721..7aa3dfb2e046 100644
Binary files a/icons/mob/species/vox/onmob_mask_vox.dmi and b/icons/mob/species/vox/onmob_mask_vox.dmi differ
diff --git a/icons/mob/species/vox/onmob_suit_vox.dmi b/icons/mob/species/vox/onmob_suit_vox.dmi
index 298f46032ab1..a7052320af9c 100644
Binary files a/icons/mob/species/vox/onmob_suit_vox.dmi and b/icons/mob/species/vox/onmob_suit_vox.dmi differ
diff --git a/icons/mob/ssd_indicator.dmi b/icons/mob/ssd_indicator.dmi
new file mode 100644
index 000000000000..3f7d100b6c67
Binary files /dev/null and b/icons/mob/ssd_indicator.dmi differ
diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi
index 8bbcb7817714..86001423aeba 100644
Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ
diff --git a/icons/obj/atmos.dmi b/icons/obj/atmos.dmi
index 94df693238d0..712adf5af17f 100644
Binary files a/icons/obj/atmos.dmi and b/icons/obj/atmos.dmi differ
diff --git a/icons/obj/atmospherics/components/binary_devices.dmi b/icons/obj/atmospherics/components/binary_devices.dmi
index 0a044c498faa..b666f391e793 100644
Binary files a/icons/obj/atmospherics/components/binary_devices.dmi and b/icons/obj/atmospherics/components/binary_devices.dmi differ
diff --git a/icons/obj/atmospherics/components/turbine.dmi b/icons/obj/atmospherics/components/turbine.dmi
new file mode 100644
index 000000000000..6e499911a75b
Binary files /dev/null and b/icons/obj/atmospherics/components/turbine.dmi differ
diff --git a/icons/obj/bedsheets.dmi b/icons/obj/bedsheets.dmi
index 56657861f576..c4cae890b54c 100644
Binary files a/icons/obj/bedsheets.dmi and b/icons/obj/bedsheets.dmi differ
diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi
index df05a9d601e3..17bab47dc9ef 100644
Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ
diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi
index 1607dc47db22..82d3a62d06bd 100644
Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ
diff --git a/icons/obj/chairs.dmi b/icons/obj/chairs.dmi
index 19b49a6d34da..47de0bdd1a43 100644
Binary files a/icons/obj/chairs.dmi and b/icons/obj/chairs.dmi differ
diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi
deleted file mode 100644
index 2dd57cfc6237..000000000000
Binary files a/icons/obj/chemical.dmi and /dev/null differ
diff --git a/icons/obj/chemical/beakers.dmi b/icons/obj/chemical/beakers.dmi
new file mode 100644
index 000000000000..db43d392960d
Binary files /dev/null and b/icons/obj/chemical/beakers.dmi differ
diff --git a/icons/obj/Chem_jug.dmi b/icons/obj/chemical/chem_jug.dmi
similarity index 100%
rename from icons/obj/Chem_jug.dmi
rename to icons/obj/chemical/chem_jug.dmi
diff --git a/icons/obj/chemical/chem_machines.dmi b/icons/obj/chemical/chem_machines.dmi
new file mode 100644
index 000000000000..09e41e9f6ac4
Binary files /dev/null and b/icons/obj/chemical/chem_machines.dmi differ
diff --git a/icons/obj/chemical/grenade.dmi b/icons/obj/chemical/grenade.dmi
new file mode 100644
index 000000000000..af748c687089
Binary files /dev/null and b/icons/obj/chemical/grenade.dmi differ
diff --git a/icons/obj/chemical/hypovial.dmi b/icons/obj/chemical/hypovial.dmi
new file mode 100644
index 000000000000..608af9f77bb3
Binary files /dev/null and b/icons/obj/chemical/hypovial.dmi differ
diff --git a/icons/obj/chemical/medicine.dmi b/icons/obj/chemical/medicine.dmi
new file mode 100644
index 000000000000..34b332d0178f
Binary files /dev/null and b/icons/obj/chemical/medicine.dmi differ
diff --git a/icons/obj/chemical/misc.dmi b/icons/obj/chemical/misc.dmi
new file mode 100644
index 000000000000..4afacabfe286
Binary files /dev/null and b/icons/obj/chemical/misc.dmi differ
diff --git a/icons/obj/chemical/mortar.dmi b/icons/obj/chemical/mortar.dmi
new file mode 100644
index 000000000000..e47543454f9d
Binary files /dev/null and b/icons/obj/chemical/mortar.dmi differ
diff --git a/icons/obj/closet.dmi b/icons/obj/closet.dmi
index 715fb82d988e..119b420f182a 100644
Binary files a/icons/obj/closet.dmi and b/icons/obj/closet.dmi differ
diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi
index e0818c6853df..ecf54fb9f61a 100644
Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ
diff --git a/icons/obj/clothing/cloaks.dmi b/icons/obj/clothing/cloaks.dmi
index 48f09da9a178..4e863875c47f 100644
Binary files a/icons/obj/clothing/cloaks.dmi and b/icons/obj/clothing/cloaks.dmi differ
diff --git a/icons/obj/clothing/faction/clip/head.dmi b/icons/obj/clothing/faction/clip/head.dmi
index 3982f324b9a2..06962106e6e7 100644
Binary files a/icons/obj/clothing/faction/clip/head.dmi and b/icons/obj/clothing/faction/clip/head.dmi differ
diff --git a/icons/obj/clothing/faction/clip/suits.dmi b/icons/obj/clothing/faction/clip/suits.dmi
index 16390028fee7..8dcc6fa72e9f 100644
Binary files a/icons/obj/clothing/faction/clip/suits.dmi and b/icons/obj/clothing/faction/clip/suits.dmi differ
diff --git a/icons/obj/clothing/faction/frontiersmen/belt.dmi b/icons/obj/clothing/faction/frontiersmen/belt.dmi
new file mode 100644
index 000000000000..01a020e47cfb
Binary files /dev/null and b/icons/obj/clothing/faction/frontiersmen/belt.dmi differ
diff --git a/icons/obj/clothing/faction/frontiersmen/head.dmi b/icons/obj/clothing/faction/frontiersmen/head.dmi
new file mode 100644
index 000000000000..f68169a5be65
Binary files /dev/null and b/icons/obj/clothing/faction/frontiersmen/head.dmi differ
diff --git a/icons/obj/clothing/faction/frontiersmen/mask.dmi b/icons/obj/clothing/faction/frontiersmen/mask.dmi
new file mode 100644
index 000000000000..961d27b0891f
Binary files /dev/null and b/icons/obj/clothing/faction/frontiersmen/mask.dmi differ
diff --git a/icons/obj/clothing/faction/frontiersmen/suits.dmi b/icons/obj/clothing/faction/frontiersmen/suits.dmi
new file mode 100644
index 000000000000..65c817191371
Binary files /dev/null and b/icons/obj/clothing/faction/frontiersmen/suits.dmi differ
diff --git a/icons/obj/clothing/faction/frontiersmen/uniforms.dmi b/icons/obj/clothing/faction/frontiersmen/uniforms.dmi
new file mode 100644
index 000000000000..7228ca93fc81
Binary files /dev/null and b/icons/obj/clothing/faction/frontiersmen/uniforms.dmi differ
diff --git a/icons/obj/clothing/faction/hardliners/belt.dmi b/icons/obj/clothing/faction/hardliners/belt.dmi
new file mode 100644
index 000000000000..e8925f9c5d36
Binary files /dev/null and b/icons/obj/clothing/faction/hardliners/belt.dmi differ
diff --git a/icons/obj/clothing/faction/hardliners/eyes.dmi b/icons/obj/clothing/faction/hardliners/eyes.dmi
new file mode 100644
index 000000000000..2e339c1b510a
Binary files /dev/null and b/icons/obj/clothing/faction/hardliners/eyes.dmi differ
diff --git a/icons/obj/clothing/faction/hardliners/head.dmi b/icons/obj/clothing/faction/hardliners/head.dmi
new file mode 100644
index 000000000000..5101eeedce9c
Binary files /dev/null and b/icons/obj/clothing/faction/hardliners/head.dmi differ
diff --git a/icons/obj/clothing/faction/hardliners/suits.dmi b/icons/obj/clothing/faction/hardliners/suits.dmi
new file mode 100644
index 000000000000..39da1c952739
Binary files /dev/null and b/icons/obj/clothing/faction/hardliners/suits.dmi differ
diff --git a/icons/obj/clothing/faction/hardliners/uniforms.dmi b/icons/obj/clothing/faction/hardliners/uniforms.dmi
new file mode 100644
index 000000000000..233eb500c826
Binary files /dev/null and b/icons/obj/clothing/faction/hardliners/uniforms.dmi differ
diff --git a/icons/obj/clothing/faction/nanotrasen/head.dmi b/icons/obj/clothing/faction/nanotrasen/head.dmi
new file mode 100644
index 000000000000..f1de235c57f5
Binary files /dev/null and b/icons/obj/clothing/faction/nanotrasen/head.dmi differ
diff --git a/icons/obj/clothing/faction/nanotrasen/neck.dmi b/icons/obj/clothing/faction/nanotrasen/neck.dmi
new file mode 100644
index 000000000000..ff9e1c4e77b7
Binary files /dev/null and b/icons/obj/clothing/faction/nanotrasen/neck.dmi differ
diff --git a/icons/obj/clothing/faction/nanotrasen/suits.dmi b/icons/obj/clothing/faction/nanotrasen/suits.dmi
new file mode 100644
index 000000000000..cc87542cf6c7
Binary files /dev/null and b/icons/obj/clothing/faction/nanotrasen/suits.dmi differ
diff --git a/icons/obj/clothing/faction/nanotrasen/uniforms.dmi b/icons/obj/clothing/faction/nanotrasen/uniforms.dmi
new file mode 100644
index 000000000000..fb4bd1b11c04
Binary files /dev/null and b/icons/obj/clothing/faction/nanotrasen/uniforms.dmi differ
diff --git a/icons/obj/clothing/faction/ngr/belt.dmi b/icons/obj/clothing/faction/ngr/belt.dmi
new file mode 100644
index 000000000000..d88e67d332ba
Binary files /dev/null and b/icons/obj/clothing/faction/ngr/belt.dmi differ
diff --git a/icons/obj/clothing/faction/ngr/eyes.dmi b/icons/obj/clothing/faction/ngr/eyes.dmi
new file mode 100644
index 000000000000..8359963e7212
Binary files /dev/null and b/icons/obj/clothing/faction/ngr/eyes.dmi differ
diff --git a/icons/obj/clothing/faction/ngr/head.dmi b/icons/obj/clothing/faction/ngr/head.dmi
new file mode 100644
index 000000000000..d2258c5565dd
Binary files /dev/null and b/icons/obj/clothing/faction/ngr/head.dmi differ
diff --git a/icons/obj/clothing/faction/ngr/mask.dmi b/icons/obj/clothing/faction/ngr/mask.dmi
new file mode 100644
index 000000000000..c867f6f569d7
Binary files /dev/null and b/icons/obj/clothing/faction/ngr/mask.dmi differ
diff --git a/icons/obj/clothing/faction/ngr/neck.dmi b/icons/obj/clothing/faction/ngr/neck.dmi
new file mode 100644
index 000000000000..3da79f8da04b
Binary files /dev/null and b/icons/obj/clothing/faction/ngr/neck.dmi differ
diff --git a/icons/obj/clothing/faction/ngr/suits.dmi b/icons/obj/clothing/faction/ngr/suits.dmi
new file mode 100644
index 000000000000..49344c553e03
Binary files /dev/null and b/icons/obj/clothing/faction/ngr/suits.dmi differ
diff --git a/icons/obj/clothing/faction/ngr/uniforms.dmi b/icons/obj/clothing/faction/ngr/uniforms.dmi
new file mode 100644
index 000000000000..e1b5e1faf5e8
Binary files /dev/null and b/icons/obj/clothing/faction/ngr/uniforms.dmi differ
diff --git a/icons/obj/clothing/faction/srm/head.dmi b/icons/obj/clothing/faction/srm/head.dmi
new file mode 100644
index 000000000000..8503fda7e3cf
Binary files /dev/null and b/icons/obj/clothing/faction/srm/head.dmi differ
diff --git a/icons/obj/clothing/faction/srm/suits.dmi b/icons/obj/clothing/faction/srm/suits.dmi
new file mode 100644
index 000000000000..031fb45e3ba6
Binary files /dev/null and b/icons/obj/clothing/faction/srm/suits.dmi differ
diff --git a/icons/obj/clothing/faction/srm/uniforms.dmi b/icons/obj/clothing/faction/srm/uniforms.dmi
new file mode 100644
index 000000000000..ec410e52e600
Binary files /dev/null and b/icons/obj/clothing/faction/srm/uniforms.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 4025f70990f6..402ce131a988 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/head/armor.dmi b/icons/obj/clothing/head/armor.dmi
new file mode 100644
index 000000000000..6757e591c853
Binary files /dev/null and b/icons/obj/clothing/head/armor.dmi differ
diff --git a/icons/obj/clothing/head/spacesuits.dmi b/icons/obj/clothing/head/spacesuits.dmi
new file mode 100644
index 000000000000..8befad3b380f
Binary files /dev/null and b/icons/obj/clothing/head/spacesuits.dmi differ
diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi
index 049da153701a..3109928ff7ae 100644
Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ
diff --git a/icons/obj/clothing/suits/armor.dmi b/icons/obj/clothing/suits/armor.dmi
index 9eaa67f04a42..232a2f6ec2bd 100644
Binary files a/icons/obj/clothing/suits/armor.dmi and b/icons/obj/clothing/suits/armor.dmi differ
diff --git a/icons/obj/clothing/suits/hooded.dmi b/icons/obj/clothing/suits/hooded.dmi
index 06d98acf2358..6d449550ad43 100644
Binary files a/icons/obj/clothing/suits/hooded.dmi and b/icons/obj/clothing/suits/hooded.dmi differ
diff --git a/icons/obj/clothing/suits/spacesuits.dmi b/icons/obj/clothing/suits/spacesuits.dmi
index fee16c76919d..2208c8b7cf98 100644
Binary files a/icons/obj/clothing/suits/spacesuits.dmi and b/icons/obj/clothing/suits/spacesuits.dmi differ
diff --git a/icons/obj/clothing/suits/toggle.dmi b/icons/obj/clothing/suits/toggle.dmi
index 54df84ad5def..75a2f1a891b3 100644
Binary files a/icons/obj/clothing/suits/toggle.dmi and b/icons/obj/clothing/suits/toggle.dmi differ
diff --git a/icons/obj/clothing/under/medical.dmi b/icons/obj/clothing/under/medical.dmi
index 8c3c6917319f..dce9b20106f3 100644
Binary files a/icons/obj/clothing/under/medical.dmi and b/icons/obj/clothing/under/medical.dmi differ
diff --git a/icons/obj/contraband.dmi b/icons/obj/contraband.dmi
index b34b3777adac..20fe8abf2d5c 100644
Binary files a/icons/obj/contraband.dmi and b/icons/obj/contraband.dmi differ
diff --git a/icons/obj/deskflags.dmi b/icons/obj/deskflags.dmi
index cf1eaacf5bb3..6a950bcebc4e 100644
Binary files a/icons/obj/deskflags.dmi and b/icons/obj/deskflags.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 360e4cd0f3e4..d7a44b667a0c 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/drinks/drinks.dmi b/icons/obj/drinks/drinks.dmi
index 03fdf63dd00b..2ab3cd0db5ef 100644
Binary files a/icons/obj/drinks/drinks.dmi and b/icons/obj/drinks/drinks.dmi differ
diff --git a/icons/obj/dyespray.dmi b/icons/obj/dyespray.dmi
index eb056036799a..1d1813f38c50 100644
Binary files a/icons/obj/dyespray.dmi and b/icons/obj/dyespray.dmi differ
diff --git a/icons/obj/economy.dmi b/icons/obj/economy.dmi
index 5d82ef881973..cffb7c94b6e5 100644
Binary files a/icons/obj/economy.dmi and b/icons/obj/economy.dmi differ
diff --git a/icons/obj/flora/snowflora.dmi b/icons/obj/flora/snowflora.dmi
index 002fd90c9fcd..74a1f6dabaf0 100644
Binary files a/icons/obj/flora/snowflora.dmi and b/icons/obj/flora/snowflora.dmi differ
diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi
index 118ce7693637..a200515c324f 100644
Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ
diff --git a/icons/obj/guncase.dmi b/icons/obj/guncase.dmi
new file mode 100644
index 000000000000..4941b965f2f8
Binary files /dev/null and b/icons/obj/guncase.dmi differ
diff --git a/icons/obj/guncase_48x32.dmi b/icons/obj/guncase_48x32.dmi
new file mode 100644
index 000000000000..b5dc20bc64e5
Binary files /dev/null and b/icons/obj/guncase_48x32.dmi differ
diff --git a/icons/obj/guns/48x32guns.dmi b/icons/obj/guns/48x32guns.dmi
index 232ecdb35e02..960b9ec448af 100644
Binary files a/icons/obj/guns/48x32guns.dmi and b/icons/obj/guns/48x32guns.dmi differ
diff --git a/icons/obj/guns/attachments.dmi b/icons/obj/guns/attachments.dmi
new file mode 100644
index 000000000000..29ae084d5759
Binary files /dev/null and b/icons/obj/guns/attachments.dmi differ
diff --git a/icons/obj/guns/bayonets.dmi b/icons/obj/guns/bayonets.dmi
deleted file mode 100644
index 32b5448b8edc..000000000000
Binary files a/icons/obj/guns/bayonets.dmi and /dev/null differ
diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi
index 3208083cd0bd..6a32de5b08fb 100644
Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ
diff --git a/icons/obj/guns/faction/gezena/48x32.dmi b/icons/obj/guns/faction/gezena/48x32.dmi
deleted file mode 100644
index 29c89ec1edb1..000000000000
Binary files a/icons/obj/guns/faction/gezena/48x32.dmi and /dev/null differ
diff --git a/icons/obj/guns/faction/gezena/energy.dmi b/icons/obj/guns/faction/gezena/energy.dmi
deleted file mode 100644
index be3b5b2f71d6..000000000000
Binary files a/icons/obj/guns/faction/gezena/energy.dmi and /dev/null differ
diff --git a/icons/obj/guns/flashlights.dmi b/icons/obj/guns/flashlights.dmi
deleted file mode 100644
index eef6d953f94a..000000000000
Binary files a/icons/obj/guns/flashlights.dmi and /dev/null differ
diff --git a/icons/obj/guns/manufacturer/clip_lanchester/48x32.dmi b/icons/obj/guns/manufacturer/clip_lanchester/48x32.dmi
new file mode 100644
index 000000000000..d87a6f3c8433
Binary files /dev/null and b/icons/obj/guns/manufacturer/clip_lanchester/48x32.dmi differ
diff --git a/icons/obj/guns/manufacturer/clip_lanchester/lefthand.dmi b/icons/obj/guns/manufacturer/clip_lanchester/lefthand.dmi
new file mode 100644
index 000000000000..7673c2f6d642
Binary files /dev/null and b/icons/obj/guns/manufacturer/clip_lanchester/lefthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/clip_lanchester/onmob.dmi b/icons/obj/guns/manufacturer/clip_lanchester/onmob.dmi
new file mode 100644
index 000000000000..4f9158d2d36d
Binary files /dev/null and b/icons/obj/guns/manufacturer/clip_lanchester/onmob.dmi differ
diff --git a/icons/obj/guns/manufacturer/clip_lanchester/righthand.dmi b/icons/obj/guns/manufacturer/clip_lanchester/righthand.dmi
new file mode 100644
index 000000000000..4549f30f4ff9
Binary files /dev/null and b/icons/obj/guns/manufacturer/clip_lanchester/righthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/eoehoma/48x32.dmi b/icons/obj/guns/manufacturer/eoehoma/48x32.dmi
new file mode 100644
index 000000000000..5ab3ee4a0cb0
Binary files /dev/null and b/icons/obj/guns/manufacturer/eoehoma/48x32.dmi differ
diff --git a/icons/obj/guns/manufacturer/eoehoma/lefthand.dmi b/icons/obj/guns/manufacturer/eoehoma/lefthand.dmi
new file mode 100644
index 000000000000..9fd5086f4003
Binary files /dev/null and b/icons/obj/guns/manufacturer/eoehoma/lefthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/eoehoma/onmob.dmi b/icons/obj/guns/manufacturer/eoehoma/onmob.dmi
new file mode 100644
index 000000000000..f4b14ced71a7
Binary files /dev/null and b/icons/obj/guns/manufacturer/eoehoma/onmob.dmi differ
diff --git a/icons/obj/guns/manufacturer/eoehoma/righthand.dmi b/icons/obj/guns/manufacturer/eoehoma/righthand.dmi
new file mode 100644
index 000000000000..c1f9ccab3ff0
Binary files /dev/null and b/icons/obj/guns/manufacturer/eoehoma/righthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/etherbor/48x32.dmi b/icons/obj/guns/manufacturer/etherbor/48x32.dmi
new file mode 100644
index 000000000000..e5a9074f06c2
Binary files /dev/null and b/icons/obj/guns/manufacturer/etherbor/48x32.dmi differ
diff --git a/icons/obj/guns/faction/gezena/lefthand.dmi b/icons/obj/guns/manufacturer/etherbor/lefthand.dmi
similarity index 100%
rename from icons/obj/guns/faction/gezena/lefthand.dmi
rename to icons/obj/guns/manufacturer/etherbor/lefthand.dmi
diff --git a/icons/obj/guns/manufacturer/etherbor/onmob.dmi b/icons/obj/guns/manufacturer/etherbor/onmob.dmi
new file mode 100644
index 000000000000..43e539c557b8
Binary files /dev/null and b/icons/obj/guns/manufacturer/etherbor/onmob.dmi differ
diff --git a/icons/obj/guns/faction/gezena/righthand.dmi b/icons/obj/guns/manufacturer/etherbor/righthand.dmi
similarity index 100%
rename from icons/obj/guns/faction/gezena/righthand.dmi
rename to icons/obj/guns/manufacturer/etherbor/righthand.dmi
diff --git a/icons/obj/guns/manufacturer/frontier_import/48x32.dmi b/icons/obj/guns/manufacturer/frontier_import/48x32.dmi
new file mode 100644
index 000000000000..149793c43c38
Binary files /dev/null and b/icons/obj/guns/manufacturer/frontier_import/48x32.dmi differ
diff --git a/icons/obj/guns/manufacturer/frontier_import/lefthand.dmi b/icons/obj/guns/manufacturer/frontier_import/lefthand.dmi
new file mode 100644
index 000000000000..33b3381bdfe0
Binary files /dev/null and b/icons/obj/guns/manufacturer/frontier_import/lefthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/frontier_import/onmob.dmi b/icons/obj/guns/manufacturer/frontier_import/onmob.dmi
new file mode 100644
index 000000000000..a0706579ccb5
Binary files /dev/null and b/icons/obj/guns/manufacturer/frontier_import/onmob.dmi differ
diff --git a/icons/obj/guns/manufacturer/frontier_import/righthand.dmi b/icons/obj/guns/manufacturer/frontier_import/righthand.dmi
new file mode 100644
index 000000000000..73945b8524df
Binary files /dev/null and b/icons/obj/guns/manufacturer/frontier_import/righthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/hunterspride/48x32.dmi b/icons/obj/guns/manufacturer/hunterspride/48x32.dmi
new file mode 100644
index 000000000000..19b4202da78a
Binary files /dev/null and b/icons/obj/guns/manufacturer/hunterspride/48x32.dmi differ
diff --git a/icons/obj/guns/manufacturer/hunterspride/lefthand.dmi b/icons/obj/guns/manufacturer/hunterspride/lefthand.dmi
new file mode 100644
index 000000000000..4fb5eca5c011
Binary files /dev/null and b/icons/obj/guns/manufacturer/hunterspride/lefthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/hunterspride/onmob.dmi b/icons/obj/guns/manufacturer/hunterspride/onmob.dmi
new file mode 100644
index 000000000000..8911c8fbb68f
Binary files /dev/null and b/icons/obj/guns/manufacturer/hunterspride/onmob.dmi differ
diff --git a/icons/obj/guns/manufacturer/hunterspride/righthand.dmi b/icons/obj/guns/manufacturer/hunterspride/righthand.dmi
new file mode 100644
index 000000000000..043167735662
Binary files /dev/null and b/icons/obj/guns/manufacturer/hunterspride/righthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/inteq/48x32.dmi b/icons/obj/guns/manufacturer/inteq/48x32.dmi
new file mode 100644
index 000000000000..e7deb0f12ce0
Binary files /dev/null and b/icons/obj/guns/manufacturer/inteq/48x32.dmi differ
diff --git a/icons/obj/guns/manufacturer/inteq/lefthand.dmi b/icons/obj/guns/manufacturer/inteq/lefthand.dmi
new file mode 100644
index 000000000000..19335eb44ff9
Binary files /dev/null and b/icons/obj/guns/manufacturer/inteq/lefthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/inteq/onmob.dmi b/icons/obj/guns/manufacturer/inteq/onmob.dmi
new file mode 100644
index 000000000000..f402ffd24e2c
Binary files /dev/null and b/icons/obj/guns/manufacturer/inteq/onmob.dmi differ
diff --git a/icons/obj/guns/manufacturer/inteq/righthand.dmi b/icons/obj/guns/manufacturer/inteq/righthand.dmi
new file mode 100644
index 000000000000..33d087f394f1
Binary files /dev/null and b/icons/obj/guns/manufacturer/inteq/righthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi b/icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi
new file mode 100644
index 000000000000..bac0ccc8f210
Binary files /dev/null and b/icons/obj/guns/manufacturer/nanotrasen_sharplite/48x32.dmi differ
diff --git a/icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi b/icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi
new file mode 100644
index 000000000000..24ac86c3e0b5
Binary files /dev/null and b/icons/obj/guns/manufacturer/nanotrasen_sharplite/lefthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi b/icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi
new file mode 100644
index 000000000000..8a1d7f06e561
Binary files /dev/null and b/icons/obj/guns/manufacturer/nanotrasen_sharplite/onmob.dmi differ
diff --git a/icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi b/icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi
new file mode 100644
index 000000000000..b6831ec9696a
Binary files /dev/null and b/icons/obj/guns/manufacturer/nanotrasen_sharplite/righthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/scarborough/48x32.dmi b/icons/obj/guns/manufacturer/scarborough/48x32.dmi
new file mode 100644
index 000000000000..361448b49a35
Binary files /dev/null and b/icons/obj/guns/manufacturer/scarborough/48x32.dmi differ
diff --git a/icons/obj/guns/manufacturer/scarborough/lefthand.dmi b/icons/obj/guns/manufacturer/scarborough/lefthand.dmi
new file mode 100644
index 000000000000..8d184d907db6
Binary files /dev/null and b/icons/obj/guns/manufacturer/scarborough/lefthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/scarborough/onmob.dmi b/icons/obj/guns/manufacturer/scarborough/onmob.dmi
new file mode 100644
index 000000000000..5127ecfed566
Binary files /dev/null and b/icons/obj/guns/manufacturer/scarborough/onmob.dmi differ
diff --git a/icons/obj/guns/manufacturer/scarborough/righthand.dmi b/icons/obj/guns/manufacturer/scarborough/righthand.dmi
new file mode 100644
index 000000000000..5dbfb0acfc25
Binary files /dev/null and b/icons/obj/guns/manufacturer/scarborough/righthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/solararmories/48x32.dmi b/icons/obj/guns/manufacturer/solararmories/48x32.dmi
new file mode 100644
index 000000000000..690fc5b54bdf
Binary files /dev/null and b/icons/obj/guns/manufacturer/solararmories/48x32.dmi differ
diff --git a/icons/obj/guns/manufacturer/solararmories/lefthand.dmi b/icons/obj/guns/manufacturer/solararmories/lefthand.dmi
new file mode 100644
index 000000000000..b28e97e9a1db
Binary files /dev/null and b/icons/obj/guns/manufacturer/solararmories/lefthand.dmi differ
diff --git a/icons/obj/guns/manufacturer/solararmories/onmob.dmi b/icons/obj/guns/manufacturer/solararmories/onmob.dmi
new file mode 100644
index 000000000000..3e5b665f4fb0
Binary files /dev/null and b/icons/obj/guns/manufacturer/solararmories/onmob.dmi differ
diff --git a/icons/obj/guns/manufacturer/solararmories/righthand.dmi b/icons/obj/guns/manufacturer/solararmories/righthand.dmi
new file mode 100644
index 000000000000..ab82dd742a66
Binary files /dev/null and b/icons/obj/guns/manufacturer/solararmories/righthand.dmi differ
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index 690ed5d86d2f..ab051d8a21bb 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ
diff --git a/icons/obj/implants/implant.dmi b/icons/obj/implants/implant.dmi
new file mode 100644
index 000000000000..31bd68db0caf
Binary files /dev/null and b/icons/obj/implants/implant.dmi differ
diff --git a/icons/obj/item/knife.dmi b/icons/obj/item/knife.dmi
new file mode 100644
index 000000000000..2e95a9154512
Binary files /dev/null and b/icons/obj/item/knife.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index 12798b6eb2ac..a0ceaebd8383 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/icons/obj/janitor.dmi b/icons/obj/janitor.dmi
index e084df73a37a..f3b4d79436ef 100644
Binary files a/icons/obj/janitor.dmi and b/icons/obj/janitor.dmi differ
diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi
index a0bbca6bff9e..5818b7a55d81 100644
Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ
diff --git a/icons/obj/landmine.dmi b/icons/obj/landmine.dmi
new file mode 100644
index 000000000000..dd19fd9d3991
Binary files /dev/null and b/icons/obj/landmine.dmi differ
diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi
index 40e1dfbabdd3..7c31b8ac45f9 100644
Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ
diff --git a/icons/obj/machines/borgcharger.dmi b/icons/obj/machines/borgcharger.dmi
new file mode 100644
index 000000000000..c60f999ea06e
Binary files /dev/null and b/icons/obj/machines/borgcharger.dmi differ
diff --git a/icons/obj/machines/coffeemaker.dmi b/icons/obj/machines/coffeemaker.dmi
deleted file mode 100644
index 246159f1c54f..000000000000
Binary files a/icons/obj/machines/coffeemaker.dmi and /dev/null differ
diff --git a/icons/obj/machines/computer.dmi b/icons/obj/machines/computer.dmi
index 2a513215ed20..3b50ef08e89a 100644
Binary files a/icons/obj/machines/computer.dmi and b/icons/obj/machines/computer.dmi differ
diff --git a/icons/obj/machines/ship_gravity.dmi b/icons/obj/machines/ship_gravity.dmi
new file mode 100644
index 000000000000..276fcf2b6720
Binary files /dev/null and b/icons/obj/machines/ship_gravity.dmi differ
diff --git a/icons/obj/machines/suit_storage.dmi b/icons/obj/machines/suit_storage.dmi
index cf0edd2e8fdc..a40d04f500c6 100644
Binary files a/icons/obj/machines/suit_storage.dmi and b/icons/obj/machines/suit_storage.dmi differ
diff --git a/icons/obj/nanotrasen_floor.dmi b/icons/obj/nanotrasen_floor.dmi
new file mode 100644
index 000000000000..1e7dc7821a6f
Binary files /dev/null and b/icons/obj/nanotrasen_floor.dmi differ
diff --git a/icons/obj/nanotrasen_logos.dmi b/icons/obj/nanotrasen_logos.dmi
new file mode 100644
index 000000000000..27d1bd6194fb
Binary files /dev/null and b/icons/obj/nanotrasen_logos.dmi differ
diff --git a/icons/obj/nutanks.dmi b/icons/obj/nutanks.dmi
index c325dadf1c32..4365bdb86771 100644
Binary files a/icons/obj/nutanks.dmi and b/icons/obj/nutanks.dmi differ
diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi
index e7cd9797591b..1b156b9294f9 100644
Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ
diff --git a/icons/obj/ores.dmi b/icons/obj/ores.dmi
index f3451a8432dd..6ea0ed496e8f 100644
Binary files a/icons/obj/ores.dmi and b/icons/obj/ores.dmi differ
diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi
index f76e5611c93d..5d23996fb663 100644
Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ
diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi
index ea47f805dee9..a6199b8723ef 100644
Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ
diff --git a/icons/obj/stack_objects.dmi b/icons/obj/stack_objects.dmi
index 0989e1834f70..80350d2bfaa3 100644
Binary files a/icons/obj/stack_objects.dmi and b/icons/obj/stack_objects.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 90354fdf41db..df2add959648 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/icons/obj/structures/chairs/comfychair.dmi b/icons/obj/structures/chairs/comfychair.dmi
new file mode 100644
index 000000000000..8b759be5f0f1
Binary files /dev/null and b/icons/obj/structures/chairs/comfychair.dmi differ
diff --git a/icons/obj/structures/chairs/sofa.dmi b/icons/obj/structures/chairs/sofa.dmi
new file mode 100644
index 000000000000..17c976e4650e
Binary files /dev/null and b/icons/obj/structures/chairs/sofa.dmi differ
diff --git a/icons/obj/structures/handrail.dmi b/icons/obj/structures/handrail.dmi
new file mode 100644
index 000000000000..1a8d98d6697d
Binary files /dev/null and b/icons/obj/structures/handrail.dmi differ
diff --git a/icons/obj/structures/signs/sign.dmi b/icons/obj/structures/signs/sign.dmi
index e5ff1a7cf19e..f123c03a76e6 100644
Binary files a/icons/obj/structures/signs/sign.dmi and b/icons/obj/structures/signs/sign.dmi differ
diff --git a/icons/obj/structures/signs/wallflags.dmi b/icons/obj/structures/signs/wallflags.dmi
index 4b4696ad9623..837e442f27ca 100644
Binary files a/icons/obj/structures/signs/wallflags.dmi and b/icons/obj/structures/signs/wallflags.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index d94097ddf2e5..8f2566a98f8a 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/icons/obj/tiles.dmi b/icons/obj/tiles.dmi
index 5e072b68f42d..898805a0fa13 100644
Binary files a/icons/obj/tiles.dmi and b/icons/obj/tiles.dmi differ
diff --git a/icons/obj/wallcloset.dmi b/icons/obj/wallcloset.dmi
index 6d41f0ecee85..f2314d0d84c2 100644
Binary files a/icons/obj/wallcloset.dmi and b/icons/obj/wallcloset.dmi differ
diff --git a/icons/obj/watercloset.dmi b/icons/obj/watercloset.dmi
index 4fefb4a22bfc..a9f32f001798 100644
Binary files a/icons/obj/watercloset.dmi and b/icons/obj/watercloset.dmi differ
diff --git a/icons/obj/world/melee.dmi b/icons/obj/world/melee.dmi
new file mode 100644
index 000000000000..ff8e2114e827
Binary files /dev/null and b/icons/obj/world/melee.dmi differ
diff --git a/icons/turf/decals.dmi b/icons/turf/decals/decals.dmi
similarity index 57%
rename from icons/turf/decals.dmi
rename to icons/turf/decals/decals.dmi
index 9fb84aa888c2..a62024cc8e0e 100644
Binary files a/icons/turf/decals.dmi and b/icons/turf/decals/decals.dmi differ
diff --git a/icons/turf/decals/suns_floor.dmi b/icons/turf/decals/suns_floor.dmi
new file mode 100644
index 000000000000..ffebe3036722
Binary files /dev/null and b/icons/turf/decals/suns_floor.dmi differ
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index 5136279026c1..398d5550f810 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ
diff --git a/icons/turf/floors/suns.dmi b/icons/turf/floors/suns.dmi
new file mode 100644
index 000000000000..aa0df610ec55
Binary files /dev/null and b/icons/turf/floors/suns.dmi differ
diff --git a/icons/turf/walls/bananium_wall.dmi b/icons/turf/walls/bananium_wall.dmi
deleted file mode 100644
index 48a58fe20619..000000000000
Binary files a/icons/turf/walls/bananium_wall.dmi and /dev/null differ
diff --git a/icons/turf/walls/concrete.dmi b/icons/turf/walls/concrete.dmi
index a201e7ab6375..da6a6e45a4ce 100644
Binary files a/icons/turf/walls/concrete.dmi and b/icons/turf/walls/concrete.dmi differ
diff --git a/icons/turf/walls/hexacrete.dmi b/icons/turf/walls/hexacrete.dmi
index 6866ac7f536f..f120455f46ad 100644
Binary files a/icons/turf/walls/hexacrete.dmi and b/icons/turf/walls/hexacrete.dmi differ
diff --git a/interface/skin.dmf b/interface/skin.dmf
index 9d933e057c46..18122c5e3e89 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -90,6 +90,15 @@ window "mainwindow"
background-color = #272727
is-visible = false
saved-params = ""
+ elem "commandbar_spy"
+ type = BROWSER
+ is-default = false
+ pos = 0,0
+ size = 200x200
+ anchor1 = -1,-1
+ anchor2 = -1,-1
+ is-visible = false
+ saved-params = ""
window "mapwindow"
elem "mapwindow"
diff --git a/shiptest.dme b/shiptest.dme
index 41bc340bb144..c0d9a7d4df66 100644
--- a/shiptest.dme
+++ b/shiptest.dme
@@ -52,6 +52,7 @@
#include "code\__DEFINES\directional.dm"
#include "code\__DEFINES\diseases.dm"
#include "code\__DEFINES\DNA.dm"
+#include "code\__DEFINES\do_afters.dm"
#include "code\__DEFINES\dye_keys.dm"
#include "code\__DEFINES\economy.dm"
#include "code\__DEFINES\events.dm"
@@ -65,6 +66,7 @@
#include "code\__DEFINES\food.dm"
#include "code\__DEFINES\footsteps.dm"
#include "code\__DEFINES\forensics.dm"
+#include "code\__DEFINES\guns.dm"
#include "code\__DEFINES\hud.dm"
#include "code\__DEFINES\icon_smoothing.dm"
#include "code\__DEFINES\important_recursive_contents.dm"
@@ -135,11 +137,13 @@
#include "code\__DEFINES\statpanel.dm"
#include "code\__DEFINES\status_effects.dm"
#include "code\__DEFINES\stock_parts.dm"
+#include "code\__DEFINES\storage.dm"
#include "code\__DEFINES\subsystems.dm"
#include "code\__DEFINES\tgs.config.dm"
#include "code\__DEFINES\tgs.dm"
#include "code\__DEFINES\tgui.dm"
#include "code\__DEFINES\time.dm"
+#include "code\__DEFINES\timed_action.dm"
#include "code\__DEFINES\tools.dm"
#include "code\__DEFINES\traits.dm"
#include "code\__DEFINES\turfs.dm"
@@ -280,6 +284,7 @@
#include "code\_onclick\hud\robot.dm"
#include "code\_onclick\hud\screen_objects.dm"
#include "code\_onclick\hud\screentip.dm"
+#include "code\_onclick\hud\storage.dm"
#include "code\_onclick\hud\swarmer.dm"
#include "code\controllers\admin.dm"
#include "code\controllers\controller.dm"
@@ -374,6 +379,7 @@
#include "code\controllers\subsystem\processing\fastprocess.dm"
#include "code\controllers\subsystem\processing\fluids.dm"
#include "code\controllers\subsystem\processing\instruments.dm"
+#include "code\controllers\subsystem\processing\movable_physics.dm"
#include "code\controllers\subsystem\processing\nanites.dm"
#include "code\controllers\subsystem\processing\networks.dm"
#include "code\controllers\subsystem\processing\obj.dm"
@@ -393,6 +399,7 @@
#include "code\datums\changelog.dm"
#include "code\datums\chatmessage.dm"
#include "code\datums\cinematic.dm"
+#include "code\datums\cogbar.dm"
#include "code\datums\dash_weapon.dm"
#include "code\datums\datacore.dm"
#include "code\datums\datum.dm"
@@ -403,6 +410,7 @@
#include "code\datums\emotes.dm"
#include "code\datums\ert.dm"
#include "code\datums\forced_movement.dm"
+#include "code\datums\guestbook.dm"
#include "code\datums\holocall.dm"
#include "code\datums\http.dm"
#include "code\datums\hud.dm"
@@ -452,6 +460,9 @@
#include "code\datums\components\anti_magic.dm"
#include "code\datums\components\armor_plate.dm"
#include "code\datums\components\art.dm"
+#include "code\datums\components\attachment.dm"
+#include "code\datums\components\attachment_holder.dm"
+#include "code\datums\components\bandage.dm"
#include "code\datums\components\bane.dm"
#include "code\datums\components\beetlejuice.dm"
#include "code\datums\components\bloodysoles.dm"
@@ -497,6 +508,7 @@
#include "code\datums\components\material_container.dm"
#include "code\datums\components\mirv.dm"
#include "code\datums\components\mood.dm"
+#include "code\datums\components\movable_physics.dm"
#include "code\datums\components\nanites.dm"
#include "code\datums\components\ntnet_interface.dm"
#include "code\datums\components\orbiter.dm"
@@ -516,7 +528,6 @@
#include "code\datums\components\sizzle.dm"
#include "code\datums\components\slippery.dm"
#include "code\datums\components\soulstoned.dm"
-#include "code\datums\components\spawner.dm"
#include "code\datums\components\spill.dm"
#include "code\datums\components\spooky.dm"
#include "code\datums\components\squeak.dm"
@@ -537,7 +548,12 @@
#include "code\datums\components\crafting\crafting.dm"
#include "code\datums\components\crafting\guncrafting.dm"
#include "code\datums\components\crafting\recipes.dm"
-#include "code\datums\components\crafting\tailoring.dm"
+#include "code\datums\components\crafting\recipes\clothing.dm"
+#include "code\datums\components\crafting\recipes\drink.dm"
+#include "code\datums\components\crafting\recipes\misc.dm"
+#include "code\datums\components\crafting\recipes\robot.dm"
+#include "code\datums\components\crafting\recipes\tribal.dm"
+#include "code\datums\components\crafting\recipes\weapon.dm"
#include "code\datums\components\fantasy\_fantasy.dm"
#include "code\datums\components\fantasy\affix.dm"
#include "code\datums\components\fantasy\prefixes.dm"
@@ -548,6 +564,7 @@
#include "code\datums\components\plumbing\reaction_chamber.dm"
#include "code\datums\components\plumbing\splitter.dm"
#include "code\datums\components\storage\storage.dm"
+#include "code\datums\components\storage\ui.dm"
#include "code\datums\components\storage\concrete\_concrete.dm"
#include "code\datums\components\storage\concrete\bag_of_holding.dm"
#include "code\datums\components\storage\concrete\bluespace.dm"
@@ -602,7 +619,6 @@
#include "code\datums\diseases\advance\symptoms\itching.dm"
#include "code\datums\diseases\advance\symptoms\nanites.dm"
#include "code\datums\diseases\advance\symptoms\narcolepsy.dm"
-#include "code\datums\diseases\advance\symptoms\necropolis.dm"
#include "code\datums\diseases\advance\symptoms\oxygen.dm"
#include "code\datums\diseases\advance\symptoms\sensory.dm"
#include "code\datums\diseases\advance\symptoms\shedding.dm"
@@ -642,6 +658,7 @@
#include "code\datums\elements\update_icon_blocker.dm"
#include "code\datums\elements\update_icon_updates_onmob.dm"
#include "code\datums\elements\waddling.dm"
+#include "code\datums\elements\world_icon.dm"
#include "code\datums\elements\decals\_decals.dm"
#include "code\datums\elements\decals\blood.dm"
#include "code\datums\helper_datums\events.dm"
@@ -772,6 +789,7 @@
#include "code\datums\wires\explosive.dm"
#include "code\datums\wires\fax.dm"
#include "code\datums\wires\microwave.dm"
+#include "code\datums\wires\mines.dm"
#include "code\datums\wires\mulebot.dm"
#include "code\datums\wires\particle_accelerator.dm"
#include "code\datums\wires\r_n_d.dm"
@@ -849,7 +867,7 @@
#include "code\game\machinery\aug_manipulator.dm"
#include "code\game\machinery\autolathe.dm"
#include "code\game\machinery\bank_machine.dm"
-#include "code\game\machinery\Beacon.dm"
+#include "code\game\machinery\beacon.dm"
#include "code\game\machinery\bounty_board.dm"
#include "code\game\machinery\buttons.dm"
#include "code\game\machinery\cell_charger.dm"
@@ -862,7 +880,7 @@
#include "code\game\machinery\dish_drive.dm"
#include "code\game\machinery\dna_scanner.dm"
#include "code\game\machinery\doppler_array.dm"
-#include "code\game\machinery\droneDispenser.dm"
+#include "code\game\machinery\drone_dispenser.dm"
#include "code\game\machinery\exp_cloner.dm"
#include "code\game\machinery\firealarm.dm"
#include "code\game\machinery\flasher.dm"
@@ -881,6 +899,7 @@
#include "code\game\machinery\medipen_refiller.dm"
#include "code\game\machinery\navbeacon.dm"
#include "code\game\machinery\newscaster.dm"
+#include "code\game\machinery\outpost_electrolyzer.dm"
#include "code\game\machinery\PDApainter.dm"
#include "code\game\machinery\prisonlabor.dm"
#include "code\game\machinery\quantum_pad.dm"
@@ -892,7 +911,7 @@
#include "code\game\machinery\scan_gate.dm"
#include "code\game\machinery\sheetifier.dm"
#include "code\game\machinery\shieldgen.dm"
-#include "code\game\machinery\Sleeper.dm"
+#include "code\game\machinery\sleeper.dm"
#include "code\game\machinery\slotmachine.dm"
#include "code\game\machinery\spaceheater.dm"
#include "code\game\machinery\stasis.dm"
@@ -960,9 +979,11 @@
#include "code\game\machinery\porta_turret\portable_turret_construct.dm"
#include "code\game\machinery\porta_turret\portable_turret_cover.dm"
#include "code\game\machinery\shuttle\custom_shuttle.dm"
+#include "code\game\machinery\shuttle\ship_gravity.dm"
#include "code\game\machinery\shuttle\shuttle_engine.dm"
#include "code\game\machinery\shuttle\shuttle_engine_types.dm"
#include "code\game\machinery\shuttle\shuttle_heater.dm"
+#include "code\game\machinery\shuttle\turbine.dm"
#include "code\game\machinery\telecomms\broadcasting.dm"
#include "code\game\machinery\telecomms\machine_interactions.dm"
#include "code\game\machinery\telecomms\telecomunications.dm"
@@ -1028,7 +1049,6 @@
#include "code\game\objects\effects\forcefields.dm"
#include "code\game\objects\effects\glowshroom.dm"
#include "code\game\objects\effects\landmarks.dm"
-#include "code\game\objects\effects\mines.dm"
#include "code\game\objects\effects\misc.dm"
#include "code\game\objects\effects\overlays.dm"
#include "code\game\objects\effects\particle_emitter.dm"
@@ -1095,6 +1115,7 @@
#include "code\game\objects\items\AI_modules.dm"
#include "code\game\objects\items\airlock_painter.dm"
#include "code\game\objects\items\apc_frame.dm"
+#include "code\game\objects\items\bank_card.dm"
#include "code\game\objects\items\bell.dm"
#include "code\game\objects\items\binoculars.dm"
#include "code\game\objects\items\blueprints.dm"
@@ -1181,6 +1202,12 @@
#include "code\game\objects\items\vending_items.dm"
#include "code\game\objects\items\wayfinding.dm"
#include "code\game\objects\items\weaponry.dm"
+#include "code\game\objects\items\attachments\_attachment.dm"
+#include "code\game\objects\items\attachments\bayonet.dm"
+#include "code\game\objects\items\attachments\laser_sight.dm"
+#include "code\game\objects\items\attachments\rail_light.dm"
+#include "code\game\objects\items\attachments\silencer.dm"
+#include "code\game\objects\items\attachments\stock.dm"
#include "code\game\objects\items\circuitboards\circuitboard.dm"
#include "code\game\objects\items\circuitboards\computer_circuitboards.dm"
#include "code\game\objects\items\circuitboards\machine_circuitboards.dm"
@@ -1198,6 +1225,7 @@
#include "code\game\objects\items\devices\laserpointer.dm"
#include "code\game\objects\items\devices\lightreplacer.dm"
#include "code\game\objects\items\devices\megaphone.dm"
+#include "code\game\objects\items\devices\mines.dm"
#include "code\game\objects\items\devices\multitool.dm"
#include "code\game\objects\items\devices\paicard.dm"
#include "code\game\objects\items\devices\pipe_painter.dm"
@@ -1281,10 +1309,12 @@
#include "code\game\objects\items\stacks\sheets\mineral.dm"
#include "code\game\objects\items\stacks\sheets\sheet_types.dm"
#include "code\game\objects\items\stacks\sheets\sheets.dm"
+#include "code\game\objects\items\stacks\sheets\recipes\recipes_metal.dm"
#include "code\game\objects\items\stacks\tiles\light.dm"
#include "code\game\objects\items\stacks\tiles\tile_mineral.dm"
#include "code\game\objects\items\stacks\tiles\tile_reskinning.dm"
#include "code\game\objects\items\stacks\tiles\tile_types.dm"
+#include "code\game\objects\items\stacks\tiles\tiles_suns.dm"
#include "code\game\objects\items\storage\backpack.dm"
#include "code\game\objects\items\storage\bags.dm"
#include "code\game\objects\items\storage\belt.dm"
@@ -1293,6 +1323,7 @@
#include "code\game\objects\items\storage\briefcase.dm"
#include "code\game\objects\items\storage\fancy.dm"
#include "code\game\objects\items\storage\firstaid.dm"
+#include "code\game\objects\items\storage\guncases.dm"
#include "code\game\objects\items\storage\holsters.dm"
#include "code\game\objects\items\storage\lockbox.dm"
#include "code\game\objects\items\storage\ration.dm"
@@ -1333,14 +1364,13 @@
#include "code\game\objects\structures\fireplace.dm"
#include "code\game\objects\structures\flora.dm"
#include "code\game\objects\structures\fluff.dm"
-#include "code\game\objects\structures\fugitive_role_spawners.dm"
+#include "code\game\objects\structures\geyser.dm"
#include "code\game\objects\structures\ghost_role_spawners.dm"
#include "code\game\objects\structures\girders.dm"
#include "code\game\objects\structures\grille.dm"
#include "code\game\objects\structures\guillotine.dm"
#include "code\game\objects\structures\guncase.dm"
#include "code\game\objects\structures\headpike.dm"
-#include "code\game\objects\structures\hivebot.dm"
#include "code\game\objects\structures\holosign.dm"
#include "code\game\objects\structures\janicart.dm"
#include "code\game\objects\structures\kitchen_spike.dm"
@@ -1368,7 +1398,6 @@
#include "code\game\objects\structures\showcase.dm"
#include "code\game\objects\structures\shower.dm"
#include "code\game\objects\structures\signs.dm"
-#include "code\game\objects\structures\spawner.dm"
#include "code\game\objects\structures\spirit_board.dm"
#include "code\game\objects\structures\stairs.dm"
#include "code\game\objects\structures\statues.dm"
@@ -1386,6 +1415,7 @@
#include "code\game\objects\structures\beds_chairs\alien_nest.dm"
#include "code\game\objects\structures\beds_chairs\bed.dm"
#include "code\game\objects\structures\beds_chairs\chair.dm"
+#include "code\game\objects\structures\beds_chairs\comfy.dm"
#include "code\game\objects\structures\beds_chairs\pew.dm"
#include "code\game\objects\structures\beds_chairs\sofa.dm"
#include "code\game\objects\structures\crates_lockers\closets.dm"
@@ -1417,9 +1447,6 @@
#include "code\game\objects\structures\crates_lockers\crates\large.dm"
#include "code\game\objects\structures\crates_lockers\crates\secure.dm"
#include "code\game\objects\structures\crates_lockers\crates\wooden.dm"
-#include "code\game\objects\structures\icemoon\cave_entrance.dm"
-#include "code\game\objects\structures\lavaland\geyser.dm"
-#include "code\game\objects\structures\lavaland\necropolis_tendril.dm"
#include "code\game\objects\structures\plaques\_plaques.dm"
#include "code\game\objects\structures\plaques\static_plaques.dm"
#include "code\game\objects\structures\signs\_signs.dm"
@@ -1462,6 +1489,7 @@
#include "code\game\turfs\open\floor\plasteel_floor.dm"
#include "code\game\turfs\open\floor\plating.dm"
#include "code\game\turfs\open\floor\reinf_floor.dm"
+#include "code\game\turfs\open\floor\suns_floor.dm"
#include "code\game\turfs\open\floor\plating\asteroid.dm"
#include "code\game\turfs\open\floor\plating\beach.dm"
#include "code\game\turfs\open\floor\plating\icemoon.dm"
@@ -1666,7 +1694,6 @@
#include "code\modules\antagonists\cult\rune_spawn_action.dm"
#include "code\modules\antagonists\cult\runes.dm"
#include "code\modules\antagonists\devil\devil.dm"
-#include "code\modules\antagonists\devil\devil_helpers.dm"
#include "code\modules\antagonists\devil\imp\imp.dm"
#include "code\modules\antagonists\devil\sintouched\objectives.dm"
#include "code\modules\antagonists\devil\sintouched\sintouched.dm"
@@ -1685,7 +1712,6 @@
#include "code\modules\antagonists\ert\nanotrasen.dm"
#include "code\modules\antagonists\ert\solgov.dm"
#include "code\modules\antagonists\ert\syndicate.dm"
-#include "code\modules\antagonists\fugitive\fugitive_outfits.dm"
#include "code\modules\antagonists\gang\outfits.dm"
#include "code\modules\antagonists\greentext\greentext.dm"
#include "code\modules\antagonists\magic_servant\servant.dm"
@@ -1805,6 +1831,7 @@
#include "code\modules\atmospherics\machinery\portable\scrubber.dm"
#include "code\modules\autowiki\autowiki.dm"
#include "code\modules\autowiki\pages\base.dm"
+#include "code\modules\autowiki\pages\reactions.dm"
#include "code\modules\autowiki\pages\reagents.dm"
#include "code\modules\autowiki\pages\ships.dm"
#include "code\modules\autowiki\pages\techweb.dm"
@@ -1842,20 +1869,22 @@
#include "code\modules\buildmode\submodes\basic.dm"
#include "code\modules\buildmode\submodes\boom.dm"
#include "code\modules\buildmode\submodes\copy.dm"
+#include "code\modules\buildmode\submodes\lightmaker.dm"
#include "code\modules\buildmode\submodes\delete.dm"
#include "code\modules\buildmode\submodes\fill.dm"
#include "code\modules\buildmode\submodes\map_export.dm"
#include "code\modules\buildmode\submodes\outfit.dm"
#include "code\modules\buildmode\submodes\proccall.dm"
+#include "code\modules\buildmode\submodes\relocate_to.dm"
#include "code\modules\buildmode\submodes\throwing.dm"
#include "code\modules\buildmode\submodes\tweakcomps.dm"
#include "code\modules\buildmode\submodes\variable_edit.dm"
#include "code\modules\cargo\bounty.dm"
#include "code\modules\cargo\bounty_console.dm"
#include "code\modules\cargo\centcom_podlauncher.dm"
+#include "code\modules\cargo\console.dm"
#include "code\modules\cargo\export_scanner.dm"
#include "code\modules\cargo\exports.dm"
-#include "code\modules\cargo\expressconsole.dm"
#include "code\modules\cargo\gondolapod.dm"
#include "code\modules\cargo\order.dm"
#include "code\modules\cargo\packs.dm"
@@ -1867,6 +1896,8 @@
#include "code\modules\cargo\blackmarket\blackmarket_uplink.dm"
#include "code\modules\cargo\blackmarket\blackmarket_items\clothing.dm"
#include "code\modules\cargo\blackmarket\blackmarket_items\consumables.dm"
+#include "code\modules\cargo\blackmarket\blackmarket_items\emergency.dm"
+#include "code\modules\cargo\blackmarket\blackmarket_items\explosives.dm"
#include "code\modules\cargo\blackmarket\blackmarket_items\misc.dm"
#include "code\modules\cargo\blackmarket\blackmarket_items\tools.dm"
#include "code\modules\cargo\blackmarket\blackmarket_items\weapons.dm"
@@ -1933,13 +1964,19 @@
#include "code\modules\client\verbs\ooc.dm"
#include "code\modules\client\verbs\ping.dm"
#include "code\modules\client\verbs\reset_held_keys.dm"
+#include "code\modules\client\verbs\typing.dm"
#include "code\modules\client\verbs\who.dm"
#include "code\modules\clothing\chameleon.dm"
#include "code\modules\clothing\clothing.dm"
#include "code\modules\clothing\towels.dm"
#include "code\modules\clothing\ears\_ears.dm"
#include "code\modules\clothing\factions\clip.dm"
+#include "code\modules\clothing\factions\frontiersmen.dm"
#include "code\modules\clothing\factions\gezena.dm"
+#include "code\modules\clothing\factions\hardliners.dm"
+#include "code\modules\clothing\factions\nanotrasen.dm"
+#include "code\modules\clothing\factions\ngr.dm"
+#include "code\modules\clothing\factions\srm.dm"
#include "code\modules\clothing\factions\suns.dm"
#include "code\modules\clothing\glasses\_glasses.dm"
#include "code\modules\clothing\glasses\engine_goggles.dm"
@@ -2108,7 +2145,6 @@
#include "code\modules\events\wizard\invincible.dm"
#include "code\modules\events\wizard\lava.dm"
#include "code\modules\events\wizard\madness.dm"
-#include "code\modules\events\wizard\magicarp.dm"
#include "code\modules\events\wizard\petsplosion.dm"
#include "code\modules\events\wizard\race.dm"
#include "code\modules\events\wizard\rpgloot.dm"
@@ -2159,7 +2195,6 @@
#include "code\modules\food_and_drinks\food\snacks\dough.dm"
#include "code\modules\food_and_drinks\food\snacks\meat.dm"
#include "code\modules\food_and_drinks\kitchen_machinery\big_mortar.dm"
-#include "code\modules\food_and_drinks\kitchen_machinery\coffeemaker.dm"
#include "code\modules\food_and_drinks\kitchen_machinery\cutting_board.dm"
#include "code\modules\food_and_drinks\kitchen_machinery\deep_fryer.dm"
#include "code\modules\food_and_drinks\kitchen_machinery\food_cart.dm"
@@ -2397,6 +2432,7 @@
#include "code\modules\mining\equipment\regenerative_core.dm"
#include "code\modules\mining\equipment\resonator.dm"
#include "code\modules\mining\equipment\survival_pod.dm"
+#include "code\modules\mining\equipment\trophies.dm"
#include "code\modules\mining\equipment\wormhole_jaunter.dm"
#include "code\modules\mining\laborcamp\laborstacker.dm"
#include "code\modules\mining\lavaland\ash_flora.dm"
@@ -2684,13 +2720,10 @@
#include "code\modules\mob\living\simple_animal\hostile\bear.dm"
#include "code\modules\mob\living\simple_animal\hostile\bees.dm"
#include "code\modules\mob\living\simple_animal\hostile\carp.dm"
-#include "code\modules\mob\living\simple_animal\hostile\cat_butcher.dm"
#include "code\modules\mob\living\simple_animal\hostile\clown.dm"
#include "code\modules\mob\living\simple_animal\hostile\cockroach.dm"
-#include "code\modules\mob\living\simple_animal\hostile\dark_wizard.dm"
#include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm"
#include "code\modules\mob\living\simple_animal\hostile\faithless.dm"
-#include "code\modules\mob\living\simple_animal\hostile\frontiersman.dm"
#include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm"
#include "code\modules\mob\living\simple_animal\hostile\goose.dm"
#include "code\modules\mob\living\simple_animal\hostile\headcrab.dm"
@@ -2701,26 +2734,26 @@
#include "code\modules\mob\living\simple_animal\hostile\mecha_pilot.dm"
#include "code\modules\mob\living\simple_animal\hostile\mimic.dm"
#include "code\modules\mob\living\simple_animal\hostile\mushroom.dm"
-#include "code\modules\mob\living\simple_animal\hostile\nanotrasen.dm"
#include "code\modules\mob\living\simple_animal\hostile\netherworld.dm"
-#include "code\modules\mob\living\simple_animal\hostile\pirate.dm"
#include "code\modules\mob\living\simple_animal\hostile\regalrat.dm"
-#include "code\modules\mob\living\simple_animal\hostile\skeleton.dm"
#include "code\modules\mob\living\simple_animal\hostile\space_dragon.dm"
#include "code\modules\mob\living\simple_animal\hostile\statue.dm"
-#include "code\modules\mob\living\simple_animal\hostile\stickman.dm"
-#include "code\modules\mob\living\simple_animal\hostile\survivors.dm"
-#include "code\modules\mob\living\simple_animal\hostile\syndicate.dm"
#include "code\modules\mob\living\simple_animal\hostile\tree.dm"
#include "code\modules\mob\living\simple_animal\hostile\venus_human_trap.dm"
-#include "code\modules\mob\living\simple_animal\hostile\wizard.dm"
#include "code\modules\mob\living\simple_animal\hostile\wumborian_fugu.dm"
-#include "code\modules\mob\living\simple_animal\hostile\zombie.dm"
#include "code\modules\mob\living\simple_animal\hostile\bosses\boss.dm"
-#include "code\modules\mob\living\simple_animal\hostile\bosses\paperwizard.dm"
#include "code\modules\mob\living\simple_animal\hostile\gorilla\emotes.dm"
#include "code\modules\mob\living\simple_animal\hostile\gorilla\gorilla.dm"
#include "code\modules\mob\living\simple_animal\hostile\gorilla\visuals_icons.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\cat_butcher.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\frontiersman.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\human.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\nanotrasen.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\pirate.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\skeleton.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\survivors.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\syndicate.dm"
+#include "code\modules\mob\living\simple_animal\hostile\human\zombie.dm"
#include "code\modules\mob\living\simple_animal\hostile\jungle\_jungle_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\jungle\leaper.dm"
#include "code\modules\mob\living\simple_animal\hostile\jungle\mega_arachnid.dm"
@@ -2745,8 +2778,9 @@
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\goliath.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\gutlunch.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\hivelord.dm"
-#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice demon.dm"
-#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice whelp.dm"
+#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\hivelord_outfits.dm"
+#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_demon.dm"
+#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_whelp.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\lobstrosity.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\mining_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\polarbear.dm"
@@ -2769,6 +2803,10 @@
#include "code\modules\mob\living\simple_animal\slime\slime.dm"
#include "code\modules\mob\living\simple_animal\slime\slime_say.dm"
#include "code\modules\mob\living\simple_animal\slime\subtypes.dm"
+#include "code\modules\mob_spawner\burrow.dm"
+#include "code\modules\mob_spawner\hivebot.dm"
+#include "code\modules\mob_spawner\spawner.dm"
+#include "code\modules\mob_spawner\spawner_componet.dm"
#include "code\modules\modular_computers\laptop_vendor.dm"
#include "code\modules\modular_computers\computers\_modular_computer_shared.dm"
#include "code\modules\modular_computers\computers\item\computer.dm"
@@ -2936,7 +2974,6 @@
#include "code\modules\power\solar.dm"
#include "code\modules\power\terminal.dm"
#include "code\modules\power\tracker.dm"
-#include "code\modules\power\turbine.dm"
#include "code\modules\power\singularity\boh_tear.dm"
#include "code\modules\power\singularity\collector.dm"
#include "code\modules\power\singularity\containment_field.dm"
@@ -2956,7 +2993,6 @@
#include "code\modules\power\tesla\energy_ball.dm"
#include "code\modules\power\tesla\generator.dm"
#include "code\modules\projectiles\gun.dm"
-#include "code\modules\projectiles\pins.dm"
#include "code\modules\projectiles\projectile.dm"
#include "code\modules\projectiles\ammunition\_ammunition.dm"
#include "code\modules\projectiles\ammunition\_firing.dm"
@@ -2986,6 +3022,7 @@
#include "code\modules\projectiles\ammunition\special\syringe.dm"
#include "code\modules\projectiles\boxes_magazines\_box_magazine.dm"
#include "code\modules\projectiles\boxes_magazines\ammo_boxes.dm"
+#include "code\modules\projectiles\boxes_magazines\generic_ammo_box.dm"
#include "code\modules\projectiles\boxes_magazines\external\gauss.dm"
#include "code\modules\projectiles\boxes_magazines\external\grenade.dm"
#include "code\modules\projectiles\boxes_magazines\external\lmg.dm"
@@ -3009,13 +3046,13 @@
#include "code\modules\projectiles\guns\ballistic.dm"
#include "code\modules\projectiles\guns\energy.dm"
#include "code\modules\projectiles\guns\gunhud.dm"
-#include "code\modules\projectiles\guns\magic.dm"
#include "code\modules\projectiles\guns\powered.dm"
#include "code\modules\projectiles\guns\ballistic\assault.dm"
#include "code\modules\projectiles\guns\ballistic\automatic.dm"
#include "code\modules\projectiles\guns\ballistic\gauss.dm"
#include "code\modules\projectiles\guns\ballistic\hmg.dm"
#include "code\modules\projectiles\guns\ballistic\launchers.dm"
+#include "code\modules\projectiles\guns\ballistic\marksman.dm"
#include "code\modules\projectiles\guns\ballistic\pistol.dm"
#include "code\modules\projectiles\guns\ballistic\revolver.dm"
#include "code\modules\projectiles\guns\ballistic\rifle.dm"
@@ -3031,9 +3068,7 @@
#include "code\modules\projectiles\guns\energy\pulse.dm"
#include "code\modules\projectiles\guns\energy\special.dm"
#include "code\modules\projectiles\guns\energy\stun.dm"
-#include "code\modules\projectiles\guns\faction\gezena\energy_gunsword.dm"
-#include "code\modules\projectiles\guns\magic\staff.dm"
-#include "code\modules\projectiles\guns\magic\wand.dm"
+#include "code\modules\projectiles\guns\manufacturer\etherbor\energy_gunsword.dm"
#include "code\modules\projectiles\guns\misc\beam_rifle.dm"
#include "code\modules\projectiles\guns\misc\blastcannon.dm"
#include "code\modules\projectiles\guns\misc\bow.dm"
@@ -3043,7 +3078,6 @@
#include "code\modules\projectiles\guns\misc\syringe_gun.dm"
#include "code\modules\projectiles\projectile\beams.dm"
#include "code\modules\projectiles\projectile\bullets.dm"
-#include "code\modules\projectiles\projectile\magic.dm"
#include "code\modules\projectiles\projectile\bullets\_incendiary.dm"
#include "code\modules\projectiles\projectile\bullets\dart_syringe.dm"
#include "code\modules\projectiles\projectile\bullets\dnainjector.dm"
@@ -3065,7 +3099,6 @@
#include "code\modules\projectiles\projectile\energy\nuclear_particle.dm"
#include "code\modules\projectiles\projectile\energy\stun.dm"
#include "code\modules\projectiles\projectile\energy\tesla.dm"
-#include "code\modules\projectiles\projectile\magic\spellcard.dm"
#include "code\modules\projectiles\projectile\reusable\_reusable.dm"
#include "code\modules\projectiles\projectile\reusable\arrow.dm"
#include "code\modules\projectiles\projectile\reusable\foam_dart.dm"
@@ -3231,36 +3264,19 @@
#include "code\modules\research\xenobiology\crossbreeding\reproductive.dm"
#include "code\modules\research\xenobiology\crossbreeding\selfsustaining.dm"
#include "code\modules\research\xenobiology\crossbreeding\stabilized.dm"
-#include "code\modules\ruins\lavaland_ruin_code.dm"
#include "code\modules\ruins\rockplanet_ruin_code.dm"
-#include "code\modules\ruins\icemoonruin_code\hotsprings.dm"
#include "code\modules\ruins\icemoonruin_code\hydroponicslab.dm"
#include "code\modules\ruins\icemoonruin_code\library.dm"
#include "code\modules\ruins\icemoonruin_code\wrath.dm"
-#include "code\modules\ruins\lavalandruin_code\biodome_clown_planet.dm"
-#include "code\modules\ruins\lavalandruin_code\codelab.dm"
+#include "code\modules\ruins\lavalandruin_code\biodome_winter.dm"
#include "code\modules\ruins\lavalandruin_code\elephantgraveyard.dm"
-#include "code\modules\ruins\lavalandruin_code\pizzaparty.dm"
#include "code\modules\ruins\lavalandruin_code\puzzle.dm"
-#include "code\modules\ruins\lavalandruin_code\sloth.dm"
#include "code\modules\ruins\lavalandruin_code\surface.dm"
#include "code\modules\ruins\lavalandruin_code\syndicate_base.dm"
#include "code\modules\ruins\objects_and_mobs\ash_walker_den.dm"
#include "code\modules\ruins\objects_and_mobs\necropolis_gate.dm"
#include "code\modules\ruins\objects_and_mobs\sin_ruins.dm"
-#include "code\modules\ruins\spaceruin_code\asteroid4.dm"
#include "code\modules\ruins\spaceruin_code\bigderelict1.dm"
-#include "code\modules\ruins\spaceruin_code\caravanambush.dm"
-#include "code\modules\ruins\spaceruin_code\clericsden.dm"
-#include "code\modules\ruins\spaceruin_code\crashedclownship.dm"
-#include "code\modules\ruins\spaceruin_code\crashedship.dm"
-#include "code\modules\ruins\spaceruin_code\deepstorage.dm"
-#include "code\modules\ruins\spaceruin_code\DJstation.dm"
-#include "code\modules\ruins\spaceruin_code\forgottenship.dm"
-#include "code\modules\ruins\spaceruin_code\hellfactory.dm"
-#include "code\modules\ruins\spaceruin_code\hilbertshotel.dm"
-#include "code\modules\ruins\spaceruin_code\listeningstation.dm"
-#include "code\modules\ruins\spaceruin_code\spacehotel.dm"
#include "code\modules\ruins\spaceruin_code\TheDerelict.dm"
#include "code\modules\screen_alerts\_screen_alerts.dm"
#include "code\modules\security_levels\keycard_authentication.dm"
@@ -3273,9 +3289,7 @@
#include "code\modules\shuttle\ripple.dm"
#include "code\modules\shuttle\shuttle.dm"
#include "code\modules\shuttle\shuttle_rotate.dm"
-#include "code\modules\shuttle\special.dm"
#include "code\modules\shuttle\supply.dm"
-#include "code\modules\shuttle\white_ship.dm"
#include "code\modules\spells\spell.dm"
#include "code\modules\spells\spell_types\aimed.dm"
#include "code\modules\spells\spell_types\area_teleport.dm"
@@ -3293,7 +3307,6 @@
#include "code\modules\spells\spell_types\forcewall.dm"
#include "code\modules\spells\spell_types\genetic.dm"
#include "code\modules\spells\spell_types\godhand.dm"
-#include "code\modules\spells\spell_types\infinite_guns.dm"
#include "code\modules\spells\spell_types\inflict_handler.dm"
#include "code\modules\spells\spell_types\knock.dm"
#include "code\modules\spells\spell_types\lichdom.dm"
@@ -3467,7 +3480,6 @@
#include "code\modules\vending\engineering.dm"
#include "code\modules\vending\engivend.dm"
#include "code\modules\vending\games.dm"
-#include "code\modules\vending\liberation.dm"
#include "code\modules\vending\liberation_toy.dm"
#include "code\modules\vending\medical.dm"
#include "code\modules\vending\medical_wall.dm"
diff --git a/sound/items/mine_activate.ogg b/sound/items/mine_activate.ogg
new file mode 100644
index 000000000000..ed39ba283be7
Binary files /dev/null and b/sound/items/mine_activate.ogg differ
diff --git a/sound/items/mine_activate_short.ogg b/sound/items/mine_activate_short.ogg
new file mode 100644
index 000000000000..8c6e81a06bbe
Binary files /dev/null and b/sound/items/mine_activate_short.ogg differ
diff --git a/sound/machines/coffeemaker_brew.ogg b/sound/machines/coffeemaker_brew.ogg
deleted file mode 100644
index a8e25c09867a..000000000000
Binary files a/sound/machines/coffeemaker_brew.ogg and /dev/null differ
diff --git a/sound/voice/ApproachingTG.ogg b/sound/voice/ApproachingTG.ogg
deleted file mode 100644
index 3f8bc1c48801..000000000000
Binary files a/sound/voice/ApproachingTG.ogg and /dev/null differ
diff --git a/sound/voice/kepori/kepiclick.ogg b/sound/voice/kepori/kepiclick.ogg
new file mode 100644
index 000000000000..3f22b6d90d5e
Binary files /dev/null and b/sound/voice/kepori/kepiclick.ogg differ
diff --git a/sound/voice/kepori/kepiwhistle.ogg b/sound/voice/kepori/kepiwhistle.ogg
new file mode 100644
index 000000000000..f6260f4c5894
Binary files /dev/null and b/sound/voice/kepori/kepiwhistle.ogg differ
diff --git a/sound/voice/lizard/firespit.ogg b/sound/voice/lizard/firespit.ogg
new file mode 100644
index 000000000000..f60278f47827
Binary files /dev/null and b/sound/voice/lizard/firespit.ogg differ
diff --git a/strings/boomer.json b/strings/boomer.json
deleted file mode 100644
index 4fb2f733f795..000000000000
--- a/strings/boomer.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "boomer": [
- "@pick(kids) these days have it too easy!",
- "Do I look like I know what a @pick(file) is!?",
- "Listen here Jack, how do I open @pick(file)?",
- "How do I open a @pick(file) again?",
- "Unlike you snowflakes, I'm not offended so easily.",
- "Back in my day...",
- "When I was your age...",
- "This generation can't take a joke.",
- "Why are @pick(kids) these days so @pick(sad) all the time?",
- "These damn @pick(kids) need to get a @pick(impossible) for once!",
- "It's simply a matter of showing up, looking the manager in the eye, giving him a firm handshake and telling him you want the job.",
- "You'll never get anywhere in life without a degree.",
- "@pick(expense) isn't really that expensive.",
- "When I was a kid I had to walk to school uphill both ways!",
- "I hate my wife.",
- "I just want to grill for God's sake.",
- "I wish I could just go on my lawnmower and cut the grass.",
- "Yep, Quake. That was a good game...",
- "Yeah, my PDA has wi-fi. A wife I hate."
- ],
-
- "expense": ["Healthcare", "College", "A car", "A house", "Food"],
-
- "kids": ["kids", "millenials", "snowflakes"],
-
- "file": ["JPEG", "PDF", "DMI", "JSON"],
-
- "sad": ["sad", "depressed", "sad and depressed"],
-
- "impossible": ["job", "house", "job and a house", "life"]
-}
diff --git a/strings/ipc_preference_adjectives.txt b/strings/ipc_preference_adjectives.txt
new file mode 100644
index 000000000000..a243b2d77fc5
--- /dev/null
+++ b/strings/ipc_preference_adjectives.txt
@@ -0,0 +1,71 @@
+Bedraggled
+Brawny
+Bulky
+Burly
+Calm
+Chaotic
+Charming
+Delicate
+Dignified
+Disgusting
+Disturbing
+Dull
+Effeminate
+Elegant
+Energetic
+Exasperated
+Exotic
+Faint
+Feisty
+Flamboyant
+Fragile
+Frail
+Friendly
+Gentle
+Hawkish
+Hefty
+Hobbling
+Hyper
+Imposing
+Jaded
+Lax
+Lean
+Limp
+Lithe
+Lopsided
+Lovely
+Mangled
+Masculine
+Messy
+Nimble
+Petite
+Pompous
+Pugnacious
+Repulsive
+Robust
+Rough
+Rusted
+Scarred
+Shifty
+Sickly
+Skittish
+Sleek
+Slender
+Slovenly
+Sluggish
+Spacy
+Stiff
+Stony
+Stylish
+Unattractive
+Unremarkable
+Unsightly
+Verbose
+Vigorous
+Waifish
+Wilted
+Wily
+Withered
+Worn-Out
+Zealous
+Zesty
diff --git a/strings/names/kepori_names.txt b/strings/names/kepori_names.txt
new file mode 100644
index 000000000000..f5cf1fa086a7
--- /dev/null
+++ b/strings/names/kepori_names.txt
@@ -0,0 +1,40 @@
+Ademake
+Ankatse
+Atchenti
+Cautse
+Catuwe
+Dakenui
+Deduci
+Dirame
+Drakece
+Dutsesi
+Gahthi
+Halake
+Hetchel
+Huler
+Hanusi
+Lanirvi
+Latedi
+Meleri
+Meski
+Minele
+Naaka
+Natari
+Nenuda
+Nirena
+Orucati
+Pawitts
+Plakat
+Rakire
+Renuire
+Rilena
+Setasi
+Sutiraze
+Temiti
+Tetha
+Tokaibi
+Witaseni
+Winuusi
+Yikitse
+Yitosun
+Yunthedi
diff --git a/strings/names/moth_first.txt b/strings/names/moth_first.txt
deleted file mode 100644
index cfd8a8675f91..000000000000
--- a/strings/names/moth_first.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-Acantharctia
-Acco
-Acherontia
-Actias
-Aemilia
-Aethria
-Antheraea
-Aphomia
-Argema
-Ascalapha
-Asota
-Athrypsiastis
-Attacus
-Autochloris
-Axylia
-Bombyx
-Callosamia
-Callhistia
-Capricornia
-Catocala
-Cheliosea
-Chloroclystis
-Cochylimorpha
-Cryphia
-Cryptophasa
-Cucullia
-Cydia
-Diarsia
-Diaphora
-Dolichohedya
-Dyspyralis
-Eacles
-Eclipsea
-Electresia
-Elysius
-Enarmonia
-Eriomastyx
-Epiphyas
-Eugnorisma
-Eupithecia
-Euplexia
-Eurosia
-Falcatula
-Fangarctia
-Fulcrifera
-Glyphidoptera
-Gracillina
-Gravitarmata
-Haemanota
-Halysidota
-Helicoverpa
-Heliomata
-Hyalophora
-Hypomartyria
-Icelita
-Isanthrene
-Isochorista
-Izatha
-Kodiosoma
-Lacida
-Leguminivora
-Leucoptera
-Lymantria
-Macrobathra
-Maruca
-Mecodina
-Megalonycta
-Metacrisia
-Mythimna
-Naenia
-Naenia
-Neuroxena
-Nodaria
-Nymphicula
-Obscurior
-Ochropleura
-Opodiphthera
-Ostrinia
-Pacificulla
-Philomusaea
-Phragmataecia
-Plodia
-Plutella
-Rachiplusia
-Sarobela
-Selenarctia
-Shiragasane
-Sphingidae
-Socioplana
-Spodoptera
-Syllomatia
-Thaumetopoea
-Timandra
-Toxoproctis
-Uranophora
-Vestura
-Vietteria
-Xanthorhoe
-Xestia
-Zomaria
diff --git a/strings/names/moth_last.txt b/strings/names/moth_last.txt
deleted file mode 100644
index 4d6ec130c41e..000000000000
--- a/strings/names/moth_last.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-Accurata
-Adultera
-Albipuncta
-Albostriata
-Albovenosa
-Argentea
-Bicolorata
-Bifasciata
-Cameroni
-Chiangmai
-Combinata
-Convecta
-Cuneilinea
-Curvata
-Dentata
-Empyrea
-Eucrossa
-Ferrilinea
-Fraterna
-Goniosigma
-Hamifera
-Hirashimai
-Hypophaea
-Ignita
-Impura
-Insularis
-Infrargyrea
-Intermediata
-Intolerabilis
-Laevusta
-Languida
-Liebherri
-Lineatipes
-Lucida
-Maxima
-Mediana
-Modesta
-Monticola
-Naumanni
-Nepalina
-Obscura
-Osseogrisea
-Pastellina
-Phlebitis
-Pyrausta
-Radiata
-Riparia
-Rufulosa
-Semicana
-Separata
-Siamensis
-Simplex
-Toumodi
-Undicilia
-Uruma
-Vittata
-Yuennana
diff --git a/strings/preference_adjectives.txt b/strings/preference_adjectives.txt
new file mode 100644
index 000000000000..0d67f16803f8
--- /dev/null
+++ b/strings/preference_adjectives.txt
@@ -0,0 +1,117 @@
+Angsty
+Awkward
+Bedraggled
+Blemished
+Bony
+Brawny
+Breathtaking
+Bruised
+Bulky
+Burly
+Calm
+Chaotic
+Charming
+Chubby
+Coarse
+Deformed
+Delicate
+Despondent
+Dignified
+Disgusting
+Disturbing
+Dull
+Effeminate
+Elegant
+Emaciated
+Energetic
+Energetic
+Exasperated
+Exotic
+Faint
+Feisty
+Flabby
+Flamboyant
+Fragile
+Frail
+Frazzled
+Friendly
+Gap-toothed
+Gaunt
+Gentle
+Gloomy
+Gormless
+Hawkish
+Hawkish
+Healthy
+Hefty
+Hobbling
+Hyper
+Imposing
+Inscrutable
+Jaded
+Lax
+Lean
+Limp
+Lithe
+Lopsided
+Lovely
+Malnourished
+Mangled
+Mangled
+Masculine
+Messy
+Muscular
+Nimble
+Pathetic
+Peppy
+Petite
+Pompous
+Pugnacious
+Quievering
+Radical
+Repulsive
+Robust
+Roguish
+Rough
+Scarred
+Scrawny
+Sculpted
+Shifty
+Shrewd
+Sickly
+Skittish
+Sleek
+Sleepy
+Slender
+Slimy
+Slovenly
+Sluggish
+Sly
+Smooth
+Sniveling
+Soulrendered
+Spacy
+Stiff
+Stony
+Stout
+Strapping
+Sturdy
+Stylish
+Swarthy
+Tense
+Tubular
+Unattractive
+Unblemished
+Unhealthy
+Unremarkable
+Unsightly
+Verbose
+Vigorous
+Waifish
+Wilted
+Wily
+Withered
+Worn-Out
+Wrinkly
+Zealous
+Zesty
diff --git a/strings/sillytips.txt b/strings/sillytips.txt
index 192dbce6362f..165e3cbe54d6 100644
--- a/strings/sillytips.txt
+++ b/strings/sillytips.txt
@@ -5,16 +5,12 @@ When a round ends nearly everything about it is lost forever, leave your salt be
Killing the entire sector isn't fun except when it is.
You can win a pulse rifle from the arcade machine. Honest.
Just like real life the entropy of the game can only increase with time. If things aren't on fire yet, just wait.
-Completing your objectives is good practice, but the best antagonists will strive to do more than the bare minimum to really leave an impression.
The more obscure and underused a game mechanic is, the less likely your victims are to be able to deal with it.
Space is cold and it will quickly freeze you to death if you don't protect yourself. This isn't how thermodynamics really works but just go with it.
-Blobs are weak to fire! Use a flame thrower for maximum damage!
Cleanbot.
-The wizard is supposed to be extremely strong in one on one combat, stop getting mad about it.
Sometimes a round will just be a bust. C'est la vie.
This is a game that is constantly being developed for. Expect things to be added, removed, fixed, and broken on a daily basis.
It's fun to try and predict the round type from the tip of the round message.
-The quartermaster is not a head of staff and will never be one.
The bird remembers.
Your sprite represents your hitbox, so that afro makes you easier to kill. The sacrifices we make for style.
Sometimes admins will just do stuff. Roll with it.
@@ -23,14 +19,21 @@ Plenty of things that aren't traditionally considered weapons can still be used
DEATH IS IMMINENT!
This game is older than most of the people playing it.
Do not go gentle into that good night.
-Flashbangs can weaken blob tiles, allowing for you and the crew to easily destroy them.
Just the tip?
Some people are unable to read text on a game where half of it is based on text.
-As the Captain, you can use a whetstone to sharpen your fancy fountain pen for extra robustness.
-As the Lawyer, you are the last bastion of roleplay-focused jobs. Even the curator got a whip to go fight people with, that sellout!
There are at least 11 ways to get through plastic flaps. How many can you name?
FEED ME A STRAY CAT
-Did you know that tossing the clown into a singularity will either increase or decrease its size by a large amount?
Most items have names longer than "soap".
-Demoman takes skill.
Ask and you shall receive.
+Top Ten Goliath Moments!!!
+Sometimes your ship will randomly disappear or obliterate you or get cleaved in half or any combination of the above. Don't dock to a planet at the same time as someone else or undock as someone is docking.
+Go on. Saw off those beautiful Hunter's Pride stocks. The Huntsman is watching.
+The Drinkening has put countless shiptester's basic reading compehension to the test. Will you succumb?
+No, going really really fast through an electric storm won't render you immune.
+None of you would survive the uptime drought.
+Innumberable frontiersmen have died valiantly in a subshuttle chokepoint attempting to board. Sometimes, a direct subshuttle dock isn't the best tactical move.
+Full-body prosthesis are still biological and have normal blood. Don't pump a full bag of coolant into their veins, you.
+The shotgun may never miss, but it has low armour penetration with buckshot.
+When your gun gives off a pathetic click, it's out of ammo. Mashing the trigger more in a panic won't restore your ammo.
+The Trabuco is a crime against the Huntsman and the universe. There's a possibility it'll kill either yourself, your crew, the target, or all of the above.
+Don't be the captain found dead in a pit, legioned, with 600 brute and every bone in their body broken.
diff --git a/strings/tips.txt b/strings/tips.txt
index 6a8c54086d94..85eda2e01283 100644
--- a/strings/tips.txt
+++ b/strings/tips.txt
@@ -19,33 +19,26 @@ You can screwdriver any non-chemical grenade to shorten fuses from 5 seconds, to
If you find yourself in a fistfight with another player, staying on the offensive is usually the smart move. Running away often won't accomplish much.
Different weapons have different strengths. Some weapons, such as spears, floor tiles, and throwing stars, deal more damage when thrown compared to when attacked normally.
A thrown glass of water can make a slippery tile, allowing you to slow down your pursuers in a pinch.
-When dealing with security, you can often get your sentence negated entirely through cooperation and deception.
-Experiment with different setups of the supermatter engine to maximize output, but don't risk the crew's safety to do so!
We were all new once, be patient and guide new players in the right direction.
On most clothing items that go in the exosuit slot, you can put certain small items into your suit storage, such as a spraycan, your emergency oxygen tank, or a flashlight.
Most job-related exosuit clothing can fit job-related items into it, such as the atmospheric technician's hardsuit/winter coat holding an RPD, or labcoats holding most medicine.
If you're using hotkey mode, you can stop pulling things using H.
If there's something you need from others, try asking! This game isn't singleplayer and you'd be surprised what you can get accomplished together!
You'll quickly lose your interest in the game if you play to win and kill. If you find yourself doing this, take a step back and talk to people - it's a much better experience!
-Felinids get temporarily distracted by laser pointers. Use this to your advantage when being pursued by one.
Don't be afraid to ask for help, whether from your peers or from mentors.
As the Captain, you have absolute access and control over your ship, but this does not mean that being a horrible person won't result in mutiny and a ban.
A medical hardsuit can hold an entire medkit in its suit storage!
-While both heal toxin damage, the difference between charcoal and antitoxin is that charcoal will actively remove all other reagents from one's body, while antitoxin only removes various toxins - but can overdose.
-You can surgically implant or extract things from people's chests. This can range from putting in a bomb to pulling out an alien larva.
+While both heal toxin damage, the difference between charcoal and dylovene is that charcoal will actively remove all other reagents from one's body, while dylovene only removes various toxins - but can overdose.
+You can surgically implant or extract things from people's chests using either organ manipulation or cavity implant surgeries. This can range from putting in a bomb to pulling out an alien larva.
Using disarm attempt will intentionally fail a surgery step.
Corpses with the "...and their soul has departed" description no longer have a ghost attached to them and aren't revivable or clonable.
-Treating plasmamen is not impossible! Salbutamol stops them from suffocating and showers stop them from burning alive. You can even perform surgery on them by doing the procedure on a roller bed under a shower.
+Treating plasmamen is not impossible! Salbutamol stops them from suffocating and showers or stasis beds stop them from burning alive. You can even perform surgery on them by doing the procedure on a roller bed under a shower.
You can extract implants by holding an empty implant case in your offhand while performing the extraction step.
There are dozens of chemicals that can heal, and even more that can cause harm. Experiment!
Some chemicals can only be synthesized by heating up the contents with a chemical heater or manually with lighters and similar tools.
You can recharge a chemical dispenser with an inducer or by replacing its cell.
Water and Potassium mixed together will create an explosion, with power scaling by amount used. Don't do it.
-You can eject someone from cloning early by disabling power in the room. Note that they will suffer more genetic damage and may lose vital organs from this.
-Being a hulk makes you capable of dealing high melee damage, stunlocking people, and punching through walls. However, you can't fire guns, will lose your hulk status if you go into critical condition.
You can take AIs out of their cores by loading them into an intelliCard, which lets you see their laws, It can also be placed into an AI system integrity restorer computer to revive and/or repair them.
-You can use the mutation toxin obtained from green slimes to create various mutation toxins by mixing it with various chemicals!
-You can maximize the number of uses you get out of a slime by feeding it slime steroid, created from purple slimes, while alive. You can then apply extract enhancer, created from cerulean slimes, on each extract.
You can repair your cyborgs with a welding tool if they have brute damage, if they have burn damage, you can remove their battery, expose the wiring with a screwdriver and replace their wires with a cable coil.
You can reset a cyborg's module by cutting and mending the reset wire with a wire cutter.
You can augment people with cyborg limbs. Augmented limbs can easily be repaired with cables and welders.
@@ -55,45 +48,33 @@ As a AI, you can take pictures with your camera and upload them to newscasters.
As a AI, you can use CTRL + 1-9 to set a location hotkey for your camera, allowing you to save the location and jump to it at will. Tilde and zero will return you to the last spot you jumped from, and the numpad numbers act as aliases to the regular number keys.
As a Cyborg, choose your module carefully, as only cutting and mending your reset wire will let you repick it. If possible, refrain from choosing a module until a situation that requires one occurs.
As a Cyborg, you are immune to most forms of stunning, and excel at almost everything far better than humans. However, flashes can easily stunlock you and you cannot do any precision work as you lack hands.
-As a Cyborg, you are impervious to fires and heat. If you are rogue, you can release plasma fires everywhere and walk through them without a care in the world!
-As a Cyborg, you are extremely vulnerable to EMPs as EMPs both stun you and damage you. The ion rifle in the armory or a traitor with an EMP kit can kill you in seconds.
+As a Cyborg, you are impervious to fires and heat.
+As a Cyborg, you are extremely vulnerable to EMPs as EMPs both stun you and damage you.
As a Service Cyborg, your spray can knocks people down. However, it is blocked by masks and glasses.
As an Engineering Cyborg, you can attach air alarm/fire alarm/APC frames to walls by placing them on the floor and using a screwdriver on them.
As a Medical Cyborg, you can fully perform surgery and even augment people.
You can rename areas or create entirely new ones using your ship expansion permit.
The chief engineer’s hardsuit is significantly better than other engineering hardsuits. It has the best features of both engineering and atmospherics hardsuits - boasting nigh-invulnerability to radiation and all atmospheric conditions.
The supermatter shard is an extremely dangerous piece of equipment: touching it will disintegrate you. So will touching it with telepathy.
-You can electrify grilles by placing wire "nodes" beneath them: the big seemingly unconnected bulges from a half completed wiring job.
+Wire "nodes" (big, seemingly unconnected bulges from half completed wiring jobs) are able to do several things: link up thrusters to prechargers, hook up PACMAN generators, and shock grilles among other things.
You can cool a supermatter crystal by spraying it with a fire extinguisher. Only for the brave!
You can repair windows by using a welding tool on them while on any intent other than harm.
-Don't underestimate the humble P.A.C.M.A.N. generators.
A RCD can be reloaded with metal, glass or plasteel sheets instead of just compressed matter cartridges.
You can unwrench a pipe regardless of the pressures of the gases inside, but if they're too high they can burst out and injure you!
-ATMOS holofan projector blocks gases while allowing objects to pass through. With it, you can quickly contain gas spills, fires and hull breaches. Or, use it to seal a plasmaman cloning room.
+ATMOS holofan projector blocks gases while allowing objects to pass through. With it, you can quickly contain gas spills, fires and hull breaches. Beware, they wear off after an amount of time highlighted by numbers on the fans.
You can change the layer of a pipe by clicking with it on a wrenched pipe or other atmos component of the desired layer.
-As a Clown, if you lose your banana peel, you can still slip people with your PDA! Honk!
-As a Clown, eating bananas heals you slightly. Honk!
-As a Clown, your Grail is the mineral bananium, which can be used to build you a fun and robust mech beloved by everyone.
-As a Clown, you can use your stamp on a sheet of cardboard as the first step of making a honkbot. Fun for the whole crew!
-As a Clown, spice your gimmicks up! Nobody likes a one-trick pony.
-The null rod has anti magic functions: it makes you immune to magic.
Books can be turned into a container that can store small items using wire cutters, bibles have this ability without needing to cut it.
You can hack the MegaSeed Vendor to get access to more exotic seeds. These seeds can alternatively be ordered from a express console
You can mutate the plants with unstable mutagen or, as an alternative, grow glowshrooms for their radium which also mutates plants to start you up!
While growing plants you should look into increasing the potency of your plants. This increases the size, amount of chemicals, points gained from grinding them in the biogenerator, and lets people know you are a proficient botanist.
You can create a very wide variety of food with the crafting menu. You can find it by looking for the hammer icon near your intents.
You can rename custom food with a pen.
-any cooked food will be much healthier than the junk food found in vendors. Having the crew routinely eating cooked will provide minor buffs.
+Any cooked food will be much healthier than the junk food found in vendors.
Most non-custom foods will have a secondary effect, ranging from healing you to making you move at lightspeed. Experiment!
Mousetraps can be used to create bombs or booby-trap containers.
-You can order contraband items from a express console without hacking it.
-You can earn more cargo points by shipping back crates, liquid containers, plasma sheets, rare seeds from hydroponics, and more!
-The express supply console can instantly delivers crates by drop pod. The impact will cause a small explosion as well.
Every monster has a pattern you can exploit to minimize damage from the encounters.
You can harvest goliath plates from goliaths and upgrade your explorer's suit, mining hardsuits as well as Firefighter APLUs with them, greatly reducing incoming melee damage.
You can craft a variety of equipment from the local fauna. Bone axes, lava boats and ash drake armour are just a few of them!
-As a Monkey, you can crawl through air or scrubber vents by alt+left clicking them. You must drop everything you are wearing and holding to do this, however.
-As a Monkey, you can still wear a few human items, such as backpacks, gas masks and hats, and still have two free hands.
As a Drone, you can ping other drones to alert them of areas in need of repair.
As a Ghost, you can see the inside of a container on the ground by clicking on it.
As a Ghost, you can double click on just about anything to follow it. Or just warp around!
@@ -106,3 +87,72 @@ You can light a cigar on a supermatter crystal.
Using sticky tape on items can make them stick to people and walls! Be careful, grenades might stick to your hand during the moment of truth!
In a pinch, stripping yourself naked will give you a sizeable resistance to being tackled. What do you value more, your freedom or your dignity?
Wearing riot armor makes you significantly more effective at performing tackle takedowns, but will use extra stamina with each leap! It will also significantly protect you from other tackles!
+As the Captain of your vessel, do not neglect the responsibilities of your command. You are the anchor the crew is expected to rely upon, and not being present or authoritative will hurt the experience.
+As a vessel's second in command, you have the unique position of being able to temper the behaviour of the Captain. Obey their orders, but do not be afraid to offer your own advice or shoulder some of command's responsibilities.
+It is highly ill-advised to run off on your own while exploring. Many ruins and planets are perilous and a match for even experienced players, and having someone to watch your back will save you a lot of trouble.
+More often that not, most ships will be apply-only. Don't be afraid to read the memo and try for an application, many captains simply want to curate a certain type of behaviour aboard their vessels.
+Captaining is one of the best ways to curate a faction. Set standards, distinguish yourself and your crew, and keep them engaged, and they'll be coming back not only to your ship, but also to the faction.
+Most improvised ways of providing medical aid or reviving the dead can be slow or dangerous to the person if you or your character are inexperienced with medicine. Don't be afraid to call for a medical ship if the situation is dire.
+In the event most or all of your crew is incapacitated or dead, don't be afraid to ahelp to ask for a distress call. They'll be happy to get you back into the round and the medical ships will be happy as well.
+Don't be afraid to ahelp if you're unsure about another player's conduct. If they're making you uncomfortable or hurting the experience, the admins would be happy to sort things out.
+Many plants on sand and lava worlds are medicinal, and can stretch your supplies.
+For higher tier drill contracts, its recommended to bring a toolbox, spare stock parts, and plasteel if you're not confident in your abilities. The drill is prone to running low on power or needing to be repaired if damaged.
+Many weapons can get sawed off, hurting their accuracy and occasionally ammo capacity but wildly compacting them. Hunter's Pride shotguns, the Flaming Arrow, the Illestren, among others, are included.
+Static anomalies will cause brain damage in close proximity. Minimize contact with them.
+Gravitational anomalies (thronglers) can quickly kill if they're intense. Sometimes, a chair can be used to get close to neutralize them, but do so at your own risk. They cause heavy brute damage.
+Certain anomalies like heartbeat, vein, jumper, or plasmasoul anomalies can interact with you through walls. Be careful docking to worlds with anomalies.
+Safe speed for carp migrations are under 2 GM/s, for asteroids are below 3 GM/s, and for dust is below 7 GM/s. There is no safe speed for electrical storms, you need full grounding rod coverage.
+You can sometimes minimize damage from electrical storms by turning off lights and preventing all source of passive light from touching the outside of the vessel. It is notoriously gimmicky, though, do so at your own risk.
+Dwarf legions tend to try and run back towards you if you're too far away. Lure them in for an attack by withdrawing before they retreat again.
+Brimdemons oftentimes will strike you with a single melee attack before fleeing for another beam. Back away once they're done firing to minimize chip damage.
+You can examine someone twice to see which limb they're bleeding from, to administer gauze or sutures.
+Vox are allergic to Ephedrine, Atropine, Epinephrine, Mannitol, Antihol, and Stimulants. Not lethal in small amounts, but it is recommended to purge these reagents if you've made a mistake.
+Grinded iron or iron pills from oxygen deprivation kits can be used to slowly regenerate blood in living people, if your blood supplies are thin.
+Crystal goliaths, elite mobs, and ancient goliaths give research points on dissection, varying from 5000 to 40000 depending on technology and mob.
+Crystal legions and crystal goliaths are extremely dangerous up close. Try and eliminate them quickly from range with powerful firearms.
+The smaller the vessel, the more throttle will effect your acceleration. If you're piloting a subshuttle, it's recommended to keep low throttle and adjust to your liking.
+Plasma thrusters can allow for extreme speed, but it is recommended to conserve them. You can minimize fuel consumption by using them in small bursts with a low throttle before turning them back off.
+Jackhammers can be used to quickly break down walls for breaching or salvage.
+Blast doors can be taken apart for a fair amount of plasteel, if you're hurting on fuel.
+Kepori have an innate ability to tackle. It can take the enemy off guard, but recommend a helmet if you're using it near walls or prone to miss.
+Laser and energy weapons have a cell that can be removed with a screwdriver. If you're removing a cell from a weapon that is not in your hand (on a suit storage slot, for example), the cell will go into your hand instead of the ground.
+Frontiersmen clothes and Ramzi Clique rusted red hardsuits are established pirate equipment, and you're likely to be fired upon if you wear them. Use at your own risk.
+You can access the black market by building an uplink with a handheld radio, analyzer, and scanning module. It tends to have a random selection of unique items at highly varied prices. You can purchase a LTSRBT from the outpost for a more convenient delivery.
+Most armour sets outside of hardsuits do not cover the limbs. Give yourself an advantage by firing on someones legs or arms to slow them down or shoot out their weapon.
+You can remove prosthetics or IPC / FBP limbs with prosthetic removal surgery, even on yourself.
+You can early eject the en bloc of Illestrens by not firing the last round and clicking on the rifle with your empty hand to take it out manually, for a fast and tactical reload.
+The HP Shadow cannot reload all rounds at once with a speedloader, it must be reloaded one round at a time.
+You can make an emergency landing by docking to an empty space if you've lost control of your speed or are about to crash into hazards.
+It is safe to cross over the tile the system sun is on. Trust me, I've tried.
+Acid tiles and acid from anomalies can be sprayed off with fire extinguishers.
+You can extinguish yourself without walls nearby by clicking the tile you're on with your extinguisher.
+It's wise to carry a pocket extinguisher on sand and lava worlds, for acid and lava respectively.
+Directional firelocks can quickly minimize pressure loss from holofield failures, if your vessel lacks them.
+Holofields rely on extra power being on the wire net. Make sure power load is a fair bit higher than the draw so you don't get launched into vacuum.
+Elzuose are able to heal a respectable amount of damage by rooting in soil or grass. It gives a sizable mood increase, as well as charging your battery.
+If you're confused about the contents of an alcoholic drink bottle, you can examine to more often than not see what it contains on the label.
+If you don't feel like grinding 500 basic power cells to make potassium, you can buy chemicals from the outpost in bulk.
+You can synthesize most chems by clicking certain reagents with stock parts. Examples being Iodine to Bromine with a scanning module and water into 2:1 hydrogen / oxygen with a capacitor.
+Perfluorodecalin in oxygen deprivation kits convert oxygen damage to toxin damage at a very effective ratio. Just know what you're doing and be prepared to administer anti-tox chems if it is a large amount of damage.
+Epi-pens contain a small amount of formaldehyde, that prevents organs from decaying while they're in a body's system. Use it to give yourself more time while reviving.
+Anomalies will give two frequencies when you analyze them, a primary and a secondary, unstable frequency. The primary will neutralize, and the unstable will more often than not cause an explosion or a similar negative effect.
+Landmines have 4 wires; one disarms the mind, the other deactivates the pressure plate, another blows it up, and another blows it up on a delay.
+You can tamper with landmines from range by pulsing the wires with signalers.
+Not everyone is from their species' homeworld. It can be common for a human to have a Kalixcian or Teceian name, for example.
+It can be fun to brainstorm new characters. Give it a shot, you might like it.
+You can create entire new shuttles and subshuttles with a shuttle manipulator either from RND or from the outpost. It's usually resource and money-intensive, so be prepared!
+Class 3 drills are incredibly dangerous alone or in small groups, even if you're experienced with mining and combat. Bring along a larger crew or call someone willing to help if you're thinking of taking them on.
+Most smaller ships can be easily made immune to electrical storms if grounding rods are spaced out around the hull. You can make some quick money from rarely-taken storm contracts.
+Ripleys are able to hold up to ten crates and other miscellaneous items like PACMAN generators using a hydraulic clamp. The scrapper's favourite.
+Fights can be heavily in favour of the defenders if you play your cards right. Get good angles, turn off lights to give yourself cover, and be able to fire from multiple areas. More than likely, you'll know your environment better than the attacker.
+Crate shelves can be used to maximize storage in your cargo bays. No more messes for you.
+You can fashion cloth into a rag to clean up your vessel if you've tracked in some blood.
+Some ships might prioritize characters exclusively from a faction in their memos, and that's okay! You can experiment with new characters to join, or join / captain another ship.
+Moths, if their wings are intact, have full mobility in zero gravity environments that have an atmosphere.
+Vox are near-unmatched in hand-to-hand fighting; their kicks deal extra damage and hurt organs.
+IPC posibrains are contained in the chest, not the head.
+Shiptest has uptime on Wednesdays, Fridays, and Saturdays.
+Exosuits are not as durable as they might feel, and it is still wise to take cover with them.
+Turning on strafing mode on a mech for combat is wise, and allows you to keep your firing lines constantly on the enemy.
+A Gygax's leg actuators drain the cell very quickly. Use sparingly.
+Installing higher tier capacitors on mechs increases power efficiency on mech abilities, weapons, and idling.
diff --git a/strings/traumas.json b/strings/traumas.json
index f6bd9b589553..1d1e98581d4f 100644
--- a/strings/traumas.json
+++ b/strings/traumas.json
@@ -1,168 +1,4 @@
{
- "brain_damage": [
- "@pick(semicolon)IM A PONY NEEEEEEIIIIIIIIIGH",
- "without oxigen blob don't evoluate?",
- "@pick(semicolon)CAPTAINS A COMDOM",
- "can u give me @pick(mutations)?",
- "THe saiyans screwed",
- "Bi is THE BEST OF BOTH WORLDS>",
- "@pick(semicolon)I WANNA PET TEH monkeyS",
- "stop grifing me!!!!",
- "SOTP IT#",
- "shiggey diggey!!",
- "@pick(semicolon)A PIRATE APPEAR",
- "FUS RO DAH",
- "stat me",
- ">my face",
- "roll it easy!",
- "lol2cat",
- "dem dwarfs man, dem dwarfs",
- "hwee did eet fhor khayosss",
- "lifelike texture ;_;",
- "luv can bloooom",
- "PACKETS!!!",
- "port ba@pick(y_replacements) med!!!!",
- "youed call her a toeugh bithc",
- "closd for merbegging",
- "@pick(semicolon)pray can u @pick(create_verbs) @pick(create_nouns)???",
- "GEY AWAY FROM ME U GREIFING PRICK!!!!",
- "@pick(semicolon)HELP INTEG MURDERIN MEE!!!",
- "hwat dose tha @pick(random_gibberish) mean?????",
- "@pick(semicolon)DO A BLUP SPEaS JUMP!!!!!",
- "wearnig siNGUARLTY is.... FINE haHAAA",
- "@pick(semicolon)AI laW 22 Open door",
- "@pick(semicolon)this SI mY sHip......",
- "who the HELL do u thenk u r?!!!!",
- "geT THE FUCK OUTTTT",
- "@pick(semicolon)CRASHING THIS SHIMP WITH NIO SURVIVROS",
- "PSHOOOM",
- "REMOVE SINGULARITY",
- "INSTLL TEG",
- "TURBIN IS BEST ENGIENE",
- "SOLIRS CAN POWER THE HOLE FLEEHT ANEWAY @pick(bug)",
- "parasteng was best",
- "@pick(semicolon)I'VE GOT BALLS OF STEEL",
- "NO I'M ONNA KILL YOU MOTHERFUCKER OLD STYLE",
- "i will snatch erry motherfucker birthday",
- "u just did the world a little bit more sad place for someone",
- "@pick(semicolon)N-NYAAAAAA~",
- "@pick(bug)",
- "@pick(semicolon)wtf??????????? @pick(bug)",
- "@pick(semicolon)i ran into the supermattre ten i dsappeard @pick(bug)",
- "DON'T EVER TUCH ME",
- "@pick(semicolon)How do I set up the. SHow do I set u p the Singu. how I the scrungulartiy????",
- "AMOGN US IS FUNNY!!",
- "DID YOU FUCKING.",
- "i DEMAND!!! APOGEE-DEV BE DEOMTED!!!",
- "@pick(semicolon)I don't ndED tEARPAHY.",
- "@pick(semicolon)an,d CIOCK.",
- "TUWN ME INoT A CAT!!",
- "WHY WAES THE PEILL REMOVED???",
- "work on the wiki please",
- "ahelp SPAWN @pick(aspawnships) PLS",
- "Am i allowd to kil l people if thye piss me off",
- "IS THIS LIEK VOIDCREW???",
- "UNiT PANICKING.",
- "HIII!! HI!! <3 <3 <3",
- "I LOOK LKIE BEAN,S,,, CRINGE!!!",
- "SEET TH shIP TO kOS!!!!!",
- "IM SynDCIATe, I ANTag, I CAN KOS......",
- "ahelp ADMIN CAN I BE PIRTA",
- "DOCTOR YUO DO DISCETIONS!!!",
- "RESERCH NANIYES",
- "REVSRSE A NY WALLS!!!",
- "*monch",
- "Amonger",
- "Live mas",
- "top ten goliath funny moments",
- "put me... in a stew... then buryy mee...",
- "@pick(semicolon)GTT AWYA FROM HER YOU BITHC!!",
- "@pick(semicolon)IS TATH A FUCKIGN,, MOTH.",
- "@pick(semicolon)BRAZIL NUMEOR UNO...!!!!",
- "@pick(semicolon)blbue hair??? I'M GOIgN TO KILL THDT FUIKNG COW!",
- "@pick(semicolon)HOW DO I @pick(ghetto)?????",
- "ough",
- "ourgh",
- "ouughghnnnn",
- "hrrnggg",
- "HE IS BALD!!!",
- "I AM NORMAL. I CAN BE TRUSTED WITH INDUSTRIAL CHEMICALS",
- "Welcome to the bathroom",
- "THE AMOUNGS BROKE ALL MY BONES",
- "HOLY SHIT IT'S @pick(john) @pick(factions)!!",
- "BLrobo BLEEBUS.....",
- "drugs are funny because they add new rp elements",
- "ANOTHER SHIP... STERALIZED...",
- "HOpeLes WAsN'T ALwAYS NaMeD HoPelESs BeFORE THe incIDENST...",
- "@pick(semicolon)HopeLSS WAS ACTUAL. Ly a LIVIng WaePON....",
- "@pick(semicolon)WHEN SHIPQUEST????? PANEL NEW??????",
- "WHER.E SHIPQUEST???,???",
- "ei,,ither wAy... It Is WHt ti is",
- "butT ShIPPtSt nEVER was a WrAZnOe liKE thaEt!!",
- "A deEoP-setED dISEuire... fuR pERfECTiOsM...",
- "HUMORER IS A DECLIAT THINGE!!",
- "who's the asshole flying the pill class",
- "IVOR@pick(y_replacements) WHAT THE FOUCKE ARE U DUING!!!??",
- "RESIEST BIG MOETH",
- "WE MUSTE RIASE UOP AGANST BEEG MOTNH",
- "Luckily, I passed high school physics",
- "I WANT NOTHING MORE IN THIS LIFE THAN TO CUDDLE UP WITH A CUTE MOTH WAIFU!!",
- "GO TO HORNY JAIL!!"
- ],
-
- "mutations": [
- "telikesis",
- "halk",
- "eppilapse",
- "kamelien",
- "eksrey",
- "glowey skin",
- "fungal tb",
- "stun gloves"
- ],
-
- "john": ["joehn", "jonn", "jouhn", "jeeoun"],
-
- "factions": ["SYNDICT", "NATOSASEN", "EEMTEQ", "MIENUTMEN", "SOMLGOVM"],
-
- "random_gibberish": ["g", "squid", "r", "carbon dioxide"],
-
- "y_replacements": ["y", "i", "e"],
-
- "create_verbs": ["spawn", "MAke me", "creat", "tc trade me", "gib"],
-
- "create_nouns": [
- "zenomorfs",
- "ayleins",
- "treaitors",
- "sheadow lings",
- "abdoocters",
- "revinent",
- "deval",
- "deth squads",
- "bleb",
- "cock cult",
- "anteg"
- ],
-
- "aspawnships": [
- "BUblBUE",
- "RoUBE",
- "PeEL",
- "TWInkLRE",
- "MAYONEISE",
- "raEDIO",
- "joUPITR",
- "HAELR TROCK",
- "BEYOO",
- "TID"
- ],
-
- "bug": ["", "IS TIS A BUG??", "SI IST A BUGG/", "BUG!!!"],
-
- "semicolon": ["", ";", ".h"],
-
- "ghetto": ["ghetcheom", "ghettoghemc", "gahttochem"],
"god_foe": [
"MORTALS",
diff --git a/tgui/packages/tgui-dev-server/package.json b/tgui/packages/tgui-dev-server/package.json
index 56951b14846f..a026558a47a1 100644
--- a/tgui/packages/tgui-dev-server/package.json
+++ b/tgui/packages/tgui-dev-server/package.json
@@ -8,6 +8,6 @@
"glob": "^7.1.7",
"source-map": "^0.7.3",
"stacktrace-parser": "^0.1.10",
- "ws": "^7.5.3"
+ "ws": "^7.5.10"
}
}
diff --git a/tgui/packages/tgui/interfaces/Cargo.js b/tgui/packages/tgui/interfaces/Cargo.js
deleted file mode 100644
index 9dfcd417f593..000000000000
--- a/tgui/packages/tgui/interfaces/Cargo.js
+++ /dev/null
@@ -1,533 +0,0 @@
-import { flow } from 'common/fp';
-import { filter, sortBy } from 'common/collections';
-import { useBackend, useSharedState } from '../backend';
-import {
- AnimatedNumber,
- Box,
- Button,
- Flex,
- Icon,
- Input,
- LabeledList,
- NoticeBox,
- Section,
- Stack,
- Table,
- Tabs,
-} from '../components';
-import { formatMoney } from '../format';
-import { Window } from '../layouts';
-
-export const Cargo = (props, context) => {
- return (
-
-
-
-
-
- );
-};
-
-export const CargoContent = (props, context) => {
- const { act, data } = useBackend(context);
- const [tab, setTab] = useSharedState(context, 'tab', 'catalog');
- const { requestonly } = data;
- const cart = data.cart || [];
- const requests = data.requests || [];
- return (
-
-
-
-
- setTab('catalog')}
- >
- Catalog
-
- 0 && 'yellow'}
- selected={tab === 'requests'}
- onClick={() => setTab('requests')}
- >
- Requests ({requests.length})
-
- {!requestonly && (
- <>
- 0 && 'yellow'}
- selected={tab === 'cart'}
- onClick={() => setTab('cart')}
- >
- Checkout ({cart.length})
-
- setTab('help')}
- >
- Help
-
- >
- )}
-
-
- {tab === 'catalog' && }
- {tab === 'requests' && }
- {tab === 'cart' && }
- {tab === 'help' && }
-
- );
-};
-
-const CargoStatus = (props, context) => {
- const { act, data } = useBackend(context);
- const {
- department,
- grocery,
- away,
- docked,
- loan,
- loan_dispatched,
- location,
- message,
- points,
- requestonly,
- can_send,
- } = data;
- return (
-
- formatMoney(value)}
- />
- {' credits'}
-
- }
- >
-
-
- {(docked && !requestonly && can_send && (
-
- {message}
- {!!loan && !requestonly && (
-
- {(!loan_dispatched && (
-
- )}
-
-
- );
-};
-
-/**
- * Take entire supplies tree
- * and return a flat supply pack list that matches search,
- * sorted by name and only the first page.
- * @param {any[]} supplies Supplies list.
- * @param {string} search The search term
- * @returns {any[]} The flat list of supply packs.
- */
-const searchForSupplies = (supplies, search) => {
- search = search.toLowerCase();
-
- return flow([
- (categories) => categories.flatMap((category) => category.packs),
- filter(
- (pack) =>
- pack.name?.toLowerCase().includes(search.toLowerCase()) ||
- pack.desc?.toLowerCase().includes(search.toLowerCase())
- ),
- sortBy((pack) => pack.name),
- (packs) => packs.slice(0, 25),
- ])(supplies);
-};
-
-export const CargoCatalog = (props, context) => {
- const { express } = props;
- const { act, data } = useBackend(context);
-
- const { self_paid, app_cost } = data;
-
- const supplies = Object.values(data.supplies);
-
- const [activeSupplyName, setActiveSupplyName] = useSharedState(
- context,
- 'supply',
- supplies[0]?.name
- );
-
- const [searchText, setSearchText] = useSharedState(
- context,
- 'search_text',
- ''
- );
-
- const activeSupply =
- activeSupplyName === 'search_results'
- ? { packs: searchForSupplies(supplies, searchText) }
- : supplies.find((supply) => supply.name === activeSupplyName);
-
- return (
-
-
- act('toggleprivate')}
- />
- >
- )
- }
- >
-
-
-
-
-
-
-
-
-
- {
- if (value === searchText) {
- return;
- }
-
- if (value.length) {
- // Start showing results
- setActiveSupplyName('search_results');
- } else if (activeSupplyName === 'search_results') {
- // return to normal category
- setActiveSupplyName(supplies[0]?.name);
- }
- setSearchText(value);
- }}
- onChange={(e, value) => {
- // Allow edge cases like the X button to work
- const onInput = e.target?.props?.onInput;
- if (onInput) {
- onInput(e, value);
- }
- }}
- />
-
-
-
- {supplies.map((supply) => (
- {
- setActiveSupplyName(supply.name);
- setSearchText('');
- }}
- >
- {supply.name} ({supply.packs.length})
-
- ))}
-
-
-
-
- )}
- {cart.length > 0 && !requestonly && (
-
- {(away === 1 && docked === 1 && (
- act('send')}
- />
- )) || Shuttle in {location}.}
-
- )}
-
- );
-};
-
-const CargoHelp = (props, context) => {
- return (
- <>
-
- Each department on the station will order crates from their own personal
- consoles. These orders are ENTIRELY FREE! They do not come out of
- cargo's budget, and rather put the consoles on cooldown. So
- here's where you come in: The ordered crates will show up on your
- supply console, and you need to deliver the crates to the orderers.
- You'll actually be paid the full value of the department crate on
- delivery if the crate was not tampered with, making the system a good
- source of income.
-
-
- Examine a department order crate to get specific details about where
- the crate needs to go.
-
-
-
- MULEbots are slow but loyal delivery bots that will get crates delivered
- with minimal technician effort required. It is slow, though, and can be
- tampered with while en route.
-
- Setting up a MULEbot is easy:
-
- 1. Drag the crate you want to deliver next to the MULEbot.
-
- 2. Drag the crate on top of MULEbot. It should load on.
-
- 3. Open your PDA.
-
- 4. Click Delivery Bot Control.
- 5. Click Scan for Active Bots.
- 6. Choose your MULE.
-
- 7. Click on Destination: (set).
- 8. Choose a destination and click OK.
-
- 9. Click Proceed.
-
-
- In addition to MULEs and hand-deliveries, you can also make use of the
- disposals mailing system. Note that a break in the disposal piping could
- cause your package to be lost (this hardly ever happens), so this is not
- always the most secure ways to deliver something. You can wrap up a
- piece of paper and mail it the same way if you (or someone at the desk)
- wants to mail a letter.
-
- Using the Disposals Delivery System is even easier:
-
- 1. Wrap your item/crate in packaging paper.
-
- 2. Use the destinations tagger to choose where to send it.
-
- 3. Tag the package.
-
- 4. Stick it on the conveyor and let the system handle it.
-
-
-
- Pondering something not included here? When in doubt, ask the QM!
-
- >
- );
-};
diff --git a/tgui/packages/tgui/interfaces/Cloner.js b/tgui/packages/tgui/interfaces/Cloner.js
index 6ee432e694d0..0719666642cc 100644
--- a/tgui/packages/tgui/interfaces/Cloner.js
+++ b/tgui/packages/tgui/interfaces/Cloner.js
@@ -26,7 +26,7 @@ export const Cloner = (props, context) => {
beakerContents={data.beakerContents}
/>
-
+ {
+ const { act, data } = useBackend(context);
+ const { names = [] } = data;
+
+ const [lastNameBeforeEdit, setLastNameBeforeEdit] = useLocalState<
+ string | null
+ >(context, 'lastNameBeforeEdit', null);
+
+ return (
+
+
+ {(!names.length && {'No known names!'}) || (
+
+ {names.map((name) => (
+
+
+ {
+ setLastNameBeforeEdit(name.real_name);
+ }}
+ >
+ {(lastNameBeforeEdit === name.real_name && (
+ {
+ act('rename_guest', {
+ real_name: name.real_name,
+ new_name: value,
+ });
+ setLastNameBeforeEdit(null);
+ }}
+ onEscape={() => {
+ setLastNameBeforeEdit(null);
+ }}
+ value={name.given_name}
+ />
+ )) || {name.given_name}}
+
+ {
+ act('delete_guest', {
+ real_name: name.real_name,
+ });
+ }}
+ color={'bad'}
+ >
+ Forget
+
+
+
+ ))}
+
+ )}
+
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/HydrogenExchange.js b/tgui/packages/tgui/interfaces/HydrogenExchange.js
new file mode 100644
index 000000000000..c07fe40afeab
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/HydrogenExchange.js
@@ -0,0 +1,74 @@
+import { useBackend } from '../backend';
+import { Button, LabeledList, Section } from '../components';
+import { Window } from '../layouts';
+
+export const HydrogenExchange = (props, context) => {
+ const { act, data } = useBackend(context);
+ const { credits, merits, next_merit_rate, credits_to_merits, credit_tax } =
+ data;
+ return (
+
+
+
+
+
+ {' '}
+ {credit_tax + '%'}
+
+
+ {' '}
+ {next_merit_rate + 'cr'}
+
+
+
+
+
+ act('convert_to_merits')}
+ />
+ }
+ />
+ act('convert_to_credits')}
+ />
+ }
+ />
+ act('dispense')}
+ />
+ }
+ />
+
+
+
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/Orbit.js b/tgui/packages/tgui/interfaces/Orbit.js
index 91bf9d1f7929..c34dccacf367 100644
--- a/tgui/packages/tgui/interfaces/Orbit.js
+++ b/tgui/packages/tgui/interfaces/Orbit.js
@@ -54,6 +54,7 @@ const BasicSection = (props, context) => {
{things.map((thing) => (
act('orbit', {
@@ -74,6 +75,7 @@ const OrbitedButton = (props, context) => {
return (
act('orbit', {
ref: thing.ref,
diff --git a/tgui/packages/tgui/interfaces/OutpostCommunications/Catalog.js b/tgui/packages/tgui/interfaces/OutpostCommunications/Catalog.js
new file mode 100644
index 000000000000..ebcad5d6a051
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/OutpostCommunications/Catalog.js
@@ -0,0 +1,190 @@
+import { flow } from 'common/fp';
+import { filter, sortBy } from 'common/collections';
+import { useBackend, useSharedState } from '../../backend';
+import {
+ Box,
+ Button,
+ Flex,
+ Icon,
+ Input,
+ Section,
+ Stack,
+ Table,
+ Tabs,
+} from '../../components';
+import { formatMoney } from '../../format';
+
+export const CargoCatalog = (props, context) => {
+ const { act, data } = useBackend(context);
+
+ const { self_paid, app_cost } = data;
+
+ const supplies = Object.values(data.supplies);
+
+ const [activeSupplyName, setActiveSupplyName] = useSharedState(
+ context,
+ 'supply',
+ supplies[0]?.name
+ );
+
+ const [searchText, setSearchText] = useSharedState(
+ context,
+ 'search_text',
+ ''
+ );
+
+ const activeSupply =
+ activeSupplyName === 'search_results'
+ ? { packs: searchForSupplies(supplies, searchText) }
+ : supplies.find((supply) => supply.name === activeSupplyName);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {
+ if (value === searchText) {
+ return;
+ }
+
+ if (value.length) {
+ // Start showing results
+ setActiveSupplyName('search_results');
+ } else if (activeSupplyName === 'search_results') {
+ // return to normal category
+ setActiveSupplyName(supplies[0]?.name);
+ }
+ setSearchText(value);
+ }}
+ onChange={(e, value) => {
+ // Allow edge cases like the X button to work
+ const onInput = e.target?.props?.onInput;
+ if (onInput) {
+ onInput(e, value);
+ }
+ }}
+ />
+
+
+
+ {supplies.map((supply) => (
+ {
+ setActiveSupplyName(supply.name);
+ setSearchText('');
+ }}
+ >
+ {supply.name} ({supply.packs.length})
+
+ ))}
+
+
+
+