mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-21 18:26:35 +01:00
239 lines
8.9 KiB
Plaintext
239 lines
8.9 KiB
Plaintext
//* This file is explicitly licensed under the MIT license. *//
|
|
//* Copyright (c) 2023 Citadel Station developers. *//
|
|
|
|
/**
|
|
* physiology holder
|
|
*
|
|
* todo: on biologies update, we might need to lazy-cache this, and have different physiologies for each biology.
|
|
*/
|
|
/datum/global_physiology
|
|
/// carry baseline modify
|
|
var/carry_strength = CARRY_STRENGTH_BASELINE
|
|
/// carry penalty modifier
|
|
var/carry_factor = CARRY_FACTOR_BASELINE
|
|
/// carry bias modify
|
|
var/carry_bias = 1
|
|
/// carry weight add - added to carry_strength for carry weight only, not encumbrance.
|
|
var/carry_weight_add = 0
|
|
/// carry weight factor - multiplied to carry_factor for carry weight only, not encumbrance.
|
|
var/carry_weight_factor = 1
|
|
/// carry weight bias - multipled to carry_bias for carry weight only, not encumbrance
|
|
var/carry_weight_bias = 1
|
|
|
|
/datum/global_physiology/proc/reset()
|
|
carry_strength = initial(carry_strength)
|
|
carry_factor = initial(carry_factor)
|
|
carry_weight_add = initial(carry_weight_add)
|
|
carry_weight_factor = initial(carry_weight_factor)
|
|
carry_bias = initial(carry_bias)
|
|
carry_weight_bias = initial(carry_weight_bias)
|
|
return TRUE
|
|
|
|
/datum/global_physiology/proc/apply(datum/physiology_modifier/modifier)
|
|
if(!isnull(modifier.carry_strength_add))
|
|
carry_strength += modifier.carry_strength_add
|
|
if(!isnull(modifier.carry_strength_factor))
|
|
carry_factor *= modifier.carry_strength_factor
|
|
if(!isnull(modifier.carry_weight_add))
|
|
carry_weight_add += modifier.carry_weight_add
|
|
if(!isnull(modifier.carry_weight_factor))
|
|
carry_weight_factor *= modifier.carry_weight_factor
|
|
if(!isnull(modifier.carry_strength_bias))
|
|
carry_bias *= modifier.carry_strength_bias
|
|
if(!isnull(modifier.carry_weight_bias))
|
|
carry_weight_bias *= modifier.carry_weight_bias
|
|
|
|
/**
|
|
* return FALSE if we need to reset due to non-canonical operations
|
|
*/
|
|
/datum/global_physiology/proc/revert(datum/physiology_modifier/modifier)
|
|
. = TRUE
|
|
if(!isnull(modifier.carry_strength_add))
|
|
carry_strength -= modifier.carry_strength_add
|
|
if(!isnull(modifier.carry_strength_factor))
|
|
carry_factor /= modifier.carry_strength_factor
|
|
if(!isnull(modifier.carry_weight_add))
|
|
carry_weight_add -= modifier.carry_weight_add
|
|
if(!isnull(modifier.carry_weight_factor))
|
|
carry_weight_factor /= modifier.carry_weight_factor
|
|
if(!isnull(modifier.carry_strength_bias))
|
|
carry_bias /= modifier.carry_strength_bias
|
|
if(!isnull(modifier.carry_weight_bias))
|
|
carry_weight_bias /= modifier.carry_weight_bias
|
|
|
|
/datum/local_physiology
|
|
|
|
/datum/local_physiology/proc/reset()
|
|
return TRUE
|
|
|
|
/datum/local_physiology/proc/apply(datum/physiology_modifier/modifier)
|
|
return TRUE
|
|
|
|
/datum/local_physiology/proc/revert(datum/physiology_modifier/modifier)
|
|
return TRUE
|
|
|
|
/**
|
|
* physiology modifier
|
|
*/
|
|
/datum/physiology_modifier
|
|
abstract_type = /datum/physiology_modifier
|
|
|
|
/// our name
|
|
var/name = "Some Modifier"
|
|
/// is this a globally cached modifier?
|
|
var/is_globally_cached = FALSE
|
|
/// biologies this applies to, for limb-specific modifiers
|
|
var/biology_types = BIOLOGY_TYPES_ALL
|
|
|
|
//* -- global modifiers -- *//
|
|
|
|
//* carry strength / weight *//
|
|
var/carry_strength_add = 0
|
|
var/carry_strength_factor = 1
|
|
var/carry_strength_bias = 1
|
|
var/carry_weight_add = 0
|
|
var/carry_weight_factor = 1
|
|
var/carry_weight_bias = 1
|
|
|
|
/datum/physiology_modifier/serialize()
|
|
. = ..()
|
|
if(name != initial(name))
|
|
.["name"] = name
|
|
if(carry_strength_add != initial(carry_strength_add))
|
|
.["carry_strength_add"] = carry_strength_add
|
|
if(carry_strength_factor != initial(carry_strength_factor))
|
|
.["carry_strength_factor"] = carry_strength_factor
|
|
|
|
/datum/physiology_modifier/deserialize(list/data)
|
|
. = ..()
|
|
if(istext(data["name"]))
|
|
name = data["name"]
|
|
if(isnum(data["carry_strength_add"]))
|
|
carry_strength_add = data["carry_strength_add"]
|
|
if(isnum(data["carry_strength_factor"]))
|
|
carry_strength_factor = data["carry_strength_factor"]
|
|
if(isnum(data["carry_strength_bias"]))
|
|
carry_strength_bias = data["carry_strength_bias"]
|
|
if(isnum(data["carry_weight_add"]))
|
|
carry_weight_add = data["carry_weight_add"]
|
|
if(isnum(data["carry_weight_factor"]))
|
|
carry_weight_factor = data["carry_weight_factor"]
|
|
if(isnum(data["carry_weight_bias"]))
|
|
carry_weight_bias = data["carry_weight_bias"]
|
|
|
|
/**
|
|
* subtype for hardcoded physiology modifiers
|
|
*/
|
|
/datum/physiology_modifier/intrinsic
|
|
abstract_type = /datum/physiology_modifier/intrinsic
|
|
|
|
/**
|
|
* subtype for admin varedit tracking
|
|
*/
|
|
/datum/physiology_modifier/varedit
|
|
name = "Admin Varedits"
|
|
|
|
GLOBAL_LIST_EMPTY(cached_physiology_modifiers)
|
|
|
|
/proc/cached_physiology_modifier(datum/physiology_modifier/path)
|
|
ASSERT(ispath(path, /datum/physiology_modifier))
|
|
ASSERT(initial(path.abstract_type) != path)
|
|
// if it already exists, set default return value to it and return
|
|
if((. = GLOB.cached_physiology_modifiers[path]))
|
|
return
|
|
var/datum/physiology_modifier/modifier = new path
|
|
modifier.is_globally_cached = TRUE
|
|
GLOB.cached_physiology_modifiers[path] = modifier
|
|
return modifier
|
|
|
|
/**
|
|
* initializes physiology modifiers
|
|
* paths in physiology modifier are converted to the cached instances in globals.
|
|
*/
|
|
/mob/proc/init_physiology()
|
|
for(var/i in 1 to length(physiology_modifiers))
|
|
if(ispath(physiology_modifiers[i]))
|
|
physiology_modifiers[i] = cached_physiology_modifier(physiology_modifiers[i])
|
|
rebuild_physiology()
|
|
|
|
/**
|
|
* adds a modifier to physiology
|
|
* you are responsible for not double-adding
|
|
* paths are allowed; if modifier is a path, it'll be the globally cached modifier of that type.
|
|
*/
|
|
/mob/proc/add_physiology_modifier(datum/physiology_modifier/modifier)
|
|
if(ispath(modifier))
|
|
modifier = cached_physiology_modifier(modifier)
|
|
ASSERT(!(modifier in physiology_modifiers))
|
|
LAZYADD(physiology_modifiers, modifier)
|
|
physiology.apply(modifier)
|
|
return TRUE
|
|
|
|
/**
|
|
* removes a modifier from physiology
|
|
* you are responsible for not double-adding
|
|
* paths are allowed
|
|
*/
|
|
/mob/proc/remove_physiology_modifier(datum/physiology_modifier/modifier)
|
|
if(ispath(modifier))
|
|
modifier = cached_physiology_modifier(modifier)
|
|
ASSERT(modifier in physiology_modifiers)
|
|
LAZYREMOVE(physiology_modifiers, modifier)
|
|
if(!physiology.revert(modifier))
|
|
// todo: optimize with reset().
|
|
rebuild_physiology()
|
|
return TRUE
|
|
|
|
/**
|
|
* completely rebuilds physiology from our modifiers
|
|
*/
|
|
/mob/proc/rebuild_physiology()
|
|
physiology = new
|
|
for(var/datum/physiology_modifier/modifier as anything in physiology_modifiers)
|
|
if(!istype(modifier))
|
|
physiology_modifiers -= modifier
|
|
continue
|
|
physiology.apply(modifier)
|
|
|
|
// i'm not going to fucking support vv without automated backreferences and macros, holy shit.
|
|
// /mob/proc/get_varedit_physiology_modifier()
|
|
// RETURN_TYPE(/datum/physiology_modifier)
|
|
// . = locate(/datum/physiology_modifier/varedit) in physiology_modifiers
|
|
// if(!isnull(.))
|
|
// return
|
|
// var/datum/physiology_modifier/varedit/new_holder = new
|
|
// add_physiology_modifier(new_holder)
|
|
// return new_holder
|
|
|
|
// todo: you can tell from the proc name that this needs to be kicked somewhere eles later.
|
|
/proc/ask_admin_for_a_physiology_modifier(mob/user)
|
|
var/datum/tgui_dynamic_query/query = new
|
|
query.string("name", "Name", "Name your modifier.", 64, FALSE, "Custom Modifier")
|
|
query.number("carry_strength_add", "Carry Strength - Add", "Modify the person's base carry strength. Higher is better.", default = 0)
|
|
query.number("carry_strength_factor", "Carry Factor - Multiply", "Multiply the person's carry weight/encumbrance to slowdown effect when carrying over their limit. Lower is better.", default = 1)
|
|
query.number("carry_strength_bias", "Carry Bias - Multiply", "Multiply the person's carry weight/encumbrance to slowdown bias when carrying over their limit. Lower is better.", default = 1)
|
|
query.number("carry_weight_add", "Carry Weight - Add", "Modify the person's base carry weight. Higher is better. This only applies to weight, not encumbrance.", default = 0)
|
|
query.number("carry_weight_factor", "Carry Weight - Multiply", "Multiply the person's weight to slowdown effect when carrying over their limit. Lower is better. This only applies to weight, not encumbrance.", default = 1)
|
|
query.number("carry_weight_bias", "Carry Weight - Bias", "Multiply the person's weight to slowdown calculation bias; lower is better.", default = 1)
|
|
|
|
var/list/choices = tgui_dynamic_input(user, "Add a physiology modifier", "Add Physiology Modifier", query)
|
|
|
|
if(isnull(choices))
|
|
return
|
|
|
|
var/datum/physiology_modifier/modifier = new
|
|
|
|
// we manually deserialize because we might have custom datatypes
|
|
// in the future that won't be serialized by the ui necessarily in the same way
|
|
// we would serialize it via json.
|
|
|
|
modifier.name = choices["name"]
|
|
modifier.carry_strength_add = choices["carry_strength_add"]
|
|
modifier.carry_strength_factor = choices["carry_strength_factor"]
|
|
modifier.carry_strength_bias = choices["carry_strength_bias"]
|
|
modifier.carry_weight_add = choices["carry_weight_add"]
|
|
modifier.carry_weight_factor = choices["carry_weight_factor"]
|
|
modifier.carry_weight_bias = choices["carry_weight_bias"]
|
|
|
|
return modifier
|