mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Tsu's Brand Spanking New Storage: or, How I Learned To Pass Github Copilot As My Own Code (#67478)
Currently, storage works as a subtype of /datum/component, utilizing GetComponent() and signals to operate. While this is a pretty good idea in theory, the execution was pretty trash, and we end up with alot of GetComponent() snowflake code (something that shouldn't even need to be used frankly), and a heaping load of scattered procs that lead into one another, and procs that don't get utilized properly. Instead, this PR adds atom_storage and proc/create_storage(. . .) to every atom, allowing for the possibility of storage on quite frankly anything. Not only does this entirely remove the need for signals, but it heavily squashes down the number of needed procs in total (removing snowflake signal procs that just lead to one another), reducing overall proc overhead and improving performance.
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
// /datum/component/storage signals
|
||||
///() - returns bool.
|
||||
#define COMSIG_CONTAINS_STORAGE "is_storage"
|
||||
///(obj/item/inserting, mob/user, silent, force) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert"
|
||||
///(mob/show_to, force) - returns bool.
|
||||
#define COMSIG_TRY_STORAGE_SHOW "storage_show_to"
|
||||
///(mob/hide_from) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from"
|
||||
///returns bool
|
||||
#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all"
|
||||
///(newstate)
|
||||
#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state"
|
||||
///() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST!
|
||||
#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate"
|
||||
///(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types.
|
||||
#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type"
|
||||
///(type, amount = INFINITY, force = FALSE). Force will ignore max_items, and amount is normally clamped to max_items.
|
||||
#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type"
|
||||
///(obj, new_loc, force = FALSE) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj"
|
||||
///(loc) - returns bool - if loc is null it will dump at parent location.
|
||||
#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty"
|
||||
///(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE)
|
||||
#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory"
|
||||
///(obj/item/insertion_candidate, mob/user, silent) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip"
|
||||
|
||||
//from base of atom/movable/on_enter_storage(): (datum/component/storage/concrete/master_storage)
|
||||
#define COMSIG_STORAGE_ENTERED "storage_entered"
|
||||
//from base of atom/movable/on_exit_storage(): (datum/component/storage/concrete/master_storage)
|
||||
#define COMSIG_STORAGE_EXITED "storage_exited"
|
||||
@@ -58,6 +58,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define IS_PLAYER_COLORABLE_1 (1<<21)
|
||||
/// Whether or not this atom has contextual screentips when hovered OVER
|
||||
#define HAS_CONTEXTUAL_SCREENTIPS_1 (1<<22)
|
||||
// Whether or not this atom is storing contents for a disassociated storage object
|
||||
#define HAS_DISASSOCIATED_STORAGE_1 (1<<23)
|
||||
|
||||
// Update flags for [/atom/proc/update_appearance]
|
||||
/// Update the atom's name
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
//ITEM INVENTORY WEIGHT, FOR w_class
|
||||
/// Usually items smaller then a human hand, (e.g. playing cards, lighter, scalpel, coins/holochips)
|
||||
#define WEIGHT_CLASS_TINY 1
|
||||
#define WEIGHT_CLASS_TINY 1
|
||||
/// Pockets can hold small and tiny items, (e.g. flashlight, multitool, grenades, GPS device)
|
||||
#define WEIGHT_CLASS_SMALL 2
|
||||
#define WEIGHT_CLASS_SMALL 2
|
||||
/// Standard backpacks can carry tiny, small & normal items, (e.g. fire extinguisher, stun baton, gas mask, metal sheets)
|
||||
#define WEIGHT_CLASS_NORMAL 3
|
||||
#define WEIGHT_CLASS_NORMAL 3
|
||||
/// Items that can be weilded or equipped but not stored in an inventory, (e.g. defibrillator, backpack, space suits)
|
||||
#define WEIGHT_CLASS_BULKY 4
|
||||
#define WEIGHT_CLASS_BULKY 4
|
||||
/// Usually represents objects that require two hands to operate, (e.g. shotgun, two-handed melee weapons)
|
||||
#define WEIGHT_CLASS_HUGE 5
|
||||
#define WEIGHT_CLASS_HUGE 5
|
||||
/// Essentially means it cannot be picked up or placed in an inventory, (e.g. mech parts, safe)
|
||||
#define WEIGHT_CLASS_GIGANTIC 6
|
||||
|
||||
|
||||
@@ -319,11 +319,7 @@ rough example of the "cone" made by the 3 dirs checked
|
||||
. = list()
|
||||
if(!istype(target) || !(target.item_flags & IN_STORAGE))
|
||||
return
|
||||
var/datum/component/storage/concrete/storage_datum = target.loc.GetComponent(/datum/component/storage/concrete)
|
||||
var/datum/storage/storage_datum = target.loc.atom_storage
|
||||
if(!storage_datum)
|
||||
return
|
||||
. += storage_datum.parent
|
||||
for(var/datum/component/storage/slave as anything in storage_datum.slaves)
|
||||
if(!isatom(slave.parent))
|
||||
continue
|
||||
. += slave.parent
|
||||
|
||||
@@ -116,6 +116,7 @@ DEFINE_BITFIELD(flags_1, list(
|
||||
"CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1,
|
||||
"CONDUCT_1" = CONDUCT_1,
|
||||
"HAS_CONTEXTUAL_SCREENTIPS_1" = HAS_CONTEXTUAL_SCREENTIPS_1,
|
||||
"HAS_DISASSOCIATED_STORAGE_1" = HAS_DISASSOCIATED_STORAGE_1,
|
||||
"HOLOGRAM_1" = HOLOGRAM_1,
|
||||
"INITIALIZED_1" = INITIALIZED_1,
|
||||
"IS_ONTOP_1" = IS_ONTOP_1,
|
||||
|
||||
+10
-3
@@ -153,6 +153,12 @@
|
||||
if(!loc.AllowClick())
|
||||
return
|
||||
|
||||
// In a storage item with a disassociated storage parent
|
||||
var/obj/item/item_atom = A
|
||||
if(istype(item_atom))
|
||||
if((item_atom.item_flags & IN_STORAGE) && (item_atom.loc.flags_1 & HAS_DISASSOCIATED_STORAGE_1))
|
||||
UnarmedAttack(item_atom, TRUE, modifiers)
|
||||
|
||||
//Standard reach turf to turf or reaching inside storage
|
||||
if(CanReach(A,W))
|
||||
if(W)
|
||||
@@ -206,6 +212,7 @@
|
||||
|
||||
var/list/closed = list()
|
||||
var/list/checking = list(ultimate_target)
|
||||
|
||||
while (checking.len && depth > 0)
|
||||
var/list/next = list()
|
||||
--depth
|
||||
@@ -214,7 +221,7 @@
|
||||
if(closed[target] || isarea(target)) // avoid infinity situations
|
||||
continue
|
||||
|
||||
if(isturf(target) || isturf(target.loc) || (target in direct_access) || (ismovable(target) && target.flags_1 & IS_ONTOP_1)) //Directly accessible atoms
|
||||
if(isturf(target) || isturf(target.loc) || (target in direct_access) || (ismovable(target) && target.flags_1 & IS_ONTOP_1) || target.loc.atom_storage) //Directly accessible atoms
|
||||
if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks
|
||||
return TRUE
|
||||
|
||||
@@ -223,8 +230,7 @@
|
||||
if (!target.loc)
|
||||
continue
|
||||
|
||||
//Storage and things with reachable internal atoms need add to next here. Or return COMPONENT_ALLOW_REACH.
|
||||
if(SEND_SIGNAL(target.loc, COMSIG_ATOM_CANREACH, next) & COMPONENT_ALLOW_REACH)
|
||||
if(target.loc.atom_storage)
|
||||
next += target.loc
|
||||
|
||||
checking = next
|
||||
@@ -285,6 +291,7 @@
|
||||
* modifiers is a lazy list of click modifiers this attack had,
|
||||
* used for figuring out different properties of the click, mostly right vs left and such.
|
||||
*/
|
||||
|
||||
/mob/proc/UnarmedAttack(atom/A, proximity_flag, list/modifiers)
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
|
||||
@@ -247,8 +247,8 @@
|
||||
master = new_master
|
||||
|
||||
/atom/movable/screen/close/Click()
|
||||
var/datum/component/storage/S = master
|
||||
S.hide_from(usr)
|
||||
var/datum/storage/storage = master
|
||||
storage.hide_contents(usr)
|
||||
return TRUE
|
||||
|
||||
/atom/movable/screen/drop
|
||||
@@ -453,7 +453,7 @@
|
||||
return TRUE
|
||||
if(usr.incapacitated())
|
||||
return TRUE
|
||||
if (ismecha(usr.loc)) // stops inventory actions in a mech
|
||||
if(ismecha(usr.loc)) // stops inventory actions in a mech
|
||||
return TRUE
|
||||
if(master)
|
||||
var/obj/item/I = usr.get_active_held_item()
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
var/list/present_qualities = list()
|
||||
|
||||
for(var/obj/item/contained_item in source.contents)
|
||||
if(contained_item.GetComponent(/datum/component/storage))
|
||||
if(contained_item.atom_storage)
|
||||
for(var/obj/item/subcontained_item in contained_item.contents)
|
||||
available_tools[subcontained_item.type] = TRUE
|
||||
if(subcontained_item.tool_behaviour)
|
||||
|
||||
@@ -34,8 +34,10 @@
|
||||
if(isclothing(parent))
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
if(SEND_SIGNAL(parent, COMSIG_CONTAINS_STORAGE))
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/explodable_insert_item)
|
||||
|
||||
var/atom/atom_parent = parent
|
||||
if(atom_parent.atom_storage)
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/explodable_insert_item)
|
||||
|
||||
if (devastation_range)
|
||||
src.devastation_range = devastation_range
|
||||
@@ -51,9 +53,11 @@
|
||||
src.delete_after = delete_after
|
||||
|
||||
/// Explode if our parent is a storage place and something with high heat is inserted in.
|
||||
/datum/component/explodable/proc/explodable_insert_item(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
|
||||
/datum/component/explodable/proc/explodable_insert_item(datum/source, obj/item/I)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!(I.item_flags & IN_STORAGE))
|
||||
return
|
||||
|
||||
check_if_detonate(I)
|
||||
|
||||
/datum/component/explodable/proc/explodable_impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/handle_movement)
|
||||
RegisterSignal(parent, list(
|
||||
COMSIG_ITEM_PICKUP, //person picks up an item
|
||||
COMSIG_STORAGE_ENTERED), //Object enters a storage object (boxes, etc.)
|
||||
COMSIG_ATOM_ENTERED), //Object enters a storage object (boxes, etc.)
|
||||
.proc/picked_up)
|
||||
RegisterSignal(parent, list(
|
||||
COMSIG_ITEM_DROPPED, //Object is dropped anywhere
|
||||
COMSIG_STORAGE_EXITED), //Object exits a storage object (boxes, etc)
|
||||
COMSIG_ATOM_EXITED), //Object exits a storage object (boxes, etc)
|
||||
.proc/dropped)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||
|
||||
@@ -59,10 +59,10 @@
|
||||
/datum/component/decomposition/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_ITEM_PICKUP,
|
||||
COMSIG_STORAGE_ENTERED,
|
||||
COMSIG_ATOM_ENTERED,
|
||||
COMSIG_MOVABLE_MOVED,
|
||||
COMSIG_ITEM_DROPPED,
|
||||
COMSIG_STORAGE_EXITED,
|
||||
COMSIG_ATOM_EXITED,
|
||||
COMSIG_PARENT_EXAMINE))
|
||||
|
||||
/datum/component/decomposition/proc/handle_movement()
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
RegisterSignal(parent, list(
|
||||
COMSIG_ITEM_DROPPED,
|
||||
COMSIG_ITEM_EQUIPPED,
|
||||
COMSIG_STORAGE_ENTERED,
|
||||
COMSIG_STORAGE_EXITED,
|
||||
COMSIG_ATOM_ENTERED,
|
||||
COMSIG_ATOM_EXITED,
|
||||
), .proc/check_my_loc)
|
||||
|
||||
/datum/component/holderloving/UnregisterFromParent()
|
||||
@@ -44,8 +44,8 @@
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_ITEM_DROPPED,
|
||||
COMSIG_ITEM_EQUIPPED,
|
||||
COMSIG_STORAGE_ENTERED,
|
||||
COMSIG_STORAGE_EXITED,
|
||||
COMSIG_ATOM_ENTERED,
|
||||
COMSIG_ATOM_EXITED,
|
||||
))
|
||||
|
||||
/datum/component/holderloving/PostTransfer()
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
|
||||
// External storage-related logic:
|
||||
// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages
|
||||
// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement
|
||||
|
||||
/datum/component/storage/concrete
|
||||
can_transfer = TRUE
|
||||
var/drop_all_on_deconstruct = TRUE
|
||||
var/drop_all_on_destroy = FALSE
|
||||
var/transfer_contents_on_component_transfer = FALSE
|
||||
var/list/datum/component/storage/slaves = list()
|
||||
|
||||
var/list/_contents_limbo // Where objects go to live mid transfer
|
||||
var/list/_user_limbo // The last users before the component started moving
|
||||
|
||||
/datum/component/storage/concrete/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(parent, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del)
|
||||
RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, .proc/on_deconstruct)
|
||||
|
||||
/datum/component/storage/concrete/Destroy()
|
||||
var/atom/real_location = real_location()
|
||||
for(var/atom/_A in real_location)
|
||||
_A.mouse_opacity = initial(_A.mouse_opacity)
|
||||
if(drop_all_on_destroy)
|
||||
do_quick_empty()
|
||||
for(var/i in slaves)
|
||||
var/datum/component/storage/slave = i
|
||||
slave.change_master(null)
|
||||
QDEL_LIST(_contents_limbo)
|
||||
_user_limbo = null
|
||||
return ..()
|
||||
|
||||
/datum/component/storage/concrete/master()
|
||||
return src
|
||||
|
||||
/datum/component/storage/concrete/real_location()
|
||||
return parent
|
||||
|
||||
/datum/component/storage/concrete/PreTransfer()
|
||||
if(is_using)
|
||||
_user_limbo = is_using.Copy()
|
||||
close_all()
|
||||
if(transfer_contents_on_component_transfer)
|
||||
_contents_limbo = list()
|
||||
for(var/atom/movable/AM in parent)
|
||||
_contents_limbo += AM
|
||||
AM.moveToNullspace()
|
||||
|
||||
/datum/component/storage/concrete/PostTransfer()
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(transfer_contents_on_component_transfer)
|
||||
for(var/i in _contents_limbo)
|
||||
var/atom/movable/AM = i
|
||||
AM.forceMove(parent)
|
||||
_contents_limbo = null
|
||||
if(_user_limbo)
|
||||
for(var/i in _user_limbo)
|
||||
show_to(i)
|
||||
_user_limbo = null
|
||||
|
||||
/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE)
|
||||
. = TRUE
|
||||
var/atom/real_location = real_location()
|
||||
if(I.loc != real_location)
|
||||
I.forceMove(real_location)
|
||||
refresh_mob_views()
|
||||
|
||||
/datum/component/storage/concrete/refresh_mob_views()
|
||||
. = ..()
|
||||
for(var/i in slaves)
|
||||
var/datum/component/storage/slave = i
|
||||
slave.refresh_mob_views()
|
||||
|
||||
/datum/component/storage/concrete/emp_act(datum/source, severity)
|
||||
if(emp_shielded)
|
||||
return
|
||||
var/atom/real_location = real_location()
|
||||
for(var/i in real_location)
|
||||
var/atom/A = i
|
||||
A.emp_act(severity)
|
||||
|
||||
/datum/component/storage/concrete/proc/on_slave_link(datum/component/storage/S)
|
||||
if(S == src)
|
||||
return FALSE
|
||||
slaves += S
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/concrete/proc/on_slave_unlink(datum/component/storage/S)
|
||||
slaves -= S
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A)
|
||||
SIGNAL_HANDLER
|
||||
var/atom/real_location = parent
|
||||
if(A in real_location)
|
||||
usr = null
|
||||
remove_from_storage(A, null)
|
||||
|
||||
/datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled)
|
||||
SIGNAL_HANDLER
|
||||
if(drop_all_on_deconstruct)
|
||||
do_quick_empty()
|
||||
|
||||
/datum/component/storage/concrete/can_see_contents()
|
||||
. = ..()
|
||||
for(var/i in slaves)
|
||||
var/datum/component/storage/slave = i
|
||||
. |= slave.can_see_contents()
|
||||
|
||||
//Resets screen loc and other vars of something being removed from storage.
|
||||
/datum/component/storage/concrete/_removal_reset(atom/movable/thing)
|
||||
thing.layer = initial(thing.layer)
|
||||
thing.plane = initial(thing.plane)
|
||||
thing.mouse_opacity = initial(thing.mouse_opacity)
|
||||
if(thing.maptext)
|
||||
thing.maptext = ""
|
||||
|
||||
/datum/component/storage/concrete/remove_from_storage(atom/movable/AM, atom/new_location)
|
||||
//Cache this as it should be reusable down the bottom, will not apply if anyone adds a sleep to dropped
|
||||
//or moving objects, things that should never happen
|
||||
var/atom/parent = src.parent
|
||||
var/list/seeing_mobs = can_see_contents()
|
||||
for(var/mob/M in seeing_mobs)
|
||||
M.client.screen -= AM
|
||||
if(isitem(AM))
|
||||
var/obj/item/removed_item = AM
|
||||
removed_item.item_flags &= ~IN_STORAGE
|
||||
if(ismob(parent.loc))
|
||||
var/mob/carrying_mob = parent.loc
|
||||
removed_item.dropped(carrying_mob, TRUE)
|
||||
if(new_location)
|
||||
//Reset the items values
|
||||
_removal_reset(AM)
|
||||
AM.forceMove(new_location)
|
||||
//We don't want to call this if the item is being destroyed
|
||||
AM.on_exit_storage(src)
|
||||
else
|
||||
//Being destroyed, just move to nullspace now (so it's not in contents for the icon update)
|
||||
AM.moveToNullspace()
|
||||
refresh_mob_views()
|
||||
if(isobj(parent))
|
||||
var/obj/O = parent
|
||||
O.update_appearance()
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/concrete/proc/slave_can_insert_object(datum/component/storage/slave, obj/item/I, stop_messages = FALSE, mob/M)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/concrete/proc/handle_item_insertion_from_slave(datum/component/storage/slave, obj/item/I, prevent_warning = FALSE, M)
|
||||
. = handle_item_insertion(I, prevent_warning, M, slave)
|
||||
if(. && !prevent_warning)
|
||||
slave.mob_item_insertion_feedback(usr, M, I)
|
||||
|
||||
/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
var/atom/parent = src.parent
|
||||
var/moved = FALSE
|
||||
if(!istype(I))
|
||||
return FALSE
|
||||
if(M)
|
||||
if(!M.temporarilyRemoveItemFromInventory(I))
|
||||
return FALSE
|
||||
else
|
||||
moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever.
|
||||
if(I.pulledby)
|
||||
I.pulledby.stop_pulling()
|
||||
if(silent)
|
||||
prevent_warning = TRUE
|
||||
if(!_insert_physical_item(I))
|
||||
if(moved)
|
||||
if(M)
|
||||
if(!M.put_in_active_hand(I))
|
||||
I.forceMove(parent.drop_location())
|
||||
else
|
||||
I.forceMove(parent.drop_location())
|
||||
return FALSE
|
||||
I.on_enter_storage(master)
|
||||
I.item_flags |= IN_STORAGE
|
||||
refresh_mob_views()
|
||||
I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt
|
||||
if(M)
|
||||
if(M.client && M.active_storage != src)
|
||||
M.client.screen -= I
|
||||
if(M.observers && M.observers.len)
|
||||
for(var/i in M.observers)
|
||||
var/mob/dead/observe = i
|
||||
if(observe.client && observe.active_storage != src)
|
||||
observe.client.screen -= I
|
||||
if(!remote)
|
||||
parent.add_fingerprint(M)
|
||||
if(!prevent_warning)
|
||||
mob_item_insertion_feedback(usr, M, I)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/concrete/update_icon()
|
||||
if(isobj(parent))
|
||||
var/obj/O = parent
|
||||
O.update_appearance()
|
||||
for(var/i in slaves)
|
||||
var/datum/component/storage/slave = i
|
||||
slave.update_icon()
|
||||
@@ -1,27 +0,0 @@
|
||||
/datum/component/storage/concrete/bluespace/bag_of_holding/handle_item_insertion(obj/item/W, prevent_warning = FALSE, mob/living/user)
|
||||
var/atom/A = parent
|
||||
if(A == W) //don't put yourself into yourself.
|
||||
return
|
||||
var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.get_all_contents(), typecacheof(/obj/item/storage/backpack/holding))
|
||||
matching -= A
|
||||
if(istype(W, /obj/item/storage/backpack/holding) || matching.len)
|
||||
INVOKE_ASYNC(src, .proc/recursive_insertion, W, user)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/datum/component/storage/concrete/bluespace/bag_of_holding/proc/recursive_insertion(obj/item/W, mob/living/user)
|
||||
var/atom/A = parent
|
||||
var/safety = tgui_alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [A.name]?", list("Proceed", "Abort"))
|
||||
if(safety != "Proceed" || QDELETED(A) || QDELETED(W) || QDELETED(user) || !user.canUseTopic(A, BE_CLOSE, iscarbon(user)))
|
||||
return
|
||||
var/turf/loccheck = get_turf(A)
|
||||
to_chat(user, span_danger("The Bluespace interfaces of the two devices catastrophically malfunction!"))
|
||||
qdel(W)
|
||||
playsound(loccheck,'sound/effects/supermatter.ogg', 200, TRUE)
|
||||
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].")
|
||||
log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].")
|
||||
|
||||
user.gib(TRUE, TRUE, TRUE)
|
||||
new/obj/boh_tear(loccheck)
|
||||
qdel(A)
|
||||
@@ -1,22 +0,0 @@
|
||||
/datum/component/storage/concrete/bluespace
|
||||
var/dumping_range = 8
|
||||
var/dumping_sound = 'sound/items/pshoom.ogg'
|
||||
var/alt_sound = 'sound/items/pshoom_2.ogg'
|
||||
|
||||
/datum/component/storage/concrete/bluespace/dump_content_at(atom/dest, mob/M)
|
||||
var/atom/A = parent
|
||||
if(A.Adjacent(M))
|
||||
var/atom/dumping_location = dest.get_dumping_location()
|
||||
var/turf/bagT = get_turf(parent)
|
||||
var/turf/destT = get_turf(dumping_location)
|
||||
if(destT && bagT && bagT.z == destT.z && get_dist(M, dumping_location) < dumping_range)
|
||||
if(dumping_location.storage_contents_dump_act(src, M))
|
||||
if(alt_sound && prob(1))
|
||||
playsound(src, alt_sound, 40, TRUE)
|
||||
else
|
||||
playsound(src, dumping_sound, 40, TRUE)
|
||||
M.Beam(dumping_location, icon_state="rped_upgrade", time=5)
|
||||
return TRUE
|
||||
to_chat(M, span_hear("The [A.name] buzzes."))
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
|
||||
return FALSE
|
||||
@@ -1,37 +0,0 @@
|
||||
/datum/component/storage/concrete/extract_inventory
|
||||
max_combined_w_class = WEIGHT_CLASS_TINY * 3
|
||||
max_items = 3
|
||||
insert_preposition = "in"
|
||||
//These need to be false in order for the extract's food to be unextractable
|
||||
//from the inventory
|
||||
attack_hand_interact = FALSE
|
||||
quickdraw = FALSE
|
||||
can_transfer = FALSE
|
||||
drop_all_on_deconstruct = FALSE
|
||||
locked = TRUE //True in order to prevent messing with the inventory in any way other than the specified ways on reproductive.dm
|
||||
rustle_sound = FALSE
|
||||
silent = TRUE
|
||||
var/obj/item/slimecross/reproductive/parentSlimeExtract
|
||||
|
||||
|
||||
/datum/component/storage/concrete/extract_inventory/Initialize()
|
||||
. = ..()
|
||||
set_holdable(/obj/item/food/monkeycube)
|
||||
if(!istype(parent, /obj/item/slimecross/reproductive))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
parentSlimeExtract = parent
|
||||
|
||||
|
||||
/datum/component/storage/concrete/extract_inventory/proc/processCubes(obj/item/slimecross/reproductive/parentSlimeExtract, mob/user)
|
||||
|
||||
if(length(parentSlimeExtract.contents) >= max_items)
|
||||
QDEL_LIST(parentSlimeExtract.contents)
|
||||
createExtracts(parentSlimeExtract,user)
|
||||
|
||||
/datum/component/storage/concrete/extract_inventory/proc/createExtracts(obj/item/slimecross/reproductive/parentSlimeExtract, mob/user)
|
||||
var/cores = rand(1,4)
|
||||
playsound(parentSlimeExtract, 'sound/effects/splat.ogg', 40, TRUE)
|
||||
parentSlimeExtract.last_produce = world.time
|
||||
to_chat(user, span_notice("[parentSlimeExtract] briefly swells to a massive size, and expels [cores] extract[cores > 1 ? "s":""]!"))
|
||||
for(var/i in 1 to cores)
|
||||
new parentSlimeExtract.extract_type(parentSlimeExtract.drop_location())
|
||||
@@ -1,4 +0,0 @@
|
||||
/datum/component/storage/concrete/fish_case
|
||||
max_items = 1
|
||||
can_hold_trait = TRAIT_FISH_CASE_COMPATIBILE
|
||||
can_hold_description = "fish and aquarium equipment"
|
||||
@@ -1,18 +0,0 @@
|
||||
/datum/component/storage/concrete/implant
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_combined_w_class = 6
|
||||
max_items = 2
|
||||
drop_all_on_destroy = TRUE
|
||||
drop_all_on_deconstruct = TRUE
|
||||
silent = TRUE
|
||||
allow_big_nesting = TRUE
|
||||
|
||||
/datum/component/storage/concrete/implant/Initialize()
|
||||
. = ..()
|
||||
set_holdable(null, list(/obj/item/disk/nuclear))
|
||||
|
||||
/datum/component/storage/concrete/implant/InheritComponent(datum/component/storage/concrete/implant/I, original)
|
||||
if(!istype(I))
|
||||
return ..()
|
||||
max_combined_w_class += I.max_combined_w_class
|
||||
max_items += I.max_items
|
||||
@@ -1,33 +0,0 @@
|
||||
/datum/component/storage/concrete/rped
|
||||
collection_mode = COLLECT_EVERYTHING
|
||||
allow_quick_gather = TRUE
|
||||
allow_quick_empty = TRUE
|
||||
click_gather = TRUE
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_combined_w_class = 100
|
||||
max_items = 50
|
||||
display_numerical_stacking = TRUE
|
||||
|
||||
/datum/component/storage/concrete/rped/can_be_inserted(obj/item/I, stop_messages, mob/M)
|
||||
. = ..()
|
||||
if(!I.get_part_rating())
|
||||
if (!stop_messages)
|
||||
to_chat(M, span_warning("[parent] only accepts machine parts!"))
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/concrete/bluespace/rped
|
||||
collection_mode = COLLECT_EVERYTHING
|
||||
allow_quick_gather = TRUE
|
||||
allow_quick_empty = TRUE
|
||||
click_gather = TRUE
|
||||
max_w_class = WEIGHT_CLASS_BULKY // can fit vending refills
|
||||
max_combined_w_class = 800
|
||||
max_items = 400
|
||||
display_numerical_stacking = TRUE
|
||||
|
||||
/datum/component/storage/concrete/bluespace/rped/can_be_inserted(obj/item/I, stop_messages, mob/M)
|
||||
. = ..()
|
||||
if(!I.get_part_rating())
|
||||
if (!stop_messages)
|
||||
to_chat(M, span_warning("[parent] only accepts machine parts!"))
|
||||
return FALSE
|
||||
@@ -1,68 +0,0 @@
|
||||
//Stack-only storage.
|
||||
/datum/component/storage/concrete/stack
|
||||
display_numerical_stacking = TRUE
|
||||
var/max_combined_stack_amount = 300
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_combined_w_class = WEIGHT_CLASS_NORMAL * 14
|
||||
|
||||
/datum/component/storage/concrete/stack/proc/total_stack_amount()
|
||||
. = 0
|
||||
var/atom/real_location = real_location()
|
||||
for(var/i in real_location)
|
||||
var/obj/item/stack/S = i
|
||||
if(!istype(S))
|
||||
continue
|
||||
. += S.amount
|
||||
|
||||
/datum/component/storage/concrete/stack/proc/remaining_space()
|
||||
return max(0, max_combined_stack_amount - total_stack_amount())
|
||||
|
||||
//emptying procs do not need modification as stacks automatically merge.
|
||||
|
||||
/datum/component/storage/concrete/stack/_insert_physical_item(obj/item/I, override = FALSE)
|
||||
if(!istype(I, /obj/item/stack))
|
||||
if(override)
|
||||
return ..()
|
||||
return FALSE
|
||||
var/atom/real_location = real_location()
|
||||
var/obj/item/stack/S = I
|
||||
var/can_insert = min(S.amount, remaining_space())
|
||||
if(!can_insert)
|
||||
return FALSE
|
||||
for(var/i in real_location) //combine.
|
||||
if(QDELETED(I))
|
||||
return
|
||||
var/obj/item/stack/_S = i
|
||||
if(!istype(_S))
|
||||
continue
|
||||
if(_S.merge_type == S.merge_type)
|
||||
_S.add(can_insert)
|
||||
S.use(can_insert, TRUE)
|
||||
return TRUE
|
||||
I = S.split_stack(null, can_insert)
|
||||
return ..()
|
||||
|
||||
/datum/component/storage/concrete/stack/remove_from_storage(obj/item/I, atom/new_location)
|
||||
var/atom/real_location = real_location()
|
||||
var/obj/item/stack/S = I
|
||||
if(!istype(S))
|
||||
return ..()
|
||||
if(S.amount > S.max_amount)
|
||||
var/overrun = S.amount - S.max_amount
|
||||
S.amount = S.max_amount
|
||||
var/obj/item/stack/temp = new S.type(real_location, overrun)
|
||||
handle_item_insertion(temp)
|
||||
return ..(S, new_location)
|
||||
|
||||
/datum/component/storage/concrete/stack/_process_numerical_display()
|
||||
var/atom/real_location = real_location()
|
||||
. = list()
|
||||
for(var/i in real_location)
|
||||
var/obj/item/stack/I = i
|
||||
if(!istype(I) || QDELETED(I)) //We're specialized stack storage, just ignore non stacks.
|
||||
continue
|
||||
if(!.[I.merge_type])
|
||||
.[I.merge_type] = new /datum/numbered_display(I, I.amount)
|
||||
else
|
||||
var/datum/numbered_display/ND = .[I.merge_type]
|
||||
ND.number += I.amount
|
||||
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
*A storage component to be used on card piles, for use as hands/decks/discard piles. Don't use on something that's not a card pile!
|
||||
*/
|
||||
/datum/component/storage/concrete/tcg
|
||||
display_numerical_stacking = FALSE
|
||||
max_w_class = WEIGHT_CLASS_TINY
|
||||
max_items = 30
|
||||
max_combined_w_class = WEIGHT_CLASS_TINY * 30
|
||||
///The deck that the card pile is using for FAIR PLAY.
|
||||
|
||||
/datum/component/storage/concrete/tcg/Initialize()
|
||||
. = ..()
|
||||
set_holdable(list(/obj/item/tcgcard))
|
||||
|
||||
/datum/component/storage/concrete/tcg/PostTransfer()
|
||||
. = ..()
|
||||
handle_empty_deck()
|
||||
|
||||
/datum/component/storage/concrete/tcg/remove_from_storage(atom/movable/AM, atom/new_location)
|
||||
. = ..()
|
||||
handle_empty_deck()
|
||||
|
||||
/datum/component/storage/concrete/tcg/show_to(mob/M)
|
||||
. = ..()
|
||||
M.visible_message(span_notice("[M] starts to look through the contents of \the [parent]!"), \
|
||||
span_notice("You begin looking into the contents of \the [parent]!"))
|
||||
|
||||
/datum/component/storage/concrete/tcg/close(mob/M)
|
||||
. = ..()
|
||||
var/list/card_contents = contents()
|
||||
var/obj/temp_parent = parent
|
||||
temp_parent.visible_message(span_notice("\the [parent] is shuffled after looking through it."))
|
||||
card_contents = shuffle(card_contents)
|
||||
|
||||
/datum/component/storage/concrete/tcg/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found)
|
||||
. = ..()
|
||||
if(!things.len)
|
||||
qdel(parent)
|
||||
|
||||
/datum/component/storage/concrete/tcg/proc/handle_empty_deck()
|
||||
var/list/contents = contents()
|
||||
//You can't have a deck of one card!
|
||||
if(contents.len == 1)
|
||||
var/obj/item/tcgcard_deck/deck = parent
|
||||
var/obj/item/tcgcard/card = contents[1]
|
||||
remove_from_storage(card, card.drop_location())
|
||||
card.flipped = deck.flipped
|
||||
card.update_icon_state()
|
||||
qdel(parent)
|
||||
@@ -1,13 +0,0 @@
|
||||
/datum/component/storage/concrete/wallet/open_storage(mob/user)
|
||||
if(!isliving(user) || !user.CanReach(parent) || user.incapacitated())
|
||||
return FALSE
|
||||
if(locked)
|
||||
to_chat(user, span_warning("[parent] seems to be locked!"))
|
||||
return
|
||||
|
||||
var/obj/item/storage/wallet/A = parent
|
||||
if(istype(A) && A.front_id && !issilicon(user) && !(A.item_flags & IN_STORAGE)) //if it's a wallet in storage seeing the full inventory is more useful
|
||||
var/obj/item/I = A.front_id
|
||||
INVOKE_ASYNC(src, .proc/attempt_put_in_hands, I, user)
|
||||
return TRUE
|
||||
return ..()
|
||||
@@ -1,960 +0,0 @@
|
||||
// External storage-related logic:
|
||||
// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages
|
||||
// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement
|
||||
|
||||
/datum/component/storage
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE
|
||||
///If not null, all actions act on master and this is just an access point.
|
||||
var/datum/component/storage/concrete/master
|
||||
|
||||
///if this is set, only items, and their children, will fit
|
||||
var/list/can_hold
|
||||
///if this is set, items, and their children, won't fit
|
||||
var/list/cant_hold
|
||||
///if set, these items will be the exception to the max size of object that can fit.
|
||||
var/list/exception_hold
|
||||
/// If set can only contain stuff with this single trait present.
|
||||
var/list/can_hold_trait
|
||||
|
||||
var/can_hold_description
|
||||
|
||||
///lazy list of mobs looking at the contents of this storage.
|
||||
var/list/mob/is_using
|
||||
|
||||
///when locked nothing can see inside or use it.
|
||||
var/locked = FALSE
|
||||
|
||||
///max size of objects that will fit.
|
||||
var/max_w_class = WEIGHT_CLASS_SMALL
|
||||
///max combined sizes of objects that will fit.
|
||||
var/max_combined_w_class = 14
|
||||
///max number of objects that will fit.
|
||||
var/max_items = 7
|
||||
|
||||
var/emp_shielded = FALSE
|
||||
|
||||
///whether this makes a message when things are put in.
|
||||
var/silent = FALSE
|
||||
///whether this can be clicked on items to pick it up rather than the other way around.
|
||||
var/click_gather = FALSE
|
||||
///play rustle sound on interact.
|
||||
var/rustle_sound = TRUE
|
||||
///allow empty verb which allows dumping on the floor of everything inside quickly.
|
||||
var/allow_quick_empty = FALSE
|
||||
///allow toggle mob verb which toggles collecting all items from a tile.
|
||||
var/allow_quick_gather = FALSE
|
||||
|
||||
var/collection_mode = COLLECT_EVERYTHING
|
||||
|
||||
///you put things "in" a bag, but "on" a tray.
|
||||
var/insert_preposition = "in"
|
||||
|
||||
///stack things of the same type and show as a single object with a number.
|
||||
var/display_numerical_stacking = FALSE
|
||||
|
||||
///storage display object
|
||||
var/atom/movable/screen/storage/boxes
|
||||
///close button object
|
||||
var/atom/movable/screen/close/closer
|
||||
|
||||
///allow storage objects of the same or greater size.
|
||||
var/allow_big_nesting = FALSE
|
||||
|
||||
///interact on attack hand.
|
||||
var/attack_hand_interact = TRUE
|
||||
///altclick interact
|
||||
var/quickdraw = FALSE
|
||||
|
||||
var/datum/weakref/modeswitch_action_ref
|
||||
|
||||
//Screen variables: Do not mess with these vars unless you know what you're doing. They're not defines so storage that isn't in the same location can be supported in the future.
|
||||
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_start_x = 4 //These two are where the storage starts being rendered, screen_loc wise.
|
||||
var/screen_start_y = 2
|
||||
//End
|
||||
|
||||
/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/on_check)
|
||||
RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, .proc/check_locked)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_SHOW, .proc/signal_show_attempt)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/signal_insertion_attempt)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_CAN_INSERT, .proc/signal_can_insert)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE_TYPE, .proc/signal_take_type)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_FILL_TYPE, .proc/signal_fill_type)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_SET_LOCKSTATE, .proc/set_locked)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE, .proc/signal_take_obj)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_QUICK_EMPTY, .proc/signal_quick_empty)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_FROM, .proc/signal_hide_attempt)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_ALL, .proc/close_all)
|
||||
RegisterSignal(parent, COMSIG_TRY_STORAGE_RETURN_INVENTORY, .proc/signal_return_inv)
|
||||
|
||||
RegisterSignal(parent, COMSIG_TOPIC, .proc/topic_handle)
|
||||
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby)
|
||||
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_PAW, .proc/on_attack_hand)
|
||||
RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/emp_act)
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost)
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/refresh_mob_views)
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/_remove_and_refresh)
|
||||
RegisterSignal(parent, COMSIG_ATOM_CANREACH, .proc/canreach_react)
|
||||
|
||||
RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/attack_self)
|
||||
RegisterSignal(parent, COMSIG_ITEM_PICKUP, .proc/signal_on_pickup)
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/update_actions)
|
||||
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, .proc/close_all)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_move)
|
||||
|
||||
RegisterSignal(parent, list(COMSIG_CLICK_ALT, COMSIG_ATOM_ATTACK_HAND_SECONDARY), .proc/on_open_storage_click)
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY_SECONDARY, .proc/on_open_storage_attackby)
|
||||
RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto)
|
||||
RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_receive)
|
||||
|
||||
update_actions()
|
||||
|
||||
/datum/component/storage/Destroy()
|
||||
close_all()
|
||||
QDEL_NULL(boxes)
|
||||
QDEL_NULL(closer)
|
||||
LAZYCLEARLIST(is_using)
|
||||
return ..()
|
||||
|
||||
/datum/component/storage/PreTransfer()
|
||||
update_actions()
|
||||
|
||||
/// Almost 100% of the time the lists passed into set_holdable are reused for each instance of the component
|
||||
/// Just fucking cache it 4head
|
||||
/// Yes I could generalize this, but I don't want anyone else using it. in fact, DO NOT COPY THIS
|
||||
/// If you find yourself needing this pattern, you're likely better off using static typecaches
|
||||
/// I'm not because I do not trust implementers of the storage component to use them, BUT
|
||||
/// IF I FIND YOU USING THIS PATTERN IN YOUR CODE I WILL BREAK YOU ACROSS MY KNEES
|
||||
/// ~Lemon
|
||||
GLOBAL_LIST_EMPTY(cached_storage_typecaches)
|
||||
|
||||
/datum/component/storage/proc/set_holdable(list/can_hold_list, list/cant_hold_list)
|
||||
if(!islist(can_hold_list))
|
||||
can_hold_list = list(can_hold_list)
|
||||
if(!islist(cant_hold_list))
|
||||
cant_hold_list = list(cant_hold_list)
|
||||
|
||||
can_hold_description = generate_hold_desc(can_hold_list)
|
||||
if (can_hold_list)
|
||||
var/unique_key = can_hold_list.Join("-")
|
||||
if(!GLOB.cached_storage_typecaches[unique_key])
|
||||
GLOB.cached_storage_typecaches[unique_key] = typecacheof(can_hold_list)
|
||||
can_hold = GLOB.cached_storage_typecaches[unique_key]
|
||||
|
||||
if (cant_hold_list != null)
|
||||
var/unique_key = cant_hold_list.Join("-")
|
||||
if(!GLOB.cached_storage_typecaches[unique_key])
|
||||
GLOB.cached_storage_typecaches[unique_key] = typecacheof(cant_hold_list)
|
||||
cant_hold = GLOB.cached_storage_typecaches[unique_key]
|
||||
|
||||
/datum/component/storage/proc/generate_hold_desc(can_hold_list)
|
||||
var/list/desc = list()
|
||||
|
||||
for(var/valid_type in can_hold_list)
|
||||
var/obj/item/valid_item = valid_type
|
||||
desc += "\a [initial(valid_item.name)]"
|
||||
|
||||
return "\n\t[span_notice("[desc.Join("\n\t")]")]"
|
||||
|
||||
/datum/component/storage/proc/update_actions()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!isitem(parent) || !allow_quick_gather)
|
||||
QDEL_NULL(modeswitch_action_ref)
|
||||
return
|
||||
|
||||
var/datum/action/existing = modeswitch_action_ref?.resolve()
|
||||
if(!QDELETED(existing))
|
||||
return
|
||||
|
||||
var/obj/item/item_parent = parent
|
||||
var/datum/action/modeswitch_action = item_parent.add_item_action(/datum/action/item_action/storage_gather_mode)
|
||||
RegisterSignal(modeswitch_action, COMSIG_ACTION_TRIGGER, .proc/action_trigger)
|
||||
modeswitch_action_ref = WEAKREF(modeswitch_action)
|
||||
|
||||
/datum/component/storage/proc/change_master(datum/component/storage/concrete/new_master)
|
||||
if(new_master == src || (!isnull(new_master) && !istype(new_master)))
|
||||
return FALSE
|
||||
if(master)
|
||||
master.on_slave_unlink(src)
|
||||
master = new_master
|
||||
if(master)
|
||||
master.on_slave_link(src)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/master()
|
||||
if(master == src)
|
||||
return //infinite loops yo.
|
||||
return master
|
||||
|
||||
/datum/component/storage/proc/real_location()
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
return master? master.real_location() : null
|
||||
|
||||
/datum/component/storage/proc/canreach_react(datum/source, list/next)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
if(!master)
|
||||
return
|
||||
. = COMPONENT_ALLOW_REACH
|
||||
next += master.parent
|
||||
for(var/i in master.slaves)
|
||||
var/datum/component/storage/slave = i
|
||||
next += slave.parent
|
||||
|
||||
/datum/component/storage/proc/on_move()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/A = parent
|
||||
for(var/mob/living/L in can_see_contents())
|
||||
if(!L.CanReach(A))
|
||||
hide_from(L)
|
||||
|
||||
/datum/component/storage/proc/attack_self(datum/source, mob/M)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(locked)
|
||||
to_chat(M, span_warning("[parent] seems to be locked!"))
|
||||
return FALSE
|
||||
if((M.get_active_held_item() == parent) && allow_quick_empty)
|
||||
INVOKE_ASYNC(src, .proc/quick_empty, M)
|
||||
|
||||
/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE))
|
||||
return FALSE
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
if(locked)
|
||||
to_chat(M, span_warning("[parent] seems to be locked!"))
|
||||
return FALSE
|
||||
var/obj/item/I = O
|
||||
if(collection_mode == COLLECT_ONE)
|
||||
if(can_be_inserted(I, null, M))
|
||||
handle_item_insertion(I, null, M)
|
||||
return
|
||||
if(!isturf(I.loc))
|
||||
return
|
||||
INVOKE_ASYNC(src, .proc/async_preattack_intercept, I, M)
|
||||
|
||||
///async functionality from preattack_intercept
|
||||
/datum/component/storage/proc/async_preattack_intercept(obj/item/attack_item, mob/pre_attack_mob)
|
||||
var/list/things = attack_item.loc.contents.Copy()
|
||||
if(collection_mode == COLLECT_SAME)
|
||||
things = typecache_filter_list(things, typecacheof(attack_item.type))
|
||||
var/len = length(things)
|
||||
if(!len)
|
||||
to_chat(pre_attack_mob, span_warning("You failed to pick up anything with [parent]!"))
|
||||
return
|
||||
var/datum/progressbar/progress = new(pre_attack_mob, len, attack_item.loc)
|
||||
var/list/rejections = list()
|
||||
while(do_after(pre_attack_mob, 1 SECONDS, parent, NONE, FALSE, CALLBACK(src, .proc/handle_mass_pickup, things, attack_item.loc, rejections, progress)))
|
||||
stoplag(1)
|
||||
progress.end_progress()
|
||||
to_chat(pre_attack_mob, span_notice("You put everything you could [insert_preposition] [parent]."))
|
||||
|
||||
/datum/component/storage/proc/handle_mass_item_insertion(list/things, datum/component/storage/src_object, mob/user, datum/progressbar/progress)
|
||||
var/atom/source_real_location = src_object.real_location()
|
||||
for(var/obj/item/I in things)
|
||||
things -= I
|
||||
if(I.loc != source_real_location)
|
||||
continue
|
||||
if(user.active_storage != src_object)
|
||||
if(I.on_found(user))
|
||||
break
|
||||
if(can_be_inserted(I,FALSE,user))
|
||||
handle_item_insertion(I, TRUE, user)
|
||||
if (TICK_CHECK)
|
||||
progress.update(progress.goal - things.len)
|
||||
return TRUE
|
||||
|
||||
progress.update(progress.goal - things.len)
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/proc/handle_mass_pickup(list/things, atom/thing_loc, list/rejections, datum/progressbar/progress)
|
||||
var/atom/real_location = real_location()
|
||||
for(var/obj/item/I in things)
|
||||
things -= I
|
||||
if(I.loc != thing_loc)
|
||||
continue
|
||||
if(I.type in rejections) // To limit bag spamming: any given type only complains once
|
||||
continue
|
||||
if(!can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no
|
||||
if(real_location.contents.len >= max_items)
|
||||
break
|
||||
rejections += I.type // therefore full bags are still a little spammy
|
||||
continue
|
||||
|
||||
handle_item_insertion(I, TRUE) //The TRUE stops the "You put the [parent] into [S]" insertion message from being displayed.
|
||||
|
||||
if (TICK_CHECK)
|
||||
progress.update(progress.goal - things.len)
|
||||
return TRUE
|
||||
|
||||
progress.update(progress.goal - things.len)
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/proc/quick_empty(mob/M)
|
||||
var/atom/A = parent
|
||||
if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated())
|
||||
return
|
||||
if(locked)
|
||||
to_chat(M, span_warning("[parent] seems to be locked!"))
|
||||
return FALSE
|
||||
A.add_fingerprint(M)
|
||||
to_chat(M, span_notice("You start dumping out [parent]."))
|
||||
var/turf/T = get_turf(A)
|
||||
var/list/things = contents()
|
||||
var/datum/progressbar/progress = new(M, length(things), T)
|
||||
while (do_after(M, 1 SECONDS, T, NONE, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress)))
|
||||
stoplag(1)
|
||||
progress.end_progress()
|
||||
|
||||
/datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found = TRUE)
|
||||
var/atom/real_location = real_location()
|
||||
for(var/obj/item/I in things)
|
||||
things -= I
|
||||
if(I.loc != real_location)
|
||||
continue
|
||||
remove_from_storage(I, target)
|
||||
I.pixel_x = rand(-10,10)
|
||||
I.pixel_y = rand(-10,10)
|
||||
if(trigger_on_found && I.on_found())
|
||||
return FALSE
|
||||
if(TICK_CHECK)
|
||||
progress.update(progress.goal - length(things))
|
||||
return TRUE
|
||||
progress.update(progress.goal - length(things))
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/proc/do_quick_empty(atom/_target)
|
||||
if(!_target)
|
||||
_target = get_turf(parent)
|
||||
if(usr)
|
||||
hide_from(usr)
|
||||
var/list/contents = contents()
|
||||
var/atom/real_location = real_location()
|
||||
for(var/obj/item/I in contents)
|
||||
if(I.loc != real_location)
|
||||
continue
|
||||
remove_from_storage(I, _target)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/set_locked(datum/source, new_state)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
locked = new_state
|
||||
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 = MAPTEXT("<font color='white'>[(ND.number > 1)? "[ND.number]" : ""]</font>")
|
||||
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.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)
|
||||
if(ismovable(real_location))
|
||||
var/atom/movable/movable_loc = real_location
|
||||
movable_loc.become_active_storage(src)
|
||||
LAZYOR(is_using, M)
|
||||
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/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()
|
||||
if(!length(is_using) && ismovable(real_location))
|
||||
var/atom/movable/movable_loc = real_location
|
||||
movable_loc.lose_active_storage(src)
|
||||
|
||||
M.client.screen -= boxes
|
||||
M.client.screen -= closer
|
||||
M.client.screen -= real_location.contents
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/close(mob/M)
|
||||
hide_from(M)
|
||||
|
||||
/datum/component/storage/proc/close_all()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
. = FALSE
|
||||
for(var/mob/M in can_see_contents())
|
||||
close(M)
|
||||
. = TRUE //returns TRUE if any mobs actually got a close(M) call
|
||||
|
||||
/datum/component/storage/proc/emp_act(datum/source, severity)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(emp_shielded)
|
||||
return
|
||||
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.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))
|
||||
return FALSE
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
if(!istype(master))
|
||||
return FALSE
|
||||
return master._removal_reset(thing)
|
||||
|
||||
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/gone, direction)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
_removal_reset(gone)
|
||||
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
|
||||
/datum/component/storage/proc/remove_from_storage(atom/movable/AM, atom/new_location)
|
||||
if(!istype(AM))
|
||||
return FALSE
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
if(!istype(master))
|
||||
return FALSE
|
||||
return master.remove_from_storage(AM, new_location)
|
||||
|
||||
/datum/component/storage/proc/refresh_mob_views()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/list/seeing = can_see_contents()
|
||||
for(var/i in seeing)
|
||||
show_to(i)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/can_see_contents()
|
||||
var/list/cansee = list()
|
||||
for(var/mob/M in is_using)
|
||||
if(M.active_storage == src && M.client)
|
||||
cansee |= M
|
||||
else
|
||||
LAZYREMOVE(is_using, M)
|
||||
UnregisterSignal(M, COMSIG_PARENT_QDELETING)
|
||||
return cansee
|
||||
|
||||
//Tries to dump content
|
||||
/datum/component/storage/proc/dump_content_at(atom/dest_object, mob/M)
|
||||
var/atom/A = parent
|
||||
var/atom/dump_destination = get_dumping_location(dest_object)
|
||||
if(M.CanReach(A) && dump_destination && M.CanReach(dump_destination))
|
||||
if(locked)
|
||||
to_chat(M, span_warning("[parent] seems to be locked!"))
|
||||
return FALSE
|
||||
if(dump_destination.storage_contents_dump_act(src, M))
|
||||
playsound(A, SFX_RUSTLE, 50, TRUE, -5)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/proc/get_dumping_location(atom/dest_object)
|
||||
var/datum/component/storage/storage = dest_object.GetComponent(/datum/component/storage)
|
||||
if(storage)
|
||||
return storage.real_location()
|
||||
return dest_object.get_dumping_location()
|
||||
|
||||
//This proc is called when you want to place an item into the storage item.
|
||||
/datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!I.attackby_storage_insert(src, parent, M))
|
||||
return FALSE
|
||||
. = TRUE //no afterattack
|
||||
if(iscyborg(M))
|
||||
return
|
||||
if(!can_be_inserted(I, FALSE, M))
|
||||
var/atom/real_location = real_location()
|
||||
if(real_location.contents.len >= max_items) //don't use items on the backpack if they don't fit
|
||||
return TRUE
|
||||
return FALSE
|
||||
handle_item_insertion(I, FALSE, M)
|
||||
|
||||
/datum/component/storage/proc/return_inv(recursive)
|
||||
var/list/ret = list()
|
||||
ret |= contents()
|
||||
if(recursive)
|
||||
for(var/i in ret.Copy())
|
||||
var/atom/A = i
|
||||
SEND_SIGNAL(A, COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE)
|
||||
return ret
|
||||
|
||||
/datum/component/storage/proc/contents() //ONLY USE IF YOU NEED TO COPY CONTENTS OF REAL LOCATION, COPYING IS NOT AS FAST AS DIRECT ACCESS!
|
||||
var/atom/real_location = real_location()
|
||||
return real_location.contents.Copy()
|
||||
|
||||
//Abuses the fact that lists are just references, or something like that.
|
||||
/datum/component/storage/proc/signal_return_inv(datum/source, list/interface, recursive = TRUE)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!islist(interface))
|
||||
return FALSE
|
||||
interface |= return_inv(recursive)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/topic_handle(datum/source, user, href_list)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(href_list["show_valid_pocket_items"])
|
||||
handle_show_valid_items(source, user)
|
||||
|
||||
/datum/component/storage/proc/handle_show_valid_items(datum/source, user)
|
||||
to_chat(user, span_notice("[source] can hold: [can_hold_description]"))
|
||||
|
||||
/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
set waitfor = FALSE
|
||||
. = COMPONENT_NO_MOUSEDROP
|
||||
if(!ismob(M))
|
||||
return
|
||||
if(!over_object)
|
||||
return
|
||||
if(ismecha(M.loc)) // stops inventory actions in a mech
|
||||
return
|
||||
if(M.incapacitated() || !M.canUseStorage())
|
||||
return
|
||||
var/atom/A = parent
|
||||
A.add_fingerprint(M)
|
||||
// this must come before the screen objects only block, dunno why it wasn't before
|
||||
if(over_object == M)
|
||||
user_show_to_mob(M)
|
||||
if(!istype(over_object, /atom/movable/screen))
|
||||
INVOKE_ASYNC(src, .proc/dump_content_at, over_object, M)
|
||||
return
|
||||
if(A.loc != M)
|
||||
return
|
||||
playsound(A, SFX_RUSTLE, 50, TRUE, -5)
|
||||
if(istype(over_object, /atom/movable/screen/inventory/hand))
|
||||
var/atom/movable/screen/inventory/hand/H = over_object
|
||||
M.putItemFromInventoryInHandIfPossible(A, H.held_index)
|
||||
return
|
||||
A.add_fingerprint(M)
|
||||
|
||||
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE)
|
||||
var/atom/A = parent
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
A.add_fingerprint(M)
|
||||
if(locked && !force)
|
||||
to_chat(M, span_warning("[parent] seems to be locked!"))
|
||||
return FALSE
|
||||
if(force || M.CanReach(parent, view_only = TRUE))
|
||||
show_to(M)
|
||||
|
||||
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(isitem(O))
|
||||
var/obj/item/I = O
|
||||
if(iscarbon(M) || isdrone(M))
|
||||
var/mob/living/L = M
|
||||
if(!L.incapacitated() && I == L.get_active_held_item())
|
||||
if(!SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE) && can_be_inserted(I, FALSE)) //If it has storage it should be trying to dump, not insert.
|
||||
handle_item_insertion(I, FALSE, L)
|
||||
|
||||
//This proc return 1 if the item can be picked up and 0 if it can't.
|
||||
//Set the stop_messages to stop it from printing messages
|
||||
/datum/component/storage/proc/can_be_inserted(obj/item/I, stop_messages = FALSE, mob/M)
|
||||
if(!istype(I) || (I.item_flags & ABSTRACT))
|
||||
return FALSE //Not an item
|
||||
if(I == parent)
|
||||
return FALSE //no paradoxes for you
|
||||
var/atom/real_location = real_location()
|
||||
var/atom/host = parent
|
||||
if(real_location == I.loc)
|
||||
return FALSE //Means the item is already in the storage item
|
||||
if(locked)
|
||||
if(M && !stop_messages)
|
||||
host.add_fingerprint(M)
|
||||
to_chat(M, span_warning("[host] seems to be locked!"))
|
||||
return FALSE
|
||||
if(real_location.contents.len >= max_items)
|
||||
if(!stop_messages)
|
||||
to_chat(M, span_warning("[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)
|
||||
to_chat(M, span_warning("[host] cannot hold [I]!"))
|
||||
return FALSE
|
||||
if(is_type_in_typecache(I, cant_hold) || HAS_TRAIT(I, TRAIT_NO_STORAGE_INSERT) || (can_hold_trait && !HAS_TRAIT(I, can_hold_trait))) //Items which this container can't hold.
|
||||
if(!stop_messages)
|
||||
to_chat(M, span_warning("[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, span_warning("[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, span_warning("[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, span_warning("[I] won't 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)
|
||||
if((I.w_class >= IP.w_class) && STR_I && !allow_big_nesting)
|
||||
if(!stop_messages)
|
||||
to_chat(M, span_warning("[IP] cannot hold [I] as it's a storage item of the same size!"))
|
||||
return FALSE //To prevent the stacking of same sized storage items.
|
||||
if(HAS_TRAIT(I, TRAIT_NODROP)) //SHOULD be handled in unEquip, but better safe than sorry.
|
||||
if(!stop_messages)
|
||||
to_chat(M, span_warning("\the [I] is stuck to your hand, you can't put it in \the [host]!"))
|
||||
return FALSE
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
if(!istype(master))
|
||||
return FALSE
|
||||
return master.slave_can_insert_object(src, I, stop_messages, M)
|
||||
|
||||
/datum/component/storage/proc/_insert_physical_item(obj/item/I, override = FALSE)
|
||||
return FALSE
|
||||
|
||||
//This proc handles items being inserted. It does not perform any checks of whether an item can or can't be inserted. That's done by can_be_inserted()
|
||||
//The prevent_warning parameter will stop the insertion message from being displayed. It is intended for cases where you are inserting multiple items at once,
|
||||
//such as when picking up all the items on a tile with one click.
|
||||
/datum/component/storage/proc/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote)
|
||||
var/atom/parent = src.parent
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
if(!istype(master))
|
||||
return FALSE
|
||||
if(silent)
|
||||
prevent_warning = TRUE
|
||||
if(M)
|
||||
parent.add_fingerprint(M)
|
||||
. = master.handle_item_insertion_from_slave(src, I, prevent_warning, M)
|
||||
|
||||
/datum/component/storage/proc/mob_item_insertion_feedback(mob/user, mob/M, obj/item/I, override = FALSE)
|
||||
if(silent && !override)
|
||||
return
|
||||
if(rustle_sound)
|
||||
playsound(parent, SFX_RUSTLE, 50, TRUE, -5)
|
||||
for(var/mob/viewing in viewers(user, null))
|
||||
if(M == viewing)
|
||||
to_chat(usr, span_notice("You put [I] [insert_preposition]to [parent]."))
|
||||
else if(in_range(M, viewing)) //If someone is standing close enough, they can tell what it is...
|
||||
viewing.show_message(span_notice("[M] puts [I] [insert_preposition]to [parent]."), MSG_VISUAL)
|
||||
else if(I && I.w_class >= 3) //Otherwise they can only see large or normal items from a distance...
|
||||
viewing.show_message(span_notice("[M] puts [I] [insert_preposition]to [parent]."), MSG_VISUAL)
|
||||
|
||||
/datum/component/storage/proc/update_icon()
|
||||
if(isobj(parent))
|
||||
var/obj/O = parent
|
||||
O.update_appearance()
|
||||
|
||||
/datum/component/storage/proc/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if((!force && !can_be_inserted(I, TRUE, M)) || (I == parent))
|
||||
return FALSE
|
||||
return handle_item_insertion(I, silent, M)
|
||||
|
||||
/datum/component/storage/proc/signal_can_insert(datum/source, obj/item/I, mob/M, silent = FALSE)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
return can_be_inserted(I, silent, M)
|
||||
|
||||
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
return user_show_to_mob(M, TRUE)
|
||||
|
||||
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
return user_show_to_mob(showto, force)
|
||||
|
||||
/datum/component/storage/proc/on_check()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/check_locked()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
return locked
|
||||
|
||||
/datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!force)
|
||||
if(check_adjacent)
|
||||
if(!user || !user.CanReach(destination) || !user.CanReach(parent))
|
||||
return FALSE
|
||||
var/list/taking = typecache_filter_list(contents(), typecacheof(type))
|
||||
if(taking.len > amount)
|
||||
taking.len = amount
|
||||
if(inserted) //duplicated code for performance, don't bother checking retval/checking for list every item.
|
||||
for(var/i in taking)
|
||||
if(remove_from_storage(i, destination))
|
||||
inserted |= i
|
||||
else
|
||||
for(var/i in taking)
|
||||
remove_from_storage(i, destination)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/remaining_space_items()
|
||||
var/atom/real_location = real_location()
|
||||
return max(0, max_items - real_location.contents.len)
|
||||
|
||||
/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/real_location = real_location()
|
||||
if(!force)
|
||||
amount = min(remaining_space_items(), amount)
|
||||
for(var/i in 1 to amount)
|
||||
if(!handle_item_insertion(new type(real_location), TRUE))
|
||||
return i > 1 //return TRUE only if at least one insertion has been successful.
|
||||
if(QDELETED(src))
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/component/storage/proc/on_attack_hand(datum/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/A = parent
|
||||
if(!attack_hand_interact)
|
||||
return
|
||||
if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item
|
||||
user.active_storage.close(user)
|
||||
close(user)
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
return
|
||||
|
||||
if(rustle_sound)
|
||||
playsound(A, SFX_RUSTLE, 50, TRUE, -5)
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.l_store == A && !H.get_active_held_item()) //Prevents opening if it's in a pocket.
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
INVOKE_ASYNC(H, /mob.proc/put_in_hands, A)
|
||||
H.l_store = null
|
||||
return
|
||||
if(H.r_store == A && !H.get_active_held_item())
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
INVOKE_ASYNC(H, /mob.proc/put_in_hands, A)
|
||||
H.r_store = null
|
||||
return
|
||||
|
||||
if(A.loc == user)
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
if(locked)
|
||||
to_chat(user, span_warning("[parent] seems to be locked!"))
|
||||
else
|
||||
show_to(user)
|
||||
|
||||
|
||||
/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
update_actions()
|
||||
for(var/mob/M in can_see_contents() - user)
|
||||
close(M)
|
||||
|
||||
/datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!(AM in real_location()))
|
||||
return FALSE
|
||||
return remove_from_storage(AM, new_loc)
|
||||
|
||||
/datum/component/storage/proc/signal_quick_empty(datum/source, atom/loctarget)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
return do_quick_empty(loctarget)
|
||||
|
||||
/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
return hide_from(target)
|
||||
|
||||
|
||||
/datum/component/storage/proc/open_storage(mob/user)
|
||||
if(!user.CanReach(parent))
|
||||
user.balloon_alert(user, "can't reach!")
|
||||
return FALSE
|
||||
if(!isliving(user) || user.incapacitated())
|
||||
return FALSE
|
||||
if(locked)
|
||||
to_chat(user, span_warning("[parent] seems to be locked!"))
|
||||
return FALSE
|
||||
|
||||
. = TRUE
|
||||
var/atom/A = parent
|
||||
if(!quickdraw)
|
||||
A.add_fingerprint(user)
|
||||
user_show_to_mob(user)
|
||||
playsound(A, SFX_RUSTLE, 50, TRUE, -5)
|
||||
return
|
||||
|
||||
var/obj/item/to_remove = locate() in real_location()
|
||||
if(!to_remove)
|
||||
return
|
||||
|
||||
INVOKE_ASYNC(src, .proc/attempt_put_in_hands, to_remove, user)
|
||||
|
||||
/datum/component/storage/proc/on_open_storage_click(datum/source, mob/user, list/modifiers)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(open_storage(user))
|
||||
return COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
return COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/datum/component/storage/proc/on_open_storage_attackby(datum/source, obj/item/weapon, mob/user, params)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(open_storage(user))
|
||||
return COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN
|
||||
|
||||
///attempt to put an item from contents into the users hands
|
||||
/datum/component/storage/proc/attempt_put_in_hands(obj/item/to_remove, mob/user)
|
||||
var/atom/parent_as_atom = parent
|
||||
|
||||
parent_as_atom.add_fingerprint(user)
|
||||
remove_from_storage(to_remove, get_turf(user))
|
||||
if(!user.put_in_hands(to_remove))
|
||||
to_chat(user, span_notice("You fumble for [to_remove] and it falls on the floor."))
|
||||
return
|
||||
user.visible_message(span_warning("[user] draws [to_remove] from [parent]!"), span_notice("You draw [to_remove] from [parent]."))
|
||||
|
||||
/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
gather_mode_switch(source.owner)
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
|
||||
/datum/component/storage/proc/gather_mode_switch(mob/user)
|
||||
collection_mode = (collection_mode+1)%3
|
||||
switch(collection_mode)
|
||||
if(COLLECT_SAME)
|
||||
to_chat(user, span_notice("[parent] now picks up all items of a single type at once."))
|
||||
if(COLLECT_EVERYTHING)
|
||||
to_chat(user, span_notice("[parent] now picks up all items in a tile at once."))
|
||||
if(COLLECT_ONE)
|
||||
to_chat(user, span_notice("[parent] now picks up one item at a time."))
|
||||
@@ -42,10 +42,10 @@
|
||||
// Make sure overlays also inherit the scaling.
|
||||
ADD_KEEP_TOGETHER(target, ITEM_SCALING_TRAIT)
|
||||
|
||||
// Object scaled when dropped/thrown OR when exiting a storage component.
|
||||
RegisterSignal(target, list(COMSIG_ITEM_DROPPED, COMSIG_STORAGE_EXITED), .proc/scale_overworld)
|
||||
// Object scaled when dropped/thrown OR when exiting a storage object.
|
||||
RegisterSignal(target, list(COMSIG_ITEM_DROPPED, COMSIG_ATOM_EXITED), .proc/scale_overworld)
|
||||
// Object scaled when placed in an inventory slot OR when entering a storage component.
|
||||
RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_STORAGE_ENTERED), .proc/scale_storage)
|
||||
RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ATOM_ENTERED), .proc/scale_storage)
|
||||
|
||||
/**
|
||||
* Detach proc for the item_scaling element.
|
||||
@@ -58,8 +58,8 @@
|
||||
UnregisterSignal(target, list(
|
||||
COMSIG_ITEM_PICKUP,
|
||||
COMSIG_ITEM_DROPPED,
|
||||
COMSIG_STORAGE_ENTERED,
|
||||
COMSIG_STORAGE_EXITED,
|
||||
COMSIG_ATOM_ENTERED,
|
||||
COMSIG_ATOM_EXITED,
|
||||
))
|
||||
|
||||
REMOVE_KEEP_TOGETHER(target, ITEM_SCALING_TRAIT)
|
||||
@@ -82,7 +82,7 @@
|
||||
scalable_object.transform = M.Scale(scaling)
|
||||
|
||||
/**
|
||||
* Signal handler for COMSIG_ITEM_DROPPED or COMSIG_STORAGE_EXITED
|
||||
* Signal handler for COMSIG_ITEM_DROPPED or COMSIG_ATOM_EXITED
|
||||
*
|
||||
* Longer detailed paragraph about the proc
|
||||
* including any relevant detail
|
||||
@@ -95,7 +95,7 @@
|
||||
scale(source, overworld_scaling)
|
||||
|
||||
/**
|
||||
* Signal handler for COMSIG_ITEM_EQUIPPED or COMSIG_STORAGE_ENTERED.
|
||||
* Signal handler for COMSIG_ITEM_EQUIPPED or COMSIG_ATOM_ENTERED.
|
||||
*
|
||||
* Longer detailed paragraph about the proc
|
||||
* including any relevant detail
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
var/mob/living/carbon/human/human_holder = quirk_holder
|
||||
// post_add() can be called via delayed callback. Check they still have a backpack equipped before trying to open it.
|
||||
if(human_holder.back)
|
||||
SEND_SIGNAL(human_holder.back, COMSIG_TRY_STORAGE_SHOW, human_holder)
|
||||
human_holder.back.atom_storage.show_contents(human_holder)
|
||||
|
||||
for(var/chat_string in where_items_spawned)
|
||||
to_chat(quirk_holder, chat_string)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
/datum/storage/bag_of_holding/attempt_insert(datum/source, obj/item/to_insert, mob/user, override, force)
|
||||
var/obj/item/resolve_parent = parent?.resolve()
|
||||
if(!resolve_parent)
|
||||
return
|
||||
|
||||
var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(to_insert.get_all_contents(), typecacheof(/obj/item/storage/backpack/holding))
|
||||
matching -= resolve_parent
|
||||
|
||||
if(istype(to_insert, /obj/item/storage/backpack/holding) || matching.len)
|
||||
INVOKE_ASYNC(src, .proc/recursive_insertion, to_insert, user)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/storage/bag_of_holding/proc/recursive_insertion(obj/item/to_insert, mob/living/user)
|
||||
var/obj/item/resolve_parent = parent?.resolve()
|
||||
if(!resolve_parent)
|
||||
return
|
||||
|
||||
var/safety = tgui_alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [to_insert.name]?", list("Proceed", "Abort"))
|
||||
if(safety != "Proceed" || QDELETED(to_insert) || QDELETED(resolve_parent) || QDELETED(user) || !user.canUseTopic(resolve_parent, BE_CLOSE, iscarbon(user)))
|
||||
return
|
||||
|
||||
var/turf/loccheck = get_turf(resolve_parent)
|
||||
to_chat(user, span_danger("The Bluespace interfaces of the two devices catastrophically malfunction!"))
|
||||
qdel(to_insert)
|
||||
playsound(loccheck,'sound/effects/supermatter.ogg', 200, TRUE)
|
||||
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].")
|
||||
log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].")
|
||||
|
||||
user.gib(TRUE, TRUE, TRUE)
|
||||
new/obj/boh_tear(loccheck)
|
||||
qdel(resolve_parent)
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
*A storage component to be used on card piles, for use as hands/decks/discard piles. Don't use on something that's not a card pile!
|
||||
*/
|
||||
/datum/storage/tcg
|
||||
max_specific_storage = WEIGHT_CLASS_TINY
|
||||
max_slots = 30
|
||||
max_total_storage = WEIGHT_CLASS_TINY * 30
|
||||
|
||||
/datum/storage/tcg/New()
|
||||
. = ..()
|
||||
set_holdable(list(/obj/item/tcgcard))
|
||||
|
||||
/datum/storage/tcg/attempt_remove(silent = FALSE)
|
||||
. = ..()
|
||||
handle_empty_deck()
|
||||
|
||||
/datum/storage/tcg/show_contents(mob/to_show)
|
||||
. = ..()
|
||||
|
||||
var/obj/item/resolve_parent = parent?.resolve()
|
||||
if(!resolve_parent)
|
||||
return
|
||||
|
||||
to_show.visible_message(span_notice("[to_show] starts to look through the contents of \the [resolve_parent]!"), \
|
||||
span_notice("You begin looking into the contents of \the [resolve_parent]!"))
|
||||
|
||||
/datum/storage/tcg/hide_contents()
|
||||
. = ..()
|
||||
var/obj/item/resolve_parent = parent?.resolve()
|
||||
if(!resolve_parent)
|
||||
return
|
||||
|
||||
var/obj/item/resolve_location = real_location?.resolve()
|
||||
if(!resolve_location)
|
||||
return
|
||||
|
||||
resolve_location.visible_message(span_notice("\the [resolve_parent] is shuffled after looking through it."))
|
||||
resolve_location.contents = shuffle(resolve_location.contents)
|
||||
|
||||
/datum/storage/tcg/remove_all()
|
||||
. = ..()
|
||||
|
||||
var/obj/item/resolve_parent = parent?.resolve()
|
||||
if(!resolve_parent)
|
||||
return
|
||||
|
||||
if(!resolve_parent.contents.len)
|
||||
qdel(resolve_parent)
|
||||
|
||||
/datum/storage/tcg/proc/handle_empty_deck()
|
||||
var/obj/item/resolve_parent = parent?.resolve()
|
||||
if(!resolve_parent)
|
||||
return
|
||||
|
||||
var/obj/item/resolve_location = real_location?.resolve()
|
||||
if(!real_location)
|
||||
return
|
||||
|
||||
//You can't have a deck of one card!
|
||||
if(resolve_location.contents.len == 1)
|
||||
var/obj/item/tcgcard_deck/deck = resolve_location
|
||||
var/obj/item/tcgcard/card = resolve_location.contents[1]
|
||||
attempt_remove(card, card.drop_location())
|
||||
card.flipped = deck.flipped
|
||||
card.update_icon_state()
|
||||
qdel(resolve_parent)
|
||||
@@ -0,0 +1,43 @@
|
||||
/datum/storage/extract_inventory
|
||||
max_total_storage = WEIGHT_CLASS_TINY * 3
|
||||
max_slots = 3
|
||||
insert_preposition = "in"
|
||||
attack_hand_interact = FALSE
|
||||
quickdraw = FALSE
|
||||
locked = TRUE
|
||||
rustle_sound = FALSE
|
||||
silent = TRUE
|
||||
|
||||
/datum/storage/extract_inventory/New()
|
||||
. = ..()
|
||||
set_holdable(/obj/item/food/monkeycube)
|
||||
|
||||
var/obj/item/slimecross/reproductive/parentSlimeExtract = parent?.resolve()
|
||||
if(!parentSlimeExtract)
|
||||
return
|
||||
|
||||
if(!istype(parentSlimeExtract, /obj/item/slimecross/reproductive))
|
||||
stack_trace("storage subtype extract_inventory incompatible with [parentSlimeExtract]")
|
||||
qdel(src)
|
||||
|
||||
/datum/storage/extract_inventory/proc/processCubes(mob/user)
|
||||
var/obj/item/slimecross/reproductive/parentSlimeExtract = parent?.resolve()
|
||||
if(!parentSlimeExtract)
|
||||
return
|
||||
|
||||
message_admins(parentSlimeExtract.contents.len)
|
||||
if(parentSlimeExtract.contents.len >= max_slots)
|
||||
QDEL_LIST(parentSlimeExtract.contents)
|
||||
createExtracts(user)
|
||||
|
||||
/datum/storage/extract_inventory/proc/createExtracts(mob/user)
|
||||
var/obj/item/slimecross/reproductive/parentSlimeExtract = parent?.resolve()
|
||||
if(!parentSlimeExtract)
|
||||
return
|
||||
|
||||
var/cores = rand(1,4)
|
||||
playsound(parentSlimeExtract, 'sound/effects/splat.ogg', 40, TRUE)
|
||||
parentSlimeExtract.last_produce = world.time
|
||||
to_chat(user, span_notice("[parentSlimeExtract] briefly swells to a massive size, and expels [cores] extract[cores > 1 ? "s":""]!"))
|
||||
for(var/i in 1 to cores)
|
||||
new parentSlimeExtract.extract_type(parentSlimeExtract.drop_location())
|
||||
@@ -0,0 +1,10 @@
|
||||
/datum/storage/implant
|
||||
max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
max_total_storage = 6
|
||||
max_slots = 2
|
||||
silent = TRUE
|
||||
allow_big_nesting = TRUE
|
||||
|
||||
/datum/storage/implant/New()
|
||||
. = ..()
|
||||
set_holdable(cant_hold_list = list(/obj/item/disk/nuclear))
|
||||
+44
-43
@@ -1,28 +1,33 @@
|
||||
/datum/component/storage/concrete/pockets
|
||||
max_items = 2
|
||||
max_w_class = WEIGHT_CLASS_SMALL
|
||||
max_combined_w_class = 50
|
||||
/datum/storage/pockets
|
||||
max_slots = 2
|
||||
max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
max_total_storage = 50
|
||||
rustle_sound = FALSE
|
||||
|
||||
/datum/component/storage/concrete/pockets/handle_item_insertion(obj/item/I, prevent_warning, mob/user)
|
||||
/datum/storage/pockets/attempt_insert(datum/source, obj/item/to_insert, mob/user, override, force)
|
||||
. = ..()
|
||||
if(. && silent && !prevent_warning)
|
||||
|
||||
var/obj/item/resolve_parent = parent?.resolve()
|
||||
if(!resolve_parent)
|
||||
return
|
||||
|
||||
if(. && silent && !override)
|
||||
if(quickdraw)
|
||||
to_chat(user, span_notice("You discreetly slip [I] into [parent]. Right-click [parent] to remove it."))
|
||||
to_chat(user, span_notice("You discreetly slip [to_insert] into [resolve_parent]. Right-click [resolve_parent] to remove it."))
|
||||
else
|
||||
to_chat(user, span_notice("You discreetly slip [I] into [parent]."))
|
||||
to_chat(user, span_notice("You discreetly slip [to_insert] into [resolve_parent]."))
|
||||
|
||||
/datum/component/storage/concrete/pockets/small
|
||||
max_items = 1
|
||||
max_w_class = WEIGHT_CLASS_SMALL
|
||||
/datum/storage/pockets/small
|
||||
max_slots = 1
|
||||
max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
attack_hand_interact = FALSE
|
||||
|
||||
/datum/component/storage/concrete/pockets/tiny
|
||||
max_items = 1
|
||||
max_w_class = WEIGHT_CLASS_TINY
|
||||
/datum/storage/pockets/tiny
|
||||
max_slots = 1
|
||||
max_specific_storage = WEIGHT_CLASS_TINY
|
||||
attack_hand_interact = FALSE
|
||||
|
||||
/datum/component/storage/concrete/pockets/small/fedora/Initialize()
|
||||
/datum/storage/pockets/small/fedora/New()
|
||||
. = ..()
|
||||
var/static/list/exception_cache = typecacheof(list(
|
||||
/obj/item/katana,
|
||||
@@ -33,35 +38,36 @@
|
||||
))
|
||||
exception_hold = exception_cache
|
||||
|
||||
/datum/component/storage/concrete/pockets/small/fedora/detective
|
||||
/datum/storage/pockets/small/fedora/detective
|
||||
attack_hand_interact = TRUE // so the detectives would discover pockets in their hats
|
||||
|
||||
/datum/component/storage/concrete/pockets/chefhat
|
||||
/datum/storage/pockets/chefhat
|
||||
attack_hand_interact = TRUE
|
||||
max_items = 1
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_slots = 1
|
||||
max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/datum/component/storage/concrete/pockets/chefhat/Initialize()
|
||||
/datum/storage/pockets/chefhat/New()
|
||||
. = ..()
|
||||
set_holdable(list(
|
||||
/obj/item/clothing/head/mob_holder,
|
||||
/obj/item/food/deadmouse
|
||||
))
|
||||
|
||||
/datum/component/storage/concrete/pockets/chefhat/can_be_inserted(obj/item/I, stop_messages, mob/M)
|
||||
/datum/storage/pockets/chefhat/can_insert(obj/item/to_insert, mob/user, messages, force)
|
||||
. = ..()
|
||||
if(istype(I,/obj/item/clothing/head/mob_holder))
|
||||
var/obj/item/clothing/head/mob_holder/mausholder = I
|
||||
if(istype(to_insert, /obj/item/clothing/head/mob_holder))
|
||||
var/obj/item/clothing/head/mob_holder/mausholder = to_insert
|
||||
if(locate(/mob/living/simple_animal/mouse) in mausholder.contents)
|
||||
return
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/concrete/pockets/shoes
|
||||
/datum/storage/pockets/shoes
|
||||
max_slots = 2
|
||||
attack_hand_interact = FALSE
|
||||
quickdraw = TRUE
|
||||
silent = TRUE
|
||||
|
||||
/datum/component/storage/concrete/pockets/shoes/Initialize()
|
||||
/datum/storage/pockets/shoes/New()
|
||||
. = ..()
|
||||
set_holdable(list(
|
||||
/obj/item/knife,
|
||||
@@ -92,7 +98,7 @@
|
||||
/obj/item/toy/crayon/spraycan)
|
||||
)
|
||||
|
||||
/datum/component/storage/concrete/pockets/shoes/clown/Initialize()
|
||||
/datum/storage/pockets/shoes/clown/New()
|
||||
. = ..()
|
||||
set_holdable(list(
|
||||
/obj/item/knife,
|
||||
@@ -124,13 +130,11 @@
|
||||
/obj/item/toy/crayon/spraycan)
|
||||
)
|
||||
|
||||
/datum/component/storage/concrete/pockets/pocketprotector
|
||||
max_items = 3
|
||||
max_w_class = WEIGHT_CLASS_TINY
|
||||
var/atom/original_parent
|
||||
/datum/storage/pockets/pocketprotector
|
||||
max_slots = 3
|
||||
max_specific_storage = WEIGHT_CLASS_TINY
|
||||
|
||||
/datum/component/storage/concrete/pockets/pocketprotector/Initialize()
|
||||
original_parent = parent
|
||||
/datum/storage/pockets/pocketprotector/New()
|
||||
. = ..()
|
||||
set_holdable(list( //Same items as a PDA
|
||||
/obj/item/pen,
|
||||
@@ -140,15 +144,12 @@
|
||||
/obj/item/clothing/mask/cigarette)
|
||||
)
|
||||
|
||||
/datum/component/storage/concrete/pockets/pocketprotector/real_location()
|
||||
// if the component is reparented to a jumpsuit, the items still go in the protector
|
||||
return original_parent
|
||||
|
||||
/datum/component/storage/concrete/pockets/helmet
|
||||
/datum/storage/pockets/helmet
|
||||
max_slots = 2
|
||||
quickdraw = TRUE
|
||||
max_combined_w_class = 6
|
||||
max_total_storage = 6
|
||||
|
||||
/datum/component/storage/concrete/pockets/helmet/Initialize()
|
||||
/datum/storage/pockets/helmet/New()
|
||||
. = ..()
|
||||
set_holdable(list(/obj/item/reagent_containers/food/drinks/bottle/vodka,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/molotov,
|
||||
@@ -156,12 +157,12 @@
|
||||
/obj/item/ammo_box/a762))
|
||||
|
||||
|
||||
/datum/component/storage/concrete/pockets/void_cloak
|
||||
/datum/storage/pockets/void_cloak
|
||||
quickdraw = TRUE
|
||||
max_combined_w_class = 5 // 2 small items + 1 tiny item, or 1 normal item + 1 small item
|
||||
max_items = 3
|
||||
max_total_storage = 5 // 2 small items + 1 tiny item, or 1 normal item + 1 small item
|
||||
max_slots = 3
|
||||
|
||||
/datum/component/storage/concrete/pockets/void_cloak/Initialize()
|
||||
/datum/storage/pockets/void_cloak/New()
|
||||
. = ..()
|
||||
set_holdable(list(
|
||||
/obj/item/ammo_box/a762/lionhunter,
|
||||
+52
-11
@@ -162,6 +162,9 @@
|
||||
/// forensics datum, contains fingerprints, fibres, blood_dna and hiddenprints on this atom
|
||||
var/datum/forensics/forensics
|
||||
|
||||
/// the datum handler for our contents - see create_storage() for creation method
|
||||
var/datum/storage/atom_storage
|
||||
|
||||
/**
|
||||
* Called when an atom is created in byond (built in engine proc)
|
||||
*
|
||||
@@ -314,6 +317,9 @@
|
||||
if(forensics)
|
||||
QDEL_NULL(forensics)
|
||||
|
||||
if(atom_storage)
|
||||
QDEL_NULL(atom_storage)
|
||||
|
||||
orbiters = null // The component is attached to us normaly and will be deleted elsewhere
|
||||
|
||||
LAZYCLEARLIST(overlays)
|
||||
@@ -327,6 +333,43 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/// A quick and easy way to create a storage datum for an atom
|
||||
/atom/proc/create_storage(
|
||||
max_slots,
|
||||
max_specific_storage,
|
||||
max_total_storage,
|
||||
numerical_stacking = FALSE,
|
||||
allow_quick_gather = FALSE,
|
||||
allow_quick_empty = FALSE,
|
||||
collection_mode = COLLECT_ONE,
|
||||
attack_hand_interact = TRUE,
|
||||
list/canhold,
|
||||
list/canthold,
|
||||
type = /datum/storage,
|
||||
)
|
||||
|
||||
if(atom_storage)
|
||||
QDEL_NULL(atom_storage)
|
||||
|
||||
atom_storage = new type(src, max_slots, max_specific_storage, max_total_storage, numerical_stacking, allow_quick_gather, collection_mode, attack_hand_interact)
|
||||
|
||||
if(canhold || canthold)
|
||||
atom_storage.set_holdable(canhold, canthold)
|
||||
|
||||
return atom_storage
|
||||
|
||||
/// A quick and easy way to /clone/ a storage datum for an atom (does not copy over contents, only the datum details)
|
||||
/atom/proc/clone_storage(datum/storage/cloning)
|
||||
if(atom_storage)
|
||||
QDEL_NULL(atom_storage)
|
||||
|
||||
atom_storage = new cloning.type(src, cloning.max_slots, cloning.max_specific_storage, cloning.max_total_storage, cloning.numerical_stacking, cloning.allow_quick_gather, cloning.collection_mode, cloning.attack_hand_interact)
|
||||
|
||||
if(cloning.can_hold || cloning.cant_hold)
|
||||
atom_storage.set_holdable(cloning.can_hold, cloning.cant_hold)
|
||||
|
||||
return atom_storage
|
||||
|
||||
/atom/proc/handle_ricochet(obj/projectile/ricocheting_projectile)
|
||||
var/turf/p_turf = get_turf(ricocheting_projectile)
|
||||
var/face_direction = get_dir(src, p_turf)
|
||||
@@ -991,8 +1034,8 @@
|
||||
* TODO these should be purely component items that intercept the atom clicks higher in the
|
||||
* call chain
|
||||
*/
|
||||
/atom/proc/storage_contents_dump_act(obj/item/storage/src_object, mob/user)
|
||||
if(GetComponent(/datum/component/storage))
|
||||
/atom/proc/storage_contents_dump_act(obj/item/src_object, mob/user)
|
||||
if(atom_storage)
|
||||
return component_storage_contents_dump_act(src_object, user)
|
||||
return FALSE
|
||||
|
||||
@@ -1005,19 +1048,17 @@
|
||||
* TODO these should be purely component items that intercept the atom clicks higher in the
|
||||
* call chain
|
||||
*/
|
||||
/atom/proc/component_storage_contents_dump_act(datum/component/storage/src_object, mob/user)
|
||||
var/list/things = src_object.contents()
|
||||
/atom/proc/component_storage_contents_dump_act(obj/item/src_object, mob/user)
|
||||
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, 1 SECONDS, src, NONE, FALSE, CALLBACK(STR, /datum/component/storage.proc/handle_mass_item_insertion, things, src_object, user, progress)))
|
||||
while (do_after(user, 1 SECONDS, src, NONE, FALSE, CALLBACK(src_object.atom_storage, /datum/storage.proc/handle_mass_transfer, user, src)))
|
||||
stoplag(1)
|
||||
progress.end_progress()
|
||||
to_chat(user, span_notice("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)
|
||||
to_chat(user, span_notice("You dump as much of [src_object]'s contents [atom_storage.insert_preposition]to [src] as you can."))
|
||||
atom_storage.orient_to_hud(user)
|
||||
src_object.atom_storage.orient_to_hud(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.refresh_views()
|
||||
return TRUE
|
||||
|
||||
///Get the best place to dump the items contained in the source storage item?
|
||||
|
||||
@@ -880,17 +880,17 @@
|
||||
UNSETEMPTY(movable_loc.important_recursive_contents)
|
||||
|
||||
///called when this movable becomes the parent of a storage component that is currently being viewed by a player. uses important_recursive_contents
|
||||
/atom/movable/proc/become_active_storage(datum/component/storage/component_source)
|
||||
/atom/movable/proc/become_active_storage(datum/storage/source)
|
||||
if(!HAS_TRAIT(src, TRAIT_ACTIVE_STORAGE))
|
||||
for(var/atom/movable/location as anything in get_nested_locs(src) + src)
|
||||
LAZYADDASSOCLIST(location.important_recursive_contents, RECURSIVE_CONTENTS_ACTIVE_STORAGE, src)
|
||||
ADD_TRAIT(src, TRAIT_ACTIVE_STORAGE, component_source)
|
||||
ADD_TRAIT(src, TRAIT_ACTIVE_STORAGE, REF(source))
|
||||
|
||||
///called when this movable's storage component is no longer viewed by any players, unsets important_recursive_contents
|
||||
/atom/movable/proc/lose_active_storage(datum/component/storage/component_source)
|
||||
/atom/movable/proc/lose_active_storage(datum/storage/source)
|
||||
if(!HAS_TRAIT(src, TRAIT_ACTIVE_STORAGE))
|
||||
return
|
||||
REMOVE_TRAIT(src, TRAIT_ACTIVE_STORAGE, component_source)
|
||||
REMOVE_TRAIT(src, TRAIT_ACTIVE_STORAGE, REF(source))
|
||||
if(HAS_TRAIT(src, TRAIT_ACTIVE_STORAGE))
|
||||
return
|
||||
|
||||
@@ -1198,12 +1198,12 @@
|
||||
return blocker_opinion
|
||||
|
||||
/// called when this atom is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
|
||||
/atom/movable/proc/on_exit_storage(datum/component/storage/concrete/master_storage)
|
||||
SEND_SIGNAL(src, COMSIG_STORAGE_EXITED, master_storage)
|
||||
/atom/movable/proc/on_exit_storage(datum/storage/master_storage)
|
||||
return
|
||||
|
||||
/// called when this atom is added into a storage item, which is passed on as S. The loc variable is already set to the storage item.
|
||||
/atom/movable/proc/on_enter_storage(datum/component/storage/concrete/master_storage)
|
||||
SEND_SIGNAL(src, COMSIG_STORAGE_ENTERED, master_storage)
|
||||
/atom/movable/proc/on_enter_storage(datum/storage/master_storage)
|
||||
return
|
||||
|
||||
/atom/movable/proc/get_spacemove_backup()
|
||||
for(var/checked_range in orange(1, get_turf(src)))
|
||||
|
||||
@@ -924,10 +924,10 @@
|
||||
var/obj/item/stack/secondary_inserted = new secondary_stack.merge_type(null,used_amt)
|
||||
component_parts += secondary_inserted
|
||||
else
|
||||
if(SEND_SIGNAL(replacer_tool, COMSIG_TRY_STORAGE_TAKE, secondary_part, src))
|
||||
if(replacer_tool.atom_storage.attempt_remove(secondary_part, src))
|
||||
component_parts += secondary_part
|
||||
secondary_part.forceMove(src)
|
||||
SEND_SIGNAL(replacer_tool, COMSIG_TRY_STORAGE_INSERT, primary_part, null, null, TRUE)
|
||||
replacer_tool.atom_storage.attempt_insert(replacer_tool, primary_part, user, TRUE)
|
||||
component_parts -= primary_part
|
||||
to_chat(user, span_notice("[capitalize(primary_part.name)] replaced with [secondary_part.name]."))
|
||||
shouldplaysound = 1 //Only play the sound when parts are actually replaced!
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
req_components[path] -= used_amt
|
||||
else
|
||||
added_components[part] = path
|
||||
if(SEND_SIGNAL(replacer, COMSIG_TRY_STORAGE_TAKE, part, src))
|
||||
if(replacer.atom_storage.attempt_remove(part, src))
|
||||
req_components[path]--
|
||||
|
||||
for(var/obj/item/part in added_components)
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
pad.update_indicator()
|
||||
pad.closed = FALSE
|
||||
user.transferItemToLoc(src, pad, TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_ALL)
|
||||
atom_storage.close_all()
|
||||
|
||||
/obj/item/storage/briefcase/launchpad/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/launchpad_remote))
|
||||
|
||||
+13
-10
@@ -544,7 +544,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
|
||||
|
||||
//If the item is in a storage item, take it out
|
||||
SEND_SIGNAL(loc, COMSIG_TRY_STORAGE_TAKE, src, user.loc, TRUE)
|
||||
loc.atom_storage?.attempt_remove(src, user.loc, silent = TRUE)
|
||||
if(QDELETED(src)) //moving it out of the storage to the floor destroyed it.
|
||||
return
|
||||
|
||||
@@ -579,7 +579,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
return
|
||||
|
||||
//If the item is in a storage item, take it out
|
||||
SEND_SIGNAL(loc, COMSIG_TRY_STORAGE_TAKE, src, user.loc, TRUE)
|
||||
loc.atom_storage?.attempt_remove(src, user.loc, silent = TRUE)
|
||||
if(QDELETED(src)) //moving it out of the storage to the floor destroyed it.
|
||||
return
|
||||
|
||||
@@ -768,9 +768,9 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/on_exit_storage(datum/component/storage/concrete/master_storage)
|
||||
/obj/item/on_exit_storage(datum/storage/master_storage)
|
||||
. = ..()
|
||||
var/atom/location = master_storage.real_location()
|
||||
var/atom/location = master_storage.real_location?.resolve()
|
||||
do_drop_animation(location)
|
||||
|
||||
/obj/item/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
@@ -819,8 +819,8 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
/obj/item/proc/remove_item_from_storage(atom/newLoc) //please use this if you're going to snowflake an item out of a obj/item/storage
|
||||
if(!newLoc)
|
||||
return FALSE
|
||||
if(SEND_SIGNAL(loc, COMSIG_CONTAINS_STORAGE))
|
||||
return SEND_SIGNAL(loc, COMSIG_TRY_STORAGE_TAKE, src, newLoc, TRUE)
|
||||
if(loc.atom_storage)
|
||||
return loc.atom_storage.attempt_remove(src, newLoc, silent = TRUE)
|
||||
return FALSE
|
||||
|
||||
/// Returns the icon used for overlaying the object on a belt
|
||||
@@ -971,7 +971,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
|
||||
/obj/item/MouseEntered(location, control, params)
|
||||
. = ..()
|
||||
if(get(src, /mob) == usr && !QDELETED(src))
|
||||
if(((get(src, /mob) == usr) || src.loc.atom_storage || (src.item_flags & IN_STORAGE)) && !QDELETED(src))
|
||||
var/mob/living/L = usr
|
||||
if(usr.client.prefs.read_preference(/datum/preference/toggle/enable_tooltips))
|
||||
var/timedelay = usr.client.prefs.read_preference(/datum/preference/numeric/tooltip_delay) / 100
|
||||
@@ -992,8 +992,8 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
remove_filter("hover_outline")
|
||||
|
||||
/obj/item/proc/apply_outline(outline_color = null)
|
||||
if(get(src, /mob) != usr || QDELETED(src) || isobserver(usr)) //cancel if the item isn't in an inventory, is being deleted, or if the person hovering is a ghost (so that people spectating you don't randomly make your items glow)
|
||||
return
|
||||
if(((get(src, /mob) != usr) && !src.loc.atom_storage && !(src.item_flags & IN_STORAGE)) || QDELETED(src) || isobserver(usr)) //cancel if the item isn't in an inventory, is being deleted, or if the person hovering is a ghost (so that people spectating you don't randomly make your items glow)
|
||||
return FALSE
|
||||
var/theme = lowertext(usr.client?.prefs?.read_preference(/datum/preference/choiced/ui_style))
|
||||
if(!outline_color) //if we weren't provided with a color, take the theme's color
|
||||
switch(theme) //yeah it kinda has to be this way
|
||||
@@ -1345,7 +1345,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
return
|
||||
|
||||
/// Whether or not this item can be put into a storage item through attackby
|
||||
/obj/item/proc/attackby_storage_insert(datum/component/storage, atom/storage_holder, mob/user)
|
||||
/obj/item/proc/attackby_storage_insert(datum/storage, atom/storage_holder, mob/user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/proc/do_pickup_animation(atom/target)
|
||||
@@ -1385,6 +1385,9 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
|
||||
if(!istype(loc, /turf))
|
||||
return
|
||||
|
||||
if(!istype(moving_from))
|
||||
return
|
||||
|
||||
var/turf/current_turf = get_turf(src)
|
||||
var/direction = get_dir(moving_from, current_turf)
|
||||
var/from_x = moving_from.base_pixel_x
|
||||
|
||||
@@ -599,9 +599,7 @@
|
||||
|
||||
/obj/item/storage/crayons/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 7
|
||||
STR.set_holdable(list(/obj/item/toy/crayon))
|
||||
create_storage(canhold = list(/obj/item/toy/crayon))
|
||||
|
||||
/obj/item/storage/crayons/PopulateContents()
|
||||
new /obj/item/toy/crayon/red(src)
|
||||
@@ -822,7 +820,7 @@
|
||||
|
||||
return SECONDARY_ATTACK_CONTINUE_CHAIN
|
||||
|
||||
/obj/item/toy/crayon/spraycan/attackby_storage_insert(datum/component/storage, atom/storage_holder, mob/user)
|
||||
/obj/item/toy/crayon/spraycan/attackby_storage_insert(datum/storage, atom/storage_holder, mob/user)
|
||||
return is_capped
|
||||
|
||||
/obj/item/toy/crayon/spraycan/update_icon_state()
|
||||
|
||||
@@ -18,13 +18,11 @@
|
||||
///If the UI has the pH meter shown
|
||||
var/show_ph = TRUE
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/ComponentInitialize()
|
||||
/obj/item/storage/portable_chem_mixer/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 200
|
||||
STR.max_items = 50
|
||||
STR.insert_preposition = "in"
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_total_storage = 200
|
||||
atom_storage.max_slots = 50
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/reagent_containers/glass/beaker,
|
||||
/obj/item/reagent_containers/glass/bottle,
|
||||
/obj/item/reagent_containers/food/drinks/waterbottle,
|
||||
@@ -40,8 +38,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/attackby(obj/item/I, mob/user, params)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if (istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container() && locked)
|
||||
if (istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container() && atom_storage.locked)
|
||||
var/obj/item/reagent_containers/B = I
|
||||
. = TRUE //no afterattack
|
||||
if(!user.transferItemToLoc(B, src))
|
||||
@@ -70,7 +67,7 @@
|
||||
return
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/update_icon_state()
|
||||
if(!SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED))
|
||||
if(!atom_storage.locked)
|
||||
icon_state = "portablechemicalmixer_open"
|
||||
return ..()
|
||||
if(beaker)
|
||||
@@ -81,8 +78,7 @@
|
||||
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/AltClick(mob/living/user)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if(!locked)
|
||||
if(!atom_storage.locked)
|
||||
return ..()
|
||||
if(!can_interact(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
@@ -90,11 +86,10 @@
|
||||
update_appearance()
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/CtrlClick(mob/living/user)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !locked)
|
||||
if (!locked)
|
||||
atom_storage.locked = !atom_storage.locked
|
||||
if (!atom_storage.locked)
|
||||
update_contents()
|
||||
if (locked)
|
||||
if (atom_storage.locked)
|
||||
replace_beaker(user)
|
||||
update_appearance()
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50)
|
||||
@@ -122,17 +117,15 @@
|
||||
if (loc != user)
|
||||
return ..()
|
||||
else
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if (!locked)
|
||||
if (!atom_storage.locked)
|
||||
return ..()
|
||||
if(SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED))
|
||||
if(atom_storage?.locked)
|
||||
ui_interact(user)
|
||||
return
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/attack_self(mob/user)
|
||||
if(loc == user)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if (locked)
|
||||
if (atom_storage.locked)
|
||||
ui_interact(user)
|
||||
return
|
||||
else
|
||||
|
||||
@@ -8,10 +8,8 @@
|
||||
|
||||
/obj/item/storage/dice/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/component/storage/storage = GetComponent(/datum/component/storage)
|
||||
storage.allow_quick_gather = TRUE
|
||||
storage.click_gather = TRUE
|
||||
storage.set_holdable(list(/obj/item/dice))
|
||||
atom_storage.allow_quick_gather = TRUE
|
||||
atom_storage.set_holdable(list(/obj/item/dice))
|
||||
|
||||
/obj/item/storage/dice/PopulateContents()
|
||||
new /obj/item/dice/d4(src)
|
||||
|
||||
@@ -7,31 +7,34 @@
|
||||
|
||||
/obj/item/implant/storage/activate()
|
||||
. = ..()
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SHOW, imp_in, TRUE)
|
||||
atom_storage?.open_storage(src, imp_in)
|
||||
|
||||
/obj/item/implant/storage/removed(source, silent = FALSE, special = 0)
|
||||
if(!special)
|
||||
var/datum/component/storage/lostimplant = GetComponent(/datum/component/storage/concrete/implant)
|
||||
var/mob/living/implantee = source
|
||||
for (var/obj/item/I in lostimplant.contents())
|
||||
|
||||
var/atom/resolve_parent = atom_storage.parent?.resolve()
|
||||
if(!resolve_parent)
|
||||
return
|
||||
|
||||
for (var/obj/item/I in resolve_parent.contents)
|
||||
I.add_mob_blood(implantee)
|
||||
lostimplant.do_quick_empty()
|
||||
atom_storage.remove_all(implantee)
|
||||
implantee.visible_message(span_warning("A bluespace pocket opens around [src] as it exits [implantee], spewing out its contents and rupturing the surrounding tissue!"))
|
||||
implantee.apply_damage(20, BRUTE, BODY_ZONE_CHEST)
|
||||
qdel(lostimplant)
|
||||
qdel(atom_storage)
|
||||
return ..()
|
||||
|
||||
/obj/item/implant/storage/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE)
|
||||
for(var/X in target.implants)
|
||||
if(istype(X, type))
|
||||
var/obj/item/implant/storage/imp_e = X
|
||||
var/datum/component/storage/STR = imp_e.GetComponent(/datum/component/storage)
|
||||
if(!STR || (STR && STR.max_items < max_slot_stacking))
|
||||
imp_e.AddComponent(/datum/component/storage/concrete/implant)
|
||||
if(!imp_e.atom_storage || (imp_e.atom_storage && imp_e.atom_storage.max_slots < max_slot_stacking))
|
||||
imp_e.create_storage(type = /datum/storage/implant)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
AddComponent(/datum/component/storage/concrete/implant)
|
||||
create_storage(type = /datum/storage/implant)
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -268,14 +268,13 @@
|
||||
worn_icon_state = "mailbag"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/mail/ComponentInitialize()
|
||||
/obj/item/storage/bag/mail/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/storage = GetComponent(/datum/component/storage)
|
||||
storage.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
storage.max_combined_w_class = 42
|
||||
storage.max_items = 21
|
||||
storage.display_numerical_stacking = FALSE
|
||||
storage.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 42
|
||||
atom_storage.max_slots = 21
|
||||
atom_storage.numerical_stacking = FALSE
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/mail,
|
||||
/obj/item/delivery/small,
|
||||
/obj/item/paper
|
||||
|
||||
@@ -86,13 +86,13 @@
|
||||
final_block_chance = 0 //Don't bring a sword to a gunfight
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/sabre/on_exit_storage(datum/component/storage/concrete/container)
|
||||
var/obj/item/storage/belt/sabre/sabre = container.real_location()
|
||||
/obj/item/melee/sabre/on_exit_storage(datum/storage/container)
|
||||
var/obj/item/storage/belt/sabre/sabre = container.real_location?.resolve()
|
||||
if(istype(sabre))
|
||||
playsound(sabre, 'sound/items/unsheath.ogg', 25, TRUE)
|
||||
|
||||
/obj/item/melee/sabre/on_enter_storage(datum/component/storage/concrete/container)
|
||||
var/obj/item/storage/belt/sabre/sabre = container.real_location()
|
||||
/obj/item/melee/sabre/on_enter_storage(datum/storage/container)
|
||||
var/obj/item/storage/belt/sabre/sabre = container.real_location?.resolve()
|
||||
if(istype(sabre))
|
||||
playsound(sabre, 'sound/items/sheath.ogg', 25, TRUE)
|
||||
|
||||
|
||||
@@ -254,8 +254,7 @@
|
||||
|
||||
/obj/item/storage/backpack/bannerpack/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times.
|
||||
atom_storage.max_total_storage = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times.
|
||||
|
||||
/obj/item/storage/backpack/bannerpack/red
|
||||
name = "red banner backpack"
|
||||
|
||||
@@ -670,6 +670,7 @@
|
||||
var/obj/item/stack/F = new type(user? user : drop_location(), amount, FALSE, mats_per_unit)
|
||||
. = F
|
||||
F.copy_evidences(src)
|
||||
loc.atom_storage?.refresh_views()
|
||||
if(user)
|
||||
if(!user.put_in_hands(F, merge_stacks = FALSE))
|
||||
F.forceMove(user.drop_location())
|
||||
|
||||
@@ -21,21 +21,17 @@
|
||||
resistance_flags = NONE
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/storage/backpack/ComponentInitialize()
|
||||
/obj/item/storage/backpack/Initialize()
|
||||
. = ..()
|
||||
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
|
||||
create_storage(max_slots = 21, max_total_storage = 21)
|
||||
|
||||
/*
|
||||
* Backpack Types
|
||||
*/
|
||||
|
||||
/obj/item/storage/backpack/old/ComponentInitialize()
|
||||
/obj/item/storage/backpack/old/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 12
|
||||
atom_storage.max_total_storage = 12
|
||||
|
||||
/obj/item/bag_of_holding_inert
|
||||
name = "inert bag of holding"
|
||||
@@ -57,14 +53,12 @@
|
||||
resistance_flags = FIRE_PROOF
|
||||
item_flags = NO_MAT_REDEMPTION
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 60, ACID = 50)
|
||||
component_type = /datum/component/storage/concrete/bluespace/bag_of_holding
|
||||
|
||||
/obj/item/storage/backpack/holding/ComponentInitialize()
|
||||
/obj/item/storage/backpack/holding/Initialize()
|
||||
. = ..()
|
||||
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
|
||||
|
||||
create_storage(max_specific_storage = WEIGHT_CLASS_GIGANTIC, max_total_storage = 35, max_slots = 30, type = /datum/storage/bag_of_holding)
|
||||
atom_storage.allow_big_nesting = TRUE
|
||||
|
||||
/obj/item/storage/backpack/holding/suicide_act(mob/living/user)
|
||||
user.visible_message(span_suicide("[user] is jumping into [src]! It looks like [user.p_theyre()] trying to commit suicide."))
|
||||
@@ -85,11 +79,10 @@
|
||||
. = ..()
|
||||
regenerate_presents()
|
||||
|
||||
/obj/item/storage/backpack/santabag/ComponentInitialize()
|
||||
/obj/item/storage/backpack/santabag/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 60
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 60
|
||||
|
||||
/obj/item/storage/backpack/santabag/suicide_act(mob/user)
|
||||
user.visible_message(span_suicide("[user] places [src] over [user.p_their()] head and pulls it tight! It looks like [user.p_they()] [user.p_are()]n't in the Christmas spirit..."))
|
||||
@@ -98,17 +91,14 @@
|
||||
/obj/item/storage/backpack/santabag/proc/regenerate_presents()
|
||||
addtimer(CALLBACK(src, .proc/regenerate_presents), 30 SECONDS)
|
||||
|
||||
var/mob/M = get(loc, /mob)
|
||||
if(!istype(M))
|
||||
var/mob/user = get(loc, /mob)
|
||||
if(!istype(user))
|
||||
return
|
||||
if(M.mind && HAS_TRAIT(M.mind, TRAIT_CANNOT_OPEN_PRESENTS))
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
if(user.mind && HAS_TRAIT(user.mind, TRAIT_CANNOT_OPEN_PRESENTS))
|
||||
var/turf/floor = get_turf(src)
|
||||
var/obj/item/I = new /obj/item/a_gift/anything(floor)
|
||||
if(STR.can_be_inserted(I, stop_messages=TRUE))
|
||||
STR.handle_item_insertion(I, prevent_warning=TRUE)
|
||||
else
|
||||
qdel(I)
|
||||
var/obj/item/thing = new /obj/item/a_gift/anything(floor)
|
||||
if(!atom_storage.attempt_insert(src, thing, user, override = TRUE))
|
||||
qdel(thing)
|
||||
|
||||
|
||||
/obj/item/storage/backpack/cultpack
|
||||
@@ -314,12 +304,8 @@
|
||||
/obj/item/storage/backpack/satchel/flat/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE, INVISIBILITY_OBSERVER, use_anchor = TRUE)
|
||||
|
||||
/obj/item/storage/backpack/satchel/flat/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 15
|
||||
STR.set_holdable(null, list(/obj/item/storage/backpack/satchel/flat)) //muh recursive backpacks)
|
||||
atom_storage.max_total_storage = 15
|
||||
atom_storage.set_holdable(cant_hold_list = list(/obj/item/storage/backpack/satchel/flat)) //muh recursive backpacks)
|
||||
|
||||
/obj/item/storage/backpack/satchel/flat/PopulateContents()
|
||||
var/datum/supply_pack/costumes_toys/randomised/contraband/C = new
|
||||
@@ -345,10 +331,9 @@
|
||||
inhand_icon_state = "duffel"
|
||||
slowdown = 1
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/ComponentInitialize()
|
||||
/obj/item/storage/backpack/duffelbag/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 30
|
||||
atom_storage.max_total_storage = 30
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/cursed
|
||||
name = "living duffel bag"
|
||||
@@ -498,10 +483,9 @@
|
||||
slowdown = 0
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/syndie/ComponentInitialize()
|
||||
/obj/item/storage/backpack/duffelbag/syndie/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.silent = TRUE
|
||||
atom_storage.silent = TRUE
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/syndie/hitman
|
||||
desc = "A large duffel bag for holding extra things. There is a Nanotrasen logo on the back."
|
||||
@@ -655,11 +639,10 @@
|
||||
new /obj/item/grenade/syndieminibomb(src)
|
||||
|
||||
// For ClownOps.
|
||||
/obj/item/storage/backpack/duffelbag/clown/syndie/ComponentInitialize()
|
||||
/obj/item/storage/backpack/duffelbag/clown/syndie/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
slowdown = 0
|
||||
STR.silent = TRUE
|
||||
atom_storage.silent = TRUE
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/clown/syndie/PopulateContents()
|
||||
new /obj/item/modular_computer/tablet/pda/clown(src)
|
||||
|
||||
@@ -20,13 +20,11 @@
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/storage/bag/ComponentInitialize()
|
||||
/obj/item/storage/bag/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.allow_quick_gather = TRUE
|
||||
STR.allow_quick_empty = TRUE
|
||||
STR.display_numerical_stacking = TRUE
|
||||
STR.click_gather = TRUE
|
||||
atom_storage.allow_quick_gather = TRUE
|
||||
atom_storage.allow_quick_empty = TRUE
|
||||
atom_storage.numerical_stacking = TRUE
|
||||
|
||||
// -----------------------------
|
||||
// Trash bag
|
||||
@@ -43,13 +41,12 @@
|
||||
///If true, can be inserted into the janitor cart
|
||||
var/insertable = TRUE
|
||||
|
||||
/obj/item/storage/bag/trash/ComponentInitialize()
|
||||
/obj/item/storage/bag/trash/Initialize()
|
||||
. = ..()
|
||||
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.set_holdable(null, list(/obj/item/disk/nuclear))
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
atom_storage.max_total_storage = 30
|
||||
atom_storage.max_slots = 30
|
||||
atom_storage.set_holdable(cant_hold_list = list(/obj/item/disk/nuclear))
|
||||
|
||||
/obj/item/storage/bag/trash/suicide_act(mob/user)
|
||||
user.visible_message(span_suicide("[user] puts [src] over [user.p_their()] head and starts chomping at the insides! Disgusting!"))
|
||||
@@ -87,11 +84,10 @@
|
||||
inhand_icon_state = "bluetrashbag"
|
||||
item_flags = NO_MAT_REDEMPTION
|
||||
|
||||
/obj/item/storage/bag/trash/bluespace/ComponentInitialize()
|
||||
/obj/item/storage/bag/trash/bluespace/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 60
|
||||
STR.max_items = 60
|
||||
atom_storage.max_total_storage = 60
|
||||
atom_storage.max_slots = 60
|
||||
|
||||
/obj/item/storage/bag/trash/bluespace/cyborg
|
||||
insertable = FALSE
|
||||
@@ -108,17 +104,17 @@
|
||||
worn_icon_state = "satchel"
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
component_type = /datum/component/storage/concrete/stack
|
||||
var/spam_protection = FALSE //If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it
|
||||
var/mob/listeningTo
|
||||
|
||||
/obj/item/storage/bag/ore/ComponentInitialize()
|
||||
/obj/item/storage/bag/ore/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
|
||||
STR.allow_quick_empty = TRUE
|
||||
STR.set_holdable(list(/obj/item/stack/ore))
|
||||
STR.max_w_class = WEIGHT_CLASS_HUGE
|
||||
STR.max_combined_stack_amount = 50
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_HUGE
|
||||
atom_storage.max_total_storage = 50
|
||||
atom_storage.numerical_stacking = TRUE
|
||||
atom_storage.allow_quick_empty = TRUE
|
||||
atom_storage.allow_quick_gather = TRUE
|
||||
atom_storage.set_holdable(list(/obj/item/stack/ore))
|
||||
|
||||
/obj/item/storage/bag/ore/equipped(mob/user)
|
||||
. = ..()
|
||||
@@ -126,7 +122,7 @@
|
||||
return
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/Pickup_ores)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/pickup_ores)
|
||||
listeningTo = user
|
||||
|
||||
/obj/item/storage/bag/ore/dropped()
|
||||
@@ -135,24 +131,27 @@
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
|
||||
/obj/item/storage/bag/ore/proc/Pickup_ores(mob/living/user)
|
||||
/obj/item/storage/bag/ore/proc/pickup_ores(mob/living/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/show_message = FALSE
|
||||
var/obj/structure/ore_box/box
|
||||
var/turf/tile = user.loc
|
||||
if (!isturf(tile))
|
||||
var/turf/tile = get_turf(user)
|
||||
|
||||
if(!isturf(tile))
|
||||
return
|
||||
if (istype(user.pulling, /obj/structure/ore_box))
|
||||
|
||||
if(istype(user.pulling, /obj/structure/ore_box))
|
||||
box = user.pulling
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
if(STR)
|
||||
for(var/A in tile)
|
||||
if (!is_type_in_typecache(A, STR.can_hold))
|
||||
|
||||
if(atom_storage)
|
||||
for(var/thing in tile)
|
||||
if(!is_type_in_typecache(thing, atom_storage.can_hold))
|
||||
continue
|
||||
if (box)
|
||||
user.transferItemToLoc(A, box)
|
||||
if(box)
|
||||
user.transferItemToLoc(thing, box)
|
||||
show_message = TRUE
|
||||
else if(SEND_SIGNAL(src, COMSIG_TRY_STORAGE_INSERT, A, user, TRUE))
|
||||
else if(atom_storage.attempt_insert(src, thing, user))
|
||||
show_message = TRUE
|
||||
else
|
||||
if(!spam_protection)
|
||||
@@ -161,12 +160,14 @@
|
||||
continue
|
||||
if(show_message)
|
||||
playsound(user, SFX_RUSTLE, 50, TRUE)
|
||||
|
||||
if (box)
|
||||
user.visible_message(span_notice("[user] offloads the ores beneath [user.p_them()] into [box]."), \
|
||||
span_notice("You offload the ores beneath you into your [box]."))
|
||||
span_notice("You offload the ores beneath you into your [box]."))
|
||||
else
|
||||
user.visible_message(span_notice("[user] scoops up the ores beneath [user.p_them()]."), \
|
||||
span_notice("You scoop up the ores beneath you with your [name]."))
|
||||
|
||||
spam_protection = FALSE
|
||||
|
||||
/obj/item/storage/bag/ore/cyborg
|
||||
@@ -177,12 +178,11 @@
|
||||
desc = "A revolution in convenience, this satchel allows for huge amounts of ore storage. It's been outfitted with anti-malfunction safety measures."
|
||||
icon_state = "satchel_bspace"
|
||||
|
||||
/obj/item/storage/bag/ore/holding/ComponentInitialize()
|
||||
/obj/item/storage/bag/ore/holding/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
|
||||
STR.max_items = INFINITY
|
||||
STR.max_combined_w_class = INFINITY
|
||||
STR.max_combined_stack_amount = INFINITY
|
||||
atom_storage.max_slots = INFINITY
|
||||
atom_storage.max_specific_storage = INFINITY
|
||||
atom_storage.max_total_storage = INFINITY
|
||||
|
||||
// -----------------------------
|
||||
// Plant bag
|
||||
@@ -195,13 +195,12 @@
|
||||
worn_icon_state = "plantbag"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/plants/ComponentInitialize()
|
||||
/obj/item/storage/bag/plants/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 100
|
||||
STR.max_items = 100
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 100
|
||||
atom_storage.max_slots = 100
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/food/grown,
|
||||
/obj/item/graft,
|
||||
/obj/item/grown,
|
||||
@@ -243,8 +242,7 @@
|
||||
// -----------------------------
|
||||
// Sheet Snatcher
|
||||
// -----------------------------
|
||||
// Because it stacks stacks, this doesn't operate normally.
|
||||
// However, making it a storage/bag allows us to reuse existing code in some places. -Sayu
|
||||
// sorry sayu your sheet snatcher is now OBSOLETE but i'm leaving it because idc
|
||||
|
||||
/obj/item/storage/bag/sheetsnatcher
|
||||
name = "sheet snatcher"
|
||||
@@ -254,20 +252,20 @@
|
||||
worn_icon_state = "satchel"
|
||||
|
||||
var/capacity = 300; //the number of sheets it can carry.
|
||||
component_type = /datum/component/storage/concrete/stack
|
||||
|
||||
/obj/item/storage/bag/sheetsnatcher/ComponentInitialize()
|
||||
/obj/item/storage/bag/sheetsnatcher/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
|
||||
STR.allow_quick_empty = TRUE
|
||||
STR.set_holdable(list(
|
||||
atom_storage.allow_quick_empty = TRUE
|
||||
atom_storage.allow_quick_gather = TRUE
|
||||
atom_storage.numerical_stacking = TRUE
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/stack/sheet
|
||||
),
|
||||
list(
|
||||
/obj/item/stack/sheet/mineral/sandstone,
|
||||
/obj/item/stack/sheet/mineral/wood,
|
||||
))
|
||||
STR.max_combined_stack_amount = 300
|
||||
atom_storage.max_total_storage = capacity / 2
|
||||
|
||||
// -----------------------------
|
||||
// Sheet Snatcher (Cyborg)
|
||||
@@ -278,11 +276,6 @@
|
||||
desc = ""
|
||||
capacity = 500//Borgs get more because >specialization
|
||||
|
||||
/obj/item/storage/bag/sheetsnatcher/borg/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
|
||||
STR.max_combined_stack_amount = 500
|
||||
|
||||
// -----------------------------
|
||||
// Book bag
|
||||
// -----------------------------
|
||||
@@ -295,14 +288,12 @@
|
||||
worn_icon_state = "bookbag"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/books/ComponentInitialize()
|
||||
/obj/item/storage/bag/books/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 21
|
||||
STR.max_items = 7
|
||||
STR.display_numerical_stacking = FALSE
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 21
|
||||
atom_storage.max_slots = 7
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/book,
|
||||
/obj/item/spellbook,
|
||||
/obj/item/storage/book,
|
||||
@@ -326,11 +317,10 @@
|
||||
custom_materials = list(/datum/material/iron=3000)
|
||||
custom_price = PAYCHECK_CREW * 0.6
|
||||
|
||||
/obj/item/storage/bag/tray/ComponentInitialize()
|
||||
/obj/item/storage/bag/tray/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY //Plates are required bulky to keep them out of backpacks
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY //Plates are required bulky to keep them out of backpacks
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/clothing/mask/cigarette,
|
||||
/obj/item/food,
|
||||
/obj/item/kitchen,
|
||||
@@ -345,14 +335,14 @@
|
||||
/obj/item/storage/fancy,
|
||||
/obj/item/trash,
|
||||
)) //Should cover: Bottles, Beakers, Bowls, Booze, Glasses, Food, Food Containers, Food Trash, Organs, Tobacco Products, Lighters, and Kitchen Tools.
|
||||
STR.insert_preposition = "on"
|
||||
STR.max_items = 7
|
||||
atom_storage.insert_preposition = "on"
|
||||
atom_storage.max_slots = 7
|
||||
|
||||
/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user)
|
||||
. = ..()
|
||||
// Drop all the things. All of them.
|
||||
var/list/obj/item/oldContents = contents.Copy()
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_QUICK_EMPTY)
|
||||
atom_storage.remove_all(user)
|
||||
// Make each item scatter a bit
|
||||
for(var/obj/item/tray_item in oldContents)
|
||||
do_scatter(tray_item)
|
||||
@@ -414,13 +404,11 @@
|
||||
desc = "A bag for storing pills, patches, and bottles."
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/chemistry/ComponentInitialize()
|
||||
/obj/item/storage/bag/chemistry/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 200
|
||||
STR.max_items = 50
|
||||
STR.insert_preposition = "in"
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_total_storage = 200
|
||||
atom_storage.max_slots = 50
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/reagent_containers/chem_pack,
|
||||
/obj/item/reagent_containers/dropper,
|
||||
/obj/item/reagent_containers/food/drinks/waterbottle,
|
||||
@@ -443,13 +431,11 @@
|
||||
desc = "A bag for the safe transportation and disposal of biowaste and other virulent materials."
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/bio/ComponentInitialize()
|
||||
/obj/item/storage/bag/bio/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 200
|
||||
STR.max_items = 25
|
||||
STR.insert_preposition = "in"
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_total_storage = 200
|
||||
atom_storage.max_slots = 25
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/bodypart,
|
||||
/obj/item/food/monkeycube,
|
||||
/obj/item/healthanalyzer,
|
||||
@@ -474,13 +460,11 @@
|
||||
desc = "A bag for the storage and transport of anomalous materials."
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/xeno/ComponentInitialize()
|
||||
/obj/item/storage/bag/xeno/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 200
|
||||
STR.max_items = 25
|
||||
STR.insert_preposition = "in"
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_total_storage = 200
|
||||
atom_storage.max_slots = 25
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/bodypart,
|
||||
/obj/item/food/deadmouse,
|
||||
/obj/item/food/monkeycube,
|
||||
@@ -507,14 +491,12 @@
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/construction/ComponentInitialize()
|
||||
/obj/item/storage/bag/construction/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 100
|
||||
STR.max_items = 50
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
STR.insert_preposition = "in"
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_total_storage = 100
|
||||
atom_storage.max_slots = 50
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/assembly,
|
||||
/obj/item/circuitboard,
|
||||
/obj/item/electronics,
|
||||
@@ -532,13 +514,12 @@
|
||||
inhand_icon_state = "quiver"
|
||||
worn_icon_state = "harpoon_quiver"
|
||||
|
||||
/obj/item/storage/bag/harpoon_quiver/ComponentInitialize()
|
||||
/obj/item/storage/bag/harpoon_quiver/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_TINY
|
||||
STR.max_items = 40
|
||||
STR.max_combined_w_class = 100
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_TINY
|
||||
atom_storage.max_slots = 40
|
||||
atom_storage.max_total_storage = 100
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/ammo_casing/caseless/harpoon
|
||||
))
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/basket/ComponentInitialize()
|
||||
/obj/item/storage/basket/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 21
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 21
|
||||
|
||||
@@ -41,12 +41,11 @@
|
||||
drop_sound = 'sound/items/handling/toolbelt_drop.ogg'
|
||||
pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg'
|
||||
|
||||
/obj/item/storage/belt/utility/ComponentInitialize()
|
||||
/obj/item/storage/belt/utility/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 21
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 21
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/airlock_painter,
|
||||
/obj/item/analyzer,
|
||||
/obj/item/assembly/signaler,
|
||||
@@ -206,12 +205,11 @@
|
||||
inhand_icon_state = "medical"
|
||||
worn_icon_state = "medical"
|
||||
|
||||
/obj/item/storage/belt/medical/ComponentInitialize()
|
||||
/obj/item/storage/belt/medical/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 21
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 21
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/bikehorn/rubberducky,
|
||||
/obj/item/blood_filter,
|
||||
/obj/item/bonesetter,
|
||||
@@ -320,12 +318,11 @@
|
||||
worn_icon_state = "security"
|
||||
content_overlays = TRUE
|
||||
|
||||
/obj/item/storage/belt/security/ComponentInitialize()
|
||||
/obj/item/storage/belt/security/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 5
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 5
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/assembly/flash/handheld,
|
||||
@@ -360,10 +357,9 @@
|
||||
content_overlays = FALSE
|
||||
custom_premium_price = PAYCHECK_COMMAND * 3
|
||||
|
||||
/obj/item/storage/belt/security/webbing/ComponentInitialize()
|
||||
/obj/item/storage/belt/security/webbing/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
atom_storage.max_slots = 6
|
||||
|
||||
/obj/item/storage/belt/mining
|
||||
name = "explorer's webbing"
|
||||
@@ -373,13 +369,12 @@
|
||||
worn_icon_state = "explorer1"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/storage/belt/mining/ComponentInitialize()
|
||||
/obj/item/storage/belt/mining/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 20
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 6
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 20
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/analyzer,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/crowbar,
|
||||
@@ -435,10 +430,9 @@
|
||||
inhand_icon_state = "ebelt"
|
||||
worn_icon_state = "ebelt"
|
||||
|
||||
/obj/item/storage/belt/mining/primitive/ComponentInitialize()
|
||||
/obj/item/storage/belt/mining/primitive/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 5
|
||||
atom_storage.max_slots = 5
|
||||
|
||||
/obj/item/storage/belt/soulstone
|
||||
name = "soul stone belt"
|
||||
@@ -447,11 +441,10 @@
|
||||
inhand_icon_state = "soulstonebelt"
|
||||
worn_icon_state = "soulstonebelt"
|
||||
|
||||
/obj/item/storage/belt/soulstone/ComponentInitialize()
|
||||
/obj/item/storage/belt/soulstone/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 6
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/soulstone
|
||||
))
|
||||
|
||||
@@ -471,11 +464,10 @@
|
||||
worn_icon_state = "championbelt"
|
||||
custom_materials = list(/datum/material/gold=400)
|
||||
|
||||
/obj/item/storage/belt/champion/ComponentInitialize()
|
||||
/obj/item/storage/belt/champion/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 1
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 1
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/clothing/mask/luchador
|
||||
))
|
||||
|
||||
@@ -494,10 +486,9 @@
|
||||
worn_icon_state = "militarywebbing"
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/storage/belt/military/ComponentInitialize()
|
||||
/obj/item/storage/belt/military/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/storage/belt/military/snack
|
||||
name = "tactical snack rig"
|
||||
@@ -507,12 +498,11 @@
|
||||
var/sponsor = pick("Donk Co.", "Waffle Co.", "Roffle Co.", "Gorlax Marauders", "Tiger Cooperative")
|
||||
desc = "A set of snack-tical webbing worn by athletes of the [sponsor] VR sports division."
|
||||
|
||||
/obj/item/storage/belt/military/snack/ComponentInitialize()
|
||||
/obj/item/storage/belt/military/snack/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 6
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/food,
|
||||
/obj/item/reagent_containers/food/drinks
|
||||
))
|
||||
@@ -578,10 +568,9 @@
|
||||
inhand_icon_state = "security"
|
||||
worn_icon_state = "assault"
|
||||
|
||||
/obj/item/storage/belt/military/assault/ComponentInitialize()
|
||||
/obj/item/storage/belt/military/assault/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
atom_storage.max_slots = 6
|
||||
|
||||
/obj/item/storage/belt/military/assault/full/PopulateContents()
|
||||
generate_items_inside(list(
|
||||
@@ -596,14 +585,13 @@
|
||||
inhand_icon_state = "security"
|
||||
worn_icon_state = "grenadebeltnew"
|
||||
|
||||
/obj/item/storage/belt/grenade/ComponentInitialize()
|
||||
/obj/item/storage/belt/grenade/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 30
|
||||
STR.display_numerical_stacking = TRUE
|
||||
STR.max_combined_w_class = 60
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 30
|
||||
atom_storage.numerical_stacking = TRUE
|
||||
atom_storage.max_total_storage = 60
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/food/grown/cherry_bomb,
|
||||
/obj/item/food/grown/firelemon,
|
||||
/obj/item/grenade,
|
||||
@@ -636,11 +624,10 @@
|
||||
inhand_icon_state = "soulstonebelt"
|
||||
worn_icon_state = "soulstonebelt"
|
||||
|
||||
/obj/item/storage/belt/wands/ComponentInitialize()
|
||||
/obj/item/storage/belt/wands/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 6
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/gun/magic/wand
|
||||
))
|
||||
|
||||
@@ -663,12 +650,11 @@
|
||||
inhand_icon_state = "janibelt"
|
||||
worn_icon_state = "janibelt"
|
||||
|
||||
/obj/item/storage/belt/janitor/ComponentInitialize()
|
||||
/obj/item/storage/belt/janitor/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL // Set to this so the light replacer can fit.
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 6
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL // Set to this so the light replacer can fit.
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/assembly/mousetrap,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/flashlight,
|
||||
@@ -699,13 +685,12 @@
|
||||
inhand_icon_state = "bandolier"
|
||||
worn_icon_state = "bandolier"
|
||||
|
||||
/obj/item/storage/belt/bandolier/ComponentInitialize()
|
||||
/obj/item/storage/belt/bandolier/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 18
|
||||
STR.max_combined_w_class = 18
|
||||
STR.display_numerical_stacking = TRUE
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 18
|
||||
atom_storage.max_total_storage = 18
|
||||
atom_storage.numerical_stacking = TRUE
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/ammo_casing/a762,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
))
|
||||
@@ -719,11 +704,10 @@
|
||||
dying_key = DYE_REGISTRY_FANNYPACK
|
||||
custom_price = PAYCHECK_CREW * 2
|
||||
|
||||
/obj/item/storage/belt/fannypack/ComponentInitialize()
|
||||
/obj/item/storage/belt/fannypack/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 3
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
atom_storage.max_slots = 3
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/storage/belt/fannypack/black
|
||||
name = "black fannypack"
|
||||
@@ -793,14 +777,14 @@
|
||||
worn_icon_state = "sheath"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/storage/belt/sabre/ComponentInitialize()
|
||||
/obj/item/storage/belt/sabre/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 1
|
||||
STR.rustle_sound = FALSE
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY
|
||||
STR.set_holdable(list(
|
||||
|
||||
atom_storage.max_slots = 1
|
||||
atom_storage.rustle_sound = FALSE
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/melee/sabre,
|
||||
))
|
||||
|
||||
@@ -842,12 +826,11 @@
|
||||
worn_icon_state = "plantbelt"
|
||||
content_overlays = TRUE
|
||||
|
||||
/obj/item/storage/belt/plant/ComponentInitialize()
|
||||
/obj/item/storage/belt/plant/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 6
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/cultivator,
|
||||
/obj/item/geneshears,
|
||||
/obj/item/graft,
|
||||
|
||||
@@ -10,10 +10,9 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
var/title = "book"
|
||||
|
||||
/obj/item/storage/book/ComponentInitialize()
|
||||
/obj/item/storage/book/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 1
|
||||
atom_storage.max_slots = 1
|
||||
|
||||
/obj/item/storage/book/attack_self(mob/user)
|
||||
to_chat(user, span_notice("The pages of [title] have been cut out!"))
|
||||
|
||||
@@ -462,10 +462,9 @@
|
||||
for(var/i in 1 to 6)
|
||||
new donktype(src)
|
||||
|
||||
/obj/item/storage/box/donkpockets/ComponentInitialize()
|
||||
/obj/item/storage/box/donkpockets/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.set_holdable(list(/obj/item/food/donkpocket))
|
||||
atom_storage.set_holdable(list(/obj/item/food/donkpocket))
|
||||
|
||||
/obj/item/storage/box/donkpockets/donkpocketspicy
|
||||
name = "box of spicy-flavoured donk-pockets"
|
||||
@@ -504,11 +503,10 @@
|
||||
illustration = null
|
||||
var/cube_type = /obj/item/food/monkeycube
|
||||
|
||||
/obj/item/storage/box/monkeycubes/ComponentInitialize()
|
||||
/obj/item/storage/box/monkeycubes/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 7
|
||||
STR.set_holdable(list(/obj/item/food/monkeycube))
|
||||
atom_storage.max_slots = 7
|
||||
atom_storage.set_holdable(list(/obj/item/food/monkeycube))
|
||||
|
||||
/obj/item/storage/box/monkeycubes/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
@@ -524,11 +522,10 @@
|
||||
icon_state = "monkeycubebox"
|
||||
illustration = null
|
||||
|
||||
/obj/item/storage/box/gorillacubes/ComponentInitialize()
|
||||
/obj/item/storage/box/gorillacubes/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 3
|
||||
STR.set_holdable(list(/obj/item/food/monkeycube))
|
||||
atom_storage.max_slots = 3
|
||||
atom_storage.set_holdable(list(/obj/item/food/monkeycube))
|
||||
|
||||
/obj/item/storage/box/gorillacubes/PopulateContents()
|
||||
for(var/i in 1 to 3)
|
||||
@@ -682,15 +679,15 @@
|
||||
icon_state = "spbox"
|
||||
illustration = ""
|
||||
|
||||
/obj/item/storage/box/snappops/ComponentInitialize()
|
||||
/obj/item/storage/box/snappops/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.set_holdable(list(/obj/item/toy/snappop))
|
||||
STR.max_items = 8
|
||||
atom_storage.set_holdable(list(/obj/item/toy/snappop))
|
||||
atom_storage.max_slots = 8
|
||||
|
||||
/obj/item/storage/box/snappops/PopulateContents()
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_FILL_TYPE, /obj/item/toy/snappop)
|
||||
|
||||
for(var/i in 1 to 8)
|
||||
new /obj/item/toy/snappop(src)
|
||||
|
||||
/obj/item/storage/box/matches
|
||||
name = "matchbox"
|
||||
desc = "A small box of Almost But Not Quite Plasma Premium Matches."
|
||||
@@ -706,14 +703,14 @@
|
||||
base_icon_state = "matchbox"
|
||||
illustration = null
|
||||
|
||||
/obj/item/storage/box/matches/ComponentInitialize()
|
||||
/obj/item/storage/box/matches/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 10
|
||||
STR.set_holdable(list(/obj/item/match))
|
||||
atom_storage.max_slots = 10
|
||||
atom_storage.set_holdable(list(/obj/item/match))
|
||||
|
||||
/obj/item/storage/box/matches/PopulateContents()
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_FILL_TYPE, /obj/item/match)
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/match(src)
|
||||
|
||||
/obj/item/storage/box/matches/attackby(obj/item/match/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/match))
|
||||
@@ -741,13 +738,12 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
foldable = /obj/item/stack/sheet/cardboard //BubbleWrap
|
||||
|
||||
/obj/item/storage/box/lights/ComponentInitialize()
|
||||
/obj/item/storage/box/lights/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 21
|
||||
STR.set_holdable(list(/obj/item/light/tube, /obj/item/light/bulb))
|
||||
STR.max_combined_w_class = 21
|
||||
STR.click_gather = FALSE //temp workaround to re-enable filling the light replacer with the box
|
||||
atom_storage.max_slots = 21
|
||||
atom_storage.set_holdable(list(/obj/item/light/tube, /obj/item/light/bulb))
|
||||
atom_storage.max_total_storage = 21
|
||||
atom_storage.allow_quick_gather = FALSE //temp workaround to re-enable filling the light replacer with the box
|
||||
|
||||
/obj/item/storage/box/lights/bulbs/PopulateContents()
|
||||
for(var/i in 1 to 21)
|
||||
@@ -1239,11 +1235,10 @@
|
||||
foldable = null
|
||||
custom_price = PAYCHECK_CREW
|
||||
|
||||
/obj/item/storage/box/gum/ComponentInitialize()
|
||||
/obj/item/storage/box/gum/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.set_holdable(list(/obj/item/food/bubblegum))
|
||||
STR.max_items = 4
|
||||
atom_storage.set_holdable(list(/obj/item/food/bubblegum))
|
||||
atom_storage.max_slots = 4
|
||||
|
||||
/obj/item/storage/box/gum/PopulateContents()
|
||||
for(var/i in 1 to 4)
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
max_integrity = 150
|
||||
var/folder_path = /obj/item/folder //this is the path of the folder that gets spawned in New()
|
||||
|
||||
/obj/item/storage/briefcase/ComponentInitialize()
|
||||
/obj/item/storage/briefcase/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 21
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 21
|
||||
|
||||
/obj/item/storage/briefcase/PopulateContents()
|
||||
new /obj/item/pen(src)
|
||||
|
||||
@@ -21,16 +21,22 @@
|
||||
var/contents_tag = "errors"
|
||||
/// What type of thing to fill this storage with.
|
||||
var/spawn_type = null
|
||||
/// How many of the things to fill this storage with.
|
||||
var/spawn_count = 0
|
||||
/// Whether the container is open or not
|
||||
var/is_open = FALSE
|
||||
/// What this container folds up into when it's empty.
|
||||
var/obj/fold_result = /obj/item/stack/sheet/cardboard
|
||||
|
||||
/obj/item/storage/fancy/Initialize()
|
||||
. = ..()
|
||||
|
||||
atom_storage.max_slots = spawn_count
|
||||
|
||||
/obj/item/storage/fancy/PopulateContents()
|
||||
if(!spawn_type)
|
||||
return
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
for(var/i = 1 to STR.max_items)
|
||||
for(var/i = 1 to spawn_count)
|
||||
new spawn_type(src)
|
||||
|
||||
/obj/item/storage/fancy/update_icon_state()
|
||||
@@ -80,16 +86,15 @@
|
||||
icon_state = "donutbox_open" //composite image used for mapping
|
||||
base_icon_state = "donutbox"
|
||||
spawn_type = /obj/item/food/donut/plain
|
||||
spawn_count = 6
|
||||
is_open = TRUE
|
||||
appearance_flags = KEEP_TOGETHER|LONG_GLIDE
|
||||
custom_premium_price = PAYCHECK_COMMAND * 1.75
|
||||
contents_tag = "donut"
|
||||
|
||||
/obj/item/storage/fancy/donut_box/ComponentInitialize()
|
||||
/obj/item/storage/fancy/donut_box/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.set_holdable(list(/obj/item/food/donut))
|
||||
atom_storage.set_holdable(list(/obj/item/food/donut))
|
||||
|
||||
/obj/item/storage/fancy/donut_box/PopulateContents()
|
||||
. = ..()
|
||||
@@ -131,13 +136,12 @@
|
||||
name = "egg box"
|
||||
desc = "A carton for containing eggs."
|
||||
spawn_type = /obj/item/food/egg
|
||||
spawn_count = 12
|
||||
contents_tag = "egg"
|
||||
|
||||
/obj/item/storage/fancy/egg_box/ComponentInitialize()
|
||||
/obj/item/storage/fancy/egg_box/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 12
|
||||
STR.set_holdable(list(/obj/item/food/egg))
|
||||
atom_storage.set_holdable(list(/obj/item/food/egg))
|
||||
|
||||
/*
|
||||
* Candle Box
|
||||
@@ -154,14 +158,10 @@
|
||||
throwforce = 2
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
spawn_type = /obj/item/candle
|
||||
spawn_count = 5
|
||||
is_open = TRUE
|
||||
contents_tag = "candle"
|
||||
|
||||
/obj/item/storage/fancy/candle_box/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 5
|
||||
|
||||
/obj/item/storage/fancy/candle_box/attack_self(mob/user)
|
||||
if(!contents.len)
|
||||
new fold_result(user.drop_location())
|
||||
@@ -184,6 +184,7 @@
|
||||
throwforce = 0
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
spawn_type = /obj/item/clothing/mask/cigarette/space_cigarette
|
||||
spawn_count = 6
|
||||
custom_price = PAYCHECK_CREW
|
||||
age_restricted = TRUE
|
||||
contents_tag = "cigarette"
|
||||
@@ -208,15 +209,13 @@
|
||||
spawn_coupon = FALSE
|
||||
name = "discarded cigarette packet"
|
||||
desc = "An old cigarette packet with the back torn off, worth less than nothing now."
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 0
|
||||
atom_storage.max_slots = 0
|
||||
return
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/ComponentInitialize()
|
||||
/obj/item/storage/fancy/cigarettes/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.set_holdable(list(/obj/item/clothing/mask/cigarette, /obj/item/lighter))
|
||||
atom_storage.quickdraw = TRUE
|
||||
atom_storage.set_holdable(list(/obj/item/clothing/mask/cigarette, /obj/item/lighter))
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -225,18 +224,6 @@
|
||||
if(spawn_coupon)
|
||||
. += span_notice("There's a coupon on the back of the pack! You can tear it off once it's empty.")
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/AltClick(mob/user)
|
||||
if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERITY, FALSE, TRUE))
|
||||
return
|
||||
var/obj/item/clothing/mask/cigarette/W = locate(/obj/item/clothing/mask/cigarette) in contents
|
||||
if(W && contents.len > 0)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, W, user)
|
||||
user.put_in_hands(W)
|
||||
contents -= W
|
||||
to_chat(user, span_notice("You take \a [W] out of the pack."))
|
||||
else
|
||||
to_chat(user, span_notice("There are no [contents_tag]s left in the pack."))
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/update_icon_state()
|
||||
. = ..()
|
||||
icon_state = "[base_icon_state][contents.len ? null : "_empty"]"
|
||||
@@ -267,24 +254,6 @@
|
||||
. += "[use_icon_state]_[cig_position]"
|
||||
cig_position++
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/target, mob/living/carbon/user)
|
||||
if(!istype(target))
|
||||
return
|
||||
|
||||
var/obj/item/clothing/mask/cigarette/cig = locate() in contents
|
||||
if(!cig)
|
||||
to_chat(user, span_notice("There are no [contents_tag]s left in the pack."))
|
||||
return
|
||||
if(target != user || !contents.len || user.wear_mask)
|
||||
return ..()
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, cig, target)
|
||||
target.equip_to_slot_if_possible(cig, ITEM_SLOT_MASK)
|
||||
contents -= cig
|
||||
to_chat(user, span_notice("You take \a [cig] out of the pack."))
|
||||
return
|
||||
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/dromedaryco
|
||||
name = "\improper DromedaryCo packet"
|
||||
desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\""
|
||||
@@ -388,11 +357,10 @@
|
||||
spawn_type = /obj/item/rollingpaper
|
||||
custom_price = PAYCHECK_LOWER
|
||||
|
||||
/obj/item/storage/fancy/rollingpapers/ComponentInitialize()
|
||||
/obj/item/storage/fancy/rollingpapers/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 10
|
||||
STR.set_holdable(list(/obj/item/rollingpaper))
|
||||
atom_storage.max_slots = 10
|
||||
atom_storage.set_holdable(list(/obj/item/rollingpaper))
|
||||
|
||||
///Overrides to do nothing because fancy boxes are fucking insane.
|
||||
/obj/item/storage/fancy/rollingpapers/update_icon_state()
|
||||
@@ -417,14 +385,13 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
contents_tag = "premium cigar"
|
||||
spawn_type = /obj/item/clothing/mask/cigarette/cigar
|
||||
spawn_count = 5
|
||||
spawn_coupon = FALSE
|
||||
display_cigs = FALSE
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigars/ComponentInitialize()
|
||||
/obj/item/storage/fancy/cigarettes/cigars/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 5
|
||||
STR.set_holdable(list(/obj/item/clothing/mask/cigarette/cigar))
|
||||
atom_storage.set_holdable(list(/obj/item/clothing/mask/cigarette/cigar))
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigars/update_icon_state()
|
||||
. = ..()
|
||||
@@ -469,12 +436,11 @@
|
||||
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
|
||||
contents_tag = "chocolate"
|
||||
spawn_type = /obj/item/food/tinychocolate
|
||||
spawn_count = 8
|
||||
|
||||
/obj/item/storage/fancy/heart_box/ComponentInitialize()
|
||||
/obj/item/storage/fancy/heart_box/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 8
|
||||
STR.set_holdable(list(/obj/item/food/tinychocolate))
|
||||
atom_storage.set_holdable(list(/obj/item/food/tinychocolate))
|
||||
|
||||
|
||||
/obj/item/storage/fancy/nugget_box
|
||||
@@ -485,9 +451,8 @@
|
||||
base_icon_state = "nuggetbox"
|
||||
contents_tag = "nugget"
|
||||
spawn_type = /obj/item/food/nugget
|
||||
spawn_count = 6
|
||||
|
||||
/obj/item/storage/fancy/nugget_box/ComponentInitialize()
|
||||
/obj/item/storage/fancy/nugget_box/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 6
|
||||
STR.set_holdable(list(/obj/item/food/nugget))
|
||||
atom_storage.set_holdable(list(/obj/item/food/nugget))
|
||||
|
||||
@@ -30,15 +30,14 @@
|
||||
name = "chief engineer's garment bag"
|
||||
desc = "A bag for storing extra clothes and shoes. This one belongs to the chief engineer."
|
||||
|
||||
/obj/item/storage/bag/garment/ComponentInitialize()
|
||||
/obj/item/storage/bag/garment/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.display_numerical_stacking = FALSE
|
||||
STR.max_combined_w_class = 200
|
||||
STR.max_items = 15
|
||||
STR.insert_preposition = "in"
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.numerical_stacking = FALSE
|
||||
atom_storage.max_total_storage = 200
|
||||
atom_storage.max_slots = 15
|
||||
atom_storage.insert_preposition = "in"
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/clothing,
|
||||
))
|
||||
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
. = ..()
|
||||
REMOVE_TRAIT(user, TRAIT_GUNFLIP, CLOTHING_TRAIT)
|
||||
|
||||
/obj/item/storage/belt/holster/ComponentInitialize()
|
||||
/obj/item/storage/belt/holster/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 1
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 1
|
||||
atom_storage.max_total_storage = 16
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/gun/ballistic/automatic/pistol,
|
||||
/obj/item/gun/ballistic/revolver,
|
||||
/obj/item/gun/energy/e_gun/mini,
|
||||
@@ -36,12 +35,11 @@
|
||||
name = "thermal shoulder holsters"
|
||||
desc = "A rather plain pair of shoulder holsters with a bit of insulated padding inside. Meant to hold a twinned pair of thermal pistols, but can fit several kinds of energy handguns as well."
|
||||
|
||||
/obj/item/storage/belt/holster/thermal/ComponentInitialize()
|
||||
/obj/item/storage/belt/holster/thermal/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 2
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 2
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/gun/energy/e_gun/mini,
|
||||
/obj/item/gun/energy/disabler,
|
||||
/obj/item/gun/energy/dueling,
|
||||
@@ -60,12 +58,11 @@
|
||||
desc = "A holster able to carry handguns and some ammo. WARNING: Badasses only."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/storage/belt/holster/detective/ComponentInitialize()
|
||||
/obj/item/storage/belt/holster/detective/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 3
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 3
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/gun/ballistic/automatic/pistol,
|
||||
/obj/item/ammo_box/magazine/m9mm, // Pistol magazines.
|
||||
/obj/item/ammo_box/magazine/m9mm_aps,
|
||||
@@ -119,10 +116,9 @@
|
||||
chameleon_action.initialize_disguises()
|
||||
add_item_action(chameleon_action)
|
||||
|
||||
/obj/item/storage/belt/holster/chameleon/ComponentInitialize()
|
||||
/obj/item/storage/belt/holster/chameleon/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.silent = TRUE
|
||||
atom_storage.silent = TRUE
|
||||
|
||||
/obj/item/storage/belt/holster/chameleon/emp_act(severity)
|
||||
. = ..()
|
||||
@@ -134,12 +130,11 @@
|
||||
. = ..()
|
||||
chameleon_action.emp_randomise(INFINITY)
|
||||
|
||||
/obj/item/storage/belt/holster/chameleon/ComponentInitialize()
|
||||
/obj/item/storage/belt/holster/chameleon/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 2
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 2
|
||||
atom_storage.max_total_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/gun/ballistic/automatic/pistol,
|
||||
/obj/item/ammo_box/magazine/m9mm,
|
||||
/obj/item/ammo_box/magazine/m9mm_aps,
|
||||
@@ -164,12 +159,11 @@
|
||||
worn_icon_state = "syndicate_holster"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/storage/belt/holster/nukie/ComponentInitialize()
|
||||
/obj/item/storage/belt/holster/nukie/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 2
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 2
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/gun, // ALL guns.
|
||||
/obj/item/ammo_box/magazine, // ALL magazines.
|
||||
/obj/item/ammo_box/c38, //There isn't a speedloader parent type, so I just put these three here by hand.
|
||||
|
||||
@@ -13,27 +13,26 @@
|
||||
var/icon_closed = "lockbox"
|
||||
var/icon_broken = "lockbox+b"
|
||||
|
||||
/obj/item/storage/lockbox/ComponentInitialize()
|
||||
/obj/item/storage/lockbox/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 14
|
||||
STR.max_items = 4
|
||||
STR.locked = TRUE
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 14
|
||||
atom_storage.max_slots = 4
|
||||
atom_storage.locked = TRUE
|
||||
|
||||
/obj/item/storage/lockbox/attackby(obj/item/W, mob/user, params)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
var/locked = atom_storage.locked
|
||||
if(W.GetID())
|
||||
if(broken)
|
||||
to_chat(user, span_danger("It appears to be broken."))
|
||||
return
|
||||
if(allowed(user))
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !locked)
|
||||
locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
atom_storage.locked = !locked
|
||||
locked = atom_storage.locked
|
||||
if(locked)
|
||||
icon_state = icon_locked
|
||||
to_chat(user, span_danger("You lock the [src.name]!"))
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_ALL)
|
||||
atom_storage.close_all()
|
||||
return
|
||||
else
|
||||
icon_state = icon_closed
|
||||
@@ -50,7 +49,7 @@
|
||||
/obj/item/storage/lockbox/emag_act(mob/user)
|
||||
if(!broken)
|
||||
broken = TRUE
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, FALSE)
|
||||
atom_storage.locked = FALSE
|
||||
desc += "It appears to be broken."
|
||||
icon_state = src.icon_broken
|
||||
if(user)
|
||||
@@ -97,22 +96,21 @@
|
||||
icon_closed = "medalbox"
|
||||
icon_broken = "medalbox+b"
|
||||
|
||||
/obj/item/storage/lockbox/medal/ComponentInitialize()
|
||||
/obj/item/storage/lockbox/medal/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
STR.max_items = 10
|
||||
STR.max_combined_w_class = 20
|
||||
STR.set_holdable(list(/obj/item/clothing/accessory/medal))
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
atom_storage.max_slots = 10
|
||||
atom_storage.max_total_storage = 20
|
||||
atom_storage.set_holdable(list(/obj/item/clothing/accessory/medal))
|
||||
|
||||
/obj/item/storage/lockbox/medal/examine(mob/user)
|
||||
. = ..()
|
||||
if(!SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED))
|
||||
if(!atom_storage.locked)
|
||||
. += span_notice("Alt-click to [open ? "close":"open"] it.")
|
||||
|
||||
/obj/item/storage/lockbox/medal/AltClick(mob/user)
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
if(!SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED))
|
||||
if(!atom_storage.locked)
|
||||
open = (open ? FALSE : TRUE)
|
||||
update_appearance()
|
||||
..()
|
||||
@@ -129,8 +127,7 @@
|
||||
new /obj/item/clothing/accessory/medal/conduct(src)
|
||||
|
||||
/obj/item/storage/lockbox/medal/update_icon_state()
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if(locked)
|
||||
if(atom_storage?.locked)
|
||||
icon_state = "medalbox+l"
|
||||
return ..()
|
||||
|
||||
@@ -145,8 +142,7 @@
|
||||
. = ..()
|
||||
if(!contents || !open)
|
||||
return
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if(locked)
|
||||
if(atom_storage?.locked)
|
||||
return
|
||||
for(var/i in 1 to contents.len)
|
||||
var/obj/item/clothing/accessory/medal/M = contents[i]
|
||||
@@ -240,8 +236,8 @@
|
||||
to_chat(user, span_warning("Bank account does not match with buyer!"))
|
||||
return
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !privacy_lock)
|
||||
privacy_lock = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
atom_storage.locked = !privacy_lock
|
||||
privacy_lock = atom_storage.locked
|
||||
user.visible_message(span_notice("[user] [privacy_lock ? "" : "un"]locks [src]'s privacy lock."),
|
||||
span_notice("You [privacy_lock ? "" : "un"]lock [src]'s privacy lock."))
|
||||
|
||||
|
||||
@@ -60,13 +60,12 @@
|
||||
inhand_icon_state = "medkit"
|
||||
desc = "A high capacity aid kit for doctors, full of medical supplies and basic surgical equipment"
|
||||
|
||||
/obj/item/storage/medkit/surgery/ComponentInitialize()
|
||||
/obj/item/storage/medkit/surgery/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL //holds the same equipment as a medibelt
|
||||
STR.max_items = 12
|
||||
STR.max_combined_w_class = 24
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL //holds the same equipment as a medibelt
|
||||
atom_storage.max_slots = 12
|
||||
atom_storage.max_total_storage = 24
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/healthanalyzer,
|
||||
/obj/item/dnainjector,
|
||||
/obj/item/reagent_containers/dropper,
|
||||
@@ -259,10 +258,9 @@
|
||||
icon_state = "medkit_tactical"
|
||||
damagetype_healed = "all"
|
||||
|
||||
/obj/item/storage/medkit/tactical/ComponentInitialize()
|
||||
/obj/item/storage/medkit/tactical/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/storage/medkit/tactical/PopulateContents()
|
||||
if(empty)
|
||||
@@ -318,12 +316,10 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/storage/pill_bottle/ComponentInitialize()
|
||||
/obj/item/storage/pill_bottle/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.allow_quick_gather = TRUE
|
||||
STR.click_gather = TRUE
|
||||
STR.set_holdable(list(/obj/item/reagent_containers/pill))
|
||||
atom_storage.allow_quick_gather = TRUE
|
||||
atom_storage.set_holdable(list(/obj/item/reagent_containers/pill))
|
||||
|
||||
/obj/item/storage/pill_bottle/suicide_act(mob/user)
|
||||
user.visible_message(span_suicide("[user] is trying to get the cap off [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
@@ -528,12 +524,11 @@
|
||||
/// var to prevent it freezing the same things over and over
|
||||
var/cooling = FALSE
|
||||
|
||||
/obj/item/storage/organbox/ComponentInitialize()
|
||||
/obj/item/storage/organbox/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY /// you have to remove it from your bag before opening it but I think that's fine
|
||||
STR.max_combined_w_class = 21
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY /// you have to remove it from your bag before opening it but I think that's fine
|
||||
atom_storage.max_total_storage = 21
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/organ,
|
||||
/obj/item/bodypart,
|
||||
/obj/item/food/icecream
|
||||
@@ -543,7 +538,7 @@
|
||||
. = ..()
|
||||
create_reagents(100, TRANSPARENT)
|
||||
RegisterSignal(src, COMSIG_ATOM_ENTERED, .proc/freeze)
|
||||
RegisterSignal(src, COMSIG_TRY_STORAGE_TAKE, .proc/unfreeze)
|
||||
RegisterSignal(src, COMSIG_ATOM_EXITED, .proc/unfreeze)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/storage/organbox/process(delta_time)
|
||||
|
||||
@@ -33,11 +33,10 @@
|
||||
var/can_hack_open = TRUE
|
||||
|
||||
|
||||
/obj/item/storage/secure/ComponentInitialize()
|
||||
/obj/item/storage/secure/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
STR.max_combined_w_class = 14
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
atom_storage.max_total_storage = 14
|
||||
|
||||
/obj/item/storage/secure/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -45,7 +44,7 @@
|
||||
. += "The service panel is currently <b>[panel_open ? "unscrewed" : "screwed shut"]</b>."
|
||||
|
||||
/obj/item/storage/secure/tool_act(mob/living/user, obj/item/tool)
|
||||
if(can_hack_open && SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED))
|
||||
if(can_hack_open && atom_storage.locked)
|
||||
return ..()
|
||||
else
|
||||
return FALSE
|
||||
@@ -78,7 +77,7 @@
|
||||
to_chat(user, span_warning("You must <b>unscrew</b> the service panel before you can pulse the wiring!"))
|
||||
|
||||
/obj/item/storage/secure/attack_self(mob/user)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
var/locked = atom_storage.locked
|
||||
user.set_machine(src)
|
||||
var/dat = text("<TT><B>[]</B><BR>\n\nLock Status: []",src, (locked ? "LOCKED" : "UNLOCKED"))
|
||||
var/message = "Code"
|
||||
@@ -100,7 +99,7 @@
|
||||
lock_code = entered_code
|
||||
lock_set = TRUE
|
||||
else if ((entered_code == lock_code) && lock_set)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, FALSE)
|
||||
atom_storage.locked = TRUE
|
||||
cut_overlays()
|
||||
add_overlay(icon_opened)
|
||||
entered_code = null
|
||||
@@ -108,10 +107,10 @@
|
||||
entered_code = "ERROR"
|
||||
else
|
||||
if (href_list["type"] == "R")
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, TRUE)
|
||||
atom_storage.locked = FALSE
|
||||
cut_overlays()
|
||||
entered_code = null
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_FROM, usr)
|
||||
atom_storage.hide_contents(usr)
|
||||
else
|
||||
entered_code += text("[]", sanitize_text(href_list["type"]))
|
||||
if (length(entered_code) > 5)
|
||||
@@ -144,11 +143,10 @@
|
||||
new /obj/item/paper(src)
|
||||
new /obj/item/pen(src)
|
||||
|
||||
/obj/item/storage/secure/briefcase/ComponentInitialize()
|
||||
/obj/item/storage/secure/briefcase/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 21
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 21
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
|
||||
///Syndie variant of Secure Briefcase. Contains space cash, slightly more robust.
|
||||
/obj/item/storage/secure/briefcase/syndie
|
||||
@@ -174,11 +172,10 @@
|
||||
|
||||
MAPPING_DIRECTIONAL_HELPERS(/obj/item/storage/secure/safe, 32)
|
||||
|
||||
/obj/item/storage/secure/safe/ComponentInitialize()
|
||||
/obj/item/storage/secure/safe/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.set_holdable(null, list(/obj/item/storage/secure/briefcase))
|
||||
STR.max_w_class = 8 //??
|
||||
atom_storage.set_holdable(cant_hold_list = list(/obj/item/storage/secure/briefcase))
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_GIGANTIC
|
||||
|
||||
/obj/item/storage/secure/safe/PopulateContents()
|
||||
new /obj/item/paper(src)
|
||||
@@ -219,7 +216,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/storage/secure/safe/caps_spare, 32)
|
||||
|
||||
lock_code = SSid_access.spare_id_safe_code
|
||||
lock_set = TRUE
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, TRUE)
|
||||
atom_storage.locked = TRUE
|
||||
|
||||
/obj/item/storage/secure/safe/caps_spare/PopulateContents()
|
||||
new /obj/item/card/id/advanced/gold/captains_spare(src)
|
||||
|
||||
@@ -21,13 +21,12 @@
|
||||
. = ..()
|
||||
update_appearance()
|
||||
|
||||
/obj/item/storage/cans/ComponentInitialize()
|
||||
/obj/item/storage/cans/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
STR.max_combined_w_class = 12
|
||||
STR.max_items = 6
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
atom_storage.max_total_storage = 12
|
||||
atom_storage.max_slots = 6
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/beer,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/ale,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/rummage_if_nodrop = TRUE
|
||||
var/component_type = /datum/component/storage/concrete
|
||||
/// Should we preload the contents of this type?
|
||||
/// BE CAREFUL, THERE'S SOME REALLY NASTY SHIT IN THIS TYPEPATH
|
||||
/// SANTA IS EVIL
|
||||
@@ -11,13 +10,14 @@
|
||||
|
||||
/obj/item/storage/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage()
|
||||
|
||||
PopulateContents()
|
||||
|
||||
for (var/obj/item/item in src)
|
||||
item.item_flags |= IN_STORAGE
|
||||
|
||||
/obj/item/storage/ComponentInitialize()
|
||||
AddComponent(component_type)
|
||||
|
||||
/obj/item/storage/AllowDrop()
|
||||
return FALSE
|
||||
|
||||
@@ -37,8 +37,7 @@
|
||||
|
||||
/obj/item/storage/doStrip(mob/who)
|
||||
if(HAS_TRAIT(src, TRAIT_NODROP) && rummage_if_nodrop)
|
||||
var/datum/component/storage/CP = GetComponent(/datum/component/storage)
|
||||
CP.do_quick_empty()
|
||||
atom_storage.remove_all()
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
@@ -48,8 +47,7 @@
|
||||
/obj/item/storage/proc/PopulateContents()
|
||||
|
||||
/obj/item/storage/proc/emptyStorage()
|
||||
var/datum/component/storage/ST = GetComponent(/datum/component/storage)
|
||||
ST.do_quick_empty()
|
||||
atom_storage.remove_all()
|
||||
|
||||
/obj/item/storage/Destroy()
|
||||
for(var/obj/important_thing in contents)
|
||||
|
||||
@@ -38,10 +38,9 @@
|
||||
if(has_latches)
|
||||
. += latches
|
||||
|
||||
/obj/item/storage/toolbox/ComponentInitialize()
|
||||
/obj/item/storage/toolbox/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/storage/toolbox/suicide_act(mob/user)
|
||||
user.visible_message(span_suicide("[user] robusts [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
@@ -102,10 +101,9 @@
|
||||
force = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/storage/toolbox/mechanical/old/heirloom/ComponentInitialize()
|
||||
/obj/item/storage/toolbox/mechanical/old/heirloom/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_SMALL
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/storage/toolbox/mechanical/old/heirloom/PopulateContents()
|
||||
return
|
||||
@@ -170,10 +168,9 @@
|
||||
throwforce = 18
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/syndicate/ComponentInitialize()
|
||||
/obj/item/storage/toolbox/syndicate/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.silent = TRUE
|
||||
atom_storage.silent = TRUE
|
||||
|
||||
/obj/item/storage/toolbox/syndicate/PopulateContents()
|
||||
new /obj/item/screwdriver/nuke(src)
|
||||
@@ -208,11 +205,10 @@
|
||||
w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox!
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/artistic/ComponentInitialize()
|
||||
/obj/item/storage/toolbox/artistic/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 20
|
||||
STR.max_items = 10
|
||||
atom_storage.max_total_storage = 20
|
||||
atom_storage.max_slots = 10
|
||||
|
||||
/obj/item/storage/toolbox/artistic/PopulateContents()
|
||||
new /obj/item/storage/crayons(src)
|
||||
@@ -275,13 +271,12 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
has_latches = FALSE
|
||||
|
||||
/obj/item/storage/toolbox/infiltrator/ComponentInitialize()
|
||||
/obj/item/storage/toolbox/infiltrator/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 10
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = 24
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 10
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.max_total_storage = 24
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/clothing/head/helmet/infiltrator,
|
||||
/obj/item/clothing/suit/armor/vest/infiltrator,
|
||||
/obj/item/clothing/under/syndicate/bloodred,
|
||||
|
||||
@@ -385,11 +385,10 @@
|
||||
/obj/item/storage/box/syndie_kit/space
|
||||
name = "boxed space suit and helmet"
|
||||
|
||||
/obj/item/storage/box/syndie_kit/space/ComponentInitialize()
|
||||
/obj/item/storage/box/syndie_kit/space/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.set_holdable(list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate))
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL
|
||||
atom_storage.set_holdable(list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate))
|
||||
|
||||
/obj/item/storage/box/syndie_kit/space/PopulateContents()
|
||||
if(prob(50))
|
||||
@@ -411,10 +410,9 @@
|
||||
/obj/item/storage/box/syndie_kit/chemical
|
||||
name = "chemical kit"
|
||||
|
||||
/obj/item/storage/box/syndie_kit/chemical/ComponentInitialize()
|
||||
/obj/item/storage/box/syndie_kit/chemical/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 14
|
||||
atom_storage.max_slots = 14
|
||||
|
||||
/obj/item/storage/box/syndie_kit/chemical/PopulateContents()
|
||||
new /obj/item/reagent_containers/glass/bottle/polonium(src)
|
||||
|
||||
@@ -5,17 +5,15 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
resistance_flags = FLAMMABLE
|
||||
slot_flags = ITEM_SLOT_ID
|
||||
component_type = /datum/component/storage/concrete/wallet
|
||||
|
||||
var/obj/item/card/id/front_id = null
|
||||
var/list/combined_access
|
||||
var/cached_flat_icon
|
||||
|
||||
/obj/item/storage/wallet/ComponentInitialize()
|
||||
/obj/item/storage/wallet/Initialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage/concrete/wallet)
|
||||
STR.max_items = 4
|
||||
STR.set_holdable(list(
|
||||
atom_storage.max_slots = 4
|
||||
atom_storage.set_holdable(list(
|
||||
/obj/item/stack/spacecash,
|
||||
/obj/item/holochip,
|
||||
/obj/item/card,
|
||||
|
||||
@@ -184,7 +184,7 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices)
|
||||
|
||||
/obj/item/tcgcard_deck/Initialize(mapload)
|
||||
. = ..()
|
||||
LoadComponent(/datum/component/storage/concrete/tcg)
|
||||
create_storage(type = /datum/storage/tcg)
|
||||
|
||||
/obj/item/tcgcard_deck/update_icon_state()
|
||||
if(!flipped)
|
||||
@@ -284,7 +284,7 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices)
|
||||
return
|
||||
contents = shuffle(contents)
|
||||
if(user.active_storage)
|
||||
user.active_storage.close(user)
|
||||
user.active_storage.hide_contents(user)
|
||||
if(visable)
|
||||
user.visible_message(span_notice("[user] shuffles \the [src]!"), \
|
||||
span_notice("You shuffle \the [src]!"))
|
||||
@@ -396,10 +396,9 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices)
|
||||
|
||||
/obj/item/storage/card_binder/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.set_holdable(list(/obj/item/tcgcard))
|
||||
STR.max_combined_w_class = 120
|
||||
STR.max_items = 60
|
||||
atom_storage.set_holdable(list(/obj/item/tcgcard))
|
||||
atom_storage.max_total_storage = 120
|
||||
atom_storage.max_slots = 60
|
||||
|
||||
///Returns a list of cards ids of card_cnt weighted by rarity from the pack's tables that have matching series, with gnt_cnt of the guarenteed table.
|
||||
/obj/item/cardpack/proc/buildCardListWithRarity(card_cnt, rarity_cnt)
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
break
|
||||
for(var/i in reverse_range(location.get_all_contents()))
|
||||
var/atom/movable/thing = i
|
||||
SEND_SIGNAL(thing, COMSIG_TRY_STORAGE_HIDE_ALL)
|
||||
thing.atom_storage?.close_all()
|
||||
|
||||
/obj/structure/closet/proc/open(mob/living/user, force = FALSE)
|
||||
if(!can_open(user, force))
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
var/obj/item/storage/bag/trash/T = W
|
||||
to_chat(user, span_notice("You fill the bag."))
|
||||
for(var/obj/item/O in src)
|
||||
SEND_SIGNAL(T, COMSIG_TRY_STORAGE_INSERT, O, user, TRUE)
|
||||
T.atom_storage?.attempt_insert(T, O, user, TRUE)
|
||||
T.update_appearance()
|
||||
do_animate()
|
||||
return TRUE
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
for(var/x in T.contents)
|
||||
var/obj/item/item = x
|
||||
AfterPutItemOnTable(item, user)
|
||||
SEND_SIGNAL(I, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location())
|
||||
I.atom_storage.remove_all(drop_location())
|
||||
user.visible_message(span_notice("[user] empties [I] on [src]."))
|
||||
return
|
||||
// If the tray IS empty, continue on (tray will be placed on the table like other items)
|
||||
|
||||
+10
-9
@@ -452,20 +452,21 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
/turf/proc/Bless()
|
||||
new /obj/effect/blessing(src)
|
||||
|
||||
/turf/storage_contents_dump_act(datum/component/storage/src_object, mob/user)
|
||||
/turf/storage_contents_dump_act(atom/src_object, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(length(src_object.contents()))
|
||||
to_chat(usr, span_notice("You start dumping out the contents..."))
|
||||
if(!do_after(usr,20,target=src_object.parent))
|
||||
if(!src_object.atom_storage)
|
||||
return
|
||||
var/atom/resolve_parent = src_object.atom_storage.real_location?.resolve()
|
||||
if(!resolve_parent)
|
||||
return FALSE
|
||||
if(length(resolve_parent.contents))
|
||||
to_chat(user, span_notice("You start dumping out the contents of [src_object]..."))
|
||||
if(!do_after(user, 20, target=resolve_parent))
|
||||
return FALSE
|
||||
|
||||
var/list/things = src_object.contents()
|
||||
var/datum/progressbar/progress = new(user, things.len, src)
|
||||
while (do_after(usr, 1 SECONDS, src, NONE, FALSE, CALLBACK(src_object, /datum/component/storage.proc/mass_remove_from_storage, src, things, progress)))
|
||||
stoplag(1)
|
||||
progress.end_progress()
|
||||
src_object.atom_storage.remove_all(src)
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -20,7 +20,11 @@
|
||||
armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 90, FIRE = 70, ACID = 50)
|
||||
strip_delay = 70
|
||||
resistance_flags = NONE
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/combat/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
/// Recharging rate in PPS (peels per second)
|
||||
#define BANANA_SHOES_RECHARGE_RATE 17
|
||||
@@ -34,11 +38,13 @@
|
||||
armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 50, FIRE = 90, ACID = 50)
|
||||
strip_delay = 70
|
||||
resistance_flags = NONE
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
always_noslip = TRUE
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
|
||||
bananium.insert_amount_mat(BANANA_SHOES_MAX_CHARGE, /datum/material/bananium)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
else
|
||||
to_chat(mob, span_danger("You have a [item_name] in your [where]."))
|
||||
if(where == "backpack")
|
||||
SEND_SIGNAL(mob.back, COMSIG_TRY_STORAGE_SHOW, mob)
|
||||
mob.back.atom_storage?.show_contents(mob)
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/cult/apply_innate_effects(mob/living/mob_override)
|
||||
|
||||
@@ -60,8 +60,12 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
// slightly worse than normal cult robes
|
||||
armor = list(MELEE = 30, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 15, BIO = 0, FIRE = 0, ACID = 0)
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/void_cloak
|
||||
alternative_mode = TRUE
|
||||
|
||||
/obj/item/clothing/suit/hooded/cultrobes/void/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/void_cloak)
|
||||
|
||||
/obj/item/clothing/suit/hooded/cultrobes/void/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -602,12 +602,14 @@
|
||||
desc = "A pair of black shoes."
|
||||
resistance_flags = NONE
|
||||
armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 90, FIRE = 50, ACID = 50)
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
|
||||
var/datum/action/item_action/chameleon/change/chameleon_action
|
||||
|
||||
/obj/item/clothing/shoes/chameleon/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
chameleon_action = new(src)
|
||||
chameleon_action.chameleon_type = /obj/item/clothing/shoes
|
||||
chameleon_action.chameleon_name = "Shoes"
|
||||
@@ -665,10 +667,7 @@
|
||||
chameleon_action.initialize_disguises()
|
||||
add_item_action(chameleon_action)
|
||||
|
||||
/obj/item/storage/belt/chameleon/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.silent = TRUE
|
||||
atom_storage.silent = TRUE
|
||||
|
||||
/obj/item/storage/belt/chameleon/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
@@ -287,20 +287,19 @@
|
||||
if(30 to 59)
|
||||
. += span_danger("The [zone_name] is partially shredded.")
|
||||
|
||||
var/datum/component/storage/pockets = GetComponent(/datum/component/storage)
|
||||
if(pockets)
|
||||
if(atom_storage)
|
||||
var/list/how_cool_are_your_threads = list("<span class='notice'>")
|
||||
if(pockets.attack_hand_interact)
|
||||
if(atom_storage.attack_hand_interact)
|
||||
how_cool_are_your_threads += "[src]'s storage opens when clicked.\n"
|
||||
else
|
||||
how_cool_are_your_threads += "[src]'s storage opens when dragged to yourself.\n"
|
||||
if (pockets.can_hold?.len) // If pocket type can hold anything, vs only specific items
|
||||
how_cool_are_your_threads += "[src] can store [pockets.max_items] <a href='?src=[REF(src)];show_valid_pocket_items=1'>item\s</a>.\n"
|
||||
if (atom_storage.can_hold?.len) // If pocket type can hold anything, vs only specific items
|
||||
how_cool_are_your_threads += "[src] can store [atom_storage.max_slots] <a href='?src=[REF(src)];show_valid_pocket_items=1'>item\s</a>.\n"
|
||||
else
|
||||
how_cool_are_your_threads += "[src] can store [pockets.max_items] item\s that are [weight_class_to_text(pockets.max_w_class)] or smaller.\n"
|
||||
if(pockets.quickdraw)
|
||||
how_cool_are_your_threads += "[src] can store [atom_storage.max_slots] item\s that are [weight_class_to_text(atom_storage.max_specific_storage)] or smaller.\n"
|
||||
if(atom_storage.quickdraw)
|
||||
how_cool_are_your_threads += "You can quickly remove an item from [src] using Right-Click.\n"
|
||||
if(pockets.silent)
|
||||
if(atom_storage.silent)
|
||||
how_cool_are_your_threads += "Adding or removing items from [src] makes no noise.\n"
|
||||
how_cool_are_your_threads += "</span>"
|
||||
. += how_cool_are_your_threads.Join()
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
icon_state = "fedora"
|
||||
inhand_icon_state = "fedora"
|
||||
desc = "A really cool hat if you're a mobster. A really lame hat if you're not."
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/fedora
|
||||
|
||||
/obj/item/clothing/head/fedora/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/small/fedora)
|
||||
|
||||
/obj/item/clothing/head/fedora/white
|
||||
name = "white fedora"
|
||||
|
||||
@@ -340,7 +340,11 @@
|
||||
icon_state = "rus_helmet"
|
||||
inhand_icon_state = "rus_helmet"
|
||||
armor = list(MELEE = 25, BULLET = 30, LASER = 0, ENERGY = 10, BOMB = 10, BIO = 0, FIRE = 20, ACID = 50, WOUND = 5)
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/helmet
|
||||
|
||||
/obj/item/clothing/head/helmet/rus_helmet/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/helmet)
|
||||
|
||||
/obj/item/clothing/head/helmet/rus_ushanka
|
||||
name = "battle ushanka"
|
||||
|
||||
@@ -13,11 +13,15 @@
|
||||
strip_delay = 10
|
||||
equip_delay_other = 10
|
||||
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/chefhat
|
||||
dog_fashion = /datum/dog_fashion/head/chef
|
||||
///the chance that the movements of a mouse inside of this hat get relayed to the human wearing the hat
|
||||
var/mouse_control_probability = 20
|
||||
|
||||
/obj/item/clothing/head/chefhat/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/chefhat)
|
||||
|
||||
/obj/item/clothing/head/chefhat/i_am_assuming_direct_control
|
||||
desc = "The commander in chef's head wear. Upon closer inspection, there seem to be dozens of tiny levers, buttons, dials, and screens inside of this hat. What the hell...?"
|
||||
mouse_control_probability = 100
|
||||
@@ -94,11 +98,13 @@
|
||||
armor = list(MELEE = 25, BULLET = 5, LASER = 25, ENERGY = 35, BOMB = 0, BIO = 0, FIRE = 30, ACID = 50, WOUND = 5)
|
||||
icon_state = "detective"
|
||||
var/candy_cooldown = 0
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/fedora/detective
|
||||
dog_fashion = /datum/dog_fashion/head/detective
|
||||
|
||||
/obj/item/clothing/head/fedora/det_hat/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/small/fedora/detective)
|
||||
|
||||
new /obj/item/reagent_containers/food/drinks/flask/det(src)
|
||||
|
||||
/obj/item/clothing/head/fedora/det_hat/examine(mob/user)
|
||||
|
||||
@@ -17,10 +17,18 @@
|
||||
name = "white taqiyah"
|
||||
desc = "An extra-mustahabb way of showing your devotion to Allah."
|
||||
icon_state = "taqiyahwhite"
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small
|
||||
|
||||
/obj/item/clothing/head/taqiyahwhite/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/small)
|
||||
|
||||
/obj/item/clothing/head/taqiyahred
|
||||
name = "red taqiyah"
|
||||
desc = "An extra-mustahabb way of showing your devotion to Allah."
|
||||
icon_state = "taqiyahred"
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/small
|
||||
|
||||
/obj/item/clothing/head/taqiyahred/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/small)
|
||||
|
||||
@@ -252,11 +252,11 @@
|
||||
for(var/obj/item/briefcase_item in sec_briefcase)
|
||||
qdel(briefcase_item)
|
||||
for(var/i = 3 to 0 step -1)
|
||||
SEND_SIGNAL(sec_briefcase, COMSIG_TRY_STORAGE_INSERT, new /obj/item/stack/spacecash/c1000, null, TRUE, TRUE)
|
||||
SEND_SIGNAL(sec_briefcase, COMSIG_TRY_STORAGE_INSERT, new /obj/item/gun/energy/recharge/ebow, null, TRUE, TRUE)
|
||||
SEND_SIGNAL(sec_briefcase, COMSIG_TRY_STORAGE_INSERT, new /obj/item/gun/ballistic/revolver/mateba, null, TRUE, TRUE)
|
||||
SEND_SIGNAL(sec_briefcase, COMSIG_TRY_STORAGE_INSERT, new /obj/item/ammo_box/a357, null, TRUE, TRUE)
|
||||
SEND_SIGNAL(sec_briefcase, COMSIG_TRY_STORAGE_INSERT, new /obj/item/grenade/c4/x4, null, TRUE, TRUE)
|
||||
sec_briefcase.contents += new /obj/item/stack/spacecash/c1000
|
||||
sec_briefcase.contents += new /obj/item/gun/energy/recharge/ebow
|
||||
sec_briefcase.contents += new /obj/item/gun/ballistic/revolver/mateba
|
||||
sec_briefcase.contents += new /obj/item/ammo_box/a357
|
||||
sec_briefcase.contents += new /obj/item/grenade/c4/x4
|
||||
|
||||
var/obj/item/modular_computer/tablet/pda/heads/pda = H.belt
|
||||
pda.saved_identification = H.real_name
|
||||
|
||||
@@ -107,10 +107,10 @@
|
||||
O.vv_values = result
|
||||
//Copy backpack contents if exist.
|
||||
var/obj/item/backpack = get_item_by_slot(ITEM_SLOT_BACK)
|
||||
if(istype(backpack) && SEND_SIGNAL(backpack, COMSIG_CONTAINS_STORAGE))
|
||||
if(istype(backpack) && backpack.atom_storage)
|
||||
var/list/bp_stuff = list()
|
||||
var/list/typecounts = list()
|
||||
SEND_SIGNAL(backpack, COMSIG_TRY_STORAGE_RETURN_INVENTORY, bp_stuff, FALSE)
|
||||
backpack.atom_storage.return_inv(bp_stuff, FALSE)
|
||||
for(var/obj/item/I in bp_stuff)
|
||||
if(typecounts[I.type])
|
||||
typecounts[I.type] += 1
|
||||
|
||||
@@ -8,9 +8,13 @@
|
||||
armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 90, FIRE = 70, ACID = 50)
|
||||
strip_delay = 40
|
||||
resistance_flags = NONE
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
lace_time = 12 SECONDS
|
||||
|
||||
/obj/item/clothing/shoes/combat/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
/obj/item/clothing/shoes/combat/sneakboots
|
||||
name = "sneakboots"
|
||||
desc = "These boots have special noise cancelling soles. Perfect for stealth, if it wasn't for the color scheme."
|
||||
@@ -37,9 +41,13 @@
|
||||
equip_delay_other = 50
|
||||
resistance_flags = NONE
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 90, FIRE = 0, ACID = 0)
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
can_be_tied = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/jackboots/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
/obj/item/clothing/shoes/jackboots/fast
|
||||
slowdown = -1
|
||||
|
||||
@@ -53,9 +61,13 @@
|
||||
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
|
||||
heat_protection = FEET|LEGS
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
lace_time = 8 SECONDS
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/ice_boots
|
||||
name = "ice hiking boots"
|
||||
desc = "A pair of winter boots with special grips on the bottom, designed to prevent slipping on frozen surfaces."
|
||||
@@ -73,10 +85,14 @@
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 80, FIRE = 0, ACID = 0)
|
||||
strip_delay = 20
|
||||
equip_delay_other = 40
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
lace_time = 8 SECONDS
|
||||
species_exception = list(/datum/species/golem/uranium)
|
||||
|
||||
/obj/item/clothing/shoes/workboots/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
/obj/item/clothing/shoes/workboots/mining
|
||||
name = "mining boots"
|
||||
desc = "Steel-toed mining boots for mining in hazardous environments. Very good at keeping toes uncrushed."
|
||||
@@ -88,9 +104,13 @@
|
||||
desc = "Comfy shoes."
|
||||
icon_state = "rus_shoes"
|
||||
inhand_icon_state = "rus_shoes"
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
lace_time = 8 SECONDS
|
||||
|
||||
/obj/item/clothing/shoes/russian/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
/obj/item/clothing/shoes/discoshoes
|
||||
name = "green lizardskin shoes"
|
||||
desc = "They may have lost some of their lustre over the years, but these green lizardskin shoes fit you perfectly."
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
icon_state = "clown"
|
||||
inhand_icon_state = "clown_shoes"
|
||||
slowdown = SHOES_SLOWDOWN+1
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes/clown
|
||||
var/enabled_waddle = TRUE
|
||||
lace_time = 20 SECONDS // how the hell do these laces even work??
|
||||
species_exception = list(/datum/species/golem/bananium)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes/clown)
|
||||
LoadComponent(/datum/component/squeak, list('sound/effects/clownstep1.ogg'=1,'sound/effects/clownstep2.ogg'=1), 50, falloff_exponent = 20) //die off quick please
|
||||
AddElement(/datum/element/swabable, CELL_LINE_TABLE_CLOWN, CELL_VIRUS_TABLE_GENERIC, rand(2,3), 0)
|
||||
|
||||
|
||||
@@ -13,9 +13,13 @@
|
||||
desc = "A pair of costume boots fashioned after bird talons."
|
||||
icon_state = "griffinboots"
|
||||
inhand_icon_state = "griffinboots"
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
lace_time = 8 SECONDS
|
||||
|
||||
/obj/item/clothing/shoes/griffin/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
/obj/item/clothing/shoes/singery
|
||||
name = "yellow performer's boots"
|
||||
desc = "These boots were made for dancing."
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
desc = "A small sticker lets you know they've been inspected for snakes, It is unclear how long ago the inspection took place..."
|
||||
icon_state = "cowboy_brown"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 90, FIRE = 0, ACID = 0) //these are quite tall
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
custom_price = PAYCHECK_CREW
|
||||
var/max_occupants = 4
|
||||
can_be_tied = FALSE
|
||||
|
||||
/obj/item/clothing/shoes/cowboy/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
if(prob(2))
|
||||
//There's a snake in my boot
|
||||
new /mob/living/simple_animal/hostile/retaliate/snake(src)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
inhand_icon_state = "jackboots"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
/// What projectile do we shoot?
|
||||
var/projectile_type = /obj/projectile/bullet/c10mm
|
||||
/// Each step, this is the chance we fire a shot
|
||||
@@ -13,6 +12,9 @@
|
||||
|
||||
/obj/item/clothing/shoes/gunboots/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
RegisterSignal(src, COMSIG_SHOES_STEP_ACTION, .proc/check_step)
|
||||
|
||||
/obj/item/clothing/shoes/gunboots/equipped(mob/user, slot)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
icon_state = "jetboots"
|
||||
inhand_icon_state = "jetboots"
|
||||
resistance_flags = FIRE_PROOF
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
actions_types = list(/datum/action/item_action/bhop)
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 90, FIRE = 0, ACID = 0)
|
||||
strip_delay = 30
|
||||
@@ -13,6 +12,11 @@
|
||||
var/recharging_rate = 60 //default 6 seconds between each dash
|
||||
var/recharging_time = 0 //time until next dash
|
||||
|
||||
/obj/item/clothing/shoes/bhop/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/shoes)
|
||||
|
||||
/obj/item/clothing/shoes/bhop/ui_action_click(mob/user, action)
|
||||
if(!isliving(user))
|
||||
return
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
/obj/item/clothing/suit/mothcoat/original
|
||||
desc = "An old-school flightsuit from the moth fleet. A perfect token of mothic survivalistic and adaptable attitude, yet a bitter reminder that with the loss of their home planet and institution of the fleet, their beloved wings remain as a burden to bear, condemned to never fly again."
|
||||
greyscale_colors = "#dfa409"
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets
|
||||
|
||||
/obj/item/clothing/suit/mothcoat/original/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets)
|
||||
|
||||
/obj/item/clothing/suit/mothcoat/winter
|
||||
name = "mothic mantella"
|
||||
|
||||
@@ -11,15 +11,9 @@
|
||||
var/above_suit = TRUE
|
||||
/// TRUE if shown as a small icon in corner, FALSE if overlayed
|
||||
var/minimize_when_attached = TRUE
|
||||
/// Whether the accessory has any storage to apply to the clothing it's attached to.
|
||||
var/datum/component/storage/detached_pockets
|
||||
/// What equipment slot the accessory attaches to.
|
||||
var/attachment_slot = CHEST
|
||||
|
||||
/obj/item/clothing/accessory/Destroy()
|
||||
set_detached_pockets(null)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/accessory/proc/can_attach_accessory(obj/item/clothing/U, mob/user)
|
||||
if(!attachment_slot || (U && U.body_parts_covered & attachment_slot))
|
||||
return TRUE
|
||||
@@ -27,12 +21,11 @@
|
||||
to_chat(user, span_warning("There doesn't seem to be anywhere to put [src]..."))
|
||||
|
||||
/obj/item/clothing/accessory/proc/attach(obj/item/clothing/under/U, user)
|
||||
var/datum/component/storage/storage = GetComponent(/datum/component/storage)
|
||||
if(storage)
|
||||
if(SEND_SIGNAL(U, COMSIG_CONTAINS_STORAGE))
|
||||
if(atom_storage)
|
||||
if(U.atom_storage)
|
||||
return FALSE
|
||||
U.TakeComponent(storage)
|
||||
set_detached_pockets(storage)
|
||||
U.clone_storage(atom_storage)
|
||||
U.atom_storage.set_real_location(src)
|
||||
U.attached_accessory = src
|
||||
forceMove(U)
|
||||
layer = FLOAT_LAYER
|
||||
@@ -57,8 +50,8 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/U, user)
|
||||
if(detached_pockets && detached_pockets.parent == U)
|
||||
TakeComponent(detached_pockets)
|
||||
if(U.atom_storage && U.atom_storage.real_location?.resolve() == src)
|
||||
QDEL_NULL(U.atom_storage)
|
||||
|
||||
U.armor = U.armor.detachArmor(armor)
|
||||
|
||||
@@ -75,16 +68,6 @@
|
||||
U.attached_accessory = null
|
||||
U.accessory_overlay = null
|
||||
|
||||
/obj/item/clothing/accessory/proc/set_detached_pockets(new_pocket)
|
||||
if(detached_pockets)
|
||||
UnregisterSignal(detached_pockets, COMSIG_PARENT_QDELETING)
|
||||
detached_pockets = new_pocket
|
||||
if(detached_pockets)
|
||||
RegisterSignal(detached_pockets, COMSIG_PARENT_QDELETING, .proc/handle_pockets_del)
|
||||
|
||||
/obj/item/clothing/accessory/proc/handle_pockets_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
set_detached_pockets(null)
|
||||
|
||||
/obj/item/clothing/accessory/proc/on_uniform_equip(obj/item/clothing/under/U, user)
|
||||
return
|
||||
@@ -356,10 +339,12 @@
|
||||
name = "pocket protector"
|
||||
desc = "Can protect your clothing from ink stains, but you'll look like a nerd if you're using one."
|
||||
icon_state = "pocketprotector"
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/pocketprotector
|
||||
|
||||
/obj/item/clothing/accessory/pocketprotector/full/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
create_storage(type = /datum/storage/pockets/pocketprotector)
|
||||
|
||||
new /obj/item/pen/red(src)
|
||||
new /obj/item/pen(src)
|
||||
new /obj/item/pen/blue(src)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
if(!istype(I) || I.anchored)
|
||||
return
|
||||
|
||||
if(SEND_SIGNAL(loc, COMSIG_CONTAINS_STORAGE) && SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE))
|
||||
if(loc.atom_storage && I.atom_storage)
|
||||
to_chat(user, span_warning("No matter what way you try, you can't get [I] to fit inside [src]."))
|
||||
return TRUE //begone infinite storage ghosts, begone from me
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
return
|
||||
|
||||
if(!isturf(I.loc)) //If it isn't on the floor. Do some checks to see if it's in our hands or a box. Otherwise give up.
|
||||
if(SEND_SIGNAL(I.loc, COMSIG_CONTAINS_STORAGE)) //in a container.
|
||||
SEND_SIGNAL(I.loc, COMSIG_TRY_STORAGE_TAKE, I, src)
|
||||
if(I.loc.atom_storage) //in a container.
|
||||
I.loc.atom_storage.attempt_remove(I, src)
|
||||
if(!user.dropItemToGround(I))
|
||||
return
|
||||
|
||||
|
||||
@@ -86,10 +86,10 @@ GLOBAL_DATUM(rpgloot_controller, /datum/rpgloot_controller)
|
||||
|
||||
if(istype(fantasy_item, /obj/item/storage))
|
||||
var/obj/item/storage/storage_item = fantasy_item
|
||||
var/datum/component/storage/storage_component = storage_item.GetComponent(/datum/component/storage)
|
||||
if(prob(upgrade_scroll_chance) && storage_item.contents.len < storage_component.max_items && !storage_item.invisibility)
|
||||
var/datum/storage/storage_component = storage_item.atom_storage
|
||||
if(prob(upgrade_scroll_chance) && storage_item.contents.len < storage_component.max_slots && !storage_item.invisibility)
|
||||
var/obj/item/upgradescroll/scroll = new(get_turf(storage_item))
|
||||
SEND_SIGNAL(storage_item, COMSIG_TRY_STORAGE_INSERT, scroll, null, TRUE, TRUE)
|
||||
storage_item.atom_storage?.attempt_insert(storage_item, scroll, null, TRUE)
|
||||
upgrade_scroll_chance = max(0,upgrade_scroll_chance-100)
|
||||
if(isturf(scroll.loc))
|
||||
qdel(scroll)
|
||||
|
||||
@@ -71,10 +71,8 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
|
||||
name_counter[name] = 1
|
||||
GLOB.exodrones += src
|
||||
/// Cargo storage
|
||||
var/datum/component/storage/storage = AddComponent(/datum/component/storage/concrete)
|
||||
storage.cant_hold = GLOB.blacklisted_cargo_types
|
||||
storage.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
storage.max_items = EXODRONE_CARGO_SLOTS
|
||||
create_storage(max_slots = EXODRONE_CARGO_SLOTS)
|
||||
atom_storage.set_holdable(cant_hold_list = GLOB.blacklisted_cargo_types)
|
||||
|
||||
/obj/item/exodrone/Destroy()
|
||||
. = ..()
|
||||
@@ -148,8 +146,7 @@ GLOBAL_LIST_EMPTY(exodrone_launchers)
|
||||
|
||||
/// Resizes storage component depending on slots used by tools.
|
||||
/obj/item/exodrone/proc/update_storage_size()
|
||||
var/datum/component/storage/storage = GetComponent(/datum/component/storage/concrete)
|
||||
storage.max_items = EXODRONE_CARGO_SLOTS - length(tools)
|
||||
atom_storage.max_slots = EXODRONE_CARGO_SLOTS - length(tools)
|
||||
|
||||
/// Builds ui data for drone storage.
|
||||
/obj/item/exodrone/proc/get_cargo_data()
|
||||
|
||||
@@ -21,12 +21,14 @@
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
|
||||
component_type = /datum/component/storage/concrete/fish_case
|
||||
|
||||
/obj/item/storage/fish_case/Initialize(mapload)
|
||||
ADD_TRAIT(src, TRAIT_FISH_SAFE_STORAGE, TRAIT_GENERIC) // Before populate so fish instatiates in ready container already
|
||||
. = ..()
|
||||
|
||||
create_storage(max_slots = 1)
|
||||
atom_storage.can_hold_trait = TRAIT_FISH_CASE_COMPATIBILE
|
||||
atom_storage.can_hold_description = "fish and aquarium equipment"
|
||||
|
||||
///Fish case with single random fish inside.
|
||||
/obj/item/storage/fish_case/random/PopulateContents()
|
||||
. = ..()
|
||||
|
||||
@@ -70,12 +70,11 @@
|
||||
inhand_icon_state = "artistic_toolbox"
|
||||
material_flags = NONE
|
||||
|
||||
/obj/item/storage/toolbox/ComponentInitialize()
|
||||
/obj/item/storage/toolbox/Initialize()
|
||||
. = ..()
|
||||
// Can hold fishing rod despite the size
|
||||
var/static/list/exception_cache = typecacheof(/obj/item/fishing_rod)
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.exception_hold = exception_cache
|
||||
atom_storage.exception_hold = exception_cache
|
||||
|
||||
/obj/item/storage/toolbox/fishing/PopulateContents()
|
||||
new /obj/item/bait_can/worm(src)
|
||||
|
||||
@@ -86,7 +86,7 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list(
|
||||
if(default_deconstruction_screwdriver(user, "fryer_off", "fryer_off", weapon)) //where's the open maint panel icon?!
|
||||
return
|
||||
else
|
||||
if(is_type_in_typecache(weapon, deepfry_blacklisted_items) || is_type_in_typecache(weapon, GLOB.oilfry_blacklisted_items) || SEND_SIGNAL(weapon, COMSIG_CONTAINS_STORAGE) || HAS_TRAIT(weapon, TRAIT_NODROP) || (weapon.item_flags & (ABSTRACT | DROPDEL)))
|
||||
if(is_type_in_typecache(weapon, deepfry_blacklisted_items) || is_type_in_typecache(weapon, GLOB.oilfry_blacklisted_items) || weapon.atom_storage || HAS_TRAIT(weapon, TRAIT_NODROP) || (weapon.item_flags & (ABSTRACT | DROPDEL)))
|
||||
return ..()
|
||||
else if(!frying && user.transferItemToLoc(weapon, src))
|
||||
fry(weapon, user)
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
if(ingredients.len >= max_n_of_items)
|
||||
to_chat(user, span_warning("\The [src] is full, you can't put anything in!"))
|
||||
return TRUE
|
||||
if(SEND_SIGNAL(T, COMSIG_TRY_STORAGE_TAKE, S, src))
|
||||
if(T.atom_storage.attempt_remove(S, src))
|
||||
loaded++
|
||||
ingredients += S
|
||||
if(loaded)
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
continue
|
||||
var/datum/food_processor_process/P = PROCESSOR_SELECT_RECIPE(S)
|
||||
if(P)
|
||||
if(SEND_SIGNAL(T, COMSIG_TRY_STORAGE_TAKE, S, src))
|
||||
if(T.atom_storage.attempt_remove(S, src))
|
||||
LAZYADD(processor_contents, S)
|
||||
loaded++
|
||||
|
||||
|
||||
@@ -155,8 +155,8 @@
|
||||
else
|
||||
return TRUE
|
||||
else
|
||||
if(SEND_SIGNAL(O.loc, COMSIG_CONTAINS_STORAGE))
|
||||
return SEND_SIGNAL(O.loc, COMSIG_TRY_STORAGE_TAKE, O, src)
|
||||
if(O.loc.atom_storage)
|
||||
return O.loc.atom_storage.attempt_remove(O, src)
|
||||
else
|
||||
O.forceMove(src)
|
||||
return TRUE
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
|
||||
/obj/item/storage/basket/easter/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.set_holdable(list(/obj/item/food/egg, /obj/item/food/chocolateegg, /obj/item/food/boiledegg, /obj/item/surprise_egg))
|
||||
atom_storage.set_holdable(list(/obj/item/food/egg, /obj/item/food/chocolateegg, /obj/item/food/boiledegg, /obj/item/surprise_egg))
|
||||
|
||||
/obj/item/storage/basket/easter/proc/countEggs()
|
||||
cut_overlays()
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
for(var/obj/item/food/grown/G in PB.contents)
|
||||
if(i >= max_items)
|
||||
break
|
||||
if(SEND_SIGNAL(PB, COMSIG_TRY_STORAGE_TAKE, G, src))
|
||||
if(PB.atom_storage.attempt_remove(G, src))
|
||||
i++
|
||||
if(i<max_items)
|
||||
to_chat(user, span_info("You empty the plant bag into the biogenerator."))
|
||||
|
||||
@@ -891,7 +891,7 @@
|
||||
else if(istype(O, /obj/item/storage/bag/plants))
|
||||
attack_hand(user)
|
||||
for(var/obj/item/food/grown/G in locate(user.x,user.y,user.z))
|
||||
SEND_SIGNAL(O, COMSIG_TRY_STORAGE_INSERT, G, user, TRUE)
|
||||
O.atom_storage?.attempt_insert(O, G, user, TRUE)
|
||||
return
|
||||
|
||||
else if(istype(O, /obj/item/shovel/spade))
|
||||
|
||||
@@ -167,9 +167,8 @@
|
||||
to_chat(usr, span_notice("\The [src] is full."))
|
||||
return FALSE
|
||||
|
||||
var/datum/component/storage/STR = O.loc.GetComponent(/datum/component/storage)
|
||||
if(STR)
|
||||
if(!STR.remove_from_storage(O,src))
|
||||
if(atom_storage)
|
||||
if(!atom_storage.attempt_remove(O, src, silent = TRUE))
|
||||
return FALSE
|
||||
else if(ismob(O.loc))
|
||||
var/mob/M = O.loc
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user