Files
Bubberstation/code/game/objects/items/stacks/wrap.dm
SkyratBot 665fe76566 [MIRROR] Modifies right click logic so that it is not the same priority as modifier keys. (#6498)
* Modifies right click logic so that it is not the same priority as modifier keys. (#59656)

Strips out the existing right click code - Due to the myriad of ways right clicking has been implemented, dedicated signals and procs for right clicking without modifiers are fundamentally incompatible with our system of primary and secondary attacks.

Adds additional signals to attacking code. These signals allow atoms to cancel the attack chain early on secondary attacks, or override the standard procs and not send signals to prevent any undesired behaviour from signal handlers.

Items that used RightClick procs have been converted to attack_hand_secondary.

The slaughter demon, having its own set of snowflake code as poor OOP principles have been applied in UnarmedAttack() procs with lacking calls to parent procs and arbitrary redefinition of behaviour, checks for a right click in its own UnarmedAttack() and performs a bodyslam off that.

Storage components now hijack the secondary attackby stage via signals to handle their opening and closing shortcuts on right click. When you right click a storage component equipped item with an object in your active hand, the object has an opportunity to perform its logic in pre secondary attack code and cancel the attack chain. If it does not cancel the attack chain in pre-attack, then the storage component takes over for attackby and, if possible, opens the relevant inventory and ends the attack chain.

The forensic scanner is a proof-of-concept of this working in action. With its scan logic moved from afterattack code to pre attack code for right clicking, right clicking with the scanner will now perform a scan where previously one was impossible. Left clicking still does what it always does - Scans at the very end of the attack chain.

The logic still isn't perfect - For example, you still can't attack containers in melee even in combat mode (you'll either open them or put your weapon into them regardless of which option you choose) - But this is a better setup overall which allows for items to at least override this behaviour in pre-attack if needed.

* Modifies right click logic so that it is not the same priority as modifier keys.

* a

Co-authored-by: Timberpoes <silent_insomnia_pp@hotmail.co.uk>
Co-authored-by: Gandalf <jzo123@hotmail.com>
2021-06-27 16:10:15 +01:00

176 lines
5.1 KiB
Plaintext

/*
* Wrapping Paper
*/
/obj/item/stack/wrapping_paper
name = "wrapping paper"
desc = "Wrap packages with this festive paper to make gifts."
icon = 'icons/obj/stack_objects.dmi'
icon_state = "wrap_paper"
greyscale_config = /datum/greyscale_config/wrap_paper
item_flags = NOBLUDGEON
amount = 25
max_amount = 25
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/wrapping_paper
/obj/item/stack/wrapping_paper/Initialize()
. = ..()
if(!greyscale_colors)
//Generate random valid colors for paper and ribbon
var/generated_base_color = "#" + random_color()
var/generated_ribbon_color = "#" + random_color()
var/temp_base_hsv = RGBtoHSV(generated_base_color)
var/temp_ribbon_hsv = RGBtoHSV(generated_ribbon_color)
//If colors are too dark, set to original colors
if(ReadHSV(temp_base_hsv)[3] < ReadHSV("7F7F7F")[3])
generated_base_color = "#00FF00"
if(ReadHSV(temp_ribbon_hsv)[3] < ReadHSV("7F7F7F")[3])
generated_ribbon_color = "#FF0000"
//Set layers to these colors, base then ribbon
set_greyscale(colors = list(generated_base_color, generated_ribbon_color))
/obj/item/stack/wrapping_paper/attack_hand_secondary(mob/user, modifiers)
var/new_base = input(user, "", "Select a base color", color) as color
var/new_ribbon = input(user, "", "Select a ribbon color", color) as color
if(!user.canUseTopic(src, BE_CLOSE))
return
set_greyscale(colors = list(new_base, new_ribbon))
return TRUE
//preset wrapping paper meant to fill the original color configuration
/obj/item/stack/wrapping_paper/xmas
greyscale_colors = "#00FF00#FF0000"
/obj/item/stack/wrapping_paper/use(used, transfer)
var/turf/T = get_turf(src)
. = ..()
if(QDELETED(src) && !transfer)
new /obj/item/c_tube(T)
/obj/item/stack/wrapping_paper/small
desc = "Wrap packages with this festive paper to make gifts. This roll looks a bit skimpy."
amount = 10
merge_type = /obj/item/stack/wrapping_paper/small
/*
* Package Wrap
*/
/obj/item/stack/package_wrap
name = "package wrapper"
singular_name = "wrapping sheet"
desc = "You can use this to wrap items in."
icon = 'icons/obj/stack_objects.dmi'
icon_state = "deliveryPaper"
item_flags = NOBLUDGEON
amount = 25
max_amount = 25
resistance_flags = FLAMMABLE
grind_results = list(/datum/reagent/cellulose = 5)
merge_type = /obj/item/stack/package_wrap
/obj/item/stack/package_wrap/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] begins wrapping [user.p_them()]self in \the [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
if(use(3))
var/obj/structure/big_delivery/P = new /obj/structure/big_delivery(get_turf(user.loc))
P.icon_state = "deliverypackage5"
user.forceMove(P)
P.add_fingerprint(user)
return OXYLOSS
else
to_chat(user, span_warning("You need more paper!"))
return SHAME
/obj/item/proc/can_be_package_wrapped() //can the item be wrapped with package wrapper into a delivery package
return TRUE
/obj/item/storage/can_be_package_wrapped()
return FALSE
/obj/item/storage/box/can_be_package_wrapped()
return TRUE
/obj/item/small_delivery/can_be_package_wrapped()
return FALSE
/obj/item/stack/package_wrap/afterattack(obj/target, mob/user, proximity)
. = ..()
if(!proximity)
return
if(!istype(target))
return
if(target.anchored)
return
if(isitem(target))
var/obj/item/I = target
if(!I.can_be_package_wrapped())
return
if(user.is_holding(I))
if(!user.dropItemToGround(I))
return
else if(!isturf(I.loc))
return
if(use(1))
var/obj/item/small_delivery/P = new /obj/item/small_delivery(get_turf(I.loc))
if(user.Adjacent(I))
P.add_fingerprint(user)
I.add_fingerprint(user)
user.put_in_hands(P)
I.forceMove(P)
var/size = round(I.w_class)
P.name = "[weightclass2text(size)] parcel"
P.w_class = size
size = min(size, 5)
P.icon_state = "deliverypackage[size]"
else if(istype (target, /obj/structure/closet))
var/obj/structure/closet/O = target
if(O.opened)
return
if(!O.delivery_icon) //no delivery icon means unwrappable closet (e.g. body bags)
to_chat(user, span_warning("You can't wrap this!"))
return
if(use(3))
var/obj/structure/big_delivery/P = new /obj/structure/big_delivery(get_turf(O.loc))
P.icon_state = O.delivery_icon
O.forceMove(P)
P.add_fingerprint(user)
O.add_fingerprint(user)
else
to_chat(user, span_warning("You need more paper!"))
return
else
to_chat(user, span_warning("The object you are trying to wrap is unsuitable for the sorting machinery!"))
return
user.visible_message(span_notice("[user] wraps [target]."))
user.log_message("has used [name] on [key_name(target)]", LOG_ATTACK, color="blue")
/obj/item/stack/package_wrap/use(used, transfer = FALSE)
var/turf/T = get_turf(src)
. = ..()
if(QDELETED(src) && !transfer)
new /obj/item/c_tube(T)
/obj/item/stack/package_wrap/small
desc = "You can use this to wrap items in. This roll looks a bit skimpy."
w_class = WEIGHT_CLASS_SMALL
amount = 5
merge_type = /obj/item/stack/package_wrap/small
/obj/item/c_tube
name = "cardboard tube"
desc = "A tube... of cardboard."
icon = 'icons/obj/stack_objects.dmi'
icon_state = "c_tube"
throwforce = 0
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 5