Skip to content

Commit

Permalink
Merge branch 'Citadel-Station-13:master' into pie-rat-ship
Browse files Browse the repository at this point in the history
  • Loading branch information
AlphaM01 authored Dec 25, 2024
2 parents a9edba2 + 4d9274e commit fffeb60
Show file tree
Hide file tree
Showing 107 changed files with 9,693 additions and 6,567 deletions.
6 changes: 6 additions & 0 deletions citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,7 @@
#include "code\game\objects\items\storage\wallets.dm"
#include "code\game\objects\items\storage\medical\firstaid.dm"
#include "code\game\objects\items\storage\medical\hypokit.dm"
#include "code\game\objects\items\storage\misc\survival.dm"
#include "code\game\objects\items\storage\misc_legacy\bible.dm"
#include "code\game\objects\items\storage\misc_legacy\fancy.dm"
#include "code\game\objects\items\storage\misc_legacy\laundry_basket.dm"
Expand Down Expand Up @@ -2026,6 +2027,10 @@
#include "code\game\objects\structures\tables\update_triggers.dm"
#include "code\game\objects\systems\_system.dm"
#include "code\game\objects\systems\cell_slot.dm"
#include "code\game\objects\systems\storage\storage-filters.dm"
#include "code\game\objects\systems\storage\storage-indirection.dm"
#include "code\game\objects\systems\storage\storage-indirection_holder.dm"
#include "code\game\objects\systems\storage\storage-limits.dm"
#include "code\game\objects\systems\storage\storage-screen_object.dm"
#include "code\game\objects\systems\storage\storage-ui.dm"
#include "code\game\objects\systems\storage\storage.dm"
Expand Down Expand Up @@ -2259,6 +2264,7 @@
#include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm"
#include "code\modules\admin\verbs\SDQL2\SDQL_2_wrappers.dm"
#include "code\modules\admin\verbs\SDQL2\wrappers\map.dm"
#include "code\modules\admin\verbs\SDQL2\wrappers\math.dm"
#include "code\modules\admin\verbs\server\admin_reboot.dm"
#include "code\modules\admin\view_variables\admin_delete.dm"
#include "code\modules\admin\view_variables\color_matrix_editor.dm"
Expand Down
35 changes: 33 additions & 2 deletions code/__DEFINES/materials/helpers.dm
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2023 Citadel Station developers. *//

//* object checks
//* /datum/prototype/material declaration helpers *//

#define DECLARE_MATERIAL(PATH_FRAGMENT) \
/datum/prototype/material##PATH_FRAGMENT

/**
* Generates material stacks for a material.
*
* The material must have:
*
* * a defined `display_name`
* * a defined `sheet_singular_name`
* * a defined `sheet_plural_name`
* * a defined `icon`
* * a defined `icon_stack_count`
*/
#define GENERATE_MATERIAL_STACKS(PATH_FRAGMENT) \
/obj/item/stack/material##PATH_FRAGMENT { \
name = /datum/prototype/material##PATH_FRAGMENT::name + " " + /datum/prototype/material##PATH_FRAGMENT::sheet_singular_name; \
icon = /datum/prototype/material##PATH_FRAGMENT::icon; \
icon_state = "stack-1"; \
material = /datum/prototype/material##PATH_FRAGMENT; \
no_variants = TRUE; \
amount = 1; \
} \
/obj/item/stack/material##PATH_FRAGMENT/full_stack { \
name = /datum/prototype/material##PATH_FRAGMENT::name + " " + /datum/prototype/material##PATH_FRAGMENT::sheet_plural_name; \
icon_state = "stack"; \
amount = 50; \
}

//* Material Traits - Checks *//

/// We are ticking materials.
#define IS_TICKING_MATERIALS(A) (A.atom_flags & ATOM_MATERIALS_TICKING)
#define START_TICKING_MATERIALS(A) SSmaterials.add_ticked_object(src)
#define STOP_TICKING_MATERIALS(A) SSmaterials.remove_ticked_object(src)

//* /atom level invocation of traits
//* Material Traits - /atom invocation *//

/// Invocation of material traits
/// A - the atom
Expand Down
23 changes: 16 additions & 7 deletions code/__DEFINES/objects/objects.dm
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 silicons *//
//* Copyright (c) 2024 Citadel Station Developers *//

//* /obj/var/hides_underfloor

/// do not change these willy-nilly, these are strings for the map editor.

