Gives AIs on Lowpop a Halcyon Pearl (#1385)

* Adds halcyon pearls and makes them spawn next to new AIs once per round.
This commit is contained in:
QuiteLiterallyAnything
2025-03-26 15:19:04 -07:00
committed by GitHub
parent 9f0a6342df
commit 91bfcfc944
4 changed files with 122 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
/// Used by the Halcyon pearl which can spawn near AIs on lowpop.
#define HALCYON_SONG "BPM: 120\nG4,C5,D5,E5,D,C,G,C4,G,C5,D,E/0.65,C/0.65,G,C4,G,C5,D,E,D,C,G,C4,G,C5,D,E/0.65,C/0.65,G,D4,A4,D5,E,F5,E,D,A,D4,A,D5,E,F/0.65,D/0.65,A,D4,A,D5,E,F,E,D,A,D4,A,D5,E,F/0.65,D/0.65,A,C4,G,C5,D,E,D,C,G\nC4,G,C5,D,E/0.65,C/0.65,G,C4,G,C5,D,E,D,C,G,C4,G,C5,D,E/0.65,C/0.65,G,D4,A/13,G5/1.3,C6/6.5,D5/1.62,D6/2.17,E/3.25,E6/1.44,F/13,D/1.3,C/6.5,E5/1.62,G/2.17,D5/3.25,C5/1.44,A/13,G/1.3,C6/6.5,D4/1.62\nD6/2.17,A/3.25,E6/1.44,D5/2.17,C/1.86,E5/1.62,G/2.6,F/2.6,C5/1.3,G/2.6,D/2.6,C6/1.3,D6/2.6,A/2.6,E6/1.44,D4/13,D6/1.3,C/6.5,A/1.62,G/2.6,D5/2.6,C5/1.44,E5/13,G/1.18,C6/13,F/1.08,D6/13,E/1.08,E6/13\nD5,A/2.17,C/1.62,D4/1.08,G/13,A/1.08,C5/13,D5,E5,F/0.65,D/0.65,A,C4/0.65"

View File

@@ -0,0 +1,118 @@
/// An instrument that spawns in the AI satellite on lowpop (reference to Rain World: Downpour)
/// Hardcoded to only play a rough version of "Halcyon Memories"
/// (https://www.youtube.com/watch?v=z04shakaUcE)
/obj/item/instrument/halcyon_pearl
name = "Strange Pearl"
desc = "A purple pearl that resonates with subtle warmth."
force = 1
max_integrity = 200
resistance_flags = FIRE_PROOF | ACID_PROOF
icon = 'fulp_modules/icons/toys/instruments.dmi'
icon_state = "halcyon_pearl"
base_icon_state = "halcyon_pearl"
inhand_icon_state = "harmonica"
allowed_instrument_ids = "sine"
hitsound = 'sound/effects/rock/rocktap1.ogg'
/obj/item/instrument/halcyon_pearl/Initialize(mapload)
. = ..()
var/song_lines = HALCYON_SONG
song.note_shift = 12
song.ParseSong(new_song = song_lines)
// So it can float when active.
AddElement(/datum/element/movetype_handler)
register_context()
RegisterSignal(src, COMSIG_INSTRUMENT_START, PROC_REF(on_instrument_start))
RegisterSignal(src, COMSIG_INSTRUMENT_END, PROC_REF(on_instrument_end))
/obj/item/instrument/halcyon_pearl/Destroy()
. = ..()
UnregisterSignal(src, list(COMSIG_INSTRUMENT_START, COMSIG_INSTRUMENT_END))
/obj/item/instrument/halcyon_pearl/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if(!isAI(user))
return NONE
if(in_range(src, user))
context[SCREENTIP_CONTEXT_CTRL_LMB] = "Toggle [song.playing ? "Off" : "On"]"
context[SCREENTIP_CONTEXT_SHIFT_LMB] = "Maximize Song Duration"
else
context[SCREENTIP_CONTEXT_CTRL_LMB] = "ERR% TARGET OUT OF RANGE"
return CONTEXTUAL_SCREENTIP_SET
/obj/item/instrument/halcyon_pearl/examine(mob/user)
. = ..()
if(!isAI(user))
. += span_notice("It looks vaguely electronic— an <b>AI</b> might be able to interface with it.")
else
. += span_notice("This is an exotic data storage device that you could probably manipulate at close-range.")
/obj/item/instrument/halcyon_pearl/ui_interact(mob/user, datum/tgui/ui)
if(isliving(user))
to_chat(user, span_notice("You're not sure how to operate it..."))
/obj/item/instrument/halcyon_pearl/AICtrlClick(mob/living/silicon/ai/user)
. = ..()
if(song.playing)
song.stop_playing()
else
song.start_playing(user)
/obj/item/instrument/halcyon_pearl/AIShiftClick(mob/living/silicon/ai/user)
. = ..()
song.repeat = 10
/obj/item/instrument/halcyon_pearl/proc/on_instrument_start()
SIGNAL_HANDLER
ADD_TRAIT(src, TRAIT_MOVE_FLOATING, TRAIT_GENERIC)
update_appearance(UPDATE_ICON)
/obj/item/instrument/halcyon_pearl/proc/on_instrument_end()
SIGNAL_HANDLER
REMOVE_TRAIT(src, TRAIT_MOVE_FLOATING, TRAIT_GENERIC)
update_appearance(UPDATE_ICON)
/obj/item/instrument/halcyon_pearl/update_icon_state()
. = ..()
if(HAS_TRAIT(src, TRAIT_MOVE_FLOATING))
icon_state = "[base_icon_state]_active"
else
icon_state = base_icon_state
//////////////////////////////////////////////////////////////////
/// "OVERRIDES" SO THAT THE PEARL ACTUALLY SPAWNS IN ///
//////////////////////////////////////////////////////////////////
/// Overriding 'Initialize()' causes the spawn turf location logic to become faulty for some reason,
/// so we'll just "override" the preexisting 'after_round_start()' proc with itself and then append
/// the necessary code.
/obj/effect/landmark/start/ai/after_round_start()
. = ..()
if(!primary_ai)
return
// If at lowpop then find a turf to spawn a halcyon pearl at.
// This turf should always be directly above or below the AI start landmark.
// (If it's to the left or right then it'll pan/sound weird; if it's not right next to them then
// they can't use it.)
if(!at_lowpop())
return
// The landmark's turf.
var/turf/source_turf = get_turf(src)
// The turf we'll ultimately end up spawning the pearl at.
// Defaults to our 'source_turf' just in case we can't find a better alternative.
var/turf/open/target_turf = source_turf
for(var/turf/open/open_turf in orange(1, source_turf))
if(open_turf == source_turf)
continue
if(open_turf.x == src.loc.x)
target_turf = open_turf
break
new /obj/item/instrument/halcyon_pearl(target_turf)

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

View File

@@ -404,6 +404,7 @@
#include "code\__DEFINES\fulp_defines\fulp_helpers.dm"
#include "code\__DEFINES\fulp_defines\mentors.dm"
#include "code\__DEFINES\fulp_defines\nanites.dm"
#include "code\__DEFINES\fulp_defines\song.dm"
#include "code\__DEFINES\fulp_defines\species_defines.dm"
#include "code\__DEFINES\fulp_defines\traits.dm"
#include "code\__DEFINES\research\anomalies.dm"
@@ -6788,6 +6789,7 @@
#include "fulp_modules\features\spells\spell_granters\_fulp_spell_granter.dm"
#include "fulp_modules\features\spells\spell_granters\direct_cat_meteor.dm"
#include "fulp_modules\features\spells\spell_granters\summon_dancefloor.dm"
#include "fulp_modules\features\toys\code\halcyon_pearl.dm"
#include "fulp_modules\features\toys\code\plushies.dm"
#include "fulp_modules\features\toys\code\shrimp_plush.dm"
#include "fulp_modules\fulp_world\_global_vars.dm"