mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
## About The Pull Request In similar fashion to what was done with crafting recipes last year, this year it's time for techweb designs and printed items to be audited. This is mostly just about consistency, we've a lot of items that can be printed by protolathes, autolathes, circuit printers and techfab etc. However they almost all (except most stacks, mainly) have custom materials that do not match in one way or another with the materials used by the design, which is what this PR is for. "But items printed from lathes etc. already get the mats used to make them." Yes, they do, however that isn't the case for items of the same type that were spawned in some other way (cargo shuttle, space/maints loot, mapped, admins), this create a subtle discrepancy. It isn't a huge deal (in spite of the size of this PR, ton of designs), but given that I have done something similar with crafting recipes before, I may as well give it a second arc of some sort and bring things to completion. And fix a few possible oversights. TL;DR consistency and stuff ## Why It's Good For The Game Consistency, unit test checks to make it harder not to be consistent in the future. Still has a few TODOs like: - [x] Fixed newly printed, fully charged RCDs costing less than the RCD cartridges required to fully charge one. EDIT: I had to tweak the newly added RDD as well because it suffered from the same fundamental issue. - [x] Fixed plates being made of iron and yet shattering like ceramic ones. A new subtype for metallic ones has been made. ## Changelog 🆑 refactor: Refactored a few things with techweb designs (the ones for autolathes, protolathes, circuit printers, mechfabs etc.) to make sure that the materials of items that can be made from these designs more closely match the materials used to make them. fix: Lizard fries no longer need a plate to be made, like all other treats that used to require plates in a distant past. balance: Tweaked the materials cost of RCD, RDD and RCD cartridges. image: Oven trays now have a more metallic hue. balance: Plates printed printed from lathes won't shatter like ceramic ones, in virtue of them being made out of iron instead. /🆑
625 lines
21 KiB
Plaintext
625 lines
21 KiB
Plaintext
#define ORE_BAG_BALOON_COOLDOWN (2 SECONDS)
|
|
|
|
/*
|
|
* These absorb the functionality of the plant bag, ore satchel, etc.
|
|
* They use the use_to_pickup, quick_gather, and quick_empty functions
|
|
* that were already defined in weapon/storage, but which had been
|
|
* re-implemented in other classes.
|
|
*
|
|
* Contains:
|
|
* Trash Bag
|
|
* Mining Satchel
|
|
* Plant Bag
|
|
* Sheet Snatcher
|
|
* Book Bag
|
|
* Biowaste Bag
|
|
*
|
|
* -Sayu
|
|
*/
|
|
|
|
// Generic non-item
|
|
/obj/item/storage/bag
|
|
abstract_type = /obj/item/storage/bag
|
|
slot_flags = ITEM_SLOT_BELT
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
storage_type = /datum/storage/bag
|
|
|
|
/obj/item/storage/bag/trash
|
|
name = "trash bag"
|
|
desc = "It's the heavy-duty black polymer kind. Time to take out the trash!"
|
|
icon = 'icons/obj/service/janitor.dmi'
|
|
icon_state = "trashbag"
|
|
inhand_icon_state = "trashbag"
|
|
worn_icon_state = "trashbag"
|
|
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
|
|
storage_type = /datum/storage/bag/trash
|
|
custom_materials = list(/datum/material/plastic = SHEET_MATERIAL_AMOUNT)
|
|
///If true, can be inserted into the janitor cart
|
|
var/insertable = TRUE
|
|
|
|
/obj/item/storage/bag/trash/Initialize(mapload)
|
|
. = ..()
|
|
|
|
RegisterSignal(atom_storage, COMSIG_STORAGE_DUMP_POST_TRANSFER, PROC_REF(post_insertion))
|
|
|
|
/// If you dump a trash bag into something, anything that doesn't get inserted will spill out onto your feet
|
|
/obj/item/storage/bag/trash/proc/post_insertion(datum/storage/source, atom/dest_object, mob/user)
|
|
SIGNAL_HANDLER
|
|
// If there's no item in there, don't do anything
|
|
if(!(locate(/obj/item) in src))
|
|
return
|
|
|
|
// Otherwise, we're gonna dump into the dest object
|
|
var/turf/dump_onto = get_turf(dest_object)
|
|
user.visible_message(
|
|
span_notice("[user] dumps the contents of [src] all out on \the [dump_onto]"),
|
|
span_notice("The remaining trash in \the [src] falls out onto \the [dump_onto]"),
|
|
)
|
|
source.remove_all(dump_onto)
|
|
|
|
/obj/item/storage/bag/trash/suicide_act(mob/living/user)
|
|
user.visible_message(span_suicide("[user] puts [src] over [user.p_their()] head and starts chomping at the insides! Disgusting!"))
|
|
playsound(loc, 'sound/items/eatfood.ogg', 50, TRUE, -1)
|
|
return TOXLOSS
|
|
|
|
/obj/item/storage/bag/trash/update_icon_state()
|
|
switch(contents.len)
|
|
if(20 to INFINITY)
|
|
icon_state = "[initial(icon_state)]3"
|
|
if(11 to 20)
|
|
icon_state = "[initial(icon_state)]2"
|
|
if(1 to 11)
|
|
icon_state = "[initial(icon_state)]1"
|
|
else
|
|
icon_state = "[initial(icon_state)]"
|
|
return ..()
|
|
|
|
/obj/item/storage/bag/trash/filled/PopulateContents()
|
|
. = ..()
|
|
for(var/i in 1 to rand(1, 7))
|
|
new /obj/effect/spawner/random/trash/garbage(src)
|
|
update_icon_state()
|
|
|
|
/obj/item/storage/bag/trash/bluespace
|
|
name = "trash bag of holding"
|
|
desc = "The latest and greatest in custodial convenience, a trashbag that is capable of holding vast quantities of garbage."
|
|
icon_state = "bluetrashbag"
|
|
worn_icon_state = "bluetrashbag"
|
|
inhand_icon_state = "bluetrashbag"
|
|
item_flags = NO_MAT_REDEMPTION
|
|
storage_type = /datum/storage/bag/trash/bluespace
|
|
custom_materials = list(/datum/material/gold = SHEET_MATERIAL_AMOUNT * 0.75, /datum/material/plasma = SHEET_MATERIAL_AMOUNT * 0.75, /datum/material/uranium = SMALL_MATERIAL_AMOUNT * 2.5)
|
|
|
|
/obj/item/storage/bag/trash/bluespace/cyborg
|
|
insertable = FALSE
|
|
|
|
/obj/item/storage/bag/ore
|
|
name = "mining satchel"
|
|
desc = "This little bugger can be used to store and transport ores."
|
|
icon = 'icons/obj/mining.dmi'
|
|
icon_state = "satchel"
|
|
worn_icon_state = "satchel"
|
|
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS
|
|
w_class = WEIGHT_CLASS_NORMAL
|
|
storage_type = /datum/storage/bag/ore
|
|
/// If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it
|
|
var/spam_protection = FALSE
|
|
/// Mob we're currently tracking
|
|
var/mob/listening_to = null
|
|
/// Are we currently dropping off ores? Used to prevent the bag from instantly picking up ores after dropping them
|
|
var/dropping_ores = FALSE
|
|
/// Cooldown on balloon alerts when picking ore
|
|
COOLDOWN_DECLARE(ore_bag_balloon_cooldown)
|
|
|
|
/obj/item/storage/bag/ore/Destroy(force)
|
|
listening_to = null
|
|
return ..()
|
|
|
|
/obj/item/storage/bag/ore/equipped(mob/user)
|
|
. = ..()
|
|
if (listening_to)
|
|
return
|
|
RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(on_user_moved))
|
|
if (isturf(user.loc))
|
|
RegisterSignal(user.loc, COMSIG_ATOM_ENTERED, PROC_REF(on_obj_entered))
|
|
RegisterSignal(user.loc, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, PROC_REF(on_atom_initialized_on))
|
|
listening_to = user
|
|
|
|
/obj/item/storage/bag/ore/dropped()
|
|
. = ..()
|
|
if(!listening_to)
|
|
return
|
|
UnregisterSignal(listening_to, COMSIG_MOVABLE_MOVED)
|
|
if (listening_to.loc)
|
|
UnregisterSignal(listening_to.loc, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON))
|
|
listening_to = null
|
|
|
|
// Ensure we don't suck up ores that we've just dropped off
|
|
/obj/item/storage/bag/ore/attack_self(mob/user, modifiers)
|
|
dropping_ores = TRUE
|
|
. = ..()
|
|
dropping_ores = FALSE
|
|
|
|
/obj/item/storage/bag/ore/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
|
|
if(istype(tool, /obj/item/boulder))
|
|
to_chat(user, span_warning("You can't fit [tool] into [src]. \
|
|
Perhaps you should break it down first, or find an ore box."))
|
|
return ITEM_INTERACT_BLOCKING
|
|
return NONE
|
|
|
|
/obj/item/storage/bag/ore/proc/on_user_moved(mob/living/user, atom/old_loc, dir, forced)
|
|
SIGNAL_HANDLER
|
|
|
|
if(old_loc)
|
|
UnregisterSignal(old_loc, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON))
|
|
|
|
var/turf/tile = get_turf(user)
|
|
if(!isturf(tile))
|
|
return
|
|
|
|
RegisterSignal(tile, COMSIG_ATOM_ENTERED, PROC_REF(on_obj_entered))
|
|
RegisterSignal(tile, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, PROC_REF(on_atom_initialized_on))
|
|
INVOKE_ASYNC(src, PROC_REF(handle_move), user)
|
|
|
|
/obj/item/storage/bag/ore/proc/handle_move(mob/living/user)
|
|
if(user.stat != CONSCIOUS)
|
|
return
|
|
var/turf/tile = get_turf(user)
|
|
var/obj/structure/ore_box/box = null
|
|
if(istype(user.pulling, /obj/structure/ore_box))
|
|
box = user.pulling
|
|
|
|
var/show_message = FALSE
|
|
for(var/atom/thing as anything in tile)
|
|
if(!is_type_in_typecache(thing, atom_storage.can_hold))
|
|
continue
|
|
if(pickup_ore(thing, user, box))
|
|
show_message = TRUE
|
|
|
|
if (!show_message)
|
|
spam_protection = FALSE
|
|
return
|
|
|
|
playsound(user, SFX_RUSTLE, 50, TRUE)
|
|
if(!COOLDOWN_FINISHED(src, ore_bag_balloon_cooldown))
|
|
return
|
|
|
|
spam_protection = FALSE
|
|
COOLDOWN_START(src, ore_bag_balloon_cooldown, ORE_BAG_BALOON_COOLDOWN)
|
|
|
|
if (box)
|
|
balloon_alert(user, "scoops ore into box")
|
|
user.visible_message(
|
|
span_notice("[user] offloads the ores beneath [user.p_them()] into [box]."),
|
|
ignored_mobs = user
|
|
)
|
|
return
|
|
|
|
balloon_alert(user, "scoops ore into bag")
|
|
user.visible_message(
|
|
span_notice("[user] scoops up the ores beneath [user.p_them()]."),
|
|
ignored_mobs = user
|
|
)
|
|
|
|
/obj/item/storage/bag/ore/proc/pickup_ore(obj/item/ore, mob/user, obj/structure/ore_box/box)
|
|
if (!box && istype(user.pulling, /obj/structure/ore_box))
|
|
box = user.pulling
|
|
|
|
if (box)
|
|
user.transferItemToLoc(ore, box, animated = FALSE)
|
|
return TRUE
|
|
|
|
if (istype(ore, /obj/item/stack/ore))
|
|
var/obj/item/stack/ore/real_ore = ore
|
|
for(var/obj/item/stack/ore/stored_ore as anything in src)
|
|
if(!real_ore.can_merge(stored_ore))
|
|
continue
|
|
real_ore.merge(stored_ore)
|
|
if(QDELETED(real_ore))
|
|
return TRUE
|
|
|
|
if (atom_storage.attempt_insert(ore, user))
|
|
return TRUE
|
|
|
|
if (!spam_protection)
|
|
balloon_alert(user, "bag full!")
|
|
spam_protection = TRUE
|
|
return FALSE
|
|
|
|
/obj/item/storage/bag/ore/proc/on_obj_entered(atom/new_loc, atom/movable/arrived, atom/old_loc)
|
|
SIGNAL_HANDLER
|
|
if(is_type_in_list(arrived, atom_storage.can_hold) && !dropping_ores && old_loc != loc)
|
|
INVOKE_ASYNC(src, PROC_REF(pickup_ore), arrived, listening_to)
|
|
|
|
/obj/item/storage/bag/ore/proc/on_atom_initialized_on(atom/loc, atom/new_atom)
|
|
SIGNAL_HANDLER
|
|
if(is_type_in_list(new_atom, atom_storage.can_hold))
|
|
INVOKE_ASYNC(src, PROC_REF(pickup_ore), new_atom, listening_to)
|
|
|
|
/obj/item/storage/bag/ore/cyborg
|
|
name = "cyborg mining satchel"
|
|
|
|
/obj/item/storage/bag/ore/holding //miners, your messiah has arrived
|
|
name = "mining satchel of holding"
|
|
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"
|
|
storage_type = /datum/storage/bag/ore/holding
|
|
custom_materials = list(/datum/material/uranium = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/gold = SMALL_MATERIAL_AMOUNT * 2.5)
|
|
|
|
/obj/item/storage/bag/plants
|
|
name = "plant bag"
|
|
icon = 'icons/obj/service/hydroponics/equipment.dmi'
|
|
icon_state = "plantbag"
|
|
worn_icon_state = "plantbag"
|
|
resistance_flags = FLAMMABLE
|
|
storage_type = /datum/storage/bag/plants
|
|
|
|
/obj/item/storage/bag/plants/portaseeder
|
|
name = "portable seed extractor"
|
|
desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant."
|
|
icon_state = "portaseeder"
|
|
custom_materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 4)
|
|
|
|
/obj/item/storage/bag/plants/portaseeder/Initialize(mapload)
|
|
. = ..()
|
|
register_context()
|
|
|
|
/obj/item/storage/bag/plants/portaseeder/add_context(
|
|
atom/source,
|
|
list/context,
|
|
obj/item/held_item,
|
|
mob/living/user
|
|
)
|
|
|
|
context[SCREENTIP_CONTEXT_CTRL_LMB] = "Make seeds"
|
|
return CONTEXTUAL_SCREENTIP_SET
|
|
|
|
/obj/item/storage/bag/plants/portaseeder/examine(mob/user)
|
|
. = ..()
|
|
. += span_notice("Ctrl-click to activate seed extraction.")
|
|
|
|
/obj/item/storage/bag/plants/portaseeder/item_ctrl_click(mob/user)
|
|
for(var/obj/item/plant in contents)
|
|
seedify(plant, 1)
|
|
return CLICK_ACTION_SUCCESS
|
|
|
|
/obj/item/storage/bag/plants/cyborg
|
|
name = "cyborg plant bag"
|
|
|
|
/obj/item/storage/bag/sheetsnatcher
|
|
name = "sheet snatcher"
|
|
desc = "A patented Nanotrasen storage system designed for any kind of mineral sheet."
|
|
icon = 'icons/obj/mining.dmi'
|
|
icon_state = "sheetsnatcher"
|
|
worn_icon_state = "satchel"
|
|
storage_type = /datum/storage/bag/sheet_snatcher
|
|
|
|
/obj/item/storage/bag/sheetsnatcher/borg
|
|
name = "sheet snatcher 9000"
|
|
desc = ""
|
|
storage_type = /datum/storage/bag/sheet_snatcher/borg
|
|
|
|
/obj/item/storage/bag/sheetsnatcher/debug
|
|
name = "sheet snatcher EXTREME EDITION"
|
|
desc = "A Nanotrasen storage system designed which has been given post-market alterations to hold any type of sheet. Comes pre-populated with "
|
|
color = "#ff3737" // I'm too lazy to make a unique sprite
|
|
w_class = WEIGHT_CLASS_TINY
|
|
storage_type = /datum/storage/bag/sheet_snatcher_debug
|
|
|
|
// Copy-pasted from the former /obj/item/storage/box/material, w/ small additions like rods, cardboard, plastic.
|
|
// "Only 20 uranium 'cause of radiation"
|
|
/obj/item/storage/bag/sheetsnatcher/debug/PopulateContents()
|
|
// amount should be null if it should spawn with the type's default amount
|
|
var/list/items_inside = list(
|
|
/obj/item/stack/sheet/iron/fifty = null,
|
|
/obj/item/stack/sheet/glass/fifty = null,
|
|
/obj/item/stack/sheet/rglass/fifty = null,
|
|
/obj/item/stack/sheet/plasmaglass/fifty = null,
|
|
/obj/item/stack/sheet/titaniumglass/fifty = null,
|
|
/obj/item/stack/sheet/plastitaniumglass/fifty = null,
|
|
/obj/item/stack/sheet/plasteel/fifty = null,
|
|
/obj/item/stack/sheet/mineral/titanium/fifty = null,
|
|
/obj/item/stack/sheet/mineral/gold = 50,
|
|
/obj/item/stack/sheet/mineral/silver = 50,
|
|
/obj/item/stack/sheet/mineral/plasma = 50,
|
|
/obj/item/stack/sheet/mineral/uranium = 20,
|
|
/obj/item/stack/sheet/mineral/diamond = 50,
|
|
/obj/item/stack/sheet/bluespace_crystal = 50,
|
|
/obj/item/stack/sheet/mineral/bananium = 50,
|
|
/obj/item/stack/sheet/mineral/wood/fifty = null,
|
|
/obj/item/stack/sheet/plastic/fifty = null,
|
|
/obj/item/stack/sheet/runed_metal/fifty = null,
|
|
/obj/item/stack/rods/fifty = null,
|
|
/obj/item/stack/sheet/mineral/plastitanium = 50,
|
|
/obj/item/stack/sheet/mineral/abductor = 50,
|
|
/obj/item/stack/sheet/mineral/sandbags/fifty = null,
|
|
/obj/item/stack/sheet/cardboard/fifty = null,
|
|
)
|
|
for(var/obj/item/stack/stack_type as anything in items_inside)
|
|
var/amt = items_inside[stack_type]
|
|
new stack_type(src, amt, FALSE)
|
|
|
|
/obj/item/storage/bag/books
|
|
name = "book bag"
|
|
desc = "A bag for books."
|
|
icon = 'icons/obj/service/library.dmi'
|
|
icon_state = "bookbag"
|
|
worn_icon_state = "bookbag"
|
|
resistance_flags = FLAMMABLE
|
|
storage_type = /datum/storage/bag/books
|
|
|
|
/obj/item/storage/bag/tray
|
|
name = "serving tray"
|
|
icon = 'icons/obj/food/containers.dmi'
|
|
icon_state = "tray"
|
|
worn_icon_state = "tray"
|
|
desc = "A metal tray to lay food on."
|
|
force = 5
|
|
throwforce = 10
|
|
throw_speed = 3
|
|
throw_range = 5
|
|
obj_flags = CONDUCTS_ELECTRICITY
|
|
slot_flags = ITEM_SLOT_BELT
|
|
custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT*1.5)
|
|
custom_price = PAYCHECK_CREW * 0.6
|
|
storage_type = /datum/storage/bag/tray
|
|
sound_vary = TRUE
|
|
pickup_sound = SFX_TRAY_PICKUP
|
|
drop_sound = SFX_TRAY_DROP
|
|
|
|
/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()
|
|
atom_storage.remove_all(user)
|
|
// Make each item scatter a bit
|
|
for(var/obj/item/tray_item in oldContents)
|
|
do_scatter(tray_item)
|
|
|
|
if(prob(50))
|
|
playsound(M, 'sound/items/trayhit/trayhit1.ogg', 50, TRUE)
|
|
else
|
|
playsound(M, 'sound/items/trayhit/trayhit2.ogg', 50, TRUE)
|
|
|
|
if(ishuman(M))
|
|
if(prob(10))
|
|
M.Paralyze(40)
|
|
update_appearance()
|
|
|
|
/obj/item/storage/bag/tray/proc/do_scatter(obj/item/tray_item)
|
|
var/delay = rand(2,4)
|
|
var/datum/move_loop/loop = GLOB.move_manager.move_rand(tray_item, list(NORTH,SOUTH,EAST,WEST), delay, timeout = rand(1, 2) * delay, flags = MOVEMENT_LOOP_START_FAST)
|
|
//This does mean scattering is tied to the tray. Not sure how better to handle it
|
|
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(change_speed))
|
|
|
|
/obj/item/storage/bag/tray/proc/change_speed(datum/move_loop/source)
|
|
SIGNAL_HANDLER
|
|
var/new_delay = rand(2, 4)
|
|
var/count = source.lifetime / source.delay
|
|
source.lifetime = count * new_delay
|
|
source.delay = new_delay
|
|
|
|
/obj/item/storage/bag/tray/update_overlays()
|
|
. = ..()
|
|
for(var/obj/item/I in contents)
|
|
var/mutable_appearance/I_copy = new(I)
|
|
I_copy.plane = FLOAT_PLANE
|
|
I_copy.layer = FLOAT_LAYER
|
|
. += I_copy
|
|
|
|
/obj/item/storage/bag/tray/cyborg_unequip(mob/user)
|
|
. = ..()
|
|
atom_storage.remove_all(drop_location())
|
|
|
|
/obj/item/storage/bag/tray/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
|
. = ..()
|
|
update_appearance()
|
|
|
|
/obj/item/storage/bag/tray/Exited(atom/movable/gone, direction)
|
|
. = ..()
|
|
update_appearance()
|
|
|
|
/obj/item/storage/bag/tray/cafeteria
|
|
name = "cafeteria tray"
|
|
icon = 'icons/obj/food/containers.dmi'
|
|
icon_state = "foodtray"
|
|
desc = "A cheap metal tray to pile today's meal onto."
|
|
|
|
/obj/item/storage/bag/chemistry
|
|
name = "chemistry bag"
|
|
icon = 'icons/obj/medical/chemical.dmi'
|
|
icon_state = "bag"
|
|
worn_icon_state = "chembag"
|
|
desc = "A bag for storing pills, patches, and bottles."
|
|
resistance_flags = FLAMMABLE
|
|
storage_type = /datum/storage/bag/chemistry
|
|
|
|
/obj/item/storage/bag/money
|
|
name = "money bag"
|
|
desc = "A bag for storing your profits."
|
|
icon_state = "moneybag"
|
|
worn_icon_state = "moneybag"
|
|
force = 10
|
|
throwforce = 0
|
|
resistance_flags = FLAMMABLE
|
|
max_integrity = 100
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
storage_type = /datum/storage/bag/money
|
|
|
|
/obj/item/storage/bag/money/Initialize(mapload)
|
|
. = ..()
|
|
if(prob(20))
|
|
icon_state = "moneybagalt"
|
|
|
|
/obj/item/storage/bag/money/vault/PopulateContents()
|
|
new /obj/item/coin/silver(src)
|
|
new /obj/item/coin/silver(src)
|
|
new /obj/item/coin/silver(src)
|
|
new /obj/item/coin/silver(src)
|
|
new /obj/item/coin/gold(src)
|
|
new /obj/item/coin/gold(src)
|
|
new /obj/item/coin/adamantine(src)
|
|
|
|
///Used in the dutchmen pirate shuttle.
|
|
/obj/item/storage/bag/money/dutchmen/PopulateContents()
|
|
for(var/iteration in 1 to 9)
|
|
new /obj/item/coin/silver/doubloon(src)
|
|
for(var/iteration in 1 to 9)
|
|
new /obj/item/coin/gold/doubloon(src)
|
|
new /obj/item/coin/adamantine/doubloon(src)
|
|
|
|
/obj/item/storage/bag/bio
|
|
name = "bio bag"
|
|
icon = 'icons/obj/medical/chemical.dmi'
|
|
icon_state = "biobag"
|
|
worn_icon_state = "biobag"
|
|
desc = "A bag for the safe transportation and disposal of biowaste and other virulent materials."
|
|
resistance_flags = FLAMMABLE
|
|
storage_type = /datum/storage/bag/bio
|
|
|
|
/obj/item/storage/bag/xeno
|
|
name = "science bag"
|
|
icon = 'icons/obj/medical/chemical.dmi'
|
|
icon_state = "xenobag"
|
|
worn_icon_state = "xenobag"
|
|
desc = "A bag for the storage and transport of anomalous materials."
|
|
resistance_flags = FLAMMABLE
|
|
storage_type = /datum/storage/bag/xeno
|
|
|
|
/obj/item/storage/bag/construction
|
|
name = "construction bag"
|
|
icon = 'icons/obj/tools.dmi'
|
|
icon_state = "construction_bag"
|
|
worn_icon_state = "construction_bag"
|
|
desc = "A bag for storing small construction components."
|
|
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS
|
|
resistance_flags = FLAMMABLE
|
|
storage_type = /datum/storage/bag/construction
|
|
|
|
/obj/item/storage/bag/harpoon_quiver
|
|
name = "harpoon quiver"
|
|
desc = "A quiver for holding harpoons."
|
|
icon = 'icons/obj/weapons/bows/quivers.dmi'
|
|
icon_state = "quiver"
|
|
inhand_icon_state = null
|
|
worn_icon_state = "harpoon_quiver"
|
|
storage_type = /datum/storage/bag/harpoon_quiver
|
|
|
|
/obj/item/storage/bag/harpoon_quiver/PopulateContents()
|
|
for(var/i in 1 to 40)
|
|
new /obj/item/ammo_casing/harpoon(src)
|
|
|
|
/obj/item/storage/bag/rebar_quiver
|
|
name = "rebar quiver"
|
|
icon = 'icons/obj/weapons/bows/quivers.dmi'
|
|
icon_state = "rebar_quiver"
|
|
worn_icon_state = "rebar_quiver"
|
|
inhand_icon_state = "rebar_quiver"
|
|
desc = "A oxygen tank cut in half, used for holding sharpened rods for the rebar crossbow."
|
|
slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_SUITSTORE|ITEM_SLOT_NECK
|
|
resistance_flags = FLAMMABLE
|
|
storage_type = /datum/storage/bag/rebar_quiver
|
|
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 1.15, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 1.5)
|
|
actions_types = list(/datum/action/item_action/reload_rebar)
|
|
|
|
|
|
/obj/item/storage/bag/rebar_quiver/Initialize(mapload)
|
|
. = ..()
|
|
update_appearance(UPDATE_OVERLAYS)
|
|
|
|
/obj/item/storage/bag/rebar_quiver/ui_action_click(mob/user, actiontype)
|
|
if(istype(actiontype, /datum/action/item_action/reload_rebar))
|
|
reload_held_rebar(user)
|
|
|
|
/obj/item/storage/bag/rebar_quiver/proc/reload_held_rebar(mob/user)
|
|
if(!contents.len)
|
|
user.balloon_alert(user, "no bolts left!")
|
|
return
|
|
var/obj/held_item = user.get_active_held_item()
|
|
if(!held_item || !istype(held_item, /obj/item/gun/ballistic/rifle/rebarxbow))
|
|
user.balloon_alert(user, "no held crossbow!")
|
|
return
|
|
var/obj/item/gun/ballistic/rifle/rebarxbow/held_crossbow = held_item
|
|
if(held_crossbow.magazine.contents.len >= held_crossbow.magazine.max_ammo)
|
|
user.balloon_alert(user, "no more room!")
|
|
return
|
|
if(!do_after(user, held_crossbow.reload_time, user,timed_action_flags = held_crossbow.doafter_flags))
|
|
return
|
|
|
|
var/obj/item/ammo_casing/rebar/ammo_to_load = contents[1]
|
|
held_crossbow.item_interaction(user, ammo_to_load)
|
|
|
|
/obj/item/storage/bag/rebar_quiver/syndicate
|
|
icon_state = "syndie_quiver_0"
|
|
worn_icon_state = "syndie_quiver_0"
|
|
inhand_icon_state = "holyquiver"
|
|
desc = "A specialized quiver meant to hold any kind of bolts intended for use with the rebar crossbow. Allows moving while reloading.\
|
|
Clearly a better design than a cut up oxygen tank..."
|
|
slot_flags = ITEM_SLOT_NECK
|
|
w_class = WEIGHT_CLASS_NORMAL
|
|
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
|
actions_types = list(/datum/action/item_action/reload_rebar)
|
|
storage_type = /datum/storage/bag/rebar_quiver/syndicate
|
|
|
|
/obj/item/storage/bag/rebar_quiver/syndicate/PopulateContents()
|
|
for(var/to_fill in 1 to 20)
|
|
new /obj/item/ammo_casing/rebar/syndie(src)
|
|
|
|
/obj/item/storage/bag/rebar_quiver/syndicate/update_icon_state()
|
|
. = ..()
|
|
switch(contents.len)
|
|
if(0)
|
|
icon_state = "syndie_quiver_0"
|
|
if(1 to 7)
|
|
icon_state = "syndie_quiver_1"
|
|
if(8 to 13)
|
|
icon_state = "syndie_quiver_2"
|
|
if(14 to 20)
|
|
icon_state = "syndie_quiver_3"
|
|
|
|
/obj/item/storage/bag/quiver
|
|
name = "quiver"
|
|
desc = "Holds arrows for your bow. Good, because while pocketing arrows is possible, it surely can't be pleasant."
|
|
icon = 'icons/obj/weapons/bows/quivers.dmi'
|
|
icon_state = "quiver"
|
|
inhand_icon_state = null
|
|
worn_icon_state = "harpoon_quiver"
|
|
storage_type = /datum/storage/bag/quiver
|
|
|
|
/// type of arrow the quivel should hold
|
|
var/arrow_path = /obj/item/ammo_casing/arrow
|
|
|
|
/obj/item/storage/bag/quiver/lesser
|
|
storage_type = /datum/storage/bag/quiver/less
|
|
custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT)
|
|
|
|
/obj/item/storage/bag/quiver/full/PopulateContents()
|
|
. = ..()
|
|
for(var/i in 1 to 10)
|
|
new arrow_path(src)
|
|
|
|
/obj/item/storage/bag/quiver/holy
|
|
name = "divine quiver"
|
|
desc = "Holds arrows for your divine bow, where they wait to find their target."
|
|
icon_state = "holyquiver"
|
|
inhand_icon_state = "holyquiver"
|
|
worn_icon_state = "holyquiver"
|
|
arrow_path = /obj/item/ammo_casing/arrow/holy
|
|
|
|
/obj/item/storage/bag/quiver/holy/PopulateContents()
|
|
. = ..()
|
|
for(var/i in 1 to 10)
|
|
new arrow_path(src)
|
|
|
|
/obj/item/storage/bag/quiver/endless
|
|
name = "endless quiver"
|
|
desc = "Holds arrows for your bow. A deep digital void is contained within."
|
|
storage_type = /datum/storage/bag/quiver/endless
|
|
|
|
/obj/item/storage/bag/quiver/endless/PopulateContents()
|
|
. = ..()
|
|
new arrow_path(src)
|
|
|
|
#undef ORE_BAG_BALOON_COOLDOWN
|