From 5632228327187b841004f406f4bdfb42e7403249 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 25 Oct 2023 21:22:41 +0200 Subject: [PATCH] [MIRROR] Adds charges to omens and omen smiting. Reduces omen bad luck if nobody's nearby. [MDB IGNORE] (#24583) * Adds charges to omens and omen smiting. Reduces omen bad luck if nobody's nearby. * Update door.dm * Update door.dm --------- Co-authored-by: carlarctg <53100513+carlarctg@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> --- code/datums/components/omen.dm | 94 +++++++++++++++++--------- code/game/machinery/doors/door.dm | 11 ++- code/game/objects/structures/mirror.dm | 4 +- code/modules/admin/smites/bad_luck.dm | 12 ++-- 4 files changed, 77 insertions(+), 44 deletions(-) diff --git a/code/datums/components/omen.dm b/code/datums/components/omen.dm index 3341a9c7e95..8b7a751ef27 100644 --- a/code/datums/components/omen.dm +++ b/code/datums/components/omen.dm @@ -7,30 +7,47 @@ * Omens are removed once the victim is either maimed by one of the possible injuries, or if they receive a blessing (read: bashing with a bible) from the chaplain. */ /datum/component/omen - dupe_mode = COMPONENT_DUPE_UNIQUE + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS /// Whatever's causing the omen, if there is one. Destroying the vessel won't stop the omen, but we destroy the vessel (if one exists) upon the omen ending var/obj/vessel - /// If the omen is permanent, it will never go away - var/permanent = FALSE + /// How many incidents are left. If 0 exactly, it will get deleted. + var/incidents_left = INFINITY /// Base probability of negative events. Cursed are half as unlucky. var/luck_mod = 1 /// Base damage from negative events. Cursed take 25% of this damage. var/damage_mod = 1 -/datum/component/omen/Initialize(obj/vessel, permanent, luck_mod, damage_mod) +/datum/component/omen/Initialize(obj/vessel, incidents_left = 1, luck_mod, damage_mod) if(!isliving(parent)) return COMPONENT_INCOMPATIBLE if(istype(vessel)) src.vessel = vessel RegisterSignal(vessel, COMSIG_QDELETING, PROC_REF(vessel_qdeleting)) - if(!isnull(permanent)) - src.permanent = permanent + if(!isnull(incidents_left)) + src.incidents_left = incidents_left if(!isnull(luck_mod)) src.luck_mod = luck_mod if(!isnull(damage_mod)) src.damage_mod = damage_mod +/** + * This is a omen eat omen world! The stronger omen survives. + */ +/datum/component/omen/InheritComponent(obj/vessel, incidents_left, luck_mod, damage_mod) + // If we have more incidents left the new one gets deleted. + if(src.incidents_left > incidents_left) + return // make slimes get nurtiton from plasmer + // Otherwise we set our incidents remaining to the higher, newer value. + src.incidents_left = incidents_left + // The new omen is weaker than our current omen? Let's split the difference. + if(src.luck_mod > luck_mod) + src.luck_mod += luck_mod * 0.5 + if(src.damage_mod > damage_mod) + src.luck_mod += luck_mod * 0.5 + // This means that if you had a strong temporary omen and it was replaced by a weaker but permanent omen, the latter is made worse. + // Feature! + /datum/component/omen/Destroy(force) var/mob/living/person = parent to_chat(person, span_nicegreen("You feel a horrible omen lifted off your shoulders!")) @@ -52,6 +69,11 @@ /datum/component/omen/UnregisterFromParent() UnregisterSignal(parent, list(COMSIG_ON_CARBON_SLIP, COMSIG_MOVABLE_MOVED, COMSIG_CARBON_MOOD_UPDATE, COMSIG_LIVING_DEATH)) +/datum/component/omen/proc/consume_omen() + incidents_left-- + if(incidents_left < 1) + qdel(src) + /** * check_accident() is called each step we take * @@ -71,11 +93,23 @@ INVOKE_ASYNC(living_guy, TYPE_PROC_REF(/mob, emote), "scream") living_guy.adjust_fire_stacks(20) living_guy.ignite_mob(silent = TRUE) - if(!permanent) - qdel(src) + consume_omen() return - if(!prob(8 * luck_mod)) + var/effective_luck = luck_mod + + // If there's nobody to witness the misfortune, make it less likely. + // This way, we allow for people to be able to get into hilarious situations without making the game nigh unplayable most of the time. + + var/has_watchers = FALSE + for(var/mob/viewer in viewers(our_guy, world.view)) + if(viewer.client) + has_watchers = TRUE + break + if(!has_watchers) + effective_luck *= 0.5 + + if(!prob(8 * effective_luck)) return var/our_guy_pos = get_turf(living_guy) @@ -94,8 +128,7 @@ if(living_guy.can_z_move(DOWN, the_turf, z_move_flags = ZMOVE_FALL_FLAGS)) to_chat(living_guy, span_warning("A malevolent force guides you towards the edge...")) living_guy.throw_at(the_turf, 1, 10, force = MOVE_FORCE_EXTREMELY_STRONG) - if(!permanent) - qdel(src) + consume_omen() return for(var/obj/machinery/vending/darth_vendor in the_turf) @@ -103,8 +136,7 @@ continue to_chat(living_guy, span_warning("A malevolent force tugs at the [darth_vendor]...")) INVOKE_ASYNC(darth_vendor, TYPE_PROC_REF(/obj/machinery/vending, tilt), living_guy) - if(!permanent) - qdel(src) + consume_omen() return for(var/obj/machinery/light/evil_light in the_turf) @@ -120,8 +152,7 @@ evil_light.Beam(living_guy, icon_state = "lightning[rand(1,12)]", time = 0.5 SECONDS) living_guy.electrocute_act(35 * (damage_mod * 0.5), evil_light, flags = SHOCK_NOGLOVES) INVOKE_ASYNC(living_guy, TYPE_PROC_REF(/mob, emote), "scream") - if(!permanent && prob(33.3)) - qdel(src) + consume_omen() for(var/obj/structure/mirror/evil_mirror in the_turf) to_chat(living_guy, span_warning("You pass by the mirror and glance at it...")) @@ -132,38 +163,37 @@ if(1) to_chat(living_guy, span_warning("The mirror explodes into a million pieces! Wait, does that mean you're even more unlucky?")) evil_mirror.take_damage(evil_mirror.max_integrity, BRUTE, MELEE, FALSE) - if(prob(50 * luck_mod)) // sometimes + if(prob(50 * effective_luck)) // sometimes luck_mod += 0.25 damage_mod += 0.25 if(2 to 3) to_chat(living_guy, span_big(span_hypnophrase("Oh god, you can't see your reflection!!"))) - if(isvampire(living_guy)) // not so living i suppose + if(HAS_TRAIT(living_guy, TRAIT_NO_MIRROR_REFLECTION)) // not so living i suppose to_chat(living_guy, span_green("Well, obviously.")) return INVOKE_ASYNC(living_guy, TYPE_PROC_REF(/mob, emote), "scream") if(4 to 5) - if(isvampire(living_guy)) + if(HAS_TRAIT(living_guy, TRAIT_NO_MIRROR_REFLECTION)) to_chat(living_guy, span_warning("You don't see anything of notice. Huh.")) return to_chat(living_guy, span_userdanger("You see your reflection, but it is grinning malevolently and staring directly at you!")) INVOKE_ASYNC(living_guy, TYPE_PROC_REF(/mob, emote), "scream") living_guy.set_jitter_if_lower(25 SECONDS) - if(prob(7 * luck_mod)) + if(prob(7 * effective_luck)) to_chat(living_guy, span_warning("You are completely shocked by this turn of events!")) - var/mob/living/carbon/carbon_guy = living_guy to_chat(living_guy, span_userdanger("You clutch at your heart!")) + var/mob/living/carbon/carbon_guy = living_guy if(istype(carbon_guy)) carbon_guy.set_heartattack(status = TRUE) - if(!permanent && prob(33.3)) - qdel(src) + consume_omen() /datum/component/omen/proc/slam_airlock(obj/machinery/door/airlock/darth_airlock) . = darth_airlock.close(force_crush = TRUE) - if(. && !permanent && !prob(66.6)) - qdel(src) + if(.) + consume_omen() /// If we get knocked down, see if we have a really bad slip and bash our head hard /datum/component/omen/proc/check_slip(mob/living/our_guy, amount) @@ -181,8 +211,7 @@ our_guy.visible_message(span_danger("[our_guy] hits [our_guy.p_their()] head really badly falling down!"), span_userdanger("You hit your head really badly falling down!")) the_head.receive_damage(75 * damage_mod, damage_source = "slipping") our_guy.adjustOrganLoss(ORGAN_SLOT_BRAIN, 100 * damage_mod) - if(!permanent) - qdel(src) + consume_omen() return @@ -190,19 +219,22 @@ /datum/component/omen/proc/check_bless(mob/living/our_guy, category) SIGNAL_HANDLER - if(permanent) + if(incidents_left == INFINITY) return if(!("blessing" in our_guy.mob_mood.mood_events)) return + playsound(our_guy, 'sound/effects/pray_chaplain.ogg', 40, TRUE) + to_chat(our_guy, span_green("You feel fantastic!")) + qdel(src) /// Severe deaths. Normally lifts the curse. /datum/component/omen/proc/check_death(mob/living/our_guy) SIGNAL_HANDLER - if(permanent) + if(incidents_left == INFINITY) return qdel(src) @@ -227,7 +259,7 @@ /datum/component/omen/smite /datum/component/omen/smite/check_death(mob/living/our_guy) - if(!permanent) + if(incidents_left == INFINITY) return ..() death_explode(our_guy) @@ -238,8 +270,8 @@ * Has only a 50% chance of bad things happening, and takes only 25% of normal damage. */ /datum/component/omen/quirk - permanent = TRUE - luck_mod = 0.5 // 50% chance of bad things happening + incidents_left = INFINITY + luck_mod = 0.3 // 30% chance of bad things happening damage_mod = 0.25 // 25% of normal damage /datum/component/omen/quirk/RegisterWithParent() diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 8d53b0e8727..0077839234a 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -505,15 +505,14 @@ if(isalien(future_pancake)) //For xenos future_pancake.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans. future_pancake.emote("roar") + else if(ismonkey(future_pancake)) //For monkeys + future_pancake.emote("screech") + future_pancake.adjustBruteLoss(DOOR_CRUSH_DAMAGE) + future_pancake.StaminaKnockdown(20, TRUE, TRUE) // SKYRAT EDIT CHANGE - AIRLOCKS - ORIGINAL: future_pancake.Paralyze(100) else if(ishuman(future_pancake)) //For humans future_pancake.adjustBruteLoss(DOOR_CRUSH_DAMAGE) future_pancake.emote("scream") - // future_pancake.Paralyze(100) // ORIGINAL - future_pancake.StaminaKnockdown(20, TRUE, TRUE) // SKYRAT EDIT CHANGE - AIRLOCKS - else if(ismonkey(future_pancake)) //For monkeys - future_pancake.adjustBruteLoss(DOOR_CRUSH_DAMAGE) - // future_pancake.Paralyze(100) // ORIGINAL - future_pancake.StaminaKnockdown(20, TRUE, TRUE) // SKYRAT EDIT CHANGE - AIRLOCKS + future_pancake.StaminaKnockdown(20, TRUE, TRUE) // SKYRAT EDIT CHANGE - AIRLOCKS - ORIGINAL: future_pancake.Paralyze(100) else //for simple_animals & borgs future_pancake.adjustBruteLoss(DOOR_CRUSH_DAMAGE) var/turf/location = get_turf(src) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index f51ef9c76d8..76363a1b07b 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -242,7 +242,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) . = ..() if(broken) // breaking a mirror truly gets you bad luck! to_chat(user, span_warning("A chill runs down your spine as [src] shatters...")) - user.AddComponent(/datum/component/omen) + user.AddComponent(/datum/component/omen, incidents_left = 7) /obj/structure/mirror/bullet_act(obj/projectile/P) if(broken || !isliving(P.firer) || !P.damage) @@ -252,7 +252,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) if(broken) // breaking a mirror truly gets you bad luck! var/mob/living/unlucky_dude = P.firer to_chat(unlucky_dude, span_warning("A chill runs down your spine as [src] shatters...")) - unlucky_dude.AddComponent(/datum/component/omen) + unlucky_dude.AddComponent(/datum/component/omen, incidents_left = 7) /obj/structure/mirror/atom_break(damage_flag, mapload) . = ..() diff --git a/code/modules/admin/smites/bad_luck.dm b/code/modules/admin/smites/bad_luck.dm index c9f6a94b93a..34592dd200d 100644 --- a/code/modules/admin/smites/bad_luck.dm +++ b/code/modules/admin/smites/bad_luck.dm @@ -6,21 +6,23 @@ var/silent /// Is this permanent? - var/permanent + var/incidents /datum/smite/bad_luck/configure(client/user) silent = tgui_alert(user, "Do you want to apply the omen with a player notification?", "Notify Player?", list("Notify", "Silent")) == "Silent" - permanent = tgui_alert(user, "Would you like this to be permanent or removed automatically after the first accident?", "Permanent?", list("Permanent", "Temporary")) == "Permanent" + incidents = tgui_input_number(user, "For how many incidents will the omen last? 0 means permanent.", "Duration?", default = 0, round_value = 1) + if(incidents == 0) + incidents = INFINITY /datum/smite/bad_luck/effect(client/user, mob/living/target) . = ..() //if permanent, replace any existing omen - if(permanent) + if(incidents == INFINITY) var/existing_component = target.GetComponent(/datum/component/omen) qdel(existing_component) - target.AddComponent(/datum/component/omen/smite, permanent = permanent) + target.AddComponent(/datum/component/omen/smite, incidents_left = incidents) if(silent) return to_chat(target, span_warning("You get a bad feeling...")) - if(permanent) + if(incidents == INFINITY) to_chat(target, span_warning("A very bad feeling... As if malevolent forces are watching you..."))