/// just Don't
#define OBJ_UNDERFLOOR_DISABLED "disabled"
/// * this is different from 'NEVER'
#define OBJ_UNDERFLOOR_UNSUPPORTED "unsupported"
/// never underfloor, even if floor isn't plating
#define OBJ_UNDERFLOOR_NEVER "never"
/// always underfloor, as long as floor isn't plating
#define OBJ_UNDERFLOOR_ALWAYS "always"
/// Should be underfloor, and is not currently underfloor.
/// * Setting to this at runtime is equal to setting to [OBJ_UNDERFLOOR_ACTIVE].
/// The atom will automatically hide under the floor if the floor is covered.
#define OBJ_UNDERFLOOR_INACTIVE "inactive"
/// Should be underfloor, and is currently underfloor.
/// * Setting to this at runtime is equal to setting to [OBJ_UNDERFLOOR_INACTIVE].
/// The atom will automatically hide under the floor if the floor is covered.
#define OBJ_UNDERFLOOR_ACTIVE "active"
/// automatic
///
/// * gets set to UNDERFLOOR_NEVER if we were made while the floor is intact
/// * gets set to UNDERFLOOR_ALWAYS if we were made while the floor isn't intact
#define OBJ_UNDERFLOOR_IF_CREATED_UNCOVERED "initially-covered"
/// automatic
///
/// * This is what you usually want.
/// * IF_CREATED_UNCOVERED, but always underfloor if made in mapload
#define OBJ_UNDERFLOOR_UNLESS_PLACED_ONTOP "initially-underfloor"

Expand All @@ -26,9 +34,10 @@ DEFINE_ENUM("obj_hides_underfloor", list(
"hides_underfloor",
),
), list(
"Disabled" = OBJ_UNDERFLOOR_DISABLED,
"Never" = OBJ_UNDERFLOOR_NEVER,
"Always" = OBJ_UNDERFLOOR_ALWAYS,
"Unsupported" = OBJ_UNDERFLOOR_UNSUPPORTED,
"No" = OBJ_UNDERFLOOR_NEVER,
"Yes (Currently Uncovered)" = OBJ_UNDERFLOOR_INACTIVE,
"Yes (Currently Covered)" = OBJ_UNDERFLOOR_ACTIVE,
"If Created Uncovered (Init Only)" = OBJ_UNDERFLOOR_IF_CREATED_UNCOVERED,
"If Created Uncovered Or In Mapload (Init Only)" = OBJ_UNDERFLOOR_UNLESS_PLACED_ONTOP,
))
6 changes: 0 additions & 6 deletions code/controllers/configuration_old/configuration.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

var/nudge_script_path = "nudge.py" // where the nudge.py script is located

var/hub_visibility = FALSE //CITADEL CHANGE - HUB CONFIG

var/log_ooc = 0 // log OOC channel
var/log_access = 0 // log login/logout
var/log_say = 0 // log client say
Expand Down Expand Up @@ -280,9 +278,6 @@
if ("ban_legacy_system")
config_legacy.ban_legacy_system = 1

if ("hub_visibility") //CITADEL CHANGE - ADDS HUB CONFIG
config_legacy.hub_visibility = 1

if ("jobs_have_minimal_access")
config_legacy.jobs_have_minimal_access = 1

Expand Down Expand Up @@ -834,4 +829,3 @@
config_legacy.python_path = "/usr/bin/env python2"
else //probably windows, if not this should work anyway
config_legacy.python_path = "python"
world.update_hub_visibility(hub_visibility) //CITADEL CHANGE - HUB CONFIG
27 changes: 26 additions & 1 deletion code/controllers/subsystem/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,34 @@ SUBSYSTEM_DEF(atoms)
* * ... - rest of args are passed to new() / Initialize().
*/
/datum/controller/subsystem/atoms/proc/instance_atom_immediate(path, mapload, atom/where, ...)
SHOULD_NOT_SLEEP(TRUE)
var/old_init_status = atom_init_status
atom_init_status = mapload? ATOM_INIT_IN_NEW_MAPLOAD : ATOM_INIT_IN_NEW_REGULAR
var/atom/created = new path(arglist(args.Copy()))
var/atom/created = new path(arglist(args.Copy(3)))
atom_init_status = old_init_status
return created

