Skip to content

Commit

Permalink
[MIRROR] Fix all nighter runtimes (#1801)
Browse files Browse the repository at this point in the history
* Fix all nighter runtimes (#82405)

## About The Pull Request

So, recently, someone asked me why their All Nighter eyebags weren't
working, and though after a short conversation we worked out it was
working as intended and they had just taken a few naps to train fitness,
I still checked the round logs once they were public.
https://scrubby.melonmesa.com/round/226476/runtimes

![image](https://github.com/tgstation/tgstation/assets/42909981/162d76ae-2d43-428b-bc7e-37371ba27a1c)
Coincidentally! Someone else _did_ have an All Nighter runtime!
Well. Time to fix it.

I look into the code, and lo and behold, it seems we're really just not
caring about whether the head actually exists.

https://github.com/tgstation/tgstation/blob/d38f9385b863e49f83455a227764d302629e2867/code/datums/quirks/negative_quirks/all_nighter.dm#L50-L56

But that reminds me. We have more ways to lose your head, like
H.A.R.S.... So... I boot the game, and...
Oh no.
_Oh no._
That's a _lot_ of runtimes huh. (See "Why It's Good For The Game")

Soooo we just add a check for whether our head-in-question actually
exists to both adding and removing our bags, and be done with it.
```dm
///adds the bag overlay
/datum/quirk/all_nighter/proc/add_bags()
	var/mob/living/carbon/human/sleepy_head = quirk_holder
	var/obj/item/bodypart/head/face = sleepy_head?.get_bodypart(BODY_ZONE_HEAD)
	if(isnull(face))
		return
	bodypart_overlay = new() //creates our overlay
	face.add_bodypart_overlay(bodypart_overlay)
	sleepy_head.update_body_parts() //make sure to update icon

///removes the bag overlay
/datum/quirk/all_nighter/proc/remove_bags()
	var/mob/living/carbon/human/sleepy_head = quirk_holder
	var/obj/item/bodypart/head/face = sleepy_head?.get_bodypart(BODY_ZONE_HEAD)
	if(face)
		//our overlay is stored as a datum var, so referencing it is easy
		face.remove_bodypart_overlay(bodypart_overlay)
		sleepy_head.update_body_parts()
	QDEL_NULL(bodypart_overlay)
```
Right?

Well, no. Yes, this stops the runtimes, but while testing this I also
noticed that the bags don't come back.
We lose our head, we regenerate a new one, and we don't have bags. Even
though we removed our head, we never actually removed _our bags_.
So our `bodypart_overlay` is never set to null, and it's never actually
attempting to apply them to our new head.

To resolve this, we then just add a new proc called on
`COMSIG_CARBON_REMOVE_LIMB`, which handles removing the eyebags before
we remove our head if needed.
```dm
///if we have bags and lost a head, remove them
/datum/quirk/all_nighter/proc/on_removed_limb(datum/source, obj/item/bodypart/removed_limb, special, dismembered)
	if(bodypart_overlay && istype(removed_limb, /obj/item/bodypart/head))
		remove_bags()
```

Oh, we also remove the unused `client/client_source` argument from both
the `add_bags(...)` and `remove_bags(...)` procs.
## Why It's Good For The Game

![image](https://github.com/tgstation/tgstation/assets/42909981/31fd97b5-dce3-46ec-9388-abf568fe4f0b)
## Changelog
:cl:
fix: All Nighter: fixed a runtime from not having a head, whether from
hars/deletion/somesuch.
fix: All Nighter: losing and regaining your head while you had eyebags
no longer removes your eyebags until you've slept.
/:cl:

* Fix all nighter runtimes

---------

Co-authored-by: _0Steven <[email protected]>
  • Loading branch information
2 people authored and StealsThePRs committed Apr 4, 2024
1 parent 85e061b commit ee5ad51
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions code/datums/quirks/negative_quirks/all_nighter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,40 @@

///adds the corresponding moodlet and visual effects
/datum/quirk/all_nighter/add(client/client_source)
RegisterSignal(quirk_holder, COMSIG_CARBON_REMOVE_LIMB, PROC_REF(on_removed_limb))
quirk_holder.add_mood_event("all_nighter", /datum/mood_event/all_nighter)
add_bags()

///removes the corresponding moodlet and visual effects
/datum/quirk/all_nighter/remove(client/client_source)
UnregisterSignal(quirk_holder, COMSIG_CARBON_REMOVE_LIMB)
quirk_holder.clear_mood_event("all_nighter", /datum/mood_event/all_nighter)
remove_bags()
if(bodypart_overlay)
remove_bags()

///if we have bags and lost a head, remove them
/datum/quirk/all_nighter/proc/on_removed_limb(datum/source, obj/item/bodypart/removed_limb, special, dismembered)
if(bodypart_overlay && istype(removed_limb, /obj/item/bodypart/head))
remove_bags()

///adds the bag overlay
/datum/quirk/all_nighter/proc/add_bags(client/client_source)
/datum/quirk/all_nighter/proc/add_bags()
var/mob/living/carbon/human/sleepy_head = quirk_holder
var/obj/item/bodypart/head/face = sleepy_head.get_bodypart(BODY_ZONE_HEAD)
var/obj/item/bodypart/head/face = sleepy_head?.get_bodypart(BODY_ZONE_HEAD)
if(isnull(face))
return
bodypart_overlay = new() //creates our overlay
face.add_bodypart_overlay(bodypart_overlay)
sleepy_head.update_body_parts() //make sure to update icon

///removes the bag overlay
/datum/quirk/all_nighter/proc/remove_bags(client/client_source)
/datum/quirk/all_nighter/proc/remove_bags()
var/mob/living/carbon/human/sleepy_head = quirk_holder
var/obj/item/bodypart/head/face = sleepy_head.get_bodypart(BODY_ZONE_HEAD)
//our overlay is stored as a datum var, so referencing it is easy
face.remove_bodypart_overlay(bodypart_overlay)
var/obj/item/bodypart/head/face = sleepy_head?.get_bodypart(BODY_ZONE_HEAD)
if(face)
face.remove_bodypart_overlay(bodypart_overlay)
sleepy_head.update_body_parts()
QDEL_NULL(bodypart_overlay)
sleepy_head.update_body_parts()

/**
*Here we actively handle our moodlet & eye bags, adding/removing them as necessary
Expand Down

0 comments on commit ee5ad51

Please sign in to comment.