From 8d5d194a263d214e8ee8b709e6fb5476f811ca18 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 11 Jul 2020 00:30:56 -0700 Subject: [PATCH 1/7] hahahahaha --- code/__DEFINES/misc.dm | 5 + code/_onclick/hud/alert.dm | 17 ++ .../mood_events/generic_negative_events.dm | 10 ++ code/modules/clothing/shoes/_shoes.dm | 166 ++++++++++++++++++ code/modules/clothing/shoes/miscellaneous.dm | 14 ++ .../mob/living/carbon/carbon_defines.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 12 +- icons/mob/screen_alert.dmi | Bin 108227 -> 108534 bytes 8 files changed, 224 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 2ec21c83b3..dc0fd9dba8 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -534,3 +534,8 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S #define LOOT_RESTRICTION_CKEY 2 #define LOOT_RESTRICTION_MIND_PILE 3 //limited to the current pile. #define LOOT_RESTRICTION_CKEY_PILE 4 //Idem + +//stages of shoe tying-ness +#define SHOES_UNTIED 0 +#define SHOES_TIED 1 +#define SHOES_KNOTTED 2 diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 11531a701e..f465705569 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -612,6 +612,23 @@ so as to remain in compliance with the most up-to-date laws." if(L.last_special <= world.time) return L.resist_buckle() +/obj/screen/alert/shoes/untied + name = "Untied Shoes" + desc = "Your shoes are untied! Click the alert or your shoes to tie them." + icon_state = "shoealert" + +/obj/screen/alert/shoes/knotted + name = "Knotted Shoes" + desc = "Someone tied your shoelaces together! Click the alert or your shoes to undo the knot." + icon_state = "shoealert" + +/obj/screen/alert/shoes/Click() + var/mob/living/carbon/C = usr + if(!istype(C) || !C.can_resist() || C != owner || !C.shoes) + return + C.changeNext_move(CLICK_CD_RESIST) + C.shoes.handle_tying(C) + // PRIVATE = only edit, use, or override these if you're editing the system as a whole // Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index f5692c297a..73d59aa0de 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -270,3 +270,13 @@ description = "I've produced better art than that from my ass.\n" mood_change = -2 timeout = 1200 + +/datum/mood_event/tripped + description = "I can't believe I fell for the oldest trick in the book!\n" + mood_change = -6 + timeout = 2 MINUTES + +/datum/mood_event/untied + description = "I hate when my shoes come untied!\n" + mood_change = -3 + timeout = 1 MINUTES diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 447a531717..7eb5fab312 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -20,6 +20,15 @@ var/last_blood_DNA = "" //same as last one var/last_blood_color = "" + ///Whether these shoes have laces that can be tied/untied + var/can_be_tied = TRUE + ///Are we currently tied? Can either be SHOES_UNTIED, SHOES_TIED, or SHOES_KNOTTED + var/tied = SHOES_TIED + ///How long it takes to lace/unlace these shoes + var/lace_time = 5 SECONDS + ///any alerts we have active + var/obj/screen/alert/our_alert + /obj/item/clothing/shoes/ComponentInitialize() . = ..() RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood) @@ -43,6 +52,15 @@ playsound(user, 'sound/weapons/genhit2.ogg', 50, 1) return(BRUTELOSS) +/obj/item/clothing/shoes/examine(mob/user) + . = ..() + + if(!ishuman(loc)) + return ..() + if(tied == SHOES_UNTIED) + . += "The shoelaces are untied." + else if(tied == SHOES_KNOTTED) + . += "The shoelaces are all knotted together." /obj/item/clothing/shoes/transfer_blood_dna(list/blood_dna, diseases) ..() @@ -74,6 +92,9 @@ worn_y_dimension -= (offset * 2) user.update_inv_shoes() equipped_before_drop = TRUE + if(can_be_tied && tied == SHOES_UNTIED) + our_alert = user.throw_alert("shoealert", /obj/screen/alert/shoes/untied) + RegisterSignal(src, COMSIG_SHOES_STEP_ACTION, .proc/check_trip, override=TRUE) /obj/item/clothing/shoes/proc/restore_offsets(mob/user) equipped_before_drop = FALSE @@ -81,6 +102,8 @@ worn_y_dimension = world.icon_size /obj/item/clothing/shoes/dropped(mob/user) + if(our_alert && our_alert.owner == user) + user.clear_alert("shoealert") if(offset && equipped_before_drop) restore_offsets(user) . = ..() @@ -101,3 +124,146 @@ /obj/item/proc/negates_gravity() return FALSE + +/** + * adjust_laces adjusts whether our shoes (assuming they can_be_tied) and tied, untied, or knotted + * + * In addition to setting the state, it will deal with getting rid of alerts if they exist, as well as registering and unregistering the stepping signals + * + * Arguments: + * * + * * state: SHOES_UNTIED, SHOES_TIED, or SHOES_KNOTTED, depending on what you want them to become + * * user: used to check to see if we're the ones unknotting our own laces + */ +/obj/item/clothing/shoes/proc/adjust_laces(state, mob/user) + if(!can_be_tied) + return + + var/mob/living/carbon/human/our_guy + if(ishuman(loc)) + our_guy = loc + + tied = state + if(tied == SHOES_TIED) + if(our_guy) + our_guy.clear_alert("shoealert") + UnregisterSignal(src, COMSIG_SHOES_STEP_ACTION) + else + if(tied == SHOES_UNTIED && our_guy && user == our_guy) + our_alert = our_guy.throw_alert("shoealert", /obj/screen/alert/shoes/untied) // if we're the ones unknotting our own laces, of course we know they're untied + RegisterSignal(src, COMSIG_SHOES_STEP_ACTION, .proc/check_trip, override=TRUE) + +/** + * handle_tying deals with all the actual tying/untying/knotting, inferring your intent from who you are in relation to the state of the laces + * + * If you're the wearer, you want them to move towards tied-ness (knotted -> untied -> tied). If you're not, you're pranking them, so you're moving towards knotted-ness (tied -> untied -> knotted) + * + * Arguments: + * * + * * user: who is the person interacting with the shoes? + */ +/obj/item/clothing/shoes/proc/handle_tying(mob/living/carbon/human/user) + ///our_guy here is the wearer, if one exists (and he must exist, or we don't care) + var/mob/living/carbon/human/our_guy = loc + if(!istype(our_guy)) + return + + if(user == loc && tied != SHOES_TIED) // if they're our own shoes, go tie-wards + user.visible_message("[user] begins [tied ? "unknotting" : "tying"] the laces of [user.p_their()] [src.name].", "You begin [tied ? "unknotting" : "tying"] the laces of your [src.name]...") + + if(do_after(user, lace_time, needhand=TRUE, target=src)) + to_chat(user, "You [tied ? "unknot" : "tie"] the laces of your [src.name].") + if(tied == SHOES_UNTIED) + adjust_laces(SHOES_TIED, user) + else + adjust_laces(SHOES_UNTIED, user) + + else // if they're someone else's shoes, go knot-wards + if(user.mobility_flags & MOBILITY_STAND) + to_chat(user, "You must be on the floor to interact with [src]!") + return + if(tied == SHOES_KNOTTED) + to_chat(user, "The laces on [loc]'s [src.name] are already a hopelessly tangled mess!") + return + + var/mod_time = lace_time + to_chat(user, "You quietly set to work [tied ? "untying" : "knotting"] [loc]'s [src.name]...") + if(HAS_TRAIT(user, TRAIT_CLUMSY)) // based clowns trained their whole lives for this + mod_time *= 0.75 + + if(do_after(user, mod_time, needhand=TRUE, target=src)) + to_chat(user, "You [tied ? "untie" : "knot"] the laces on [loc]'s [src.name].") + if(tied == SHOES_UNTIED) + adjust_laces(SHOES_KNOTTED, user) + else + adjust_laces(SHOES_UNTIED, user) + else // if one of us moved + user.visible_message("[our_guy] stamps on [user]'s hand, mid-shoelace [tied ? "knotting" : "untying"]!", "Ow! [our_guy] stamps on your hand!", user) + to_chat(our_guy, "You stamp on [user]'s hand! What the- they were [tied ? "knotting" : "untying"] your shoelaces!") + user.emote("scream") + var/obj/item/bodypart/ouchie = user.get_bodypart(pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + if(ouchie) + ouchie.receive_damage(15) + user.Paralyze(5) + +/** + * check_trip runs on each step to see if we fall over as a result of our lace status. Knotted laces are a guaranteed trip, while untied shoes are just a chance to stumble + */ +/obj/item/clothing/shoes/proc/check_trip() + var/mob/living/carbon/human/our_guy = loc + if(!istype(our_guy)) // are they REALLY /our guy/? + return + + if(tied == SHOES_KNOTTED) + our_guy.Paralyze(5) + our_guy.Knockdown(10) + our_guy.visible_message("[our_guy] trips on [our_guy.p_their()] knotted shoelaces and falls! What a klutz!", "You trip on your knotted shoelaces and fall over!") + SEND_SIGNAL(our_guy, COMSIG_ADD_MOOD_EVENT, "trip", /datum/mood_event/tripped) // well we realized they're knotted now! + our_alert = our_guy.throw_alert("shoealert", /obj/screen/alert/shoes/knotted) + else if(tied == SHOES_UNTIED) + var/wiser = TRUE // did we stumble and realize our laces are undone? + switch(rand(1, 1000)) + if(1) // .1% chance to trip and fall over (note these are per step while our laces are undone) + our_guy.Paralyze(5) + our_guy.Knockdown(10) + our_guy.visible_message("[our_guy] trips on [our_guy.p_their()] untied shoelaces and falls! What a klutz!", "You trip on your untied shoelaces and fall over!") + if(2 to 5) // .4% chance to stumble and lurch forward + our_guy.throw_at(get_step(our_guy, our_guy.dir), 3, 2) + to_chat(our_guy, "You stumble on your untied shoelaces and lurch forward!") + if(6 to 13) // .7% chance to stumble and fling what we're holding + var/have_anything = FALSE + for(var/obj/item/I in our_guy.held_items) + have_anything = TRUE + our_guy.accident(I) + to_chat(our_guy, "You trip on your shoelaces a bit[have_anything ? ", flinging what you were holding" : ""]!") + if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed) + to_chat(our_guy, "You stumble a bit on your untied shoelaces!") + if(!our_guy.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) + our_guy.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) + addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) + if(26 to 1000) + wiser = FALSE + + if(wiser) + SEND_SIGNAL(our_guy, COMSIG_ADD_MOOD_EVENT, "untied", /datum/mood_event/untied) // well we realized they're untied now! + our_alert = our_guy.throw_alert("shoealert", /obj/screen/alert/shoes/untied) + + +/obj/item/clothing/shoes/attack_hand(mob/living/carbon/human/user) + if(!istype(user)) + return ..() + if(loc == user && tied != SHOES_TIED) + handle_tying(user) + return + ..() + +/obj/item/clothing/shoes/attack_self(mob/user) + . = ..() + + to_chat(user, "You begin [tied ? "untying" : "tying"] the laces on [src]...") + if(do_after(user, lace_time, needhand=TRUE, target=src)) + to_chat(user, "You [tied ? "untie" : "tie"] the laces on [src].") + if(tied == SHOES_UNTIED) + adjust_laces(SHOES_TIED, user) + else + adjust_laces(SHOES_UNTIED, user) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index b68bef6329..bc71214e03 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -17,6 +17,7 @@ resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_delay = 12 SECONDS /obj/item/clothing/shoes/combat/sneakboots name = "insidious sneakboots" @@ -49,6 +50,7 @@ strip_delay = 50 equip_delay_other = 50 permeability_coefficient = 0.9 + can_be_tied = FALSE /obj/item/clothing/shoes/sandal/marisa desc = "A pair of magic black shoes." @@ -73,6 +75,7 @@ resistance_flags = NONE armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 75) custom_price = PRICE_ABOVE_EXPENSIVE + can_be_tied = FALSE /obj/item/clothing/shoes/galoshes/dry name = "absorbent galoshes" @@ -99,6 +102,7 @@ icon_state = "clown_shoes" slowdown = SHOES_SLOWDOWN+1 pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes/clown + lace_time = 20 SECONDS // how the hell do these laces even work?? /obj/item/clothing/shoes/clown_shoes/Initialize() . = ..() @@ -130,6 +134,7 @@ resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 12 SECONDS /obj/item/clothing/shoes/jackboots/fast slowdown = -1 @@ -144,6 +149,7 @@ heat_protection = FEET|LEGS max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 8 SECONDS /obj/item/clothing/shoes/winterboots/ice_boots name = "ice hiking boots" @@ -177,6 +183,7 @@ strip_delay = 40 equip_delay_other = 40 pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 8 SECONDS /obj/item/clothing/shoes/workboots/mining name = "mining boots" @@ -196,6 +203,7 @@ min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT + lace_time = 10 SECONDS /obj/item/clothing/shoes/cult/alt name = "cultist boots" @@ -226,12 +234,14 @@ strip_delay = 100 equip_delay_other = 100 permeability_coefficient = 0.9 + can_be_tied = FALSE /obj/item/clothing/shoes/griffin name = "griffon boots" desc = "A pair of costume boots fashioned after bird talons." icon_state = "griffinboots" pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 8 SECONDS /obj/item/clothing/shoes/bhop name = "jump boots" @@ -284,6 +294,7 @@ desc = "A giant, clunky pair of shoes crudely made out of bronze. Why would anyone wear these?" icon = 'icons/obj/clothing/clockwork_garb.dmi' icon_state = "clockwork_treads" + lace_time = 8 SECONDS /obj/item/clothing/shoes/bronze/Initialize() . = ..() @@ -358,6 +369,7 @@ icon_state = "rus_shoes" item_state = "rus_shoes" pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes + lace_time = 8 SECONDS // kevin is into feet /obj/item/clothing/shoes/wraps @@ -365,6 +377,7 @@ desc = "Ankle coverings. These ones have a golden design." icon_state = "gildedcuffs" body_parts_covered = FALSE + can_be_tied = FALSE /obj/item/clothing/shoes/wraps/silver name = "silver leg wraps" @@ -385,6 +398,7 @@ name = "cowboy boots" desc = "A standard pair of brown cowboy boots." icon_state = "cowboyboots" + can_be_tied = FALSE /obj/item/clothing/shoes/cowboyboots/black name = "black cowboy boots" diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 15413f76d4..74f8134d9c 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -24,7 +24,7 @@ var/obj/item/head = null var/obj/item/gloves = null //only used by humans - var/obj/item/shoes = null //only used by humans. + var/obj/item/clothing/shoes/shoes = null //only used by humans. var/obj/item/clothing/glasses/glasses = null //only used by humans. var/obj/item/ears = null //only used by humans. diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index a2d53f6f0a..75f4193edc 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -168,7 +168,11 @@ if(SLOT_SHOES in obscured) dat += "Shoes:Obscured" else - dat += "Shoes:[(shoes && !(shoes.item_flags & ABSTRACT)) ? shoes : "Empty"]" + dat += "Shoes:[(shoes && !(shoes.item_flags & ABSTRACT)) ? shoes : "Empty"]" + if(shoes && shoes.can_be_tied && shoes.tied != SHOES_KNOTTED) + dat += " [shoes.tied ? "Untie shoes" : "Knot shoes"]" + + dat += "" if(SLOT_GLOVES in obscured) dat += "Gloves:Obscured" @@ -292,6 +296,12 @@ if (!strip_silence) to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") + if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE) + // separate from first canusetopic + var/mob/living/user = usr + if(istype(user) && href_list["shoes"] && (user.mobility_flags & MOBILITY_USE)) // we need to be on the ground, so we'll be a bit looser + shoes.handle_tying(usr) + ..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index 60fe2f9839ebb172b3b7f0365f3635fb2ed8c872..30c23601a5edb51ba42b433f668236e0723072ba 100644 GIT binary patch delta 21197 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 delta 20966 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 Date: Sat, 11 Jul 2020 00:37:56 -0700 Subject: [PATCH 2/7] more --- code/__DEFINES/admin.dm | 1 + code/__DEFINES/mobs.dm | 1 + code/__HELPERS/do_after.dm | 30 +++++++++ code/game/atoms.dm | 8 +++ code/modules/admin/verbs/randomverbs.dm | 26 +++++++- code/modules/clothing/shoes/_shoes.dm | 66 ++++++++++++------- code/modules/mob/living/carbon/human/human.dm | 2 +- code/modules/mob/mob_defines.dm | 3 + 8 files changed, 112 insertions(+), 25 deletions(-) diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index e8e75c132a..3d2dae2076 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -74,6 +74,7 @@ #define ADMIN_PUNISHMENT_MAZING "Puzzle" #define ADMIN_PUNISHMENT_PIE "Cream Pie" #define ADMIN_PUNISHMENT_CUSTOM_PIE "Custom Cream Pie" +#define ADMIN_PUNISHMENT_SHOES "Knot Shoes" #define AHELP_ACTIVE 1 #define AHELP_CLOSED 2 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 42139cdeda..0801da6911 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -305,6 +305,7 @@ #define GRAB_PIXEL_SHIFT_NECK 16 #define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return; +#define INTERACTING_WITH(X, Y) (Y in X.do_afters) /// Field of vision defines. #define FOV_90_DEGREES 90 diff --git a/code/__HELPERS/do_after.dm b/code/__HELPERS/do_after.dm index f1f483c345..b2202ec9ae 100644 --- a/code/__HELPERS/do_after.dm +++ b/code/__HELPERS/do_after.dm @@ -166,6 +166,9 @@ var/target_loc = target.loc + LAZYADD(user.do_afters, target) + LAZYADD(target.targeted_by, user) + var/holding = user.get_active_held_item() var/datum/progressbar/progbar if (progress) @@ -184,6 +187,10 @@ if(uninterruptible) continue + if(!(target in user.do_afters)) + . = FALSE + break + if(drifting && !user.inertia_dir) drifting = 0 user_loc = user.loc @@ -194,6 +201,9 @@ if (progress) qdel(progbar) + if(!QDELETED(target)) + LAZYREMOVE(user.do_afters, target) + LAZYREMOVE(target.targeted_by, user) //some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action /mob/proc/break_do_after_checks(list/checked_health, check_clicks) @@ -216,6 +226,10 @@ if(target && !isturf(target)) Tloc = target.loc + if(target) + LAZYADD(user.do_afters, target) + LAZYADD(target.targeted_by, user) + var/atom/Uloc = user.loc var/drifting = 0 @@ -260,6 +274,10 @@ . = 0 break + if(target && !(target in user.do_afters)) + . = 0 + break + if(needhand) //This might seem like an odd check, but you can still need a hand even when it's empty //i.e the hand is used to pull some item/tool out of the construction @@ -273,6 +291,10 @@ if (progress) qdel(progbar) + if(!QDELETED(target)) + LAZYREMOVE(user.do_afters, target) + LAZYREMOVE(target.targeted_by, user) + /mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1 . = 1 return @@ -291,6 +313,8 @@ var/list/originalloc = list() for(var/atom/target in targets) originalloc[target] = target.loc + LAZYADD(user.do_afters, target) + LAZYADD(target.targeted_by, user) var/holding = user.get_active_held_item() var/datum/progressbar/progbar @@ -321,3 +345,9 @@ break mainloop if(progbar) qdel(progbar) + + for(var/thing in targets) + var/atom/target = thing + if(!QDELETED(target)) + LAZYREMOVE(user.do_afters, target) + LAZYREMOVE(target.targeted_by, user) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 5d29ef1598..e8e98aed78 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -70,6 +70,9 @@ /// A luminescence-shifted value of the last color calculated for chatmessage overlays var/chat_color_darkened + ///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy() + var/list/targeted_by + /atom/New(loc, ...) //atom creation method that preloads variables at creation if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New() @@ -142,6 +145,11 @@ LAZYCLEARLIST(overlays) LAZYCLEARLIST(priority_overlays) + for(var/i in targeted_by) + var/mob/M = i + LAZYREMOVE(M.do_afters, src) + targeted_by = null + QDEL_NULL(light) return ..() diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index d335cfb171..cd36d66841 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1276,7 +1276,20 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) return - var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_CUSTOM_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD) + var/list/punishment_list = list( + ADMIN_PUNISHMENT_PIE, + ADMIN_PUNISHMENT_CUSTOM_PIE, + ADMIN_PUNISHMENT_FIREBALL, + ADMIN_PUNISHMENT_LIGHTNING, + ADMIN_PUNISHMENT_BRAINDAMAGE, + ADMIN_PUNISHMENT_BSA, + ADMIN_PUNISHMENT_GIB, + ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, + ADMIN_PUNISHMENT_SUPPLYPOD, + ADMIN_PUNISHMENT_MAZING, + ADMIN_PUNISHMENT_ROD, + ADMIN_PUNISHMENT_SHOES + ) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list @@ -1355,6 +1368,17 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits A.reagents.add_reagent(chosen_id, amount) A.splat(target) + if(ADMIN_PUNISHMENT_SHOES) + if(!iscarbon(target)) + to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) + return + var/mob/living/carbon/C = target + var/obj/item/clothing/shoes/sick_kicks = C.shoes + if(!sick_kicks?.can_be_tied) + to_chat(usr,"[C] does not have knottable shoes!", confidential = TRUE) + return + sick_kicks.adjust_laces(SHOES_KNOTTED) + punish_log(target, punishment) /client/proc/punish_log(var/whom, var/punishment) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 7eb5fab312..d0ce472137 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -125,7 +125,6 @@ /obj/item/proc/negates_gravity() return FALSE -/** * adjust_laces adjusts whether our shoes (assuming they can_be_tied) and tied, untied, or knotted * * In addition to setting the state, it will deal with getting rid of alerts if they exist, as well as registering and unregistering the stepping signals @@ -162,16 +161,23 @@ * * * * user: who is the person interacting with the shoes? */ -/obj/item/clothing/shoes/proc/handle_tying(mob/living/carbon/human/user) +/obj/item/clothing/shoes/proc/handle_tying(mob/user) ///our_guy here is the wearer, if one exists (and he must exist, or we don't care) var/mob/living/carbon/human/our_guy = loc if(!istype(our_guy)) return + if(!in_range(user, our_guy)) + to_chat(user, "You aren't close enough to interact with [src]'s laces!") + return + if(user == loc && tied != SHOES_TIED) // if they're our own shoes, go tie-wards + if(INTERACTING_WITH(user, our_guy)) + to_chat(user, "You're already interacting with [src]!") + return user.visible_message("[user] begins [tied ? "unknotting" : "tying"] the laces of [user.p_their()] [src.name].", "You begin [tied ? "unknotting" : "tying"] the laces of your [src.name]...") - if(do_after(user, lace_time, needhand=TRUE, target=src)) + if(do_after(user, lace_time, needhand=TRUE, target=our_guy, extra_checks=CALLBACK(src, .proc/still_shoed, our_guy))) to_chat(user, "You [tied ? "unknot" : "tie"] the laces of your [src.name].") if(tied == SHOES_UNTIED) adjust_laces(SHOES_TIED, user) @@ -179,36 +185,43 @@ adjust_laces(SHOES_UNTIED, user) else // if they're someone else's shoes, go knot-wards - if(user.mobility_flags & MOBILITY_STAND) + var/mob/living/L = user + if(istype(L) && (L.mobility_flags & MOBILITY_STAND)) to_chat(user, "You must be on the floor to interact with [src]!") return if(tied == SHOES_KNOTTED) to_chat(user, "The laces on [loc]'s [src.name] are already a hopelessly tangled mess!") return + if(INTERACTING_WITH(user, our_guy)) + to_chat(user, "You're already interacting with [src]!") + return var/mod_time = lace_time to_chat(user, "You quietly set to work [tied ? "untying" : "knotting"] [loc]'s [src.name]...") if(HAS_TRAIT(user, TRAIT_CLUMSY)) // based clowns trained their whole lives for this mod_time *= 0.75 - if(do_after(user, mod_time, needhand=TRUE, target=src)) + if(do_after(user, mod_time, needhand=TRUE, target=our_guy, extra_checks=CALLBACK(src, .proc/still_shoed, our_guy))) to_chat(user, "You [tied ? "untie" : "knot"] the laces on [loc]'s [src.name].") if(tied == SHOES_UNTIED) adjust_laces(SHOES_KNOTTED, user) else adjust_laces(SHOES_UNTIED, user) else // if one of us moved - user.visible_message("[our_guy] stamps on [user]'s hand, mid-shoelace [tied ? "knotting" : "untying"]!", "Ow! [our_guy] stamps on your hand!", user) - to_chat(our_guy, "You stamp on [user]'s hand! What the- they were [tied ? "knotting" : "untying"] your shoelaces!") + user.visible_message("[our_guy] stamps on [user]'s hand, mid-shoelace [tied ? "knotting" : "untying"]!", "Ow! [our_guy] stamps on your hand!", list(our_guy)) + to_chat(our_guy, "You stamp on [user]'s hand! What the- [user.p_they()] [user.p_were()] [tied ? "knotting" : "untying"] your shoelaces!") user.emote("scream") - var/obj/item/bodypart/ouchie = user.get_bodypart(pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) - if(ouchie) - ouchie.receive_damage(15) - user.Paralyze(5) + if(istype(L)) + var/obj/item/bodypart/ouchie = L.get_bodypart(pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + if(ouchie) + ouchie.receive_damage(brute = 10, stamina = 40) + L.Paralyze(10) -/** - * check_trip runs on each step to see if we fall over as a result of our lace status. Knotted laces are a guaranteed trip, while untied shoes are just a chance to stumble - */ +///checking to make sure we're still on the person we're supposed to be, for lacing do_after's +/obj/item/clothing/shoes/proc/still_shoed(mob/living/carbon/our_guy) + return (loc == our_guy) + +///check_trip runs on each step to see if we fall over as a result of our lace status. Knotted laces are a guaranteed trip, while untied shoes are just a chance to stumble /obj/item/clothing/shoes/proc/check_trip() var/mob/living/carbon/human/our_guy = loc if(!istype(our_guy)) // are they REALLY /our guy/? @@ -220,30 +233,35 @@ our_guy.visible_message("[our_guy] trips on [our_guy.p_their()] knotted shoelaces and falls! What a klutz!", "You trip on your knotted shoelaces and fall over!") SEND_SIGNAL(our_guy, COMSIG_ADD_MOOD_EVENT, "trip", /datum/mood_event/tripped) // well we realized they're knotted now! our_alert = our_guy.throw_alert("shoealert", /obj/screen/alert/shoes/knotted) + else if(tied == SHOES_UNTIED) var/wiser = TRUE // did we stumble and realize our laces are undone? switch(rand(1, 1000)) if(1) // .1% chance to trip and fall over (note these are per step while our laces are undone) our_guy.Paralyze(5) our_guy.Knockdown(10) + SEND_SIGNAL(our_guy, COMSIG_ADD_MOOD_EVENT, "trip", /datum/mood_event/tripped) // well we realized they're knotted now! our_guy.visible_message("[our_guy] trips on [our_guy.p_their()] untied shoelaces and falls! What a klutz!", "You trip on your untied shoelaces and fall over!") + if(2 to 5) // .4% chance to stumble and lurch forward our_guy.throw_at(get_step(our_guy, our_guy.dir), 3, 2) to_chat(our_guy, "You stumble on your untied shoelaces and lurch forward!") + if(6 to 13) // .7% chance to stumble and fling what we're holding var/have_anything = FALSE for(var/obj/item/I in our_guy.held_items) have_anything = TRUE our_guy.accident(I) to_chat(our_guy, "You trip on your shoelaces a bit[have_anything ? ", flinging what you were holding" : ""]!") + if(14 to 25) // 1.3ish% chance to stumble and be a bit off balance (like being disarmed) to_chat(our_guy, "You stumble a bit on your untied shoelaces!") - if(!our_guy.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) - our_guy.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) + if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove)) + our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove) addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) + if(26 to 1000) wiser = FALSE - if(wiser) SEND_SIGNAL(our_guy, COMSIG_ADD_MOOD_EVENT, "untied", /datum/mood_event/untied) // well we realized they're untied now! our_alert = our_guy.throw_alert("shoealert", /obj/screen/alert/shoes/untied) @@ -252,7 +270,7 @@ /obj/item/clothing/shoes/attack_hand(mob/living/carbon/human/user) if(!istype(user)) return ..() - if(loc == user && tied != SHOES_TIED) + if(loc == user && tied != SHOES_TIED && (user.mobility_flags & MOBILITY_USE)) handle_tying(user) return ..() @@ -260,10 +278,12 @@ /obj/item/clothing/shoes/attack_self(mob/user) . = ..() + if(INTERACTING_WITH(user, src)) + to_chat(user, "You're already interacting with [src]!") + return + to_chat(user, "You begin [tied ? "untying" : "tying"] the laces on [src]...") - if(do_after(user, lace_time, needhand=TRUE, target=src)) + + if(do_after(user, lace_time, needhand=TRUE, target=src,extra_checks=CALLBACK(src, .proc/still_shoed, user))) to_chat(user, "You [tied ? "untie" : "tie"] the laces on [src].") - if(tied == SHOES_UNTIED) - adjust_laces(SHOES_TIED, user) - else - adjust_laces(SHOES_UNTIED, user) + adjust_laces(tied ? SHOES_TIED : SHOES_UNTIED, user) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 75f4193edc..3cb61f1240 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -296,7 +296,7 @@ if (!strip_silence) to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") - if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE) + if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE)) // separate from first canusetopic var/mob/living/user = usr if(istype(user) && href_list["shoes"] && (user.mobility_flags & MOBILITY_USE)) // we need to be on the ground, so we'll be a bit looser diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index dbf7b7f350..de69afbe7e 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -156,3 +156,6 @@ var/typing_indicator_timerid /// Current state of our typing indicator. Used for cut overlay, DO NOT RUNTIME ASSIGN OTHER THAN FROM SHOW/CLEAR. Used to absolutely ensure we do not get stuck overlays. var/typing_indicator_current + + ///For storing what do_after's someone has, in case we want to restrict them to only one of a certain do_after at a time + var/list/do_afters From ed847b1a58516452f5d6baf102771b7d513d54b4 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 11 Jul 2020 00:42:13 -0700 Subject: [PATCH 3/7] compile --- code/modules/clothing/shoes/_shoes.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index d0ce472137..d17eed1ef7 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -125,6 +125,7 @@ /obj/item/proc/negates_gravity() return FALSE +/** * adjust_laces adjusts whether our shoes (assuming they can_be_tied) and tied, untied, or knotted * * In addition to setting the state, it will deal with getting rid of alerts if they exist, as well as registering and unregistering the stepping signals From cc2e9530b104be89a58186627bdebb585b78cbe0 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 11 Jul 2020 00:44:17 -0700 Subject: [PATCH 4/7] fix --- code/_onclick/hud/alert.dm | 2 +- code/modules/clothing/shoes/_shoes.dm | 2 +- code/modules/clothing/shoes/miscellaneous.dm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index f465705569..64a30e0e55 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -624,7 +624,7 @@ so as to remain in compliance with the most up-to-date laws." /obj/screen/alert/shoes/Click() var/mob/living/carbon/C = usr - if(!istype(C) || !C.can_resist() || C != owner || !C.shoes) + if(!istype(C) || !C.can_resist() || C != mob_viewer || !C.shoes) return C.changeNext_move(CLICK_CD_RESIST) C.shoes.handle_tying(C) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index d17eed1ef7..0b66c1f4b6 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -102,7 +102,7 @@ worn_y_dimension = world.icon_size /obj/item/clothing/shoes/dropped(mob/user) - if(our_alert && our_alert.owner == user) + if(our_alert && our_alert.mob_viewer == user) user.clear_alert("shoealert") if(offset && equipped_before_drop) restore_offsets(user) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index bc71214e03..b0d760ebd9 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -17,7 +17,7 @@ resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes - lace_delay = 12 SECONDS + lace_time = 12 SECONDS /obj/item/clothing/shoes/combat/sneakboots name = "insidious sneakboots" From 98e727ec033cf5797398280d58055164e8e23dd8 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 11 Jul 2020 00:55:23 -0700 Subject: [PATCH 5/7] ok --- code/modules/admin/verbs/randomverbs.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index cd36d66841..dcf74db154 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1370,12 +1370,12 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(ADMIN_PUNISHMENT_SHOES) if(!iscarbon(target)) - to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) + to_chat(usr,"This must be used on a carbon mob.") return var/mob/living/carbon/C = target var/obj/item/clothing/shoes/sick_kicks = C.shoes if(!sick_kicks?.can_be_tied) - to_chat(usr,"[C] does not have knottable shoes!", confidential = TRUE) + to_chat(usr,"[C] does not have knottable shoes!") return sick_kicks.adjust_laces(SHOES_KNOTTED) From 6fbe083e1325ec5e31770b686873e715f10e5b11 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 11 Jul 2020 07:03:41 -0700 Subject: [PATCH 6/7] ok --- code/modules/clothing/shoes/_shoes.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 0b66c1f4b6..8de65b3a06 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -102,7 +102,7 @@ worn_y_dimension = world.icon_size /obj/item/clothing/shoes/dropped(mob/user) - if(our_alert && our_alert.mob_viewer == user) + if(our_alert && (our_alert.mob_viewer == user)) user.clear_alert("shoealert") if(offset && equipped_before_drop) restore_offsets(user) @@ -287,4 +287,4 @@ if(do_after(user, lace_time, needhand=TRUE, target=src,extra_checks=CALLBACK(src, .proc/still_shoed, user))) to_chat(user, "You [tied ? "untie" : "tie"] the laces on [src].") - adjust_laces(tied ? SHOES_TIED : SHOES_UNTIED, user) \ No newline at end of file + adjust_laces(tied ? SHOES_TIED : SHOES_UNTIED, user) From de8ac9896a0762628f29b70532cc63550550e51f Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 11 Jul 2020 07:13:56 -0700 Subject: [PATCH 7/7] sigh --- code/_onclick/hud/alert.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 64a30e0e55..26731efd6b 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -22,7 +22,7 @@ if(alerts[category]) thealert = alerts[category] if(thealert.override_alerts) - return 0 + return thealert if(new_master && new_master != thealert.master) WARNING("[src] threw alert [category] with new_master [new_master] while already having that alert with master [thealert.master]") @@ -36,7 +36,7 @@ clear_alert(category) return .() else //no need to update - return 0 + return thealert else thealert = new type() thealert.override_alerts = override