Skip to content

Commit

Permalink
[MIRROR] Adds charges to omens and omen smiting. Reduces omen bad luc…
Browse files Browse the repository at this point in the history
…k 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 <[email protected]>
Co-authored-by: Bloop <[email protected]>
  • Loading branch information
3 people authored and FFMirrorBot committed Oct 25, 2023
1 parent 9979993 commit 5632228
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 44 deletions.
94 changes: 63 additions & 31 deletions code/datums/components/omen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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!"))
Expand All @@ -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
*
Expand All @@ -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)
Expand All @@ -94,17 +128,15 @@
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)
if(!darth_vendor.tiltable || darth_vendor.tilted)
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)
Expand All @@ -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..."))
Expand All @@ -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)
Expand All @@ -181,28 +211,30 @@
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

/// Hijack the mood system to see if we get the blessing mood event to cancel the omen
/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)
Expand All @@ -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)
Expand All @@ -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()
Expand Down
11 changes: 5 additions & 6 deletions code/game/machinery/doors/door.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/structures/mirror.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
. = ..()
Expand Down
12 changes: 7 additions & 5 deletions code/modules/admin/smites/bad_luck.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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 <b>very</b> bad feeling... As if malevolent forces are watching you..."))

0 comments on commit 5632228

Please sign in to comment.