From 7c8d2500c22dccea3a93993e83f3cf3edb890b7e Mon Sep 17 00:00:00 2001 From: harryob <55142896+harryob@users.noreply.github.com> Date: Sun, 25 Aug 2024 16:43:58 +0100 Subject: [PATCH] gamemode decorators (#7014) adds a system to allow for better variable overrides per gamemode --- code/controllers/subsystem/decorator.dm | 22 +++++++++- code/datums/decorators/gamemode_decorator.dm | 46 ++++++++++++++++++++ colonialmarines.dme | 1 + 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 code/datums/decorators/gamemode_decorator.dm diff --git a/code/controllers/subsystem/decorator.dm b/code/controllers/subsystem/decorator.dm index ac63fca47ac5..e8120cc09658 100644 --- a/code/controllers/subsystem/decorator.dm +++ b/code/controllers/subsystem/decorator.dm @@ -29,7 +29,7 @@ SUBSYSTEM_DEF(decorator) var/list/datum/weakref/currentrun = list() /datum/controller/subsystem/decorator/Initialize() - var/list/all_decors = typesof(/datum/decorator) - list(/datum/decorator) - typesof(/datum/decorator/manual) + var/list/all_decors = typesof(/datum/decorator) - list(/datum/decorator) - typesof(/datum/decorator/manual) - typesof(/datum/decorator/gamemode) for(var/decor_type in all_decors) var/datum/decorator/decor = new decor_type() if(!decor.is_active_decor()) @@ -43,6 +43,8 @@ SUBSYSTEM_DEF(decorator) registered_decorators[app_type] = list() registered_decorators[app_type] += decor + RegisterSignal(SSdcs, COMSIG_GLOB_MODE_PRESETUP, PROC_REF(handle_mode_specific)) + for(var/i in registered_decorators) registered_decorators[i] = sortDecorators(registered_decorators[i]) @@ -71,6 +73,24 @@ SUBSYSTEM_DEF(decorator) if(MC_TICK_CHECK) return +/datum/controller/subsystem/decorator/proc/handle_mode_specific() + SIGNAL_HANDLER + + for(var/decorator_type in typesof(/datum/decorator/gamemode)) + var/datum/decorator/gamemode/gamemode_decorator = new decorator_type() + + if(!istype(SSticker.mode, gamemode_decorator.gamemode)) + continue + + var/applicable_types = gamemode_decorator.get_decor_types() + if(!length(applicable_types)) + continue + + active_decorators |= gamemode_decorator + + for(var/applicable_type in applicable_types) + LAZYADD(registered_decorators[applicable_type], gamemode_decorator) + /datum/controller/subsystem/decorator/proc/add_decorator(decor_type, ...) var/list/arguments = list() if (length(args) > 1) diff --git a/code/datums/decorators/gamemode_decorator.dm b/code/datums/decorators/gamemode_decorator.dm new file mode 100644 index 000000000000..bc89d7a20632 --- /dev/null +++ b/code/datums/decorators/gamemode_decorator.dm @@ -0,0 +1,46 @@ +#define GAMEMODE_DECORATOR(type, mode, list_edits) \ +/datum/decorator/gamemode##type##mode { \ + gamemode = mode; \ + apply_type = type; \ + edits = list_edits; \ +} + +#define VARIABLE_EDIT(type, variable, value) nameof(type::variable) = value +#define ARMOR_EDIT(variable, value) VARIABLE_EDIT(/obj/item/clothing/suit/storage/marine, variable, value) +#define GUN_EDIT(variable, value) VARIABLE_EDIT(/obj/item/weapon/gun, variable, value) +#define AMMO_EDIT(variable, value) VARIABLE_EDIT(/obj/item/ammo_magazine, variable, value) + +/** + * Gamemode decorators allow us to make changes to edits on specific gamemodes, + * to assist in balancing varied gameplay in different modes + * + * They can be manually defined, and procs overridden. Alternatively, + * using the GAMEMODE_DECORATOR define, you can quickly make a decorator for + * a specific type and subtypes. + * + * eg: + * ``` + * GAMEMODE_DECORATOR(/obj/item/clothing/suit/storage/marine/smartgunner, /datum/game_mode/extended/faction_clash, list( + * ARMOR_EDIT(armor_bullet, CLOTHING_ARMOR_HIGH), + * ARMOR_EDIT(armor_internaldamage, CLOTHING_ARMOR_HIGH) + * )) + * ``` + * + * If you need to edit different types, make a new define using VARIABLE_EDIT, and provide the parent path for the type. + */ +/datum/decorator/gamemode + /// The gamemode type this should apply to + var/gamemode + + /// Which type this should apply edits to + var/apply_type + + /// The list of edits to make + var/list/edits + +/datum/decorator/gamemode/get_decor_types() + return typesof(apply_type) + +/datum/decorator/gamemode/decorate(atom/object) + for(var/edit in edits) + object.vars[edit] = edits[edit] diff --git a/colonialmarines.dme b/colonialmarines.dme index 92a0889b72ba..48996a93ec30 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -432,6 +432,7 @@ #include "code\datums\construction\construction_template.dm" #include "code\datums\construction\xenomorph\construction_template_xenomorph.dm" #include "code\datums\decorators\decorator.dm" +#include "code\datums\decorators\gamemode_decorator.dm" #include "code\datums\diseases\addiction.dm" #include "code\datums\diseases\beesease.dm" #include "code\datums\diseases\black_goo.dm"