From e0d15d0f79dae4ec7169d0ea5e2123882cdf7598 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Wed, 28 Jul 2021 00:30:00 +0100 Subject: [PATCH] Trait Define Refactor (#16327) * Adminordrazine fix * Trait Define Refactor * Fixes 1 * target.status_traits --- code/__HELPERS/traits.dm | 164 ++++++++++-------- .../reagents/chemistry/reagents/admin.dm | 2 +- 2 files changed, 95 insertions(+), 71 deletions(-) diff --git a/code/__HELPERS/traits.dm b/code/__HELPERS/traits.dm index a6d288d6af0..5534c19cdd1 100644 --- a/code/__HELPERS/traits.dm +++ b/code/__HELPERS/traits.dm @@ -2,89 +2,113 @@ #define SIGNAL_REMOVETRAIT(trait_ref) "removetrait [trait_ref]" // trait accessor defines + +/** + * Adds a status trait to the target datum. + * + * Arguments: (All Required) + * * target - The datum to add the trait to. + * * trait - The trait which is being added. + * * source - The source of the trait which is being added. + */ #define ADD_TRAIT(target, trait, source) \ do { \ - var/list/_L; \ - if (!target.status_traits) { \ - target.status_traits = list(); \ - _L = target.status_traits; \ - _L[trait] = list(source); \ - SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \ + LAZYINITLIST(target.status_traits); \ +\ + if(!target.status_traits[trait]) { \ + target.status_traits[trait] = list(source); \ } else { \ - _L = target.status_traits; \ - if (_L[trait]) { \ - _L[trait] |= list(source); \ - } else { \ - _L[trait] = list(source); \ - SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \ + target.status_traits[trait] |= list(source); \ + } \ +\ + SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \ + } while (0) + +/** + * Removes a status trait from a target datum. + * + * `ROUNDSTART_TRAIT` traits can't be removed without being specified in `sources`. + * Arguments: + * * target - The datum to remove the trait from. + * * trait - The trait which is being removed. + * * sources - If specified, only remove the trait if it is from this source. (Lists Supported) + */ +#define REMOVE_TRAIT(target, trait, sources) \ + do { \ + if(target.status_traits && target.status_traits[trait]) { \ + var/list/SOURCES = sources; \ + if(sources && !islist(sources)) { \ + SOURCES = list(sources); \ + } \ +\ + for(var/TRAIT_SOURCE in target.status_traits[trait]) { \ + if((!SOURCES && (TRAIT_SOURCE != ROUNDSTART_TRAIT)) || (TRAIT_SOURCE in SOURCES)) { \ + if(length(target.status_traits[trait]) == 1) { \ + SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(trait), trait); \ + } \ + LAZYREMOVEASSOC(target.status_traits, trait, TRAIT_SOURCE); \ + } \ } \ } \ } while (0) -#define REMOVE_TRAIT(target, trait, sources) \ - do { \ - var/list/_L = target.status_traits; \ - var/list/_S; \ - if (sources && !islist(sources)) { \ - _S = list(sources); \ - } else { \ - _S = sources\ - }; \ - if (_L && _L[trait]) { \ - for (var/_T in _L[trait]) { \ - if ((!_S && (_T != ROUNDSTART_TRAIT)) || (_T in _S)) { \ - _L[trait] -= _T \ - } \ - };\ - if (!length(_L[trait])) { \ - _L -= trait; \ - SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(trait), trait); \ - }; \ - if (!length(_L)) { \ - target.status_traits = null \ - }; \ - } \ - } while (0) + +/** + * Removes all status traits from a target datum which were NOT added by `sources`. + * + * Arguments: + * * target - The datum to remove the traits from. + * * sources - The trait source which is being searched for. + */ #define REMOVE_TRAITS_NOT_IN(target, sources) \ do { \ - var/list/_L = target.status_traits; \ - var/list/_S = sources; \ - if (_L) { \ - for (var/_T in _L) { \ - _L[_T] &= _S;\ - if (!length(_L[_T])) { \ - _L -= _T; \ - SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T), _T); \ - }; \ - };\ - if (!length(_L)) { \ - target.status_traits = null\ - };\ - }\ + if(target.status_traits) { \ + var/list/SOURCES = sources; \ + if(!islist(sources)) { \ + SOURCES = list(sources); \ + } \ +\ + for(var/TRAIT in target.status_traits) { \ + target.status_traits[TRAIT] &= SOURCES; \ + if(!length(target.status_traits[TRAIT])) { \ + target.status_traits -= TRAIT; \ + SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(TRAIT), TRAIT); \ + } \ + } \ + if(!length(target.status_traits)) { \ + target.status_traits = null; \ + } \ + } \ } while (0) +/** + * Removes all status traits from a target datum which were added by `sources`. + * + * Arguments: + * * target - The datum to remove the traits from. + * * sources - The trait source which is being searched for. + */ #define REMOVE_TRAITS_IN(target, sources) \ do { \ - var/list/_L = target.status_traits; \ - var/list/_S = sources; \ - if (sources && !islist(sources)) { \ - _S = list(sources); \ - } else { \ - _S = sources\ - }; \ - if (_L) { \ - for (var/_T in _L) { \ - _L[_T] -= _S;\ - if (!length(_L[_T])) { \ - _L -= _T; \ - SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T)); \ - }; \ - };\ - if (!length(_L)) { \ - target.status_traits = null\ - };\ - }\ + if(target.status_traits) { \ + var/list/SOURCES = sources; \ + if(!islist(sources)) { \ + SOURCES = list(sources); \ + } \ +\ + for(var/TRAIT in target.status_traits) { \ + target.status_traits[TRAIT] -= SOURCES; \ + if(!length(target.status_traits[TRAIT])) { \ + target.status_traits -= TRAIT; \ + SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(TRAIT)); \ + } \ + } \ + if(!length(target.status_traits)) { \ + target.status_traits = null; \ + } \ + } \ } while (0) + #define HAS_TRAIT(target, trait) (target.status_traits ? (target.status_traits[trait] ? TRUE : FALSE) : FALSE) #define HAS_TRAIT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (source in target.status_traits[trait]) : FALSE) : FALSE) #define HAS_TRAIT_FROM_ONLY(target, trait, source) (\ @@ -185,4 +209,4 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" //traits that should be properly converted to genetic mutations one day -#define TRAIT_LASEREYES "laser_eyes" +#define TRAIT_LASEREYES "laser_eyes" diff --git a/code/modules/reagents/chemistry/reagents/admin.dm b/code/modules/reagents/chemistry/reagents/admin.dm index 9ebad4be89f..c4faf9e86a7 100644 --- a/code/modules/reagents/chemistry/reagents/admin.dm +++ b/code/modules/reagents/chemistry/reagents/admin.dm @@ -39,7 +39,7 @@ M.SetParalysis(0, FALSE) M.SetSilence(0, FALSE) M.SetHallucinate(0) - REMOVE_TRAITS_NOT_IN(M, list(ROUNDSTART_TRAIT)) + REMOVE_TRAITS_NOT_IN(M, list(ROUNDSTART_TRAIT, SPECIES_TRAIT)) M.SetDizzy(0) M.SetDrowsy(0) M.SetStuttering(0)