Files
Bubberstation/code/modules/recycling/sortingmachinery.dm
2025-10-24 09:42:10 +02:00

408 lines
15 KiB
Plaintext

/obj/item/delivery
icon = 'icons/obj/storage/wrapping.dmi'
inhand_icon_state = "deliverypackage"
obj_flags = UNIQUE_RENAME | RENAME_NO_DESC
var/giftwrapped = 0
var/sort_tag = 0
var/obj/item/paper/note
var/obj/item/barcode/sticker
/obj/item/delivery/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_MOVABLE_DISPOSING, PROC_REF(disposal_handling))
/**
* Initial check if manually unwrapping
*/
/obj/item/delivery/proc/attempt_pre_unwrap_contents(mob/user, time = 1.5 SECONDS)
to_chat(user, span_notice("You start to unwrap the package..."))
return do_after(user, time, target = user)
/**
* Signals for unwrapping.
*/
/obj/item/delivery/proc/unwrap_contents()
if(!sticker)
return
for(var/atom/movable/movable_content as anything in contents)
SEND_SIGNAL(movable_content, COMSIG_ITEM_UNWRAPPED)
/**
* Effects after completing unwrapping
*/
/obj/item/delivery/proc/post_unwrap_contents(mob/user, rip_open = TRUE)
var/turf/turf_loc = get_turf(user || src)
if(rip_open)
playsound(loc, 'sound/items/poster/poster_ripped.ogg', 50, TRUE)
new /obj/effect/decal/cleanable/wrapping(turf_loc)
else
playsound(loc, 'sound/items/box_cut.ogg', 50, TRUE)
new /obj/item/stack/package_wrap(turf_loc)
for(var/atom/movable/movable_content as anything in contents)
movable_content.forceMove(turf_loc)
qdel(src)
/obj/item/delivery/contents_explosion(severity, target)
switch(severity)
if(EXPLODE_DEVASTATE)
SSexplosions.high_mov_atom += contents
if(EXPLODE_HEAVY)
SSexplosions.med_mov_atom += contents
if(EXPLODE_LIGHT)
SSexplosions.low_mov_atom += contents
/obj/item/delivery/atom_deconstruct(dissambled = TRUE)
unwrap_contents()
post_unwrap_contents()
/obj/item/delivery/examine(mob/user)
. = ..()
if(note)
if(!in_range(user, src))
. += span_info("There's a [EXAMINE_HINT(note.name)] attached to it. You can't read it from here.")
else
. += span_info("There's a [EXAMINE_HINT(note.name)] attached to it...")
. += note.examine(user)
if(sticker)
. += span_notice("There's a [EXAMINE_HINT("barcode")] attached to the side. The package is marked for [EXAMINE_HINT("export.")]")
if(sort_tag)
. += span_notice("There's a [EXAMINE_HINT("sorting tag")] with the destination set to [EXAMINE_HINT("[GLOB.TAGGERLOCATIONS[sort_tag]].")]")
/obj/item/delivery/proc/disposal_handling(disposal_source, obj/structure/disposalholder/disposal_holder, obj/machinery/disposal/disposal_machine, hasmob)
SIGNAL_HANDLER
if(!hasmob)
disposal_holder.destinationTag = sort_tag
/obj/item/delivery/relay_container_resist_act(mob/living/user, obj/container)
if(ismovable(loc))
var/atom/movable/movable_loc = loc //can't unwrap the wrapped container if it's inside something.
movable_loc.relay_container_resist_act(user, container)
return
to_chat(user, span_notice("You lean on the back of [container] and start pushing to rip the wrapping around it."))
if(do_after(user, 5 SECONDS, target = container))
if(!user || user.stat != CONSCIOUS || user.loc != container || container.loc != src)
return
to_chat(user, span_notice("You successfully removed [container]'s wrapping!"))
container.forceMove(loc)
unwrap_contents()
post_unwrap_contents(user)
else
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
to_chat(user, span_warning("You fail to remove [container]'s wrapping!"))
/obj/item/delivery/update_icon_state()
. = ..()
icon_state = giftwrapped ? "gift[base_icon_state]" : base_icon_state
/obj/item/delivery/update_overlays()
. = ..()
if(sort_tag)
. += "[base_icon_state]_sort"
if(note)
. += "[base_icon_state]_note"
if(sticker)
. += "[base_icon_state]_barcode"
/obj/item/delivery/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers)
if(istype(item, /obj/item/dest_tagger))
var/obj/item/dest_tagger/dest_tagger = item
if(sort_tag != dest_tagger.currTag)
var/tag = uppertext(GLOB.TAGGERLOCATIONS[dest_tagger.currTag])
to_chat(user, span_notice("*[tag]*"))
sort_tag = dest_tagger.currTag
playsound(loc, 'sound/machines/beep/twobeep_high.ogg', 100, TRUE)
update_appearance()
else if(istype(item, /obj/item/stack/wrapping_paper) && !giftwrapped)
var/obj/item/stack/wrapping_paper/wrapping_paper = item
if(wrapping_paper.use(3))
user.visible_message(span_notice("[user] wraps the package in festive paper!"))
giftwrapped = TRUE
greyscale_config = text2path("/datum/greyscale_config/gift[icon_state]")
set_greyscale(colors = wrapping_paper.greyscale_colors)
update_appearance()
else
to_chat(user, span_warning("You need more paper!"))
else if(istype(item, /obj/item/paper))
if(note)
to_chat(user, span_warning("This package already has a note attached!"))
return
if(!user.transferItemToLoc(item, src))
to_chat(user, span_warning("For some reason, you can't attach [item]!"))
return
user.visible_message(span_notice("[user] attaches [item] to [src]."), span_notice("You attach [item] to [src]."))
note = item
update_appearance()
else if(istype(item, /obj/item/universal_scanner))
var/obj/item/universal_scanner/sales_tagger = item
if(sales_tagger.scanning_mode != SCAN_SALES_TAG)
return
if(sticker)
to_chat(user, span_warning("This package already has a barcode attached!"))
return
if(!(sales_tagger.payments_acc))
to_chat(user, span_warning("Swipe an ID on [sales_tagger] first!"))
return
if(sales_tagger.paper_count <= 0)
to_chat(user, span_warning("[sales_tagger] is out of paper!"))
return
user.visible_message(span_notice("[user] attaches a barcode to [src]."), span_notice("You attach a barcode to [src]."))
sales_tagger.paper_count -= 1
sticker = new /obj/item/barcode(src)
sticker.payments_acc = sales_tagger.payments_acc //new tag gets the tagger's current account.
sticker.cut_multiplier = sales_tagger.cut_multiplier //same, but for the percentage taken.
for(var/obj/wrapped_item in get_all_contents())
if(HAS_TRAIT(wrapped_item, TRAIT_NO_BARCODES))
continue
wrapped_item.AddComponent(/datum/component/pricetag, sticker.payments_acc, sales_tagger.cut_multiplier)
update_appearance()
else if(istype(item, /obj/item/barcode))
var/obj/item/barcode/stickerA = item
if(sticker)
to_chat(user, span_warning("This package already has a barcode attached!"))
return
if(!(stickerA.payments_acc))
to_chat(user, span_warning("This barcode seems to be invalid. Guess it's trash now."))
return
if(!user.transferItemToLoc(item, src))
to_chat(user, span_warning("For some reason, you can't attach [item]!"))
return
sticker = stickerA
for(var/obj/wrapped_item in get_all_contents())
if(HAS_TRAIT(wrapped_item, TRAIT_NO_BARCODES))
continue
wrapped_item.AddComponent(/datum/component/pricetag, sticker.payments_acc, sticker.cut_multiplier)
update_appearance()
else if(istype(item, /obj/item/boxcutter))
var/obj/item/boxcutter/boxcutter_item = item
if(HAS_TRAIT(boxcutter_item, TRAIT_TRANSFORM_ACTIVE))
if(!attempt_pre_unwrap_contents(user, time = 0.5 SECONDS))
return
unwrap_contents()
balloon_alert(user, "cutting open package...")
post_unwrap_contents(user, rip_open = FALSE)
else
balloon_alert(user, "prime the boxcutter!")
else
return ..()
/obj/item/delivery/nameformat(input, user)
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
return "[name] ([input])" // This just repeatedly adds new labels, but i think that's intentional?
/**
* # Wrapped up crates and lockers - too big to carry.
*/
/obj/item/delivery/big
name = "large parcel"
desc = "A large delivery parcel."
icon_state = "deliverycloset"
density = TRUE
interaction_flags_item = 0 // Disable the ability to pick it up. Wow!
layer = BELOW_OBJ_LAYER
pass_flags_self = PASSSTRUCTURE
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND
w_class = WEIGHT_CLASS_GIGANTIC
/obj/item/delivery/big/interact(mob/user)
if(!attempt_pre_unwrap_contents(user))
return
unwrap_contents()
post_unwrap_contents()
/**
* # Wrapped up items small enough to carry.
*/
/obj/item/delivery/small
name = "parcel"
desc = "A brown paper delivery parcel."
icon_state = "deliverypackage3"
/obj/item/delivery/small/attack_self(mob/user)
if(!attempt_pre_unwrap_contents(user))
return
user.temporarilyRemoveItemFromInventory(src, TRUE)
unwrap_contents()
for(var/atom/movable/movable_content as anything in contents)
user.put_in_hands(movable_content)
post_unwrap_contents(user)
/obj/item/delivery/small/attack_self_tk(mob/user)
if(ismob(loc))
var/mob/M = loc
M.temporarilyRemoveItemFromInventory(src, TRUE)
for(var/atom/movable/movable_content as anything in contents)
M.put_in_hands(movable_content)
else
for(var/atom/movable/movable_content as anything in contents)
movable_content.forceMove(loc)
unwrap_contents()
post_unwrap_contents(user)
return ITEM_INTERACT_BLOCKING
/obj/item/dest_tagger
name = "destination tagger"
desc = "Used to set the destination of properly wrapped packages."
icon = 'icons/obj/devices/tool.dmi'
icon_state = "cargo tagger"
worn_icon_state = "cargotagger"
var/currTag = 0 //Destinations are stored in code\globalvars\lists\flavor_misc.dm
var/locked_destination = FALSE //if true, users can't open the destination tag window to prevent changing the tagger's current destination
w_class = WEIGHT_CLASS_TINY
inhand_icon_state = "electronic"
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
obj_flags = CONDUCTS_ELECTRICITY
slot_flags = ITEM_SLOT_BELT
sound_vary = TRUE
pickup_sound = SFX_GENERIC_DEVICE_PICKUP
drop_sound = SFX_GENERIC_DEVICE_DROP
/obj/item/dest_tagger/borg
name = "cyborg destination tagger"
desc = "Used to fool the disposal mail network into thinking that you're a harmless parcel. Does actually work as a regular destination tagger as well."
/obj/item/dest_tagger/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] begins tagging [user.p_their()] final destination! It looks like [user.p_theyre()] trying to commit suicide!"))
if (islizard(user))
to_chat(user, span_notice("*HELL*"))//lizard nerf
else
to_chat(user, span_notice("*HEAVEN*"))
playsound(src, 'sound/machines/beep/twobeep_high.ogg', 100, TRUE)
return BRUTELOSS
/** Standard TGUI actions */
/obj/item/dest_tagger/ui_interact(mob/user, datum/tgui/ui)
add_fingerprint(user)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "DestinationTagger", name)
ui.set_autoupdate(FALSE)
ui.open()
/** If the user dropped the tagger */
/obj/item/dest_tagger/ui_state(mob/user)
return GLOB.inventory_state
/** User activates in hand */
/obj/item/dest_tagger/attack_self(mob/user)
if(!locked_destination)
ui_interact(user)
return
/** Data sent to TGUI window */
/obj/item/dest_tagger/ui_data(mob/user)
var/list/data = list()
data["locations"] = GLOB.TAGGERLOCATIONS
data["currentTag"] = currTag
return data
/** User clicks a button on the tagger */
/obj/item/dest_tagger/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
switch(action)
if("change")
var/new_tag = round(text2num(params["index"]))
if(new_tag == currTag || new_tag < 1 || new_tag > length(GLOB.TAGGERLOCATIONS))
return
currTag = new_tag
return TRUE
/obj/item/sales_tagger
name = "sales tagger"
desc = "A scanner that lets you tag wrapped items for sale, splitting the profit between you and cargo."
icon = 'icons/obj/devices/scanner.dmi'
icon_state = "sales tagger"
worn_icon_state = "salestagger"
inhand_icon_state = "electronic"
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
slot_flags = ITEM_SLOT_BELT
///The account which is receiving the split profits.
var/datum/bank_account/payments_acc = null
var/paper_count = 10
var/max_paper_count = 20
///The person who tagged this will receive the sale value multiplied by this number.
var/cut_multiplier = 0.5
///Maximum value for cut_multiplier.
var/cut_max = 0.5
///Minimum value for cut_multiplier.
var/cut_min = 0.01
/obj/item/sales_tagger/examine(mob/user)
. = ..()
. += span_notice("[src] has [paper_count]/[max_paper_count] available barcodes. Refill with paper.")
. += span_notice("Profit split on sale is currently set to [round(cut_multiplier*100)]%. <b>Alt-click</b> to change.")
if(payments_acc)
. += span_notice("<b>Ctrl-click</b> to clear the registered account.")
/obj/item/sales_tagger/attackby(obj/item/item, mob/living/user, list/modifiers, list/attack_modifiers)
. = ..()
if(isidcard(item))
var/obj/item/card/id/potential_acc = item
if(potential_acc.registered_account)
if(payments_acc == potential_acc.registered_account)
to_chat(user, span_notice("ID card already registered."))
return
else
payments_acc = potential_acc.registered_account
playsound(src, 'sound/machines/ping.ogg', 40, TRUE)
to_chat(user, span_notice("[src] registers the ID card. Tag a wrapped item to create a barcode."))
else if(!potential_acc.registered_account)
to_chat(user, span_warning("This ID card has no account registered!"))
return
if(istype(item, /obj/item/paper))
if (!(paper_count >= max_paper_count))
paper_count += 10
qdel(item)
if (paper_count >= max_paper_count)
paper_count = max_paper_count
to_chat(user, span_notice("[src]'s paper supply is now full."))
return
to_chat(user, span_notice("You refill [src]'s paper supply, you have [paper_count] left."))
return
else
to_chat(user, span_notice("[src]'s paper supply is full."))
return
/obj/item/sales_tagger/attack_self(mob/user)
. = ..()
if(paper_count <= 0)
to_chat(user, span_warning("You're out of paper!'."))
return
if(!payments_acc)
to_chat(user, span_warning("You need to swipe [src] with an ID card first."))
return
paper_count -= 1
playsound(src, 'sound/machines/click.ogg', 40, TRUE)
to_chat(user, span_notice("You print a new barcode."))
var/obj/item/barcode/new_barcode = new /obj/item/barcode(src)
new_barcode.payments_acc = payments_acc // The sticker gets the scanner's registered account.
new_barcode.cut_multiplier = cut_multiplier // Also the registered percent cut.
user.put_in_hands(new_barcode)
/obj/item/sales_tagger/item_ctrl_click(mob/user)
payments_acc = null
to_chat(user, span_notice("You clear the registered account."))
return CLICK_ACTION_SUCCESS
/obj/item/sales_tagger/click_alt(mob/user)
var/potential_cut = input("How much would you like to pay out to the registered card?","Percentage Profit ([round(cut_min*100)]% - [round(cut_max*100)]%)") as num|null
if(!potential_cut)
cut_multiplier = initial(cut_multiplier)
cut_multiplier = clamp(round(potential_cut/100, cut_min), cut_min, cut_max)
to_chat(user, span_notice("[round(cut_multiplier*100)]% profit will be received if a package with a barcode is sold."))
return CLICK_ACTION_SUCCESS