Files
Bubberstation/code/modules/bitrunning/components/avatar_gear.dm
_0Steven fe1e071499 Bitrunning Gimmick Loadout Disks (feat. minor disk load refactor) (#88716)
## About The Pull Request

Where I forget about a pr for 5 months.

This started because there was a pr that made it so skills transfer
between the real and the digital, and so I thought it'd be really funny
if I could train boxing in virtual reality... but there's no easy way to
get boxing gloves or anything like it in the virtual world...
So! I decided to make a disk for it, but then thought about fishing and
gaming and-
Anyhow it all went downhill from there and here we are now: Gimmick
Disks. (And a refactor of disk loading)

This implements a new type of bitrunning disk that instead of a single
item or ability, grants a full set of thematic items/abilities!
Unhelpfully cosplay as a wizard! Game inside your game! Down a digital
protein shake and box some simplemobs!
As the name "Gimmick" implies, these are primarily intended to help
shake up the sometimes stale bitrunner gameplay.
By letting you invoke, if you so desire, what to me is the most
enjoyable gaming experience: doing stupid shit with your buddies.

To facilitate the new type of disk I had to refactor disk loading, as it
was hardcoded to the item types.
Instead, we make disk loading send a signal to the bitrunner, and
register for this when held in their inventory.
This allows us to do things like making the lead acid battery give you
shock touch when held, without needing to make an explicit typecheck or
iterate over every item in the bitrunner's nested contents to see if
they have a loadable item.
## Why It's Good For The Game

I think it'd be really funny if you could train your boxing in the
digital realm.
As said above, I feel the bitrunner gameplay can get stale sometimes,
and this is how I hope to help people shake it up for themselves
sometimes. By giving them more stupid shit to do.
Doing stupid extended bits with other people is one of the things I
enjoy most out of ss13, and this is there to let the bitrunners do
exactly that with each other.

And sometimes you just have to roleplay as Gamers™️ entering virtual
reality to fight the virtual syndicate in bad cosplay while roleplaying
as a wizard smoking his magic weed, an overly edgy rogue, and the healer
desperately trying to keep them from exploding into a million pieces.
## Changelog
🆑
refactor: Bitrunning item/ability loading has been refactored. Please
report any issues.
add: Added Bitrunning gimmick loadout disks. These disks contain full
sets of equipment for all your digital cosplay needs, each including
questionably helpful equipment. Currently includes Sports (Boxer,
Skater, Archer, Fisher, Gamer) and Dungeon Crawling (Alchemist, Rogue,
Healer, Wizard).
add: Taking a lead acid battery into the netpod with you now gives your
bit avatar shock touch.
/🆑
2025-01-30 13:17:08 +01:00

68 lines
2.4 KiB
Plaintext

/// Tracks the highest up human carrying this item, and loads bitrunning gear onto their avatar when they enter a virtual domain
/datum/component/loads_avatar_gear
/// The callback called when COMSIG_BITRUNNER_STOCKING_GEAR is sent to our host human
var/datum/callback/load_callback
/// Weakref to the human we are currently carried by
var/datum/weakref/tracked_human_ref
/datum/component/loads_avatar_gear/Initialize(datum/callback/load_callback)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
src.load_callback = load_callback
/datum/component/loads_avatar_gear/RegisterWithParent()
RegisterSignal(parent, COMSIG_ATOM_ENTERING, PROC_REF(on_entered_loc))
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERING = PROC_REF(on_entered_loc),
)
AddComponent(/datum/component/connect_containers, parent, loc_connections)
/datum/component/loads_avatar_gear/UnregisterFromParent()
UnregisterSignal(parent, list(
COMSIG_ATOM_ENTERING,
))
qdel(GetComponent(/datum/component/connect_containers))
/datum/component/loads_avatar_gear/Destroy(force)
load_callback = null
tracked_human_ref = null
return ..()
/datum/component/loads_avatar_gear/proc/on_entered_loc(datum/source, atom/destination, atom/old_loc, list/atom/old_locs)
SIGNAL_HANDLER
// No need to do checks if we're just moving turfs
if(isturf(destination) && isturf(old_loc))
return
// Iterate over list in reverse so we get the topmost human first
// Because it's funnier if you get to use the avatar gear of the people you're carrying
var/list/nested_locs = get_nested_locs(parent)
for(var/i in length(nested_locs) to 1 step -1)
var/atom/container = nested_locs[i]
if(ishuman(container))
switch_tracking(container)
return
// No humans found, stop tracking
switch_tracking(null)
/datum/component/loads_avatar_gear/proc/switch_tracking(mob/living/carbon/human/to_track)
var/mob/living/carbon/human/tracked_human = tracked_human_ref?.resolve()
if(tracked_human == to_track)
return
if(tracked_human)
UnregisterSignal(tracked_human, COMSIG_BITRUNNER_STOCKING_GEAR)
tracked_human_ref = WEAKREF(to_track)
RegisterSignal(to_track, COMSIG_BITRUNNER_STOCKING_GEAR, PROC_REF(load_onto_avatar))
/datum/component/loads_avatar_gear/proc/load_onto_avatar(mob/living/carbon/human/neo, mob/living/carbon/human/avatar, external_load_flags)
SIGNAL_HANDLER
return load_callback?.Invoke(neo, avatar, external_load_flags)