From e836e6fdac0764aff5bb055f640fd39c95ea74f4 Mon Sep 17 00:00:00 2001
From: Molti <108117184+Moltijoe@users.noreply.github.com>
Date: Wed, 17 Jul 2024 14:36:50 -0500
Subject: [PATCH] Rewrites how species are granted abilities + rewrites some of
abilities themselves (#22366)
* guh, the work begins
* done for now hopefully
* lint
* Update maglock.dm
* Update maglock.dm
* done
---
.../mob/living/carbon/human/_species.dm | 15 +
.../living/carbon/human/species_types/IPC.dm | 7 +-
.../carbon/human/species_types/jellypeople.dm | 268 +++++++-----------
.../spells/spell_types/toggle/_toggle.dm | 9 +-
code/modules/surgery/organs/augment_legs.dm | 43 +--
yogstation.dme | 1 +
.../carbon/human/species_types/jellypeople.dm | 20 +-
.../human/species_types/preternis/maglock.dm | 38 +++
.../species_types/preternis/preternis.dm | 62 +---
9 files changed, 181 insertions(+), 282 deletions(-)
create mode 100644 yogstation/code/modules/mob/living/carbon/human/species_types/preternis/maglock.dm
diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm
index ac906eb83dcb..ece396b14978 100644
--- a/code/modules/mob/living/carbon/human/_species.dm
+++ b/code/modules/mob/living/carbon/human/_species.dm
@@ -223,6 +223,11 @@ GLOBAL_LIST_EMPTY(features_by_species)
/// Do we try to prevent reset_perspective() from working? Useful for Dullahans to stop perspective changes when they're looking through their head.
var/prevent_perspective_change = FALSE
+ /// List of the type path of every ability innate to this species
+ var/list/species_abilities = list()
+ /// List of the created abilities, stored for the purpose of removal later, please do not touch this if you don't need to
+ var/list/datum/action/instantiated_abilities = list()
+
///////////
// PROCS //
///////////
@@ -502,6 +507,11 @@ GLOBAL_LIST_EMPTY(features_by_species)
fly = new
fly.Grant(C)
+ for(var/ability_path in species_abilities)
+ var/datum/action/ability = new ability_path(C)
+ ability.Grant(C)
+ instantiated_abilities += ability
+
C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING))
C.regenerate_icons()
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
@@ -547,6 +557,11 @@ GLOBAL_LIST_EMPTY(features_by_species)
C.dna.features["wingsdetail"] = "None"
C.update_body()
+ for(var/datum/action/ability as anything in instantiated_abilities)
+ ability.Remove(C)
+ instantiated_abilities -= ability
+ qdel(ability)
+
C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES)
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
diff --git a/code/modules/mob/living/carbon/human/species_types/IPC.dm b/code/modules/mob/living/carbon/human/species_types/IPC.dm
index fbe90481050c..68573fe02931 100644
--- a/code/modules/mob/living/carbon/human/species_types/IPC.dm
+++ b/code/modules/mob/living/carbon/human/species_types/IPC.dm
@@ -51,7 +51,7 @@
// Hats need to be 1 up
offset_features = list(OFFSET_HEAD = list(0,1))
- var/datum/action/innate/change_screen/change_screen
+ species_abilities = list(/datum/action/innate/change_screen)
smells_like = "industrial lubricant"
@@ -66,9 +66,6 @@
if(A)
A.Remove(C)
QDEL_NULL(A)
- if(ishuman(C) && !change_screen)
- change_screen = new
- change_screen.Grant(C)
for(var/obj/item/bodypart/O in C.bodyparts)
O.render_like_organic = TRUE // Makes limbs render like organic limbs instead of augmented limbs, check bodyparts.dm
var/chassis = C.dna.features["ipc_chassis"]
@@ -82,8 +79,6 @@
/datum/species/ipc/on_species_loss(mob/living/carbon/C)
. = ..()
QDEL_NULL(C.particles)
- if(change_screen)
- change_screen.Remove(C)
/datum/species/ipc/proc/handle_speech(datum/source, list/speech_args)
speech_args[SPEECH_SPANS] |= SPAN_ROBOT
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index 19fb52650d45..f820b6a9483f 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -13,7 +13,6 @@
mutanttongue = /obj/item/organ/tongue/slime
mutantlungs = /obj/item/organ/lungs/slime
damage_overlay_type = ""
- var/datum/action/innate/regenerate_limbs/regenerate_limbs
liked_food = MEAT
coldmod = 6
heatmod = 0.5
@@ -23,19 +22,17 @@
swimming_component = /datum/component/swimming/dissolve
hair_color = "mutcolor"
hair_alpha = 140
+
+ species_abilities = list(/datum/action/innate/regenerate_limbs)
+
var/soggy = FALSE
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
- if(regenerate_limbs)
- regenerate_limbs.Remove(C)
C.faction -= "slime"
- ..()
+ return ..()
/datum/species/jelly/on_species_gain(mob/living/carbon/C, datum/species/old_species)
- ..()
- if(ishuman(C))
- regenerate_limbs = new
- regenerate_limbs.Grant(C)
+ . = ..()
C.faction |= "slime"
/datum/species/jelly/spec_life(mob/living/carbon/human/H)
@@ -59,8 +56,9 @@
to_chat(H, span_danger("You feel drained!"))
if(H.blood_volume < BLOOD_VOLUME_BAD(H))
Cannibalize_Body(H)
- if(regenerate_limbs)
- regenerate_limbs.build_all_button_icons()
+ var/datum/action/innate/regenerate_limbs/ability = locate() in instantiated_abilities
+ if(ability)
+ ability.build_all_button_icons()
/datum/species/jelly/proc/Cannibalize_Body(mob/living/carbon/human/H)
var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs()
@@ -198,15 +196,15 @@
hair_color = "mutcolor"
hair_alpha = 150
ignored_by = list(/mob/living/simple_animal/slime)
- var/datum/action/innate/split_body/slime_split
+
+ species_abilities = list(
+ /datum/action/innate/regenerate_limbs,
+ /datum/action/innate/split_body,
+ /datum/action/innate/swap_body
+ )
var/list/mob/living/carbon/bodies
- var/datum/action/innate/swap_body/swap_body
/datum/species/jelly/slime/on_species_loss(mob/living/carbon/C)
- if(slime_split)
- slime_split.Remove(C)
- if(swap_body)
- swap_body.Remove(C)
bodies -= C // This means that the other bodies maintain a link
// so if someone mindswapped into them, they'd still be shared.
bodies = null
@@ -216,11 +214,6 @@
/datum/species/jelly/slime/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
if(ishuman(C))
- slime_split = new
- slime_split.Grant(C)
- swap_body = new
- swap_body.Grant(C)
-
if(!bodies || !bodies.len)
bodies = list(C)
else
@@ -238,8 +231,7 @@
else if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
H.blood_volume += 3
H.adjust_nutrition(-2.5)
-
- ..()
+ return ..()
/datum/action/innate/split_body
name = "Split Body"
@@ -430,10 +422,10 @@
SS.bodies -= dupe
return FALSE
- if(dupe.stat == DEAD) //Is it alive?
+ if(H.stat != CONSCIOUS) //Are we alive and awake?
return FALSE
- if(dupe.stat != CONSCIOUS) //Is it awake?
+ if(dupe.stat != CONSCIOUS) //Is it alive and awake?
return FALSE
if(dupe.mind && dupe.mind.active) //Is it unoccupied?
@@ -470,10 +462,15 @@
id = SPECIES_LUMINESCENT
say_mod = "says"
var/glow_intensity = LUMINESCENT_DEFAULT_GLOW
+
+ species_abilities = list(
+ /datum/action/innate/regenerate_limbs,
+ /datum/action/innate/integrate_extract,
+ /datum/action/innate/use_extract,
+ /datum/action/innate/use_extract/major
+ )
+
var/obj/item/slime_extract/current_extract
- var/datum/action/innate/integrate_extract/integrate_extract
- var/datum/action/innate/use_extract/extract_minor
- var/datum/action/innate/use_extract/major/extract_major
var/extract_cooldown = 0
/// Internal dummy used to glow (very cool)
@@ -489,29 +486,15 @@
current_extract.forceMove(C.drop_location())
current_extract = null
QDEL_NULL(glow)
- if(integrate_extract)
- integrate_extract.Remove(C)
- if(extract_minor)
- extract_minor.Remove(C)
- if(extract_major)
- extract_major.Remove(C)
/datum/species/jelly/luminescent/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
glow = C.mob_light(light_type = /obj/effect/dummy/lighting_obj/moblight/species)
update_glow(C)
- integrate_extract = new(src)
- integrate_extract.Grant(C)
- extract_minor = new(src)
- extract_minor.Grant(C)
- extract_major = new(src)
- extract_major.Grant(C)
-/datum/species/jelly/luminescent/proc/update_slime_actions()
- integrate_extract.update_name()
- integrate_extract.build_all_button_icons()
- extract_minor.build_all_button_icons()
- extract_major.build_all_button_icons()
+/datum/species/jelly/luminescent/proc/update_slime_actions(mob/living/carbon/C)
+ for(var/datum/action/ability as anything in C.actions)
+ ability.build_all_button_icons()
/datum/species/jelly/luminescent/proc/update_glow(mob/living/carbon/C, intensity)
if(intensity)
@@ -528,17 +511,12 @@
overlay_icon_state = "bg_alien_border"
var/datum/species/jelly/luminescent/species
-/datum/action/innate/integrate_extract/New(_species)
- ..()
- species = _species
-
-/datum/action/innate/integrate_extract/proc/update_name()
- if(!species || !species.current_extract)
- name = "Integrate Extract"
- desc = "Eat a slime extract to use its properties."
- else
- name = "Eject Extract"
- desc = "Eject your current slime extract."
+/datum/action/innate/integrate_extract/link_to(Target)
+ . = ..()
+ if(ishuman(target))
+ var/mob/living/carbon/human/humie = target
+ if(humie?.dna?.species)
+ species = humie.dna.species
/datum/action/innate/integrate_extract/update_button_name(atom/movable/screen/movable/action_button/button, force = FALSE)
var/datum/species/jelly/luminescent/species = target
@@ -572,7 +550,7 @@
S.forceMove(H.drop_location())
species.current_extract = null
to_chat(H, span_notice("You eject [S]."))
- species.update_slime_actions()
+ species.update_slime_actions(H)
else
var/obj/item/I = H.get_active_held_item()
if(istype(I, /obj/item/slime_extract))
@@ -585,7 +563,7 @@
S.forceMove(H)
species.current_extract = S
to_chat(H, span_notice("You consume [I], and you feel it pulse within you..."))
- species.update_slime_actions()
+ species.update_slime_actions(H)
else
to_chat(H, span_warning("You need to hold an unused slime extract in your active hand!"))
@@ -640,101 +618,99 @@
name = "Stargazer"
plural_form = null
id = SPECIES_STARGAZER
- var/datum/action/innate/project_thought/project_thought
- var/datum/action/innate/link_minds/link_minds
- var/list/mob/living/linked_mobs = list()
- var/list/datum/action/innate/linked_speech/linked_actions = list()
- var/mob/living/carbon/human/slimelink_owner
- var/current_link_id = 0
+ species_abilities = list(
+ /datum/action/innate/regenerate_limbs,
+ /datum/action/cooldown/spell/touch/link_minds,
+ /datum/action/innate/project_thought
+ )
-/datum/species/jelly/stargazer/on_species_loss(mob/living/carbon/C)
- ..()
- for(var/M in linked_mobs)
- unlink_mob(M)
- if(project_thought)
- project_thought.Remove(C)
- if(link_minds)
- link_minds.Remove(C)
+/datum/action/cooldown/spell/touch/link_minds
+ name = "Link Minds"
+ desc = "Link someone's mind to your Slime Link, allowing them to communicate telepathically with other linked minds."
+ button_icon_state = "mindlink"
+ button_icon = 'icons/mob/actions/actions_slime.dmi'
+ background_icon_state = "bg_alien"
+ overlay_icon_state = "bg_alien_border"
+ spell_requirements = NONE
+ invocation_type = INVOCATION_NONE
+ var/list/datum/action/speech_abilities = list()
-/datum/species/jelly/stargazer/spec_death(gibbed, mob/living/carbon/human/H)
- ..()
- for(var/M in linked_mobs)
- unlink_mob(M)
+/datum/action/cooldown/spell/touch/link_minds/Grant(mob/grant_to)
+ . = ..()
+ var/datum/action/innate/slime_speech/action = new(grant_to)
+ action.Grant(grant_to)
+ action.linkage = src
+ speech_abilities += action
-/datum/species/jelly/stargazer/on_species_gain(mob/living/carbon/C, datum/species/old_species)
- ..()
- project_thought = new(src)
- project_thought.Grant(C)
- link_minds = new(src)
- link_minds.Grant(C)
- slimelink_owner = C
- link_mob(C)
+/datum/action/cooldown/spell/touch/link_minds/Remove(mob/living/remove_from)
+ for(var/datum/action/ability as anything in speech_abilities)
+ ability.Remove(ability.owner)
+ qdel(ability)
+ return ..()
-/datum/species/jelly/stargazer/proc/link_mob(mob/living/M)
- if(QDELETED(M) || M.stat == DEAD)
- return FALSE
- if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) //mindshield implant, no dice
- return FALSE
- if(M.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
- return FALSE
- if(M in linked_mobs)
- return FALSE
- linked_mobs.Add(M)
- to_chat(M, span_notice("You are now connected to [slimelink_owner.real_name]'s Slime Link."))
- var/datum/action/innate/linked_speech/action = new(src)
- linked_actions.Add(action)
- action.Grant(M)
+/datum/action/cooldown/spell/touch/link_minds/cast_on_hand_hit(obj/item/melee/touch_attack/hand, atom/target, mob/living/carbon/caster)
+ if(!isliving(target))
+ return
+ var/mob/living/victim = target
+
+ to_chat(caster, span_notice("You begin linking [victim]'s mind to yours..."))
+ to_chat(victim, span_warning("You feel a foreign presence within your mind..."))
+
+ if(!do_after(caster, 5 SECONDS, victim))
+ return
+
+ for(var/datum/action/ability as anything in victim.actions)
+ if(istype(ability, /datum/action/innate/slime_speech))
+ var/datum/action/innate/slime_speech/speaker = ability
+ if(speaker.linkage == src)
+ speech_abilities -= speaker
+ speaker.Remove(victim)
+ qdel(speaker)
+ to_chat(caster, span_notice("You release [victim] from your Slime Link."))
+ to_chat(victim, span_notice("You are no longer connected to [caster.real_name]'s Slime Link."))
+ return TRUE
+
+ var/datum/action/innate/slime_speech/action = new(victim)
+ action.Grant(victim)
+ action.linkage = src
+ speech_abilities += action
+ to_chat(caster, span_notice("You connect [victim]'s mind to your slime link!"))
+ to_chat(victim, span_notice("You are now connected to [caster.real_name]'s Slime Link."))
return TRUE
-/datum/species/jelly/stargazer/proc/unlink_mob(mob/living/M)
- var/link_id = linked_mobs.Find(M)
- if(!(link_id))
- return
- var/datum/action/innate/linked_speech/action = linked_actions[link_id]
- action.Remove(M)
- to_chat(M, span_notice("You are no longer connected to [slimelink_owner.real_name]'s Slime Link."))
- linked_mobs[link_id] = null
- linked_actions[link_id] = null
-
-/datum/action/innate/linked_speech
+/datum/action/innate/slime_speech
name = "Slimelink"
desc = "Send a psychic message to everyone connected to your slime link."
button_icon_state = "link_speech"
button_icon = 'icons/mob/actions/actions_slime.dmi'
background_icon_state = "bg_alien"
- var/datum/species/jelly/stargazer/species
+ var/datum/action/cooldown/spell/touch/link_minds/linkage
-/datum/action/innate/linked_speech/New(_species)
- ..()
- species = _species
-
-/datum/action/innate/linked_speech/Activate()
+/datum/action/innate/slime_speech/Activate()
var/mob/living/carbon/human/H = owner
- if(!species || !(H in species.linked_mobs))
+ if(!linkage)
to_chat(H, span_warning("The link seems to have been severed..."))
Remove(H)
return
var/message = sanitize(input("Message:", "Slime Telepathy") as text|null)
- if(!species || !(H in species.linked_mobs))
+ if(QDELETED(H) || H.stat == DEAD)
+ return
+
+ if(!linkage)
to_chat(H, span_warning("The link seems to have been severed..."))
Remove(H)
return
- if(QDELETED(H) || H.stat == DEAD)
- species.unlink_mob(H)
- return
-
if(message)
- var/msg = "\[[species.slimelink_owner.real_name]'s Slime Link\] [H]: [message]"
- log_directed_talk(H, species.slimelink_owner, msg, LOG_SAY, "slime link")
- for(var/X in species.linked_mobs)
- var/mob/living/M = X
- if(QDELETED(M) || M.stat == DEAD)
- species.unlink_mob(M)
+ var/msg = "\[[linkage.owner.real_name]'s Slime Link\] [H]: [message]"
+ log_directed_talk(H, linkage.owner, msg, LOG_SAY, "slime link")
+ for(var/X in linkage.speech_abilities)
+ var/datum/action/innate/linked_speech = X
+ if(!linked_speech || !istype(linked_speech))
continue
- to_chat(M, msg)
+ to_chat(linked_speech.owner, msg)
for(var/X in GLOB.dead_mob_list)
var/mob/M = X
@@ -780,39 +756,3 @@
var/follow_link_user = FOLLOW_LINK(dead, H)
var/follow_link_target = FOLLOW_LINK(dead, M)
to_chat(dead, "[follow_link_user] [span_name("[H]")] [span_alertalien("Slime Telepathy --> ")] [follow_link_target] [span_name("[M]")] [span_noticealien("[msg]")]")
-
-/datum/action/innate/link_minds
- name = "Link Minds"
- desc = "Link someone's mind to your Slime Link, allowing them to communicate telepathically with other linked minds."
- button_icon_state = "mindlink"
- button_icon = 'icons/mob/actions/actions_slime.dmi'
- background_icon_state = "bg_alien"
- overlay_icon_state = "bg_alien_border"
- var/datum/species/jelly/stargazer/species
-
-/datum/action/innate/link_minds/New(_species)
- ..()
- species = _species
-
-/datum/action/innate/link_minds/Activate()
- var/mob/living/carbon/human/H = owner
- if(!is_species(H, /datum/species/jelly/stargazer))
- return
- CHECK_DNA_AND_SPECIES(H)
-
- if(!H.pulling || !isliving(H.pulling) || H.grab_state < GRAB_AGGRESSIVE)
- to_chat(H, span_warning("You need to aggressively grab someone to link minds!"))
- return
-
- var/mob/living/target = H.pulling
-
- to_chat(H, span_notice("You begin linking [target]'s mind to yours..."))
- to_chat(target, span_warning("You feel a foreign presence within your mind..."))
- if(do_after(H, 6 SECONDS, target))
- if(H.pulling != target || H.grab_state < GRAB_AGGRESSIVE)
- return
- if(species.link_mob(target))
- to_chat(H, span_notice("You connect [target]'s mind to your slime link!"))
- else
- to_chat(H, span_warning("You can't seem to link [target]'s mind..."))
- to_chat(target, span_warning("The foreign presence leaves your mind."))
diff --git a/code/modules/spells/spell_types/toggle/_toggle.dm b/code/modules/spells/spell_types/toggle/_toggle.dm
index 6fa127377805..d1dd5ccf19a7 100644
--- a/code/modules/spells/spell_types/toggle/_toggle.dm
+++ b/code/modules/spells/spell_types/toggle/_toggle.dm
@@ -4,23 +4,28 @@
var/active = FALSE
/datum/action/cooldown/spell/toggle/New()
- ..()
+ . = ..()
START_PROCESSING(SSfastprocess, src)
/datum/action/cooldown/spell/toggle/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
+/datum/action/cooldown/spell/toggle/Remove(mob/living/remove_from)
+ if(active)
+ Disable()
+ return ..()
+
/datum/action/cooldown/spell/toggle/process()
build_all_button_icons(ALL) //so as to be consistent with situational requirements, keep the button updated
/datum/action/cooldown/spell/toggle/cast(atom/cast_on)
- . = ..()
active = !active
if(active)
Enable()
else
Disable()
+ return ..()
/datum/action/cooldown/spell/toggle/is_action_active(atom/movable/screen/movable/action_button/current_button)
return active
diff --git a/code/modules/surgery/organs/augment_legs.dm b/code/modules/surgery/organs/augment_legs.dm
index 706f430160dc..a5d6386fe6c4 100644
--- a/code/modules/surgery/organs/augment_legs.dm
+++ b/code/modules/surgery/organs/augment_legs.dm
@@ -343,7 +343,7 @@
name = "magboot implant"
desc = "Integrated maglock implant, allows easy movement in a zero-gravity environment."
implant_type = "magboot"
- var/datum/action/innate/magboots/implant_ability
+ var/datum/action/cooldown/spell/toggle/maglock/implant_ability
/obj/item/organ/cyberimp/leg/magboot/l
zone = BODY_ZONE_L_LEG
@@ -355,44 +355,3 @@
/obj/item/organ/cyberimp/leg/magboot/RemoveEffect()
if(implant_ability)
implant_ability.Remove(owner)
- owner.remove_movespeed_modifier("Magbootimplant")
-
-/datum/action/innate/magboots
- var/lockdown = FALSE
- name = "Maglock"
- check_flags = AB_CHECK_CONSCIOUS
- button_icon_state = "magboots0"
- button_icon = 'icons/obj/clothing/shoes.dmi'
- background_icon_state = "bg_default"
-
-/datum/action/innate/magboots/Grant(mob/M)
- if(!ishuman(M))
- return
- . = ..()
- RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(UpdateSpeed))
-
-/datum/action/innate/magboots/Remove(mob/M)
- UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE)
- . = ..()
-
-/datum/action/innate/magboots/Trigger()
- if(!lockdown)
- ADD_TRAIT(owner, TRAIT_NOSLIPWATER, "maglock implant")
- ADD_TRAIT(owner, TRAIT_NOSLIPICE, "maglock_implant")
- ADD_TRAIT(owner, TRAIT_MAGBOOTS, "maglock implant")
- button_icon_state = "magboots1"
- else
- REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER, "maglock implant")
- REMOVE_TRAIT(owner, TRAIT_NOSLIPICE, "maglock_implant")
- REMOVE_TRAIT(owner, TRAIT_MAGBOOTS, "maglock implant")
- button_icon_state = "magboots0"
- build_all_button_icons()
- lockdown = !lockdown
- to_chat(owner, span_notice("You [lockdown ? "enable" : "disable"] your mag-pulse traction system."))
- owner.update_gravity(owner.has_gravity())
-
-/datum/action/innate/magboots/proc/UpdateSpeed()
- if(lockdown && !HAS_TRAIT(owner, TRAIT_IGNORESLOWDOWN) && owner.has_gravity())
- owner.add_movespeed_modifier("Magbootimplant", update=TRUE, priority=100, multiplicative_slowdown=2, blacklisted_movetypes=(FLYING|FLOATING))
- else if(owner.has_movespeed_modifier("Magbootimplant"))
- owner.remove_movespeed_modifier("Magbootimplant")
diff --git a/yogstation.dme b/yogstation.dme
index 6daea9157439..de2116f011ca 100644
--- a/yogstation.dme
+++ b/yogstation.dme
@@ -4469,6 +4469,7 @@
#include "yogstation\code\modules\mob\living\carbon\human\species_types\plantpeople.dm"
#include "yogstation\code\modules\mob\living\carbon\human\species_types\szlachta.dm"
#include "yogstation\code\modules\mob\living\carbon\human\species_types\vox.dm"
+#include "yogstation\code\modules\mob\living\carbon\human\species_types\preternis\maglock.dm"
#include "yogstation\code\modules\mob\living\carbon\human\species_types\preternis\organs.dm"
#include "yogstation\code\modules\mob\living\carbon\human\species_types\preternis\power_suck.dm"
#include "yogstation\code\modules\mob\living\carbon\human\species_types\preternis\preternis.dm"
diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index 8347c19cf11f..e7ee5d5aa37c 100644
--- a/yogstation/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/yogstation/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -11,16 +11,20 @@
RegisterSignal(C, COMSIG_MOB_ALTCLICKON, PROC_REF(handle_altclick))
/datum/species/jelly/slime/proc/handle_altclick(mob/living/carbon/human/M, mob/living/carbon/human/target)
- if(M && M.mind && swap_body && swap_body.can_swap(target))
- swap_body.swap_to_dupe(M.mind, target)
+ if(M && M.mind)
+ var/datum/action/innate/swap_body/this_swap = locate() in instantiated_abilities
+ if(!this_swap || !this_swap.can_swap(target))
+ return
+ this_swap.swap_to_dupe(M.mind, target)
return COMSIG_MOB_CANCEL_CLICKON
/datum/action/innate/swap_body/swap_to_dupe(datum/mind/M, mob/living/carbon/human/dupe)
var/mob/living/carbon/human/old = M.current
. = ..()
if(old != M.current && dupe == M.current && isslimeperson(dupe))
- var/datum/species/jelly/slime/other_spec = dupe.dna.species
- var/datum/action/innate/swap_body/other_swap = other_spec.swap_body
+ var/datum/action/innate/swap_body/other_swap = locate() in dupe.actions
+ if(!other_swap)
+ return
// theoretically the transfer_to proc is supposed to transfer the ui from the mob.
// so I try to get the UI from one of the two mobs and schlump it over to the new action button
var/datum/tgui/ui = SStgui.get_open_ui(old, src, "main") || SStgui.get_open_ui(dupe, src, "main")
@@ -40,10 +44,10 @@
var/mob/living/carbon/human/dupe = M.current
if(old != dupe && isslimeperson(dupe) && isslimeperson(old))
// transfer the swap-body ui if it's open
- var/datum/species/jelly/slime/this_spec = old.dna.species
- var/datum/species/jelly/slime/other_spec = dupe.dna.species
- var/datum/action/innate/swap_body/this_swap = this_spec.swap_body
- var/datum/action/innate/swap_body/other_swap = other_spec.swap_body
+ var/datum/action/innate/swap_body/this_swap = locate() in old.actions
+ var/datum/action/innate/swap_body/other_swap = locate() in dupe.actions
+ if(!this_swap && !other_swap)
+ return
var/datum/tgui/ui = SStgui.get_open_ui(old, this_swap, "main") || SStgui.get_open_ui(dupe, this_swap, "main")
if(ui)
SStgui.on_close(ui) // basically removes it from lists is all this proc does.
diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/maglock.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/maglock.dm
new file mode 100644
index 000000000000..0bf5b3d2f70f
--- /dev/null
+++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/maglock.dm
@@ -0,0 +1,38 @@
+/datum/action/cooldown/spell/toggle/maglock
+ name = "Maglock"
+ check_flags = AB_CHECK_CONSCIOUS
+ button_icon_state = "magboots0"
+ button_icon = 'icons/obj/clothing/shoes.dmi'
+ background_icon_state = "bg_default"
+ overlay_icon_state = "bg_alien_border"
+ spell_requirements = NONE
+
+/datum/action/cooldown/spell/toggle/maglock/Grant(mob/M)
+ . = ..()
+ RegisterSignal(M, COMSIG_MOB_CLIENT_PRE_MOVE, PROC_REF(UpdateSpeed))
+
+/datum/action/cooldown/spell/toggle/maglock/Remove(mob/M)
+ UnregisterSignal(M, COMSIG_MOB_CLIENT_PRE_MOVE)
+ return ..()
+
+/datum/action/cooldown/spell/toggle/maglock/Enable()
+ ADD_TRAIT(owner, TRAIT_NOSLIPWATER, type)
+ ADD_TRAIT(owner, TRAIT_NOSLIPICE, type)
+ ADD_TRAIT(owner, TRAIT_MAGBOOTS, type)
+ button_icon_state = "magboots1"
+ to_chat(owner, span_notice("You enable your mag-pulse traction system."))
+ UpdateSpeed()
+
+/datum/action/cooldown/spell/toggle/maglock/Disable()
+ REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER, type)
+ REMOVE_TRAIT(owner, TRAIT_NOSLIPICE, type)
+ REMOVE_TRAIT(owner, TRAIT_MAGBOOTS, type)
+ button_icon_state = "magboots0"
+ to_chat(owner, span_notice("You disable your mag-pulse traction system."))
+ UpdateSpeed()
+
+/datum/action/cooldown/spell/toggle/maglock/proc/UpdateSpeed()
+ if(active && !HAS_TRAIT(owner, TRAIT_IGNORESLOWDOWN) && owner.has_gravity())
+ owner.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown = 1, blacklisted_movetypes=(FLYING|FLOATING))
+ else
+ owner.remove_movespeed_modifier(type)
diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm
index 1680a71cf835..6c806c3c11e3 100644
--- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm
+++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm
@@ -50,9 +50,9 @@
default_features = list("weathering" = "None", "antenna" = "None", "preternis_eye" = "Standard", "preternis_core" = "Core")
wings_icon = "Elytra"
+ species_abilities = list(/datum/action/cooldown/spell/toggle/maglock)
+
//new variables
- var/datum/action/innate/maglock/maglock
- var/lockdown = FALSE
var/eating_msg_cooldown = FALSE
var/emag_lvl = 0
var/soggy = FALSE
@@ -77,11 +77,6 @@
RegisterSignal(C, COMSIG_MOB_ALTCLICKON, PROC_REF(drain_power_from))
- if(ishuman(C))
- maglock = new
- maglock.Grant(C)
- lockdown = FALSE
-
/datum/species/preternis/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
. = ..()
for (var/V in C.bodyparts)
@@ -95,52 +90,6 @@
C.clear_alert("preternis_emag") //this means a changeling can transform from and back to a preternis to clear the emag status but w/e i cant find a solution to not do that
C.clear_fullscreen("preternis_emag")
C.remove_movespeed_modifier("preternis_water")
- C.remove_movespeed_modifier("preternis_maglock")
-
- if(lockdown)
- maglock.Trigger(TRUE)
- if(maglock)
- maglock.Remove(C)
-
-
-/datum/action/innate/maglock
- var/datum/species/preternis/owner_species
- var/lockdown = FALSE
- name = "Maglock"
- check_flags = AB_CHECK_CONSCIOUS
- button_icon_state = "magboots0"
- button_icon = 'icons/obj/clothing/shoes.dmi'
- background_icon_state = "bg_default"
-
-/datum/action/innate/maglock/Grant(mob/M)
- if(!ispreternis(M))
- return
- var/mob/living/carbon/human/H = M
- owner_species = H.dna.species
- . = ..()
-
-/datum/action/innate/maglock/Trigger(silent = FALSE)
- var/mob/living/carbon/human/H = usr
- if(!lockdown)
- ADD_TRAIT(H, TRAIT_NOSLIPWATER, "preternis_maglock")
- ADD_TRAIT(H, TRAIT_NOSLIPICE, "preternis_maglock")
- button_icon_state = "magboots1"
- else
- REMOVE_TRAIT(H, TRAIT_NOSLIPWATER, "preternis_maglock")
- REMOVE_TRAIT(H, TRAIT_NOSLIPICE, "preternis_maglock")
- button_icon_state = "magboots0"
- build_all_button_icons()
- lockdown = !lockdown
- owner_species.lockdown = !owner_species.lockdown
- if(!silent)
- to_chat(H, span_notice("You [lockdown ? "enable" : "disable"] your mag-pulse traction system."))
- H.update_gravity(H.has_gravity())
-
-/datum/species/preternis/negates_gravity(mob/living/carbon/human/H)
- return (..() || lockdown)
-
-/datum/species/preternis/has_heavy_gravity()
- return (..() || lockdown)
/datum/species/preternis/spec_emag_act(mob/living/carbon/human/H, mob/user, obj/item/card/emag/emag_card)
. = ..()
@@ -180,13 +129,6 @@
emag_lvl = 0
H.clear_alert("preternis_emag")
H.clear_fullscreen("preternis_emag")
-
-/datum/species/preternis/movement_delay(mob/living/carbon/human/H)
- . = ..()
- if(lockdown && !HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN) && H.has_gravity())
- H.add_movespeed_modifier("preternis_magboot", update=TRUE, priority=100, multiplicative_slowdown=1, blacklisted_movetypes=(FLYING|FLOATING))
- else if(H.has_movespeed_modifier("preternis_magboot"))
- H.remove_movespeed_modifier("preternis_magboot")
/datum/species/preternis/spec_life(mob/living/carbon/human/H)
. = ..()