From 1f665ef7f730fcc8aa7bde2ab5287b98cb86a2da Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Thu, 25 Feb 2021 14:37:25 +0100 Subject: [PATCH] [MIRROR] Beauty is now an element. Fixing an issue with enter/exit area comsigs. (#3639) * Beauty is now an element. Fixing an issue with enter/exit area comsigs. (#57147) Co-authored-by: Ghommie <425422238+Ghommie@ users.noreply.github.com> * Beauty is now an element. Fixing an issue with enter/exit area comsigs. Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> Co-authored-by: Ghommie <425422238+Ghommie@ users.noreply.github.com> --- code/__DEFINES/dcs/signals.dm | 4 +- code/__DEFINES/traits.dm | 9 +++ code/__HELPERS/unsorted.dm | 11 +++ code/datums/components/beauty.dm | 57 --------------- code/datums/components/fantasy/prefixes.dm | 8 +-- code/datums/components/mood.dm | 2 + code/datums/elements/beauty.dm | 69 +++++++++++++++++++ code/datums/materials/_material.dm | 6 +- code/game/area/areas.dm | 10 +-- code/game/atoms_movable.dm | 28 ++++++++ code/game/machinery/_machinery.dm | 1 + code/game/objects/effects/contraband.dm | 2 +- code/game/objects/effects/decals/cleanable.dm | 2 +- code/game/objects/items/weaponry.dm | 2 +- code/game/objects/structures/flora.dm | 2 +- code/game/objects/structures/statues.dm | 2 +- code/modules/shuttle/special.dm | 2 + tgstation.dme | 2 +- 18 files changed, 143 insertions(+), 76 deletions(-) delete mode 100644 code/datums/components/beauty.dm create mode 100644 code/datums/elements/beauty.dm diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 33157167745..1e5f6703642 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -287,9 +287,9 @@ ///////////////// -///from base of area/Entered(): (/area) +///from base of area/Entered(): (/area). Sent to "area-sensitive" movables, see __DEFINES/traits.dm for info. #define COMSIG_ENTER_AREA "enter_area" -///from base of area/Exited(): (/area) +///from base of area/Exited(): (/area). Sent to "area-sensitive" movables, see __DEFINES/traits.dm for info. #define COMSIG_EXIT_AREA "exit_area" ///from base of atom/Click(): (location, control, params, mob/user) #define COMSIG_CLICK "atom_click" diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index bb13f919cfb..f3afceeae5f 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -313,6 +313,12 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Used for limbs. #define TRAIT_DISABLED_BY_WOUND "disabled-by-wound" +/* + * Used for movables that need to be updated, via COMSIG_ENTER_AREA and COMSIG_EXIT_AREA, when transitioning areas. + * Use [/atom/movable/proc/become_area_sensitive(trait_source)] to properly enable it. How you remove it isn't as important. + */ +#define TRAIT_AREA_SENSITIVE "area-sensitive" + ///Used for managing KEEP_TOGETHER in [/atom/var/appearance_flags] #define TRAIT_KEEP_TOGETHER "keep-together" @@ -504,6 +510,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define BERSERK_TRAIT "berserk_trait" /// Trait granted by lipstick #define LIPSTICK_TRAIT "lipstick_trait" +/// Self-explainatory. +#define BEAUTY_ELEMENT_TRAIT "beauty_element" +#define MOOD_COMPONENT_TRAIT "mood_component" /** * Trait granted by [/mob/living/carbon/Initialize] and diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 63bf5f6e4d1..8d43dd4d84d 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -339,6 +339,17 @@ Turf and target are separate in case you want to teleport some distance from a t break return loc +//Returns a list of all locations (except the area) the movable is within. +/proc/get_nested_locs(atom/movable/AM, include_turf = FALSE) + . = list() + var/atom/location = AM.loc + var/turf/turf = get_turf(AM) + while(location && location != turf) + . += location + location = location.loc + if(location && include_turf) //At this point, only the turf is left, provided it exists. + . += location + // returns the turf located at the map edge in the specified direction relative to A // used for mass driver /proc/get_edge_target_turf(atom/A, direction) diff --git a/code/datums/components/beauty.dm b/code/datums/components/beauty.dm deleted file mode 100644 index 89564119fa1..00000000000 --- a/code/datums/components/beauty.dm +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Beauty component, makes the indoor area the parent is in prettier or uglier depending on the beauty var. - * Clean and well decorated areas lead to positive moodlets for passerbies, while shabbier, dirtier ones - * lead to negative moodlets exclusive to characters with the snob quirk. - * - * Keep in mind AddComponent is used for BOTH adding and removing beauty value here, - * so please don't use qdel/RemoveComponent unless necessary. - */ -/datum/component/beauty - var/beauty = 0 - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - -/datum/component/beauty/Initialize(beautyamount) - if(!isatom(parent) || isarea(parent)) - return COMPONENT_INCOMPATIBLE - - beauty = beautyamount - - if(ismovable(parent)) - RegisterSignal(parent, COMSIG_ENTER_AREA, .proc/enter_area) - RegisterSignal(parent, COMSIG_EXIT_AREA, .proc/exit_area) - - var/area/A = get_area(parent) - if(A) - enter_area(null, A) - -/datum/component/beauty/proc/enter_area(datum/source, area/A) - SIGNAL_HANDLER - - if(A.outdoors) - return - A.totalbeauty += beauty - A.update_beauty() - -/datum/component/beauty/proc/exit_area(datum/source, area/A) - SIGNAL_HANDLER - - if(A.outdoors) - return - A.totalbeauty -= beauty - A.update_beauty() - -/datum/component/beauty/InheritComponent(datum/component/beauty/new_comp , i_am_original, beautyamount) - if((beauty + beautyamount) == 0) - qdel(src) - return - beauty += beautyamount - var/area/A = get_area(parent) - if(A && !A.outdoors) - A.totalbeauty += beautyamount - A.update_beauty() - -/datum/component/beauty/Destroy() - . = ..() - var/area/A = get_area(parent) - if(A) - exit_area(null, A) diff --git a/code/datums/components/fantasy/prefixes.dm b/code/datums/components/fantasy/prefixes.dm index 3233853c7bc..1c42f0cc6bf 100644 --- a/code/datums/components/fantasy/prefixes.dm +++ b/code/datums/components/fantasy/prefixes.dm @@ -73,12 +73,12 @@ /datum/fantasy_affix/beautiful/apply(datum/component/fantasy/comp, newName) var/obj/item/master = comp.parent - master.AddComponent(/datum/component/beauty, max(comp.quality, 1) * 250) + master.AddElement(/datum/element/beauty, max(comp.quality, 1) * 250) return "[pick("aesthetic", "beautiful", "gorgeous", "pretty")] [newName]" /datum/fantasy_affix/beautiful/remove(datum/component/fantasy/comp) var/obj/item/master = comp.parent - master.AddComponent(/datum/component/beauty, -max(comp.quality, 1) * 250) + master.RemoveElement(/datum/element/beauty, max(comp.quality, 1) * 250) /datum/fantasy_affix/ugly placement = AFFIX_PREFIX @@ -86,9 +86,9 @@ /datum/fantasy_affix/ugly/apply(datum/component/fantasy/comp, newName) var/obj/item/master = comp.parent - master.AddComponent(/datum/component/beauty, min(comp.quality, -1) * 250) + master.AddElement(/datum/element/beauty, min(comp.quality, -1) * 250) return "[pick("fugly", "ugly", "grotesque", "hideous")] [newName]" /datum/fantasy_affix/ugly/remove(datum/component/fantasy/comp) var/obj/item/master = comp.parent - master.AddComponent(/datum/component/beauty, -min(comp.quality, -1) * 250) + master.AddElement(/datum/element/beauty, min(comp.quality, -1) * 250) diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 2c3460663ec..4b9c7fc85f1 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -29,6 +29,7 @@ RegisterSignal(parent, COMSIG_VOID_MASK_ACT, .proc/direct_sanity_drain) var/mob/living/owner = parent + owner.become_area_sensitive(MOOD_COMPONENT_TRAIT) if(owner.hud_used) modify_hud() var/datum/hud/hud = owner.hud_used @@ -36,6 +37,7 @@ /datum/component/mood/Destroy() STOP_PROCESSING(SSmood, src) + REMOVE_TRAIT(parent, TRAIT_AREA_SENSITIVE, MOOD_COMPONENT_TRAIT) unmodify_hud() return ..() diff --git a/code/datums/elements/beauty.dm b/code/datums/elements/beauty.dm new file mode 100644 index 00000000000..3a0be12976f --- /dev/null +++ b/code/datums/elements/beauty.dm @@ -0,0 +1,69 @@ +/** + * Beauty element. It makes the indoor area the parent is in prettier or uglier depending on the beauty var value. + * Clean and well decorated areas lead to positive moodlets for passerbies; + * Shabbier, dirtier ones lead to negative moodlets EXCLUSIVE to characters with the snob quirk. + */ +/datum/element/beauty + element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH + id_arg_index = 2 + var/beauty = 0 + /** + * Assoc list of atoms as keys and number of time the same element instance has been attached to them as assoc value. + * So things don't get odd with same-valued yet dissimilar beauty modifiers being added to the same atom. + */ + var/beauty_counter = list() + +/datum/element/beauty/Attach(datum/target, beauty) + . = ..() + if(!isatom(target) || isarea(target)) + return ELEMENT_INCOMPATIBLE + + src.beauty = beauty + + if(!beauty_counter[target] && ismovable(target)) + var/atom/movable/mov_target = target + mov_target.become_area_sensitive(BEAUTY_ELEMENT_TRAIT) + RegisterSignal(mov_target, COMSIG_ENTER_AREA, .proc/enter_area) + RegisterSignal(mov_target, COMSIG_EXIT_AREA, .proc/exit_area) + + beauty_counter[target]++ + + var/area/current_area = get_area(target) + if(current_area && !current_area.outdoors) + current_area.totalbeauty += beauty + current_area.update_beauty() + +/datum/element/beauty/proc/enter_area(datum/source, area/new_area) + SIGNAL_HANDLER + + if(new_area.outdoors) + return + new_area.totalbeauty += beauty * beauty_counter[source] + new_area.update_beauty() + +/datum/element/beauty/proc/exit_area(datum/source, area/old_area) + SIGNAL_HANDLER + + if(old_area.outdoors) + return + old_area.totalbeauty -= beauty * beauty_counter[source] + old_area.update_beauty() + +/datum/element/beauty/Detach(datum/source, force) + var/area/current_area = get_area(source) + if(QDELETED(source)) + . = ..() + UnregisterSignal(source, list(COMSIG_ENTER_AREA, COMSIG_EXIT_AREA)) + if(current_area) + exit_area(source, current_area) + beauty_counter -= source + else //lower the 'counter' down by one, update the area, and call parent if it's reached zero. + beauty_counter[source]-- + if(current_area && !current_area.outdoors) + current_area.totalbeauty -= beauty + current_area.update_beauty() + if(!beauty_counter[source]) + . = ..() + UnregisterSignal(source, list(COMSIG_ENTER_AREA, COMSIG_EXIT_AREA)) + beauty_counter -= source + REMOVE_TRAIT(source, TRAIT_AREA_SENSITIVE, BEAUTY_ELEMENT_TRAIT) diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index 819078e5ad5..4816f472882 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -77,7 +77,7 @@ Simple datum which is instanced once per type and is used for every object of sa source.name = "[name] [source.name]" if(beauty_modifier) - source.AddComponent(/datum/component/beauty, beauty_modifier * amount) + source.AddElement(/datum/element/beauty, beauty_modifier * amount) if(istype(source, /obj)) //objs on_applied_obj(source, amount, material_flags) @@ -145,8 +145,8 @@ Simple datum which is instanced once per type and is used for every object of sa if(material_flags & MATERIAL_ADD_PREFIX) source.name = initial(source.name) - if(beauty_modifier) //component/beauty/InheritComponent() will handle the removal. - source.AddComponent(/datum/component/beauty, -beauty_modifier * amount) + if(beauty_modifier) + source.RemoveElement(/datum/element/beauty, beauty_modifier * amount) if(istype(source, /obj)) //objs on_removed_obj(source, amount, material_flags) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 494ff044531..b6082a09ee1 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -567,14 +567,15 @@ GLOBAL_LIST_EMPTY(teleportlocs) /** * Call back when an atom enters an area * - * Sends signals COMSIG_AREA_ENTERED and COMSIG_ENTER_AREA (to the atom) + * Sends signals COMSIG_AREA_ENTERED and COMSIG_ENTER_AREA (to a list of atoms) * * If the area has ambience, then it plays some ambience music to the ambience channel */ /area/Entered(atom/movable/M) set waitfor = FALSE SEND_SIGNAL(src, COMSIG_AREA_ENTERED, M) - SEND_SIGNAL(M, COMSIG_ENTER_AREA, src) //The atom that enters the area + for(var/atom/movable/recipient as anything in M.area_sensitive_contents) + SEND_SIGNAL(recipient, COMSIG_ENTER_AREA, src) if(!isliving(M)) return @@ -600,11 +601,12 @@ GLOBAL_LIST_EMPTY(teleportlocs) /** * Called when an atom exits an area * - * Sends signals COMSIG_AREA_EXITED and COMSIG_EXIT_AREA (to the atom) + * Sends signals COMSIG_AREA_EXITED and COMSIG_EXIT_AREA (to a list of atoms) */ /area/Exited(atom/movable/M) SEND_SIGNAL(src, COMSIG_AREA_EXITED, M) - SEND_SIGNAL(M, COMSIG_EXIT_AREA, src) //The atom that exits the area + for(var/atom/movable/recipient as anything in M.area_sensitive_contents) + SEND_SIGNAL(recipient, COMSIG_EXIT_AREA, src) /** diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 6aeec41d020..c205c445397 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -35,6 +35,7 @@ var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move var/atom/movable/moving_from_pull //attempt to resume grab after moving instead of before. var/list/client_mobs_in_contents // This contains all the client mobs within this container + var/list/area_sensitive_contents // A (nested) list of contents that need to be sent signals to when moving between areas. Can include src. var/list/acted_explosions //for explosion dodging var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm @@ -535,6 +536,33 @@ return A.Bumped(src) +/atom/movable/Exited(atom/movable/AM, atom/newLoc) + . = ..() + if(AM.area_sensitive_contents) + for(var/atom/movable/location as anything in get_nested_locs(src) + src) + LAZYREMOVE(location.area_sensitive_contents, AM.area_sensitive_contents) + +/atom/movable/Entered(atom/movable/AM, atom/oldLoc) + . = ..() + if(AM.area_sensitive_contents) + for(var/atom/movable/location as anything in get_nested_locs(src) + src) + LAZYADD(location.area_sensitive_contents, AM.area_sensitive_contents) + +/// See traits.dm. Use this in place of ADD_TRAIT. +/atom/movable/proc/become_area_sensitive(trait_source = TRAIT_GENERIC) + if(!HAS_TRAIT(src, TRAIT_AREA_SENSITIVE)) + RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_AREA_SENSITIVE), .proc/on_area_sensitive_trait_loss) + for(var/atom/movable/location as anything in get_nested_locs(src) + src) + LAZYADD(location.area_sensitive_contents, src) + ADD_TRAIT(src, TRAIT_AREA_SENSITIVE, trait_source) + +/atom/movable/proc/on_area_sensitive_trait_loss() + SIGNAL_HANDLER + + UnregisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_AREA_SENSITIVE)) + for(var/atom/movable/location as anything in get_nested_locs(src) + src) + LAZYREMOVE(location.area_sensitive_contents, src) + ///Sets the anchored var and returns if it was sucessfully changed or not. /atom/movable/proc/set_anchored(anchorvalue) SHOULD_CALL_PARENT(TRUE) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 49c7b27acda..a8cbeb5c593 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -166,6 +166,7 @@ /obj/machinery/LateInitialize() . = ..() power_change() + become_area_sensitive(ROUNDSTART_TRAIT) RegisterSignal(src, COMSIG_ENTER_AREA, .proc/power_change) /obj/machinery/Destroy() diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index dbb632e372d..7d711cbc152 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -69,7 +69,7 @@ name = "poster - [name]" desc = "A large piece of space-resistant printed paper. [desc]" - AddComponent(/datum/component/beauty, 300) + AddElement(/datum/element/beauty, 300) /obj/structure/sign/poster/proc/randomise(base_type) var/list/poster_types = subtypesof(base_type) diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index b24d1741836..bc361fa85d5 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -28,7 +28,7 @@ if(LAZYLEN(diseases_to_add)) AddComponent(/datum/component/infective, diseases_to_add) - AddComponent(/datum/component/beauty, beauty) + AddElement(/datum/element/beauty, beauty) var/turf/T = get_turf(src) if(T && is_station_level(T.z)) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index f4d082919b7..bc3cb60dd97 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -543,7 +543,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /obj/item/statuebust/Initialize() . = ..() AddElement(/datum/element/art, impressiveness) - AddComponent(/datum/component/beauty, 1000) + AddElement(/datum/element/beauty, 1000) /obj/item/statuebust/hippocratic name = "hippocrates bust" diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 2428983f610..e4fc64fb255 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -320,7 +320,7 @@ . = ..() AddComponent(/datum/component/tactical) AddComponent(/datum/component/two_handed, require_twohands=TRUE, force_unwielded=10, force_wielded=10) - AddComponent(/datum/component/beauty, 500) + AddElement(/datum/element/beauty, 500) /obj/item/kirbyplants/attackby(obj/item/I, mob/living/user, params) . = ..() diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index df5879435f4..e9f4ef27ade 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -19,7 +19,7 @@ /obj/structure/statue/Initialize() . = ..() AddElement(art_type, impressiveness) - AddComponent(/datum/component/beauty, impressiveness * 75) + AddElement(/datum/element/beauty, impressiveness * 75) AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, .proc/can_user_rotate), CALLBACK(src, .proc/can_be_rotated), null) /obj/structure/statue/proc/can_be_rotated(mob/user) diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index 2e7bf5ea9bc..77b5a8dcd73 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -145,6 +145,7 @@ /mob/living/simple_animal/drone/snowflake/bardrone/Initialize() . = ..() access_card.access |= ACCESS_CENT_BAR + become_area_sensitive(ROUNDSTART_TRAIT) RegisterSignal(src, COMSIG_ENTER_AREA, .proc/check_barstaff_godmode) check_barstaff_godmode() @@ -165,6 +166,7 @@ access_card.access = C.get_access() access_card.access |= ACCESS_CENT_BAR ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + become_area_sensitive(ROUNDSTART_TRAIT) RegisterSignal(src, COMSIG_ENTER_AREA, .proc/check_barstaff_godmode) check_barstaff_godmode() diff --git a/tgstation.dme b/tgstation.dme index 042a8e39226..0293bd653f3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -469,7 +469,6 @@ #include "code\datums\components\areabound.dm" #include "code\datums\components\armor_plate.dm" #include "code\datums\components\bane.dm" -#include "code\datums\components\beauty.dm" #include "code\datums\components\beetlejuice.dm" #include "code\datums\components\bloodysoles.dm" #include "code\datums\components\butchering.dm" @@ -640,6 +639,7 @@ #include "code\datums\elements\art.dm" #include "code\datums\elements\atmos_sensitive.dm" #include "code\datums\elements\backblast.dm" +#include "code\datums\elements\beauty.dm" #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\bsa_blocker.dm" #include "code\datums\elements\caltrop.dm"