mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-11 17:35:05 +00:00
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.
334 lines
10 KiB
Plaintext
334 lines
10 KiB
Plaintext
/obj/item/clothing/under
|
|
name = "under"
|
|
icon = 'icons/obj/clothing/under/default.dmi'
|
|
worn_icon = 'icons/mob/clothing/under/default.dmi'
|
|
body_parts_covered = CHEST|GROIN|LEGS|ARMS
|
|
permeability_coefficient = 0.9
|
|
slot_flags = ITEM_SLOT_ICLOTHING
|
|
armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5)
|
|
equip_sound = 'sound/items/equip/jumpsuit_equip.ogg'
|
|
drop_sound = 'sound/items/handling/cloth_drop.ogg'
|
|
pickup_sound = 'sound/items/handling/cloth_pickup.ogg'
|
|
limb_integrity = 30
|
|
var/fitted = FEMALE_UNIFORM_FULL // For use in alternate clothing styles for women
|
|
var/has_sensor = HAS_SENSORS // For the crew computer
|
|
var/random_sensor = TRUE
|
|
var/sensor_mode = NO_SENSORS
|
|
var/can_adjust = TRUE
|
|
var/adjusted = NORMAL_STYLE
|
|
var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only
|
|
var/obj/item/clothing/accessory/attached_accessory
|
|
var/mutable_appearance/accessory_overlay
|
|
var/mutantrace_variation = NO_MUTANTRACE_VARIATION //Are there special sprites for specific situations? Don't use this unless you need to.
|
|
var/freshly_laundered = FALSE
|
|
|
|
/obj/item/clothing/under/worn_overlays(mutable_appearance/standing, isinhands = FALSE)
|
|
. = ..()
|
|
if(isinhands)
|
|
return
|
|
|
|
if(damaged_clothes)
|
|
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
|
|
if(HAS_BLOOD_DNA(src))
|
|
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood")
|
|
if(accessory_overlay)
|
|
. += accessory_overlay
|
|
|
|
/obj/item/clothing/under/attackby(obj/item/I, mob/user, params)
|
|
if((has_sensor == BROKEN_SENSORS) && istype(I, /obj/item/stack/cable_coil))
|
|
var/obj/item/stack/cable_coil/C = I
|
|
C.use(1)
|
|
has_sensor = HAS_SENSORS
|
|
to_chat(user,span_notice("You repair the suit sensors on [src] with [C]."))
|
|
return 1
|
|
if(!attach_accessory(I, user))
|
|
return ..()
|
|
|
|
/obj/item/clothing/under/attack_hand_secondary(mob/user, params)
|
|
. = ..()
|
|
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
|
|
return
|
|
|
|
toggle()
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
|
|
/obj/item/clothing/under/update_clothes_damaged_state(damaged_state = CLOTHING_DAMAGED)
|
|
..()
|
|
if(ismob(loc))
|
|
var/mob/M = loc
|
|
M.update_inv_w_uniform()
|
|
if(damaged_state == CLOTHING_SHREDDED && has_sensor > NO_SENSORS)
|
|
has_sensor = BROKEN_SENSORS
|
|
else if(damaged_state == CLOTHING_PRISTINE && has_sensor == BROKEN_SENSORS)
|
|
has_sensor = HAS_SENSORS
|
|
|
|
/obj/item/clothing/under/Initialize()
|
|
. = ..()
|
|
if(random_sensor)
|
|
//make the sensor mode favor higher levels, except coords.
|
|
sensor_mode = pick(SENSOR_OFF, SENSOR_LIVING, SENSOR_LIVING, SENSOR_VITALS, SENSOR_VITALS, SENSOR_VITALS, SENSOR_COORDS, SENSOR_COORDS)
|
|
|
|
/obj/item/clothing/under/emp_act()
|
|
. = ..()
|
|
if(has_sensor > NO_SENSORS)
|
|
sensor_mode = pick(SENSOR_OFF, SENSOR_OFF, SENSOR_OFF, SENSOR_LIVING, SENSOR_LIVING, SENSOR_VITALS, SENSOR_VITALS, SENSOR_COORDS)
|
|
if(ismob(loc))
|
|
var/mob/M = loc
|
|
to_chat(M,span_warning("The sensors on the [src] change rapidly!"))
|
|
|
|
/obj/item/clothing/under/visual_equipped(mob/user, slot)
|
|
..()
|
|
if(adjusted)
|
|
adjusted = NORMAL_STYLE
|
|
fitted = initial(fitted)
|
|
if(!alt_covers_chest)
|
|
body_parts_covered |= CHEST
|
|
|
|
if(mutantrace_variation && ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
if(DIGITIGRADE in H.dna.species.species_traits)
|
|
adjusted = DIGITIGRADE_STYLE
|
|
H.update_inv_w_uniform()
|
|
|
|
if(attached_accessory && slot != ITEM_SLOT_HANDS && ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
attached_accessory.on_uniform_equip(src, user)
|
|
H.fan_hud_set_fandom()
|
|
if(attached_accessory.above_suit)
|
|
H.update_inv_wear_suit()
|
|
|
|
/obj/item/clothing/under/equipped(mob/user, slot)
|
|
..()
|
|
if(slot == ITEM_SLOT_ICLOTHING && freshly_laundered)
|
|
freshly_laundered = FALSE
|
|
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "fresh_laundry", /datum/mood_event/fresh_laundry)
|
|
|
|
/obj/item/clothing/under/dropped(mob/user)
|
|
if(attached_accessory)
|
|
attached_accessory.on_uniform_dropped(src, user)
|
|
if(ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
H.fan_hud_set_fandom()
|
|
if(attached_accessory.above_suit)
|
|
H.update_inv_wear_suit()
|
|
..()
|
|
|
|
/mob/living/carbon/human/update_suit_sensors()
|
|
. = ..()
|
|
update_sensor_list()
|
|
|
|
/mob/living/carbon/human/proc/update_sensor_list()
|
|
var/obj/item/clothing/under/U = w_uniform
|
|
if(istype(U) && U.has_sensor > 0 && U.sensor_mode)
|
|
GLOB.suit_sensors_list |= src
|
|
else
|
|
GLOB.suit_sensors_list -= src
|
|
|
|
/mob/living/carbon/human/dummy/update_sensor_list()
|
|
return
|
|
|
|
/obj/item/clothing/under/proc/attach_accessory(obj/item/tool, mob/user, notifyAttach = 1)
|
|
. = FALSE
|
|
if(!istype(tool, /obj/item/clothing/accessory))
|
|
return
|
|
var/obj/item/clothing/accessory/accessory = tool
|
|
if(attached_accessory)
|
|
if(user)
|
|
to_chat(user, span_warning("[src] already has an accessory."))
|
|
return
|
|
|
|
if(!accessory.can_attach_accessory(src, user)) //Make sure the suit has a place to put the accessory.
|
|
return
|
|
if(user && !user.temporarilyRemoveItemFromInventory(accessory))
|
|
return
|
|
if(!accessory.attach(src, user))
|
|
return
|
|
|
|
. = TRUE
|
|
if(user && notifyAttach)
|
|
to_chat(user, span_notice("You attach [accessory] to [src]."))
|
|
|
|
var/accessory_color = attached_accessory.icon_state
|
|
accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', "[accessory_color]")
|
|
accessory_overlay.alpha = attached_accessory.alpha
|
|
accessory_overlay.color = attached_accessory.color
|
|
|
|
update_appearance()
|
|
if(!ishuman(loc))
|
|
return
|
|
|
|
var/mob/living/carbon/human/holder = loc
|
|
holder.update_inv_w_uniform()
|
|
holder.update_inv_wear_suit()
|
|
holder.fan_hud_set_fandom()
|
|
|
|
/obj/item/clothing/under/proc/remove_accessory(mob/user)
|
|
. = FALSE
|
|
if(!isliving(user))
|
|
return
|
|
if(!can_use(user))
|
|
return
|
|
|
|
if(!attached_accessory)
|
|
return
|
|
|
|
. = TRUE
|
|
var/obj/item/clothing/accessory/accessory = attached_accessory
|
|
attached_accessory.detach(src, user)
|
|
if(user.put_in_hands(accessory))
|
|
to_chat(user, span_notice("You detach [accessory] from [src]."))
|
|
else
|
|
to_chat(user, span_notice("You detach [accessory] from [src] and it falls on the floor."))
|
|
|
|
update_appearance()
|
|
if(!ishuman(loc))
|
|
return
|
|
|
|
var/mob/living/carbon/human/holder = loc
|
|
holder.update_inv_w_uniform()
|
|
holder.update_inv_wear_suit()
|
|
holder.fan_hud_set_fandom()
|
|
|
|
|
|
/obj/item/clothing/under/examine(mob/user)
|
|
. = ..()
|
|
if(freshly_laundered)
|
|
. += "It looks fresh and clean."
|
|
if(can_adjust)
|
|
if(adjusted == ALT_STYLE)
|
|
. += "Alt-click on [src] to wear it normally."
|
|
else
|
|
. += "Alt-click on [src] to wear it casually."
|
|
if (has_sensor == BROKEN_SENSORS)
|
|
. += "Its sensors appear to be shorted out."
|
|
else if(has_sensor > NO_SENSORS)
|
|
switch(sensor_mode)
|
|
if(SENSOR_OFF)
|
|
. += "Its sensors appear to be disabled."
|
|
if(SENSOR_LIVING)
|
|
. += "Its binary life sensors appear to be enabled."
|
|
if(SENSOR_VITALS)
|
|
. += "Its vital tracker appears to be enabled."
|
|
if(SENSOR_COORDS)
|
|
. += "Its vital tracker and tracking beacon appear to be enabled."
|
|
if(attached_accessory)
|
|
. += "\A [attached_accessory] is attached to it."
|
|
|
|
/obj/item/clothing/under/verb/toggle()
|
|
set name = "Adjust Suit Sensors"
|
|
set category = "Object"
|
|
set src in usr
|
|
var/mob/M = usr
|
|
if (istype(M, /mob/dead/))
|
|
return
|
|
if (!can_use(M))
|
|
return
|
|
if(has_sensor == LOCKED_SENSORS)
|
|
to_chat(usr, "The controls are locked.")
|
|
return
|
|
if(has_sensor == BROKEN_SENSORS)
|
|
to_chat(usr, "The sensors have shorted out!")
|
|
return
|
|
if(has_sensor <= NO_SENSORS)
|
|
to_chat(usr, "This suit does not have any sensors.")
|
|
return
|
|
|
|
var/list/modes = list("Off", "Binary vitals", "Exact vitals", "Tracking beacon")
|
|
var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes
|
|
if(get_dist(usr, src) > 1)
|
|
to_chat(usr, span_warning("You have moved too far away!"))
|
|
return
|
|
sensor_mode = modes.Find(switchMode) - 1
|
|
if (loc == usr)
|
|
switch(sensor_mode)
|
|
if(0)
|
|
to_chat(usr, span_notice("You disable your suit's remote sensing equipment."))
|
|
if(1)
|
|
to_chat(usr, span_notice("Your suit will now only report whether you are alive or dead."))
|
|
if(2)
|
|
to_chat(usr, span_notice("Your suit will now only report your exact vital lifesigns."))
|
|
if(3)
|
|
to_chat(usr, span_notice("Your suit will now report your exact vital lifesigns as well as your coordinate position."))
|
|
|
|
if(ishuman(loc))
|
|
var/mob/living/carbon/human/H = loc
|
|
if(H.w_uniform == src)
|
|
H.update_suit_sensors()
|
|
|
|
/obj/item/clothing/under/AltClick(mob/user)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
if(!user.canUseTopic(src, BE_CLOSE, NO_DEXTERITY, FALSE, !iscyborg(user)))
|
|
return
|
|
if(attached_accessory)
|
|
remove_accessory(user)
|
|
else
|
|
rolldown()
|
|
|
|
/obj/item/clothing/under/verb/jumpsuit_adjust()
|
|
set name = "Adjust Jumpsuit Style"
|
|
set category = null
|
|
set src in usr
|
|
rolldown()
|
|
|
|
/obj/item/clothing/under/proc/rolldown()
|
|
if(!can_use(usr))
|
|
return
|
|
if(!can_adjust)
|
|
to_chat(usr, span_warning("You cannot wear this suit any differently!"))
|
|
return
|
|
if(toggle_jumpsuit_adjust())
|
|
to_chat(usr, span_notice("You adjust the suit to wear it more casually."))
|
|
else
|
|
to_chat(usr, span_notice("You adjust the suit back to normal."))
|
|
if(ishuman(usr))
|
|
var/mob/living/carbon/human/H = usr
|
|
H.update_inv_w_uniform()
|
|
H.update_body()
|
|
|
|
/obj/item/clothing/under/proc/toggle_jumpsuit_adjust()
|
|
if(adjusted == DIGITIGRADE_STYLE)
|
|
return
|
|
adjusted = !adjusted
|
|
if(adjusted)
|
|
if(fitted != FEMALE_UNIFORM_TOP)
|
|
fitted = NO_FEMALE_UNIFORM
|
|
if(!alt_covers_chest) // for the special snowflake suits that expose the chest when adjusted (and also the arms, realistically)
|
|
body_parts_covered &= ~CHEST
|
|
body_parts_covered &= ~ARMS
|
|
else
|
|
fitted = initial(fitted)
|
|
if(!alt_covers_chest)
|
|
body_parts_covered |= CHEST
|
|
body_parts_covered |= ARMS
|
|
if(!LAZYLEN(damage_by_parts))
|
|
return adjusted
|
|
for(var/zone in list(BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) // ugly check to make sure we don't reenable protection on a disabled part
|
|
if(damage_by_parts[zone] > limb_integrity)
|
|
for(var/part in zone2body_parts_covered(zone))
|
|
body_parts_covered &= part
|
|
return adjusted
|
|
|
|
/obj/item/clothing/under/rank
|
|
dying_key = DYE_REGISTRY_UNDER
|
|
|
|
/obj/item/clothing/under/proc/dump_attachment()
|
|
if(!attached_accessory)
|
|
return
|
|
var/atom/drop_location = drop_location()
|
|
attached_accessory.transform *= 2
|
|
attached_accessory.pixel_x -= 8
|
|
attached_accessory.pixel_y += 8
|
|
if(drop_location)
|
|
attached_accessory.forceMove(drop_location)
|
|
cut_overlays()
|
|
attached_accessory = null
|
|
accessory_overlay = null
|
|
update_appearance()
|
|
|
|
/obj/item/clothing/under/rank/obj_destruction(damage_flag)
|
|
dump_attachment()
|
|
return ..()
|