diff --git a/code/datums/components/storage/concrete/trading_cards.dm b/code/datums/components/storage/concrete/trading_cards.dm index 853b0666ab0..0a323736c0f 100644 --- a/code/datums/components/storage/concrete/trading_cards.dm +++ b/code/datums/components/storage/concrete/trading_cards.dm @@ -12,12 +12,6 @@ . = ..() set_holdable(list(/obj/item/tcgcard)) -/datum/component/storage/concrete/tcg/can_be_inserted(obj/item/I, stop_messages, mob/M) - if(istype(I, /obj/item/tcgcard)) - var/obj/item/tcgcard/nu_card = I - nu_card.zoom_out() - return ..() - /datum/component/storage/concrete/tcg/PostTransfer() . = ..() handle_empty_deck() @@ -39,13 +33,6 @@ card_contents = shuffle(card_contents) /datum/component/storage/concrete/tcg/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found) - for(var/item in 1 to things.len) - if(istype(things[item], /obj/item/tcgcard)) - var/obj/item/tcgcard/card = things[item] - if(isturf(target)) - card.zoom_out() - else - card.zoom_in() . = ..() if(!things.len) qdel(parent) @@ -53,14 +40,10 @@ /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) + if(contents.len == 1) var/obj/item/tcgcard_deck/deck = parent var/obj/item/tcgcard/card = contents[1] - card.forceMove(card.drop_location()) + remove_from_storage(card, card.drop_location()) card.flipped = deck.flipped card.update_icon_state() - if(isturf(card.drop_location())) - card.zoom_out() - else - card.zoom_in() qdel(parent) diff --git a/code/datums/elements/item_scaling.dm b/code/datums/elements/item_scaling.dm new file mode 100644 index 00000000000..4c9fc21e32e --- /dev/null +++ b/code/datums/elements/item_scaling.dm @@ -0,0 +1,101 @@ +/** + * Element for scaling item appearances in the overworld or in inventory/storage. + * + * This bespoke element allows for items to have varying sizes depending on their location. + * The overworld simply refers to items being on a turf. Inventory includes HUD item slots, + * and storage is anywhere a storage component is used. + * Scaling should affect the item's icon and all attached overlays (such as blood decals). + * + */ +/datum/element/item_scaling + element_flags = ELEMENT_BESPOKE + id_arg_index = 2 + /// Scaling value when the attached item is in the overworld (on a turf). + var/overworld_scaling + /// Scaling value when the attached item is in a storage component or inventory slot. + var/storage_scaling + +/** + * Attach proc for the item_scaling element + * + * The proc checks the target's type before attaching. It then initializes + * the target to overworld scaling. The target should then rescale if it is placed + * in inventory/storage on initialization. Relevant signals are registered to listen + * for pickup/drop or storage events. Scaling values of 1 will result in items + * returning to their original size. + * Arguments: + * * target - Datum to attach the element to. + * * overworld_scaling - Integer or float to scale the item in the overworld. + * * storage_scaling - Integer or float to scale the item in storage/inventory. + */ +/datum/element/item_scaling/Attach(datum/target, overworld_scaling, storage_scaling) + . = ..() + if(!isatom(target)) + return ELEMENT_INCOMPATIBLE + // Initial scaling set to overworld_scaling when item is spawned. + scale(target, overworld_scaling) + + src.overworld_scaling = overworld_scaling + src.storage_scaling = storage_scaling + + // 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 placed in an inventory slot OR when entering a storage component. + RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_STORAGE_ENTERED), .proc/scale_storage) + +/** + * Detach proc for the item_scaling element. + * + * All registered signals are unregistered, and the attached element is removed from the target datum. + * Arguments: + * * target - Datum which the element is attached to. + */ +/datum/element/item_scaling/Detach(datum/target) + UnregisterSignal(target, list( + COMSIG_ITEM_PICKUP, + COMSIG_ITEM_DROPPED, + COMSIG_STORAGE_ENTERED, + COMSIG_STORAGE_EXITED, + )) + return ..() + +/** + * Scales the attached item's matrix. + * + * The proc first narrows the type of the source to (datums do not have a transform matrix). + * It then creates an identity matrix, M, which is transformed by the scaling value. + * The object's transform variable (matrix) is then set to the resulting value of M. + * Arguments: + * * source - Source datum which sent the signal. + * * scaling - Integer or float to scale the item's matrix. + */ +/datum/element/item_scaling/proc/scale(datum/source, scaling) + var/atom/scalable_object = source + var/matrix/M = matrix() + scalable_object.transform = M.Scale(scaling) + +/** + * Signal handler for COMSIG_ITEM_DROPPED or COMSIG_STORAGE_EXITED + * + * Longer detailed paragraph about the proc + * including any relevant detail + * Arguments: + * * source - Source datum which sent the signal. + */ +/datum/element/item_scaling/proc/scale_overworld(datum/source) + SIGNAL_HANDLER + + scale(source, overworld_scaling) + +/** + * Signal handler for COMSIG_ITEM_EQUIPPED or COMSIG_STORAGE_ENTERED. + * + * Longer detailed paragraph about the proc + * including any relevant detail + * Arguments: + * * source - Source datum which sent the signal. + */ +/datum/element/item_scaling/proc/scale_storage(datum/source) + SIGNAL_HANDLER + + scale(source, storage_scaling) diff --git a/code/game/objects/items/tcg/tcg.dm b/code/game/objects/items/tcg/tcg.dm index 292e6cd1ee5..ecb969a87c7 100644 --- a/code/game/objects/items/tcg/tcg.dm +++ b/code/game/objects/items/tcg/tcg.dm @@ -26,9 +26,7 @@ GLOBAL_LIST_EMPTY(cached_cards) /obj/item/tcgcard/Initialize(mapload, datum_series, datum_id) . = ..() - zoom_out() - RegisterSignal(src, COMSIG_STORAGE_ENTERED, .proc/zoom_in) - RegisterSignal(src, COMSIG_STORAGE_EXITED, .proc/zoom_out) + AddElement(/datum/element/item_scaling, 0.3, 1) //If they are passed as null let's replace them with the vars on the card. this also means we can allow for map loaded ccards if(!datum_series) datum_series = series @@ -102,14 +100,6 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) . = ..() flip_card(user) -/obj/item/tcgcard/equipped(mob/user, slot, initial) - . = ..() - zoom_in() - -/obj/item/tcgcard/dropped(mob/user, silent) - . = ..() - zoom_out() - /obj/item/tcgcard/update_icon_state() . = ..() if(!flipped) @@ -129,9 +119,7 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) var/obj/item/tcgcard_deck/new_deck = new /obj/item/tcgcard_deck(drop_location()) new_deck.flipped = flipped user.transferItemToLoc(second_card, new_deck)//Start a new pile with both cards, in the order of card placement. - second_card.zoom_in() user.transferItemToLoc(src, new_deck) - zoom_in() new_deck.update_icon_state() user.put_in_hands(new_deck) if(istype(I, /obj/item/tcgcard_deck)) @@ -141,7 +129,6 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) return user.transferItemToLoc(src, old_deck) flipped = old_deck.flipped - zoom_in() old_deck.update_icon() update_icon() return ..() @@ -162,18 +149,6 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) tapped = !tapped animate(src, transform = ntransform, time = 2, easing = (EASE_IN|EASE_OUT)) -/** - * Transforms the card's sprite to look like a small, paper card. Use when outside of inventory - */ -/obj/item/tcgcard/proc/zoom_in() - transform = matrix() - -/** - * Transforms the card's sprite to look like a large, detailed, illustrated paper card. Use when inside of inventory/storage. - */ -/obj/item/tcgcard/proc/zoom_out() - transform = matrix(0.3,0,0,0,0.3,0) - /obj/item/tcgcard/proc/flip_card(mob/user) to_chat(user, "You turn the card over.") if(!flipped) @@ -249,7 +224,6 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) for(var/card in 1 to contents.len) var/obj/item/tcgcard/stored_card = contents[card] stored_card.forceMove(drop_location()) - stored_card.zoom_out() . = ..() /obj/item/tcgcard_deck/proc/check_menu(mob/living/user) @@ -268,7 +242,6 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) var/obj/item/tcgcard/new_card = I new_card.flipped = flipped new_card.forceMove(src) - new_card.zoom_in() /obj/item/tcgcard_deck/attack_self(mob/living/carbon/user) @@ -290,7 +263,6 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) if(contents.len <= 1) var/obj/item/tcgcard/final_card = contents[1] user.transferItemToLoc(final_card, drop_location()) - final_card.zoom_out() qdel(src) @@ -320,7 +292,6 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) //Now flip the cards to their opposite positions. for(var/a in 1 to contents.len) var/obj/item/tcgcard/nu_card = contents[a] - nu_card.zoom_in() nu_card.flipped = flipped nu_card.update_icon_state() update_icon_state() @@ -377,9 +348,7 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) /obj/item/cardpack/Initialize() . = ..() - zoom_out() - RegisterSignal(src, COMSIG_STORAGE_ENTERED, .proc/zoom_in) - RegisterSignal(src, COMSIG_STORAGE_EXITED, .proc/zoom_out) + AddElement(/datum/element/item_scaling, 0.4, 1) //Pass by refrance moment //This lets us only have one rarity table per pack, badmins beware if(GLOB.cached_rarity_table[type]) @@ -391,20 +360,6 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) else GLOB.cached_guar_rarity[type] = guar_rarity -/obj/item/cardpack/equipped(mob/user, slot, initial) - . = ..() - zoom_in() - -/obj/item/cardpack/dropped(mob/user, silent) - . = ..() - zoom_out() - -/obj/item/cardpack/proc/zoom_in() - transform = matrix() - -/obj/item/cardpack/proc/zoom_out() - transform = matrix(0.4,0,0,0,0.4,0) - /obj/item/cardpack/attack_self(mob/user) . = ..() var/list/cards = buildCardListWithRarity(card_count, guaranteed_count) @@ -430,15 +385,7 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) /obj/item/coin/thunderdome/Initialize() . = ..() - transform = matrix(0.4,0,0,0,0.4,0) - -/obj/item/coin/thunderdome/equipped(mob/user, slot, initial) - . = ..() - transform = matrix() - -/obj/item/coin/thunderdome/dropped(mob/user, silent) - . = ..() - transform = matrix(0.4,0,0,0,0.4,0) + AddElement(/datum/element/item_scaling, 0.4, 1) /obj/item/storage/card_binder name = "card binder" diff --git a/tgstation.dme b/tgstation.dme index da9e878b0d4..f68d7b63036 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -621,6 +621,7 @@ #include "code\datums\elements\empprotection.dm" #include "code\datums\elements\firestacker.dm" #include "code\datums\elements\forced_gravity.dm" +#include "code\datums\elements\item_scaling.dm" #include "code\datums\elements\light_blocking.dm" #include "code\datums\elements\movetype_handler.dm" #include "code\datums\elements\obj_regen.dm"