From 3d80792e7992c1baea048e49e6d8acced926f754 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 11 Jul 2020 00:37:56 -0700 Subject: [PATCH] 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