/**
* immediately creates and inits an atom with a preloader callback.
*
* @params
* * path - typepath
* * mapload - treat as mapload?
* * preload_call - callback to invoke with (created) for the created atom. This is not allowed to sleep.
* * where - location to init at
* * ... - rest of args are passed to new() / Initialize().
*/
/datum/controller/subsystem/atoms/proc/instance_atom_immediate_with_preloader(path, mapload, datum/callback/preload_call, atom/where, ...)
SHOULD_NOT_SLEEP(TRUE)
var/old_init_status = atom_init_status
atom_init_status = ATOM_INIT_IN_SUBSYSTEM
var/atom/created = new path(arglist(args.Copy(4)))
preload_call.invoke_no_sleep(created)
atom_init_status = mapload? ATOM_INIT_IN_NEW_MAPLOAD : ATOM_INIT_IN_NEW_REGULAR
// this sets 'where' to if we should be mapload.
// this is acceptable because args[4] ('where') is not used again.
args[4] = mapload
InitAtom(created, FALSE, args.Copy(4))
atom_init_status = old_init_status
return created

Expand Down
3 changes: 2 additions & 1 deletion code/controllers/subsystem/server_maint.dm
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ SUBSYSTEM_DEF(server_maint)
var/cleanup_ticker = 0

/datum/controller/subsystem/server_maint/PreInit()
world.hub_password = "" //quickly! before the hubbies see us.
// quickly! before the hubbies see us.
world.update_hub_visibility(FALSE)

/datum/controller/subsystem/server_maint/Initialize()
if (fexists("tmp/"))
Expand Down
27 changes: 21 additions & 6 deletions code/datums/callback.dm
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,39 @@
else
calling_arguments = args
if(datum_flags & DF_VAR_EDITED)
return WrapAdminProcCall(object, delegate, calling_arguments)
if(object == GLOBAL_PROC)
return call(delegate)(arglist(calling_arguments))
return call(object, delegate)(arglist(calling_arguments))
. = WrapAdminProcCall(object, delegate, calling_arguments)
else if(object == GLOBAL_PROC)
. = call(delegate)(arglist(calling_arguments))
else
. = call(object, delegate)(arglist(calling_arguments))
pass()

/**
* Invoke this callback and crash if it sleeps.
*
* * Use when a callback should never sleep, as call() cannot be verified by static analysis.
* * Do not use in performance critical code. This wraps calls more aggressively than InvokeAsync().
* * `null` is returned if the call sleeps.
*
* The specific use case here is an async call where:
*
* * It's always invalid behavior for a callback to sleep.
* * The caller should be protected (caller shouldn't be interrupted by the sleep).
*
* This allows enforcement of the above invariants by loudly runtiming and bringing attention to the issue,
* as opposed to the usual way of compile checking it (which we can't because this is a reflection-based call to an arbitrary proc).
*/
/datum/callback/proc/invoke_no_sleep(...)
. = CALLBACK_SLEEP_SENTINEL
ASYNC
. = Invoke(arglist(args))
. = invoke_no_sleep_call(arglist(args))
if(. == CALLBACK_SLEEP_SENTINEL)
. = null
CRASH("Callback [src] slept on a no-sleeping invoke.")

/datum/callback/proc/invoke_no_sleep_call(...)
set waitfor = FALSE
. = Invoke(arglist(args))

