mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-21 17:06:35 +01:00
70 lines
2.3 KiB
Plaintext
70 lines
2.3 KiB
Plaintext
//* This file is explicitly licensed under the MIT license. *//
|
|
//* Copyright (c) 2024 Citadel Station Developers *//
|
|
|
|
/**
|
|
* Arbitrary holder for string-sequence combos.
|
|
*
|
|
* * Precomputes variables used in checking.
|
|
* * Owns the /datum/combo's in it; other things should never edit or delete them unless changing the entire combo set.
|
|
*
|
|
* ## Hey! Listen!
|
|
*
|
|
* * A design flaw in how /datum/combo_tracker works means that combo sets and their internal combos **will** be hard referenced
|
|
* and there's currently no way to inform holders to clear ref when we're being deleted. For now.
|
|
* A component signal system will be added later. For now, until we need to start deleting these / runtime-generating,
|
|
* please store combo sets in global variables.
|
|
*/
|
|
/datum/combo_set
|
|
/// expected combo type
|
|
var/expected_combo_type = /datum/combo
|
|
/// combos;
|
|
/// * set to typepaths or anonymous types to init on New()
|
|
var/list/datum/combo/combos = list()
|
|
/// cached: max sequence length of any combo's keys
|
|
var/tmp/computed_max_sequence_length = 0
|
|
|
|
/datum/combo_set/New(list/datum/combo/combos = src.combos)
|
|
src.combos = combos
|
|
hydrate()
|
|
reload()
|
|
|
|
/datum/combo_set/Destroy()
|
|
QDEL_NULL(combos)
|
|
return ..()
|
|
|
|
/datum/combo_set/proc/hydrate()
|
|
for(var/i in 1 to length(combos))
|
|
var/datum/combo/maybe_combo = combos[i]
|
|
if(ispath(maybe_combo))
|
|
maybe_combo = new maybe_combo
|
|
else if(IS_ANONYMOUS_TYPEPATH(maybe_combo))
|
|
maybe_combo = new maybe_combo
|
|
combos[i] = maybe_combo
|
|
|
|
/datum/combo_set/proc/reload()
|
|
computed_max_sequence_length = 0
|
|
|
|
for(var/datum/combo/combo as anything in combos)
|
|
computed_max_sequence_length = max(computed_max_sequence_length, combo.get_length())
|
|
|
|
/**
|
|
* check tail match, where 1 to n is first to last of current combo;
|
|
* returns the first combo resolved from the current stored set
|
|
*
|
|
* @return /datum/combo instance or null
|
|
*/
|
|
/datum/combo_set/proc/simple_tail_match(list/keys_so_far)
|
|
var/stored_length = length(keys_so_far)
|
|
var/offset = min(0, stored_length - computed_max_sequence_length)
|
|
for(var/datum/combo/combo as anything in combos)
|
|
if(length(combo.keys) > stored_length)
|
|
continue
|
|
var/adjusted_offset = offset + (computed_max_sequence_length - length(combo.keys))
|
|
for(var/i in 1 to length(combo.keys))
|
|
if(combo.keys[i] != keys_so_far[adjusted_offset + i])
|
|
continue
|
|
. = combo
|
|
break
|
|
if(.)
|
|
break
|