Remove all our quirk species whitelist code (#4030)

## About The Pull Request

Upstream now has a system for this, removes all our override code and
changes the relevant quirks to use the upstream system instead

## Why It's Good For The Game

Fixes #3732 

## Proof Of Testing

Tested it on a local with sol weakness, masquerade, and hydrophillic,
the latter wasn't selectable unless you were a slime, the former two
weren't selectable unless you were a hemophage. Sol weakness was still
removed as normal if you turned into a bloodsucker

## Changelog

🆑
fix: fixed species-locked quirks not actually working
/🆑
This commit is contained in:
Roxy
2025-06-13 16:55:48 -04:00
committed by GitHub
parent 0f6c3a1879
commit 5f18ba4881
11 changed files with 18 additions and 96 deletions

View File

@@ -78,12 +78,6 @@
var/datum/quirk_constant_data/constant_data = GLOB.all_quirk_constant_data[quirk]
var/list/datum/preference/customization_options = constant_data?.get_customization_data()
// BUBBER EDIT START - Species only quirks
var/list/species_whitelist = list()
for(var/species_id in GLOB.quirk_species_whitelist[quirk])
var/datum/species/species_type = GLOB.species_list[species_id]
var/species_name = initial(species_type.name)
species_whitelist[species_id] += species_name // BUBBER EDIT END - Species only quirks
quirk_info[sanitize_css_class_name(quirk_name)] = list(
"description" = initial(quirk.desc),
"icon" = initial(quirk.icon),
@@ -91,7 +85,6 @@
"value" = initial(quirk.value),
"customizable" = constant_data?.is_customizable(),
"customization_options" = customization_options,
"species_whitelist" = species_whitelist, //BUBBER EDIT - Species quirks
)
return list(

View File

@@ -99,11 +99,6 @@
var/mob/living/carbon/human/new_character = allocate(/mob/living/carbon/human/consistent)
new_character.mind_initialize()
abstract_player.new_character = new_character
// BUBBER EDIT ADDITION BEGIN - Code to support testing our species-locked quirks
var/datum/quirk/quirk_instance = allocate(quirk_type)
if(length(quirk_instance.species_whitelist))
new_character.set_species(GLOB.species_list[quirk_instance.species_whitelist[1]])
// BUBBER EDIT ADDITION END - Code to support testing our species-locked quirks
if (!new_character.add_quirk(quirk_type, roundstart_mock_client))
TEST_FAIL("Failed to initialize quirk [quirk_type] on a roundstart character!")
@@ -112,10 +107,6 @@
latejoin_mock_client.prefs = new(latejoin_mock_client)
latejoin_character.mock_client = latejoin_mock_client
latejoin_character.mind_initialize()
// BUBBER EDIT ADDITION BEGIN - Code to support testing our species-locked quirks
if(length(quirk_instance.species_whitelist))
latejoin_character.set_species(GLOB.species_list[quirk_instance.species_whitelist[1]])
// BUBBER EDIT ADDITION END - Code to support testing our species-locked quirks
if (!latejoin_character.add_quirk(quirk_type, latejoin_mock_client))
TEST_FAIL("Failed to initialize quirk [quirk_type] on a latejoin character!")

View File

@@ -1,20 +1,3 @@
/// Neccesary for accessing non-instanced quirk whitelists, as initial() cannot access lists
GLOBAL_LIST_INIT(quirk_species_whitelist, generate_quirk_species_whitelist())
// unfortunately we have to instance the quirks here or otherwise we cannot access a list,
// initial cannot access lists as they're not actually compile-time constants, only initialized at runtime
/proc/generate_quirk_species_whitelist()
var/list/all_quirks = subtypesof(/datum/quirk)
var/list/quirk_species_whitelist = list()
for(var/quirk_type in all_quirks)
var/datum/quirk/quirk = new quirk_type()
if(length(quirk.species_whitelist))
quirk_species_whitelist[quirk.type] = list()
for(var/species_id in quirk.species_whitelist)
quirk_species_whitelist[quirk.type] += species_id
qdel(quirk)
return quirk_species_whitelist
//Permanent Limp Quirk
GLOBAL_LIST_INIT(permanent_limp_choice, list(
"Left, minor" = /datum/wound/perm_limp/left,

View File

@@ -1,21 +1,14 @@
/datum/quirk
// Is this quirk hidden from TGUI / the character preferences window?
var/hidden_quirk = FALSE
/// List of species that this quirk is valid for, or empty if it's valid for all species. Only use species ids here.
var/list/species_whitelist = list()
/// Blacklist of species for this quirk
var/list/species_blacklist = null
/// Whitelist of species for this quirk
var/list/species_whitelist = null
/datum/quirk/add_to_holder(mob/living/new_holder, quirk_transfer = FALSE, client/client_source, unique = TRUE)
if(!can_add(new_holder))
CRASH("Attempted to add quirk to holder that can't have it.")
. = ..()
/// Returns true if the quirk is valid for the target, call parent so qurk_species_whitelist can be checked.
/datum/quirk/proc/can_add(mob/target)
SHOULD_CALL_PARENT(TRUE)
if(length(species_whitelist))
if(!ishuman(target))
return FALSE
var/mob/living/carbon/human = target
if(!(human?.dna.species.id in species_whitelist))
return FALSE
return TRUE
/datum/quirk/is_species_appropriate(datum/species/mob_species)
if(LAZYLEN(species_blacklist) && (mob_species.id in species_blacklist))
return FALSE
if(LAZYLEN(species_whitelist) && !(mob_species.id in species_whitelist))
return FALSE
return ..()

View File

@@ -14,10 +14,15 @@
They will have to hide in a coffin or a closet during the day, or risk burning to a crisp."
value = -4
hardcore_value = 6
species_whitelist = list(SPECIES_HEMOPHAGE)
quirk_flags = QUIRK_HIDE_FROM_SCAN | QUIRK_HUMAN_ONLY
species_whitelist = list(SPECIES_HEMOPHAGE)
COOLDOWN_DECLARE(sun_burn)
/datum/quirk/sol_weakness/add_to_holder(mob/living/new_holder, quirk_transfer = FALSE, client/client_source, unique = TRUE)
if(IS_BLOODSUCKER(new_holder))
return FALSE
return ..()
/datum/quirk/sol_weakness/add()
RegisterSignal(quirk_holder, COMSIG_MOB_HEMO_BLOOD_REGEN_TICK, PROC_REF(on_blood_healing))
if(!quirk_holder.hud_used)
@@ -30,12 +35,6 @@
SSsunlight.remove_sun_sufferer(quirk_holder)
UnregisterSignal(SSsunlight, list(COMSIG_SOL_RISE_TICK, COMSIG_SOL_WARNING_GIVEN))
/datum/quirk/sol_weakness/can_add(mob/target)
. = ..()
if(!.)
return
return !IS_BLOODSUCKER(target)
/datum/quirk/sol_weakness/proc/on_blood_healing(mob/owner, seconds_between_ticks, datum/status_effect/blood_regen_active/effect)
if(effect && in_coffin())
// cheaper healing as long as you're in a coffin

View File

@@ -4,9 +4,9 @@
icon = FA_ICON_BUG // I can't be asked to make an icon for this, my spritework sucks.
value = 0
quirk_flags = QUIRK_HUMAN_ONLY
species_whitelist = list(SPECIES_SLIMESTART)
gain_text = span_danger("You get the feeling you should stay away from water...")
lose_text = span_notice("Somehow, you feel as if water is no longer dangerous.")
medical_record_text = "Patient scans indicate extreme hydrophilicity."
hardcore_value = 0
mob_trait = TRAIT_HYDROPHILIC
species_whitelist = list(SPECIES_SLIMESTART)

View File

@@ -3,8 +3,8 @@
desc = "A hemophage that has adapted to be able to consume normal food and drink. Such an act is merely for pleasure, as they derive no nutritional benefit from such."
icon = FA_ICON_MASKS_THEATER
value = 2
species_whitelist = list(SPECIES_HEMOPHAGE)
mob_trait = TRAIT_MASQUERADE_FOOD
gain_text = span_notice("You feel that your body has adapted to consumption of normal food and drink without mixing in blood.")
lose_text = span_danger("You feel that your body is no longer able to consume normal food or drink without mixing in blood.")
medical_record_text = "Patient is able to consume food or drink without having to mix in blood, though they derive no nutritional benefit from it."
species_whitelist = list(SPECIES_HEMOPHAGE)

View File

@@ -1,18 +0,0 @@
// Remove any invalid quirks by the species whitelist
/datum/preference_middleware/species/post_set_preference(mob/user, preference, value)
. = ..()
var/species_id = value // one of the options that this can be is species_id, but it can be other things as well annoyingly
if(preference != "species" || !length(GLOB.quirk_species_whitelist) || !species_id)
return .
var/needs_update = FALSE
for(var/quirk_name as anything in preferences.all_quirks)
var/datum/quirk/quirk_type = SSquirks.quirks[quirk_name]
var/list/species_whitelist = GLOB.quirk_species_whitelist[quirk_type]
if(!length(species_whitelist) || (species_id in species_whitelist))
continue
preferences.all_quirks -= quirk_name
needs_update = TRUE
if(needs_update)
preferences.update_static_data(user)
return .

View File

@@ -9208,7 +9208,6 @@
#include "modular_zubbers\code\modules\client\autopunctuation\preferences.dm"
#include "modular_zubbers\code\modules\client\flavor_text\flavor_text.dm"
#include "modular_zubbers\code\modules\client\preferences\permanent_limp.dm"
#include "modular_zubbers\code\modules\client\preferences\middleware\species.dm"
#include "modular_zubbers\code\modules\client\verbs\character_directory.dm"
#include "modular_zubbers\code\modules\clothing\_job.dm"
#include "modular_zubbers\code\modules\clothing\donator_clothing.dm"

View File

@@ -341,7 +341,6 @@ export function QuirksPage(props) {
positiveQuirks += 1;
}
balance += selectedQuirk.value;
*/ // BUBBER EDIT END
}
@@ -374,22 +373,6 @@ export function QuirksPage(props) {
return `This is incompatible with ${incompatibleQuirk}!`;
}
}
// BUBBER EDIT ADDITION START - Species quirks
const currentSpeciesID = data.character_preferences.misc.species;
// keys are the species_ids, values are the species names
const speciesWhitelistKeys = Object.keys(quirk.species_whitelist);
if (
speciesWhitelistKeys?.length &&
!speciesWhitelistKeys.includes(currentSpeciesID)
) {
const speciesWhitelistNames = Object.values(quirk.species_whitelist);
if (speciesWhitelistNames.length === 1) {
return `This quirk can only be taken by the ${speciesWhitelistNames[0]} species.`;
}
const speciesList = speciesWhitelistNames.join(', ');
return `This quirk can only be taken by the following species: ${speciesList}.`;
}
// BUBBER EDIT ADDITION END
}
if (data.species_disallowed_quirks.includes(quirk.name)) {
return 'This quirk is incompatible with your selected species.';

View File

@@ -93,7 +93,6 @@ export type Quirk = {
value: number;
customizable: boolean;
customization_options?: string[];
species_whitelist: Record<string, string>[]; // BUBBER EDIT ADDITION - Species quirks
};
// SKYRAT EDIT START