/**
* Invoke this callback async (waitfor=false)
*
Expand Down
55 changes: 53 additions & 2 deletions code/datums/outfits/outfit.dm
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,59 @@
for(var/i=0,i<number,i++)
H.equip_to_slot_or_del(new path(H), /datum/inventory_slot/abstract/attach_as_accessory, INV_OP_FLUFFLESS | INV_OP_SILENT)

if(H.species)
H.species.equip_survival_gear(H, flags&OUTFIT_EXTENDED_SURVIVAL, flags&OUTFIT_COMPREHENSIVE_SURVIVAL)
// deal with racial & survival gear
var/list/to_inject_box = list()
var/list/to_inject_inv = list()
H.species.apply_survival_gear(H, to_inject_box, to_inject_inv)
H.species.apply_racial_gear(H, to_inject_box, to_inject_inv)

if(length(to_inject_box))
var/obj/item/survival_box = new /obj/item/storage/box/survival
for(var/descriptor in to_inject_box)
if(ispath(descriptor))
new descriptor(survival_box)
else if(IS_ANONYMOUS_TYPEPATH(descriptor))
new descriptor(survival_box)
else if(isitem(descriptor))
var/obj/item/moving = descriptor
moving.forceMove(survival_box)
else
stack_trace("invalid descriptor '[descriptor]' encountered")
survival_box.obj_storage.fit_to_contents(no_shrink = TRUE)

if(!H.inventory.equip_to_slot_if_possible(survival_box, /datum/inventory_slot/abstract/put_in_backpack))
if(!H.inventory.put_in_hands(survival_box))
survival_box.forceMove(H.drop_location())

if(length(to_inject_inv))
var/list/atom/movable/arbitrary_instantiated_gear = list()
for(var/descriptor in to_inject_inv)
if(ispath(descriptor))
arbitrary_instantiated_gear += new descriptor
else if(IS_ANONYMOUS_TYPEPATH(descriptor))
arbitrary_instantiated_gear += new descriptor
else if(ismovable(descriptor))
arbitrary_instantiated_gear += descriptor
else
stack_trace("invalid descriptor '[descriptor]' encountered")
for(var/atom/movable/gear as anything in arbitrary_instantiated_gear)
if(isitem(gear))
// try to put into inv, then hands, then nearby
var/obj/item/gear_item = gear
if(!H.equip_to_slots_if_possible(
gear_item,
list(
/datum/inventory_slot/abstract/put_in_backpack,
/datum/inventory_slot/abstract/put_in_belt,
/datum/inventory_slot/abstract/put_in_hands,
/datum/inventory_slot/inventory/pocket/left,
/datum/inventory_slot/inventory/pocket/right,
),
))
gear_item.forceMove(H.drop_location())
else
// put nearby
gear.forceMove(H.drop_location())

/datum/outfit/proc/equip_id(mob/living/carbon/human/H, rank, assignment)
if(!id_slot || !id_type)
Expand Down
28 changes: 26 additions & 2 deletions code/datums/recipe/stack_recipe.dm
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,30 @@
var/on_border = FALSE
// todo: material constraints

//* Product Descriptors *//

/// Automatically create empty storage / cells / containers / whatever
/// * Usually this is on, because usually stacks are not meant to create the insides of a container.
var/product_auto_create_empty = TRUE

//* Internal *//

/// preloader callback, do not touch
var/datum/callback/preloader_callback

/datum/stack_recipe/New()
if(ispath(result_type, /obj/item/stack))
result_is_stack = TRUE

var/atom/casted = result_type
on_border = !!(initial(casted.atom_flags) & ATOM_BORDER)

preloader_callback = CALLBACK(src, PROC_REF(make_preload_hook))

/datum/stack_recipe/Destroy()
QDEL_NULL(preloader_callback)
return ..()

/**
* attepmt to craft
*
Expand Down Expand Up @@ -139,16 +156,23 @@
if(!--safety)
CRASH("safety hit")
var/making_amount = min(amount, max_amount)
var/obj/item/stack/creating = new result_type(where, making_amount)
var/obj/item/stack/creating = SSatoms.instance_atom_immediate_with_preloader(result_type, FALSE, preloader_callback, where, making_amount)
amount -= making_amount
created += creating
else
for(var/i in 1 to min(amount, 50))
var/atom/movable/creating = new result_type(where)
var/atom/movable/creating = SSatoms.instance_atom_immediate_with_preloader(result_type, FALSE, preloader_callback, where)
creating.setDir(use_dir)
created += creating
return TRUE

/**
* preloads an atom we make
*/
/datum/stack_recipe/proc/make_preload_hook(atom/product)
SHOULD_NOT_SLEEP(TRUE)
product.preload_from_stack_recipe(src)

/**
* tgui stack recipe data
*/
Expand Down
12 changes: 12 additions & 0 deletions code/game/atoms/_atom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -232,20 +232,32 @@

return ..()

//* Preload Hooks *//

/**
* Called by the maploader if a dmm_context is set
*
* todo: rename to preload_from_mapload()
*/
/atom/proc/preloading_instance(datum/dmm_context/context)
return

/**
* hook for abstract direction sets from the maploader
*
* todo: this might need to be part of preloading_instance; investigate
*
* return FALSE to override maploader automatic rotation
*/
/atom/proc/preloading_dir(datum/dmm_context/context)
return TRUE

/**
* Preloads before Initialize(), invoked by init from a stack recipe.
*/
/atom/proc/preload_from_stack_recipe(datum/stack_recipe/recipe)
return

/atom/proc/reveal_blood()
return

Expand Down
Loading

0 comments on commit fffeb60

Please sign in to comment.