Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implants #776

Open
wants to merge 50 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
9d6da44
Skill implants. (Need help, on progress and dont merge that shit)
Dark-Umbrella Nov 18, 2024
977ca72
Update code/game/objects/items/implants/implant_skill.dm
Dark-Umbrella Nov 18, 2024
c085b46
Update code/game/objects/items/implants/implant_skill.dm
Dark-Umbrella Nov 18, 2024
a7a5f5c
Update code/game/objects/items/implants/implant_skill.dm
Dark-Umbrella Nov 18, 2024
740410c
Minor FIX
Dark-Umbrella Nov 18, 2024
73c37ab
. = ..()
Dark-Umbrella Nov 19, 2024
eff6055
on works....
Dark-Umbrella Nov 19, 2024
9a833df
Fix (minor)
Dark-Umbrella Nov 19, 2024
614642f
Fix again.
Dark-Umbrella Nov 22, 2024
1d21c98
I BECOME MADNESS
Dark-Umbrella Nov 23, 2024
f243683
Fix
Dark-Umbrella Nov 23, 2024
abdb988
Update code/game/objects/items/implants/skill_implants/implant_skill.dm
Dark-Umbrella Nov 25, 2024
4b8a617
Update code/game/objects/items/implants/skill_implants/implantator_sk…
Dark-Umbrella Nov 25, 2024
a72db29
Fix
Dark-Umbrella Nov 25, 2024
cb50f1b
FixMB
MalorMorfin Dec 6, 2024
33f011f
delete garbage
MalorMorfin Dec 6, 2024
b56fee3
Revert "delete garbage"
MalorMorfin Dec 7, 2024
38a8a3c
Revert "FixMB"
MalorMorfin Dec 7, 2024
d63b1ea
well?
MalorMorfin Dec 7, 2024
ef3e270
Merge branch 'master' into Skill_Implants
MalorMorfin Dec 7, 2024
9a75c9f
fix review day 96535
MalorMorfin Dec 10, 2024
735d3c5
uh, and why that exist now?
MalorMorfin Dec 10, 2024
ae880d3
Merge branch 'master' into Skill_Implants
MalorMorfin Dec 11, 2024
0e7f346
i need sleep
MalorMorfin Dec 12, 2024
b7f4f6b
ogore
MalorMorfin Dec 14, 2024
f4bf407
Merge branch 'master' into Skill_Implants
MalorMorfin Dec 16, 2024
1fd0e6d
minor
MalorMorfin Dec 16, 2024
12b268e
some..
MalorMorfin Dec 17, 2024
999c96a
Update implant.dm
MalorMorfin Dec 18, 2024
3df8e0b
some some
MalorMorfin Dec 18, 2024
29af37b
1 day before shitpost
MalorMorfin Dec 18, 2024
d488532
1984 kill AKULISHEV
MalorMorfin Dec 18, 2024
6d9482b
in process
MalorMorfin Dec 18, 2024
b788f92
final, port this pr https://github.com/tgstation/TerraGov-Marine-Corp…
MalorMorfin Dec 19, 2024
27bdc77
Merge branch 'master' into Skill_Implants
Helg2 Dec 19, 2024
6c0d7b4
fix
MalorMorfin Dec 19, 2024
0ceafc9
vrode work
MalorMorfin Dec 19, 2024
de0426a
а
MalorMorfin Dec 19, 2024
e7c5bdf
imba dlya marov
MalorMorfin Dec 19, 2024
04755b1
helg zachem ti skazal eto sdelat...(
MalorMorfin Dec 20, 2024
7ca4b6e
balance and add implant in valhalla vendors
MalorMorfin Dec 21, 2024
4c2e086
transfer
MalorMorfin Dec 21, 2024
71f8e6c
Merge branch 'master' into Skill_Implants
MalorMorfin Dec 21, 2024
805ed6d
Merge branch 'master' into Skill_Implants
Helg2 Dec 21, 2024
a2329a6
Merge branch 'Skill_Implants' of https://github.com/MalorMorfin/Unga-…
MalorMorfin Dec 21, 2024
1b33b2d
Extra ultra giga fix
MalorMorfin Dec 21, 2024
d70d9d7
review
MalorMorfin Jan 9, 2025
33bc998
Update living_health_procs.dm
MalorMorfin Jan 10, 2025
149b99f
Update living_health_procs.dm
MalorMorfin Jan 10, 2025
bbb588d
Merge branch 'master' into Skill_Implants
Helg2 Jan 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions code/__DEFINES/dcs/helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
/// A wrapper for _AddComponent that allows us to pretend we're using normal named arguments
#define AddComponent(arguments...) _AddComponent(list(##arguments))

/// A wrapper for _AddComponent that passes in a source.
/// Necessary if dupe_mode is set to COMPONENT_DUPE_SOURCES.
#define AddComponentFrom(source, arguments...) _AddComponent(list(##arguments), source)

/// A wrapper for _LoadComponent that allows us to pretend we're using normal named arguments
#define LoadComponent(arguments...) _LoadComponent(list(##arguments))

Expand Down
7 changes: 7 additions & 0 deletions code/__DEFINES/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,10 @@
#define COMSIG_MOB_PAINLOSS_CHANGED "mob_painloss_changed"
/// from mob/get_status_tab_items(): (list/items)
#define COMSIG_MOB_GET_STATUS_TAB_ITEMS "mob_get_status_tab_items"
///From mob/do_after_coefficent()
#define MOB_GET_DO_AFTER_COEFFICIENT "mob_get_do_after_coefficient"
///From get_zone_with_miss_chance
#define MOB_GET_MISS_CHANCE_MOD "mob_get_miss_chance_mod"

//mob/dead/observer
#define COMSIG_OBSERVER_CLICKON "observer_clickon" //from mob/dead/observer/ClickOn(): (atom/A, params)
Expand Down Expand Up @@ -966,6 +970,9 @@
#define COMSIG_WEAPONABILITY_AXESWEEP "weaponability_axesweep"
#define COMSIG_WEAPONABILITY_SWORDLUNGE "weaponability_swordlunge"

//Implant abilities
#define COMSIG_IMPLANT_ABILITY_SANDEVISTAN "implant_ability_sandevistan"

// human modules signals for keybindings
#define COMSIG_KB_VALI_CONFIGURE "keybinding_vali_configure"
#define COMSIG_KB_VALI_HEAL "keybinding_vali_heal"
Expand Down
7 changes: 7 additions & 0 deletions code/__DEFINES/implants.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
//Generic /obj/item/implant flags
#define GRANT_ACTIVATION_ACTION (1<<0)
///Some kind of hearing/voice activation
#define ACTIVATE_ON_HEAR (1<<1)
///The implant is something you want
#define BENEFICIAL_IMPLANT (1<<2)
///Can have more than one of the same implant in a limb
#define DUPLICATE_IMPLANT_ALLOWED (1<<3)
///Only one implant can be in a limb
#define HIGHLANDER_IMPLANT (1<<4)

#define MALFUNCTION_NONE 0
#define MALFUNCTION_TEMPORARY 1
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/is_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@

#define issentry(A) (istype(A, /obj/machinery/deployable/mounted/sentry))

#define isimplant(A) (istype(A, /obj/item/implant))

//Assemblies
#define isassembly(O) (istype(O, /obj/item/assembly))

Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/keybind.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define CATEGORY_PSIONIC "PSIONIC"
#define CATEGORY_WEAPON "WEAPON"
#define CATEGORY_ITEM "ITEM"
#define CATEGORY_CYBERWARE "CYBERWARE"
#define CATEGORY_MISC "MISC"
#define CATEGORY_EMOTE "EMOTE"
#define CATEGORY_CUSTOM_EMOTE "CUSTOM_EMOTE"
Expand Down
26 changes: 26 additions & 0 deletions code/__DEFINES/loadout.dm
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ GLOBAL_LIST_INIT(marine_selector_cats, list(
#define SANDBAG_PRICE_IN_GEAR_VENDOR 3

GLOBAL_LIST_INIT(marine_gear_listed_products, list(
/obj/item/implanter/implantator/combat/firearms = list(CAT_MARINE, "Aiming support implanter", 35, "cyan2"),
/obj/item/implanter/implantator/combat/melee = list(CAT_MARINE, "Close combat codex implanter", 25, "cyan2"),
/obj/item/implanter/implantator/codex/medical = list(CAT_MARINE, "Medtech implanter", 20, "cyan2"),
/obj/item/implanter/implantator/codex/engineer = list(CAT_MARINE, "Engineering support system implanter", 20, "cyan2"),
/obj/item/implanter/implantator/codex/construct = list(CAT_MARINE, "Construction support system implanter", 20, "cyan2"),
/obj/item/storage/backpack/marine/radiopack = list(CAT_MARINE, "Radio Pack", 5, "orange"),
/obj/item/storage/belt/marine/auto_catch = list(CAT_MARINE, "M344 pattern ammo load rig", 10, "orange"),
/obj/item/stack/sandbags_empty/half = list(CAT_MARINE, "Sandbags x25", SANDBAG_PRICE_IN_GEAR_VENDOR, "orange"),
Expand Down Expand Up @@ -120,6 +125,10 @@ GLOBAL_LIST_INIT(robot_gear_listed_products, list(

GLOBAL_LIST_INIT(engineer_gear_listed_products, list(
/obj/effect/vendor_bundle/engi = list(CAT_ESS, "Essential Engineer Set", 0, "white"),
/obj/item/implanter/implantator/combat/firearms = list(CAT_ENGSUP, "Aiming support implanter", 25, "cyan2"),
/obj/item/implanter/implantator/combat/melee = list(CAT_ENGSUP, "Close combat codex implanter", 25, "cyan2"),
/obj/item/implanter/implantator/codex/engineer = list(CAT_ENGSUP, "Engineering support system implanter", 20, "cyan2"),
/obj/item/implanter/implantator/codex/construct = list(CAT_ENGSUP, "Construction support system implanter", 20, "cyan2"),
/obj/item/stack/sheet/metal/small_stack = list(CAT_ENGSUP, "Metal x10", METAL_PRICE_IN_GEAR_VENDOR, "orange"),
/obj/item/stack/sheet/plasteel/small_stack = list(CAT_ENGSUP, "Plasteel x10", PLASTEEL_PRICE_IN_GEAR_VENDOR, "orange"),
/obj/item/stack/sandbags_empty/half = list(CAT_ENGSUP, "Sandbags x25", SANDBAG_PRICE_IN_GEAR_VENDOR, "orange"),
Expand Down Expand Up @@ -162,6 +171,10 @@ GLOBAL_LIST_INIT(engineer_gear_listed_products, list(

GLOBAL_LIST_INIT(medic_gear_listed_products, list(
/obj/effect/vendor_bundle/medic = list(CAT_ESS, "Essential Medic Set", 0, "white"),
/obj/item/implanter/implantator/combat/firearms = list(CAT_MEDSUP, "Aiming support implanter", 25, "cyan2"),
/obj/item/implanter/implantator/combat/melee = list(CAT_MEDSUP, "Close combat codex implanter", 25, "cyan2"),
/obj/item/implanter/implantator/codex/medical = list(CAT_MEDSUP, "Medtech implanter", 20, "cyan2"),
/obj/item/implanter/implantator/codex/surgery = list(CAT_MEDSUP, "Surgery assisting system implanter", 20, "cyan2"),
/obj/item/reagent_containers/glass/bottle/lemoline/doctor = list(CAT_MEDSUP, "Lemoline bottle", 14, "orange"),
/obj/item/storage/pill_bottle/meralyne = list(CAT_MEDSUP, "Meralyne pills", 14, "orange"),
/obj/item/storage/pill_bottle/dermaline = list(CAT_MEDSUP, "Dermaline pills", 14, "orange"),
Expand Down Expand Up @@ -210,6 +223,12 @@ GLOBAL_LIST_INIT(medic_gear_listed_products, list(

GLOBAL_LIST_INIT(leader_gear_listed_products, list(
/obj/effect/vendor_bundle/leader = list(CAT_ESS, "Essential SL Set", 0, "white"),
/obj/item/implanter/implantator/combat/firearms = list(CAT_LEDSUP, "Aiming support implanter", 15, "cyan2"),
/obj/item/implanter/implantator/combat/melee = list(CAT_LEDSUP, "Close combat codex implanter", 15, "cyan2"),
/obj/item/implanter/implantator/codex/medical = list(CAT_LEDSUP, "Medtech implanter", 15, "cyan2"),
/obj/item/implanter/implantator/codex/engineer = list(CAT_LEDSUP, "Engineering support system implanter", 15, "cyan2"),
/obj/item/implanter/implantator/codex/construct = list(CAT_LEDSUP, "Construction support system implanter", 15, "cyan2"),
/obj/item/implanter/implantator/oper_system/leadership = list(CAT_LEDSUP, "Command protocols 'Graiyor' codex loader", 20, "cyan2"),
/obj/item/armor_module/module/valkyrie_autodoc = list(CAT_LEDSUP, "Valkyrie Automedical Armor System", 25,"white"),
/obj/effect/vendor_bundle/tyr/two = list(CAT_LEDSUP, "Tyr 2 extra armor set", 25,"white"),
/obj/effect/vendor_bundle/mimir/two = list(CAT_LEDSUP, "Mimir 2 extra armor set", 25,"white"),
Expand Down Expand Up @@ -269,6 +288,13 @@ GLOBAL_LIST_INIT(leader_gear_listed_products, list(

GLOBAL_LIST_INIT(commander_gear_listed_products, list(
/obj/effect/vendor_bundle/commander = list(CAT_ESS, "Essential FC Set", 0, "white"),
/obj/item/implanter/implantator/combat/firearms = list(CAT_FCSUP, "Aiming support implanter", 15, "cyan2"),
/obj/item/implanter/implantator/combat/melee = list(CAT_FCSUP, "Close combat codex implanter", 15, "cyan2"),
/obj/item/implanter/implantator/codex/medical = list(CAT_FCSUP, "Medtech implanter", 15, "cyan2"),
/obj/item/implanter/implantator/codex/surgery = list(CAT_FCSUP, "Surgery assisting system implanter", 15, "cyan2"),
/obj/item/implanter/implantator/codex/engineer = list(CAT_FCSUP, "Engineering support system implanter", 15, "cyan2"),
/obj/item/implanter/implantator/codex/construct = list(CAT_FCSUP, "Construction support system implanter", 15, "cyan2"),
/obj/item/implanter/implantator/oper_system/leadership = list(CAT_FCSUP, "Command protocols 'Graiyor' codex loader", 20, "cyan2"),
/obj/item/beacon/supply_beacon = list(CAT_FCSUP, "Supply beacon", 5, "blue"),
/obj/item/beacon/orbital_bombardment_beacon = list(CAT_FCSUP, "Orbital beacon", 5, "blue"),
/obj/item/fulton_extraction_pack = list(CAT_FCSUP, "Fulton Extraction Pack", 5, "blue"),
Expand Down
3 changes: 2 additions & 1 deletion code/__DEFINES/skills.dm
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@
#define SKILL_LEAD_BEGINNER 1 //All non-Standard Marines
#define SKILL_LEAD_TRAINED 2 //PO, CMO, etc
#define SKILL_LEAD_EXPERT 3 //SL, SO
#define SKILL_LEAD_MASTER 4 //XO, CO
#define SKILL_LEAD_MASTER 4 //XO, FC
#define SKILL_LEAD_SUPER 5 // implanted FC

//melee_weapons skill
//buff to melee weapon attack damage
Expand Down
9 changes: 7 additions & 2 deletions code/__HELPERS/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,14 @@
LAZYDECREMENT(user.do_actions, target)


/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1
///Multiplier on all do_afters for this mob
/mob/proc/do_after_coefficent()
. = 1

var/list/mod_list = list()
SEND_SIGNAL(src, MOB_GET_DO_AFTER_COEFFICIENT, mod_list)
for(var/num in mod_list)
. += num
. = max(0, .)

/proc/random_unique_name(gender, attempts_to_find_unique_name = 10)
for(var/i in 1 to attempts_to_find_unique_name)
Expand Down
178 changes: 123 additions & 55 deletions code/datums/components/_component.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
*/
var/can_transfer = FALSE

/// A lazy list of the sources for this component
var/list/sources

/**
* Create a new component.
*
Expand Down Expand Up @@ -157,6 +160,28 @@
/datum/component/proc/UnregisterFromParent()
return

/**
* Called when the component has a new source registered.
* Return COMPONENT_INCOMPATIBLE to signal that the source is incompatible and should not be added
*/
/datum/component/proc/on_source_add(source, ...)
SHOULD_CALL_PARENT(TRUE)
if(dupe_mode != COMPONENT_DUPE_SOURCES)
return COMPONENT_INCOMPATIBLE
LAZYOR(sources, source)

/**
* Called when the component has a source removed.
* You probably want to call parent after you do your logic because at the end of this we qdel if we have no sources remaining!
*/
/datum/component/proc/on_source_remove(source)
SHOULD_CALL_PARENT(TRUE)
if(dupe_mode != COMPONENT_DUPE_SOURCES)
CRASH("Component '[type]' does not use sources but is trying to remove a source")
LAZYREMOVE(sources, source)
if(!LAZYLEN(sources))
qdel(src)

/**
* Called on a component when a component of the same type was added to the same parent
*
Expand Down Expand Up @@ -280,70 +305,113 @@
*
* Properly handles duplicate situations based on the `dupe_mode` var
*/
/datum/proc/_AddComponent(list/raw_args)
var/new_type = raw_args[1]
var/datum/component/nt = new_type
var/dm = initial(nt.dupe_mode)
var/dt = initial(nt.dupe_type)

var/datum/component/old_comp
var/datum/component/new_comp

if(ispath(nt))
if(nt == /datum/component)
CRASH("[nt] attempted instantiation!")
else
new_comp = nt
nt = new_comp.type

raw_args[1] = src
/datum/proc/_AddComponent(list/raw_args, source)
var/original_type = raw_args[1]
var/datum/component/component_type = original_type

if(dm != COMPONENT_DUPE_ALLOWED)
if(!dt)
old_comp = GetExactComponent(nt)
if(QDELING(src))
CRASH("Attempted to add a new component of type \[[component_type]\] to a qdeleting parent of type \[[type]\]!")

var/datum/component/new_component

if(!ispath(component_type, /datum/component))
if(!istype(component_type, /datum/component))
CRASH("Attempted to instantiate \[[component_type]\] as a component added to parent of type \[[type]\]!")
else
old_comp = GetComponent(dt)
if(old_comp)
switch(dm)
new_component = component_type
component_type = new_component.type
else if(component_type == /datum/component)
CRASH("[component_type] attempted instantiation!")

var/dupe_mode = initial(component_type.dupe_mode)
var/dupe_type = initial(component_type.dupe_type)
var/uses_sources = (dupe_mode == COMPONENT_DUPE_SOURCES)
if(uses_sources && !source)
CRASH("Attempted to add a sourced component of type '[component_type]' to '[type]' without a source!")
else if(!uses_sources && source)
CRASH("Attempted to add a normal component of type '[component_type]' to '[type]' with a source!")

var/datum/component/old_component

raw_args[1] = src
if(dupe_mode != COMPONENT_DUPE_ALLOWED && dupe_mode != COMPONENT_DUPE_SELECTIVE && dupe_mode != COMPONENT_DUPE_SOURCES)
if(!dupe_type)
old_component = GetExactComponent(component_type)
else
old_component = GetComponent(dupe_type)

if(old_component)
switch(dupe_mode)
if(COMPONENT_DUPE_UNIQUE)
if(!new_comp)
new_comp = new nt(raw_args)
if(!QDELETED(new_comp))
old_comp.InheritComponent(new_comp, TRUE)
QDEL_NULL(new_comp)
if(!new_component)
new_component = new component_type(raw_args)
if(!QDELETED(new_component))
old_component.InheritComponent(new_component, TRUE)
QDEL_NULL(new_component)

if(COMPONENT_DUPE_HIGHLANDER)
if(!new_comp)
new_comp = new nt(raw_args)
if(!QDELETED(new_comp))
new_comp.InheritComponent(old_comp, FALSE)
QDEL_NULL(old_comp)
if(!new_component)
new_component = new component_type(raw_args)
if(!QDELETED(new_component))
new_component.InheritComponent(old_component, FALSE)
QDEL_NULL(old_component)

if(COMPONENT_DUPE_UNIQUE_PASSARGS)
if(!new_comp)
if(!new_component)
var/list/arguments = raw_args.Copy(2)
arguments.Insert(1, null, TRUE)
old_comp.InheritComponent(arglist(arguments))
old_component.InheritComponent(arglist(arguments))
else
old_comp.InheritComponent(new_comp, TRUE)
if(COMPONENT_DUPE_SELECTIVE)
var/list/arguments = raw_args.Copy()
arguments[1] = new_comp
var/make_new_component = TRUE
for(var/datum/component/existing_component as anything in GetComponents(new_type))
if(existing_component.CheckDupeComponent(arglist(arguments)))
make_new_component = FALSE
QDEL_NULL(new_comp)
break
if(!new_comp && make_new_component)
new_comp = new nt(raw_args)
else if(!new_comp)
new_comp = new nt(raw_args) // There's a valid dupe mode but there's no old component, act like normal
else if(!new_comp)
new_comp = new nt(raw_args) // Dupes are allowed, act like normal

if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy
SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp)
return new_comp
return old_comp
old_component.InheritComponent(new_component, TRUE)

if(COMPONENT_DUPE_SOURCES)
if(source in old_component.sources)
return old_component // source already registered, no work to do

if(old_component.on_source_add(arglist(list(source) + raw_args.Copy(2))) == COMPONENT_INCOMPATIBLE)
stack_trace("incompatible source added to a [old_component.type]. Args: [json_encode(raw_args)]")
return null

else if(!new_component)
new_component = new component_type(raw_args) // There's a valid dupe mode but there's no old component, act like normal

else if(dupe_mode == COMPONENT_DUPE_SELECTIVE)
var/list/arguments = raw_args.Copy()
arguments[1] = new_component
var/make_new_component = TRUE
for(var/datum/component/existing_component as anything in GetComponents(original_type))
if(existing_component.CheckDupeComponent(arglist(arguments)))
make_new_component = FALSE
QDEL_NULL(new_component)
break
if(!new_component && make_new_component)
new_component = new component_type(raw_args)

else if(dupe_mode == COMPONENT_DUPE_SOURCES)
new_component = new component_type(raw_args)
if(new_component.on_source_add(arglist(list(source) + raw_args.Copy(2))) == COMPONENT_INCOMPATIBLE)
stack_trace("incompatible source added to a [new_component.type]. Args: [json_encode(raw_args)]")
return null

else if(!new_component)
new_component = new component_type(raw_args) // Dupes are allowed, act like normal

if(!old_component && !QDELETED(new_component)) // Nothing related to duplicate components happened and the new component is healthy
SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_component)
return new_component

return old_component

/**
* Removes a component source from this datum
*/
/datum/proc/RemoveComponentSource(source, datum/component/component_type)
if(ispath(component_type))
component_type = GetExactComponent(component_type)
if(!component_type)
return
component_type.on_source_remove(source)

/**
* Get existing component of type, or create it and return a reference to it
Expand Down
Loading
Loading