Files
Bubberstation/code/game/objects/items/frog_statue.dm
Useroth 7bb2f5055e [MIRROR] 81182 81367 81399 (#26492)
* Implements rgb2num, uses it to replace all our manual rgb reading. Redoes HSV management (#81182)

[Converts all manual extraction of rbg with rgb2num. It's just
better](ae798eabd5)

[Yanks out old HSV management, replaces it with list
stuff](4997e86051)

There's this old lummy era clunky code that passed HSV as text

We can now cleanly replace it with passing hsv as lists from a rgb2hsv
proc

So let's just do that.

Also, cleans up spraytan code (and ethereal lighting)

Code better

* Refactors fire overlays once again to make it not get stuck so often (#81367)

Maybe finally fixes #77701

A big reason why this kept happening is because fire uses standing
overlays. But fire isn't managed by mobs anymore. Meaning in some
situations, fire can cease to exist but the overlay can still be on the
mob. So it gets stuck.

So like, why use standing overlays anymore? We can just hook
`update_overlays` signal.
Isn't that neat.

🆑 Melbert
refactor: Fire effects get added to mobs in a different way now. Maybe
it will get stuck less. Report any oddities.
/🆑

* Fix Flaky Failure From Fire  (#81399)

## About The Pull Request

Closes #81396 , Closes #81391 , Closes #81403, Closes #81402

I don't know why but I thought this proc was only called once, when the
mob entered the turf. That was silly.

And going back at it, I'm not entirely sure why I tied
`TRAIT_NO_EXTINGUISH` to the element anyways, rather than the lava like
it originally was.

While going back over this, I cleaned up the proc a bit. 

## Changelog

Not necessary

* There we go?

* Bruh moment

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
2024-02-12 19:03:58 -05:00

166 lines
5.3 KiB
Plaintext

#define STATUE_FILTER "statue_filter"
#define FILTER_COLOR "#34b347"
#define RECALL_DURATION 3 SECONDS
#define MINIMUM_COLOR_VALUE 20
/obj/item/frog_statue
name = "frog statue"
desc = "Are they really comfortable living in this thing?"
icon = 'icons/obj/weapons/guns/magic.dmi'
icon_state = "frog_statue"
item_flags = NOBLUDGEON
///our pet frog
var/mob/living/contained_frog
///the summon cooldown
COOLDOWN_DECLARE(summon_cooldown)
/obj/item/frog_statue/attack_self(mob/user)
. = ..()
if(.)
return TRUE
if(!COOLDOWN_FINISHED(src, summon_cooldown))
user.balloon_alert(user, "recharging!")
return TRUE
COOLDOWN_START(src, summon_cooldown, 30 SECONDS)
if(isnull(contained_frog))
user.balloon_alert(user, "no frog linked!")
return TRUE
if(contained_frog.loc == src)
release_frog(user)
return TRUE
recall_frog(user)
return TRUE
/obj/item/frog_statue/examine(mob/user)
. = ..()
if(!IS_WIZARD(user))
return
if(isnull(contained_frog))
. += span_notice("There are currently no frogs linked to this statue!")
else
. += span_notice("Using it will [contained_frog in src ? "release" : "recall"] the beast!")
///resummon the frog into its home
/obj/item/frog_statue/proc/recall_frog(mob/user)
playsound(src, 'sound/items/frog_statue_release.ogg', 20)
user.Beam(contained_frog, icon_state = "lichbeam", time = RECALL_DURATION)
animate(contained_frog, transform = matrix().Scale(0.3, 0.3), time = RECALL_DURATION)
addtimer(CALLBACK(contained_frog, TYPE_PROC_REF(/atom/movable, forceMove), src), RECALL_DURATION)
///release the frog to wreak havoc
/obj/item/frog_statue/proc/release_frog(mob/user)
var/list/possible_turfs = list()
for(var/turf/possible_turf in oview(2, user))
if(possible_turf.is_blocked_turf() || isopenspaceturf(possible_turf))
continue
possible_turfs += possible_turf
playsound(src, 'sound/items/frog_statue_release.ogg', 50, TRUE)
var/turf/final_turf = length(possible_turfs) ? pick(possible_turfs) : get_turf(src)
user.Beam(final_turf, icon_state = "lichbeam", time = RECALL_DURATION)
contained_frog.forceMove(final_turf)
animate(contained_frog, transform = matrix(), time = RECALL_DURATION)
REMOVE_TRAIT(contained_frog, TRAIT_AI_PAUSED, MAGIC_TRAIT)
///set this frog as our inhabitor
/obj/item/frog_statue/proc/set_new_frog(mob/living/frog)
frog.transform = frog.transform.Scale(0.3, 0.3)
contained_frog = frog
animate_filter()
RegisterSignal(frog, COMSIG_QDELETING, PROC_REF(render_obsolete))
/// we have lost our frog, let out a scream!
/obj/item/frog_statue/proc/render_obsolete(datum/source)
SIGNAL_HANDLER
contained_frog = null
playsound(src, 'sound/magic/demon_dies.ogg', 50, TRUE)
UnregisterSignal(source, COMSIG_QDELETING)
/obj/item/frog_statue/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
. = ..()
if(arrived != contained_frog)
return
animate_filter()
ADD_TRAIT(contained_frog, TRAIT_AI_PAUSED, MAGIC_TRAIT)
if(contained_frog.health < contained_frog.maxHealth)
START_PROCESSING(SSobj, src)
/obj/item/frog_statue/process(seconds_per_tick)
if(isnull(contained_frog))
return
if(contained_frog.health == contained_frog.maxHealth)
STOP_PROCESSING(SSobj, src)
return
if(contained_frog.stat == DEAD)
contained_frog.revive()
contained_frog.adjustBruteLoss(-5)
/obj/item/frog_statue/proc/animate_filter(mob/living/frog)
add_filter(STATUE_FILTER, 2, list("type" = "outline", "color" = FILTER_COLOR, "size" = 1))
var/filter = get_filter(STATUE_FILTER)
animate(filter, alpha = 230, time = 2 SECONDS, loop = -1)
animate(alpha = 30, time = 0.5 SECONDS)
/obj/item/frog_statue/Exited(atom/movable/gone, direction)
. = ..()
if(gone != contained_frog)
return
clear_filters()
/obj/item/frog_contract
name = "frog contract"
desc = "Create a pact with an elder frog! This great beast will be your mount, protector, but most importantly your friend."
icon = 'icons/obj/scrolls.dmi'
icon_state = "scroll"
/obj/item/frog_contract/attack_self(mob/user)
. = ..()
if(.)
return TRUE
create_frog(user)
return TRUE
///customize our own frog and trap it into the statue
/obj/item/frog_contract/proc/create_frog(mob/user)
var/obj/item/frog_statue/statue = new(null)
var/mob/living/basic/leaper/new_frog = new(statue)
statue.set_new_frog(new_frog)
new_frog.befriend(user)
ADD_TRAIT(new_frog, TRAIT_AI_PAUSED, MAGIC_TRAIT)
select_frog_name(user, new_frog)
select_frog_color(user, new_frog)
user.put_in_hands(statue)
qdel(src)
/obj/item/frog_contract/proc/select_frog_name(mob/user, mob/new_frog)
var/frog_name = sanitize_name(tgui_input_text(user, "Choose your frog's name!", "Name pet toad", "leaper", MAX_NAME_LEN), allow_numbers = TRUE)
if(!frog_name)
to_chat(user, span_warning("Please enter a valid name."))
select_frog_name(user, new_frog)
return
new_frog.name = frog_name
/obj/item/frog_contract/proc/select_frog_color(mob/user, mob/living/basic/leaper/new_frog)
var/frog_color = input(user, "Select your frog's color!" , "Pet toad color", COLOR_GREEN) as color|null
if(isnull(frog_color))
to_chat(user, span_warning("Please choose a valid color."))
select_frog_color(user, new_frog)
return
var/list/hsv_frog = rgb2hsv(frog_color)
if(hsv_frog[3] < MINIMUM_COLOR_VALUE)
to_chat(user, span_danger("This color is too dark!"))
select_frog_color(user, new_frog)
return
new_frog.set_color_overlay(frog_color)
#undef STATUE_FILTER
#undef FILTER_COLOR
#undef RECALL_DURATION
#undef MINIMUM_COLOR_VALUE