From f944caa59cff3cc0a94f7cfe07b2612f9710483a Mon Sep 17 00:00:00 2001 From: The Sharkening <95130227+StrangeWeirdKitten@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:03:45 -0600 Subject: [PATCH] Fixes multiple protean issues. (Outfitting, species loss / add, suit assimilation, and you can be a ninja now) (#5947) ## About The Pull Request Fixes some really long standing Protean issues and minorly refractors Protean suit assimilation to be on the species datum. This also fixes antag selection like ninjas not functioning properly. You can be a protean ninja now. ## Why It's Good For The Game I think bugs are bad. ## Proof Of Testing I tested everything I can think of, image ## Changelog :cl: fix: Proteans can now be outfitted properly. fix: Suit assimilation no longer drops modules on the floor and it should act more sane. fix: Losing your species no longer deletes your items in storage or your assimilated suit. fix: Gaining the protean species allows you to properly be a Protean. fix: You can now be mid-round antag spawn as a Protean without being broken. fix: As a protean ninja, you can now emag doors and hack borgs. code: Minorly refactored suit assimilation. Please report any issues. /:cl: --- code/datums/outfit.dm | 2 +- code/modules/admin/verbs/selectequipment.dm | 2 + code/modules/mod/mod_control.dm | 17 +- .../modules/icspawning/code/observer.dm | 2 +- .../species/proteans/_proteans_species.dm | 155 +++++++++++++++--- .../species/proteans/protean_modsuit.dm | 133 ++------------- .../species/proteans/protean_modsuit_core.dm | 8 +- .../species/proteans/protean_shapeshift.dm | 4 + 8 files changed, 164 insertions(+), 159 deletions(-) diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm index d44c593d9ac..33539a91b96 100644 --- a/code/datums/outfit.dm +++ b/code/datums/outfit.dm @@ -273,6 +273,7 @@ for(var/i in 1 to number) user.equip_to_storage(SSwardrobe.provide_type(path, user), ITEM_SLOT_BELT, indirect_action = TRUE, del_on_fail = TRUE) + SEND_SIGNAL(user.dna.species, COMSIG_OUTFIT_EQUIP, src, visuals_only) // BUBBER EDIT: Proteans. See /datum/species/protean/proc/outfit_handling post_equip(user, visuals_only) if(!visuals_only) @@ -303,7 +304,6 @@ if(activate_msg) CRASH("Failed to activate [user]'s [skillchip_instance], on job [src]. Failure message: [activate_msg]") - SEND_SIGNAL(user.dna.species, COMSIG_OUTFIT_EQUIP, src, visuals_only) // BUBBER EDIT: Proteans. See /datum/species/protean/proc/outfit_handling user.update_body() return TRUE diff --git a/code/modules/admin/verbs/selectequipment.dm b/code/modules/admin/verbs/selectequipment.dm index 5731702e6ca..992ba469ba0 100644 --- a/code/modules/admin/verbs/selectequipment.dm +++ b/code/modules/admin/verbs/selectequipment.dm @@ -213,6 +213,8 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(select_equipment, R_FUN, "Select Equipment", mob/ta BLACKBOX_LOG_ADMIN_VERB("Select Equipment") var/includes_flags = delete_pocket ? INCLUDE_POCKETS : NONE for(var/obj/item/item in human_target.get_equipped_items(includes_flags)) + if(isprotean(human_target) && human_target.get_item_by_slot(ITEM_SLOT_BACK) == item) // BUBBER EDIT + continue // BUBBER EDIT qdel(item) var/obj/item/organ/brain/human_brain = human_target.get_organ_slot(BRAIN) diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 9b35a064119..a8b9893a187 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -626,36 +626,37 @@ return ..() /obj/item/mod/control/proc/install(obj/item/mod/module/new_module, mob/user, silent = FALSE) // Bubber Edit: Silent = FALSE + . = FALSE // BUBBER EDIT for(var/obj/item/mod/module/old_module as anything in modules) if(is_type_in_list(new_module, old_module.incompatible_modules) || is_type_in_list(old_module, new_module.incompatible_modules)) if(user && !silent) // Bubber Edit: Silent arg balloon_alert(user, "incompatible with [old_module]!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) - return FALSE //Bubber Edit: Return False + return var/complexity_with_module = complexity complexity_with_module += new_module.complexity if(complexity_with_module > complexity_max) - if(user && !silent) // Bubber Edit: Silent arg + if(user && !silent) balloon_alert(user, "above complexity max!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) - return FALSE //Bubber Edit: Return False + return if(!new_module.has_required_parts(mod_parts)) if(user && !silent) // Bubber Edit: Silent arg balloon_alert(user, "lacking required parts!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) - return FALSE //Bubber Edit: + return if(!new_module.can_install(src)) if(user && !silent) // Bubber Edit: Silent arg balloon_alert(user, "can't install!") playsound(src, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) - return FALSE // Bubber edit: Return False + return if(SEND_SIGNAL(src, COMSIG_MOD_TRY_INSTALL_MODULE, new_module, user) & MOD_ABORT_INSTALL) return if(SEND_SIGNAL(new_module, COMSIG_MODULE_TRY_INSTALL, src, user) & MOD_ABORT_INSTALL) return - finish_install(new_module, user) + return finish_install(new_module, user, silent) // BUBBER EDIT: Adds a return and silent arg. -/obj/item/mod/control/proc/finish_install(obj/item/mod/module/new_module, mob/user) +/obj/item/mod/control/proc/finish_install(obj/item/mod/module/new_module, mob/user, silent = FALSE) // Bubber edit: Silent = FALSE new_module.forceMove(src) modules += new_module complexity += new_module.complexity @@ -666,7 +667,7 @@ if(active && new_module.has_required_parts(mod_parts, need_active = TRUE)) new_module.on_part_activation() new_module.part_activated = TRUE - if(user) // Bubber Edit: Silent Arg + if(user && !silent) // Bubber Edit: Silent Arg balloon_alert(user, "[new_module] added") playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE) return TRUE // Bubber Edit: Return True diff --git a/modular_skyrat/modules/icspawning/code/observer.dm b/modular_skyrat/modules/icspawning/code/observer.dm index 74df9cf8f27..6fb5b6c4ce3 100644 --- a/modular_skyrat/modules/icspawning/code/observer.dm +++ b/modular_skyrat/modules/icspawning/code/observer.dm @@ -4,7 +4,7 @@ quickicspawn(target, src) /mob/dead/observer/proc/quickicspawn(mob/target, mob/user) - if(!isobserver(target) || !check_rights(R_SPAWN)) + if(!isobserver(target) || !check_rights(R_SPAWN, FALSE)) return /// Whether to spawn in with sparks or in a pod diff --git a/modular_zubbers/code/modules/customization/species/proteans/_proteans_species.dm b/modular_zubbers/code/modules/customization/species/proteans/_proteans_species.dm index 09fa88ff04b..b0f8566214c 100644 --- a/modular_zubbers/code/modules/customization/species/proteans/_proteans_species.dm +++ b/modular_zubbers/code/modules/customization/species/proteans/_proteans_species.dm @@ -2,7 +2,7 @@ id = SPECIES_PROTEAN examine_limb_id = SPECIES_PROTEAN - name = "Protean" + name = "protean" sexes = TRUE siemens_coeff = 1.5 // Electricty messes you up. @@ -86,10 +86,12 @@ race = /datum/species/protean /datum/species/protean/Destroy(force) + if(!QDELETED(species_modsuit)) + INVOKE_ASYNC(src, PROC_REF(unassimilate_modsuit), null, TRUE) QDEL_NULL(species_modsuit) QDEL_NULL(protean_action) owner = null - . = ..() + return ..() /datum/species/protean/on_species_gain(mob/living/carbon/human/gainer, datum/species/old_species, pref_load, regenerate_icons = TRUE) . = ..() @@ -97,10 +99,12 @@ equip_modsuit(gainer) RegisterSignal(src, COMSIG_OUTFIT_EQUIP, PROC_REF(outfit_handling)) RegisterSignal(owner, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(organ_reject)) - var/obj/item/mod/core/protean/core = species_modsuit.core - core?.linked_species = src protean_action = new(src) protean_action.Grant(owner) + var/obj/item/mod/core/protean/core = species_modsuit.core + if(!core) + CRASH("Protean: [gainer] failed to link to a core, and thus, have a functional suit!") + core.linked_species = src /datum/species/protean/proc/organ_reject(mob/living/source, obj/item/organ/inserted) SIGNAL_HANDLER @@ -122,16 +126,16 @@ organ.balloon_alert_to_viewers("rejected!", vision_distance = 1) /datum/species/protean/on_species_loss(mob/living/carbon/human/gainer, datum/species/new_species, pref_load) - . = ..() if(gainer) UnregisterSignal(owner, COMSIG_CARBON_GAIN_ORGAN) if(species_modsuit.stored_modsuit) - species_modsuit.unassimilate_modsuit(owner, TRUE) - gainer.dropItemToGround(species_modsuit, TRUE) + species_modsuit.stored_modsuit.forceMove(get_turf(gainer)) + unassimilate_modsuit(null, TRUE) if(species_modsuit) QDEL_NULL(species_modsuit) protean_action.Remove(owner) owner = null + return ..() /datum/species/protean/proc/equip_modsuit(mob/living/carbon/human/gainer) species_modsuit = new() @@ -152,29 +156,126 @@ /datum/species/protean/proc/outfit_handling(datum/species/protean, datum/outfit/outfit, visuals_only) // Very snowflakey code. I'm not making outfits for every job. SIGNAL_HANDLER - var/get_a_job = istype(outfit, /datum/outfit/job) - var/obj/item/mod/control/suit - if(ispath(outfit.back, /obj/item/mod/control)) - var/control_path = outfit.back - suit = new control_path() - INVOKE_ASYNC(species_modsuit, TYPE_PROC_REF(/obj/item/mod/control/pre_equipped/protean, assimilate_modsuit), owner, suit, TRUE) - INVOKE_ASYNC(species_modsuit, TYPE_PROC_REF(/obj/item/mod/control, quick_activation)) + if(visuals_only) + return - var/obj/item/mod/module/storage/storage = locate() in species_modsuit.modules // Give a storage if we don't have one. - if(!storage) - storage = new /obj/item/mod/module/storage/large_capacity() - species_modsuit.install(storage, owner, TRUE) + var/obj/item/mod/control/suit = outfit.back + if(ispath(suit, /obj/item/mod/control)) + suit = new outfit.back + ASYNC // Not INVOKE_ASYNC to prevent race conditions. + assimilate_modsuit(owner, suit, TRUE) + species_modsuit.quick_activation() - if(outfit.backpack_contents) - outfit.backpack_contents += /obj/item/stack/sheet/iron/twenty - for(var/path in outfit.backpack_contents) - if(!get_a_job) + LAZYINITLIST(outfit.backpack_contents) + if(istype(outfit, /datum/outfit/job)) + owner.equip_to_storage(SSwardrobe.provide_type(/obj/item/stack/sheet/iron/twenty, owner), ITEM_SLOT_BACK, TRUE, FALSE) + return + outfit.backpack_contents += /obj/item/stack/sheet/iron/twenty + for(var/path in outfit.backpack_contents) + owner.equip_to_storage(SSwardrobe.provide_type(path, owner), ITEM_SLOT_BACK, TRUE, TRUE) + if(outfit.suit_store) + owner.equip_to_slot_if_possible(SSwardrobe.provide_type(outfit.suit_store, owner), ITEM_SLOT_SUITSTORE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE) + +/datum/species/protean/proc/assimilate_modsuit(mob/living/user, obj/item/mod/control/to_assimilate, forced = FALSE) + if(species_modsuit.stored_modsuit) + to_chat(user, span_warning("Can't absorb two modsuits!")) + if(forced) + stack_trace("assimilate_modsuit() tried to assimilate two modsuits. stored_modsuit: [species_modsuit.stored_modsuit], new_modsuit: [to_assimilate]") + return + if(!user?.transferItemToLoc(to_assimilate, species_modsuit, forced)) + owner.balloon_alert(user, "stuck!") + if(!forced) + for(var/obj/item/part as anything in species_modsuit.get_parts()) + if(part.loc == src) continue - var/number = outfit.backpack_contents[path] - if(!isnum(number))//Default to 1 - number = 1 - for(var/i in 1 to number) // Copy and paste of EQUIP_OUTFIT_ITEM - owner.equip_to_storage(SSwardrobe.provide_type(path, owner), ITEM_SLOT_BACK, TRUE, TRUE) + species_modsuit.retract(null, part, TRUE) + + species_modsuit.cached_modules += species_modsuit.modules + species_modsuit.stored_modsuit = to_assimilate + species_modsuit.stored_theme = species_modsuit.theme + species_modsuit.complexity_max = species_modsuit.stored_modsuit.complexity_max + species_modsuit.theme = species_modsuit.stored_modsuit.theme + species_modsuit.name = species_modsuit.stored_modsuit.name + species_modsuit.desc = species_modsuit.stored_modsuit.desc + species_modsuit.extended_desc = species_modsuit.stored_modsuit.extended_desc + /// module handling + for(var/obj/item/mod/module/module in species_modsuit.stored_modsuit.modules) + if(istype(module, /obj/item/mod/module/storage)) + var/obj/item/mod/module/storage/existing_storage = locate() in species_modsuit.modules + if(existing_storage) + continue + if(locate(module.type) in species_modsuit.modules) + continue + species_modsuit.stored_modsuit.uninstall(module) + if(species_modsuit.install(module, owner, TRUE)) + continue + species_modsuit.theme.set_up_parts(species_modsuit, species_modsuit.theme.default_skin) + species_modsuit.update_static_data_for_all_viewers() + +/datum/species/protean/proc/unassimilate_modsuit(mob/living/user, forced = FALSE) + if(!species_modsuit.stored_modsuit) + to_chat(user, span_warning("There is no assimilated suit.")) + return + if(species_modsuit.active && !forced) + user.balloon_alert(user, "deactivate modsuit") + return + if(!(user?.has_active_hand()) && !forced) + user.balloon_alert(user, "need active hand") + return + + for(var/obj/item/part in species_modsuit.get_parts()) + if(part.loc == src) + continue + species_modsuit.retract(null, part, instant = TRUE) + species_modsuit.complexity_max = initial(species_modsuit.complexity_max) + + // Module handling + for(var/obj/item/mod/module in species_modsuit.modules) // Transfer back every module + if(locate(module) in species_modsuit.cached_modules) + continue + species_modsuit.uninstall(module, user) + if(!species_modsuit.stored_modsuit.install(module, user, TRUE)) + to_chat(user, span_notice("[module] has fallen to the floor!")) + module.forceMove(get_turf(species_modsuit)) + species_modsuit.cached_modules -= module + + // Item handling + for(var/obj/item/stuff in species_modsuit.atom_storage?.real_location.contents) + if(!species_modsuit.stored_modsuit.atom_storage) + species_modsuit.atom_storage.remove_all(owner) + break + species_modsuit.stored_modsuit.atom_storage.attempt_insert(stuff, owner, TRUE, messages = FALSE) + + species_modsuit.theme = species_modsuit.stored_theme + species_modsuit.stored_theme = null + species_modsuit.theme.set_up_parts(species_modsuit, species_modsuit.theme.default_skin) + species_modsuit.name = initial(species_modsuit.name) + species_modsuit.desc = initial(species_modsuit.desc) + species_modsuit.extended_desc = initial(species_modsuit.extended_desc) + + if(user?.can_put_in_hand(species_modsuit.stored_modsuit, user.active_hand_index)) + user.put_in_hand(species_modsuit.stored_modsuit, user.active_hand_index) + + species_modsuit.stored_modsuit = null + update_static_data_for_all_viewers() + +/datum/species/protean/proc/assimilate_theme(mob/user, plating) + var/obj/item/mod/construction/plating/plates = plating + var/datum/mod_theme/the_theme = GLOB.mod_themes[plates.theme] + + species_modsuit.name = initial(species_modsuit.name) + species_modsuit.desc = initial(species_modsuit.desc) + + for(var/obj/item/part in species_modsuit.get_parts()) + part.name = initial(part.name) + part.desc = initial(part.desc) + if(part.loc == src) + continue + species_modsuit.retract(null, part, instant = TRUE) + + species_modsuit.theme = the_theme + species_modsuit.theme.set_up_parts(species_modsuit, the_theme.default_skin) + update_static_data_for_all_viewers() /datum/species/protean/get_default_mutant_bodyparts() return list( diff --git a/modular_zubbers/code/modules/customization/species/proteans/protean_modsuit.dm b/modular_zubbers/code/modules/customization/species/proteans/protean_modsuit.dm index d6c9bc53d5b..fc450f0d454 100644 --- a/modular_zubbers/code/modules/customization/species/proteans/protean_modsuit.dm +++ b/modular_zubbers/code/modules/customization/species/proteans/protean_modsuit.dm @@ -5,6 +5,7 @@ applied_core = /obj/item/mod/core/protean applied_cell = null // Goes off stomach + applied_modules = list(/obj/item/mod/module/storage/large_capacity) resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | INDESTRUCTIBLE // funny nanite drag_pickup = FALSE /// Whether or not the wearer can undeploy parts. @@ -22,16 +23,12 @@ AddElement(/datum/element/strippable/protean, GLOB.strippable_human_items) /obj/item/mod/control/pre_equipped/protean/Destroy() + var/obj/item/mod/core/protean/p_core = core if(stored_modsuit) - for(var/obj/item/mod/module/modules in cached_modules) - if(!modules.removable) - qdel(modules) - continue - modules.forceMove(get_turf(src)) - - cached_modules = null - drop_suit() - INVOKE_ASYNC(src, PROC_REF(unassimilate_modsuit), null, forced = TRUE) + if(p_core?.linked_species) + stored_modsuit.forceMove(get_turf(src)) + INVOKE_ASYNC(p_core.linked_species, TYPE_PROC_REF(/datum/species/protean, unassimilate_modsuit), null, TRUE) + cached_modules = null return ..() /obj/item/mod/control/pre_equipped/protean/wrench_act(mob/living/user, obj/item/wrench) @@ -140,7 +137,7 @@ to_chat(user, span_notice("You begin to copy [tool], destroying it in the process!")) if(!do_after(user, 4 SECONDS)) return ITEM_INTERACT_BLOCKING - assimilate_theme(user, tool) + protean_core.linked_species.assimilate_theme(user, tool) qdel(tool) playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE) return ITEM_INTERACT_SUCCESS @@ -163,7 +160,7 @@ to_chat(user, span_notice("The suit begins to slowly absorb [tool]!")) if(!do_after(user, 4 SECONDS)) return ITEM_INTERACT_BLOCKING - assimilate_modsuit(user, tool) + protean_core.linked_species.assimilate_modsuit(user, tool) playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE) return ITEM_INTERACT_SUCCESS @@ -193,117 +190,13 @@ return UI_INTERACTIVE . = ..() -/obj/item/mod/control/pre_equipped/protean/proc/assimilate_theme(mob/user, plating) - var/obj/item/mod/construction/plating/plates = plating - var/datum/mod_theme/the_theme = GLOB.mod_themes[plates.theme] - - name = initial(name) - desc = initial(desc) - - for(var/obj/item/part as anything in get_parts()) - part.name = initial(name) - part.desc = initial(desc) - if(part.loc == src) - continue - retract(null, part, instant = TRUE) - - theme = the_theme - the_theme.set_up_parts(src, the_theme.default_skin) - update_static_data_for_all_viewers() - -/obj/item/mod/control/pre_equipped/protean/proc/assimilate_modsuit(mob/user, modsuit, forced) - var/obj/item/mod/control/to_assimilate = modsuit - if(stored_modsuit) - to_chat(user, span_warning("Can't absorb two modsuits!")) - if(forced) - stack_trace("assimilate_modsuit: Tried to assimilate modsuit while there's already a stored modsuit. stored_modsuit: [stored_modsuit], new_modsuit: [to_assimilate]") - return - if(!user?.transferItemToLoc(to_assimilate, src, forced)) - balloon_alert(user, "stuck!") - return - if(!forced) - for(var/obj/item/part as anything in get_parts()) - if(part.loc == src) - continue - retract(null, part, instant = TRUE) - stored_modsuit = to_assimilate - stored_theme = theme // Store the old theme in cache - theme = to_assimilate.theme // Set new theme - skin = to_assimilate.skin // Inheret skin - theme.set_up_parts(src, skin) // Put everything together - name = to_assimilate.name - desc = to_assimilate.desc - extended_desc = to_assimilate.extended_desc - for(var/obj/item/mod/module/module in to_assimilate.modules) // Insert every module - if(istype(module, /obj/item/mod/module/storage)) - var/obj/item/mod/module/storage/existing_storage = locate() in modules - if(existing_storage) - cached_modules += existing_storage - to_chat(user, span_notice("[existing_storage] has been pushed aside!")) - uninstall(existing_storage) - if(install(module, user, TRUE)) - continue - if(!module.removable) // Just leave it inside the original suit if it doesn't transfer. - continue - to_assimilate.uninstall(module) // Drop it - module.forceMove(get_turf(src)) - to_chat(user, span_warning("[module] has dropped onto the floor!")) - update_static_data_for_all_viewers() - -/obj/item/mod/control/pre_equipped/protean/proc/unassimilate_modsuit(mob/living/user, forced = FALSE) - if(!stored_modsuit) - to_chat(user, span_warning("There is no assimilated suit.")) - return - if(active && !forced) - balloon_alert(user, "deactivate modsuit") - return - if(!(user?.has_active_hand()) && !forced) - balloon_alert(user, "need active hand") - return - - if(!forced) - to_chat(user, span_notice("You begin to pry the assimilated modsuit away.")) - if(!do_after(user, 4 SECONDS)) - return - - for(var/obj/item/part as anything in get_parts()) - if(part.loc == src) - continue - retract(null, part, instant = TRUE) - - complexity_max = initial(complexity_max) - for(var/obj/item/mod/module in modules) // Transfer back every module - if(stored_modsuit.install(module, user, TRUE)) - continue - uninstall(module) - to_chat(user, span_notice("[module] has fallen to the floor!")) - module.forceMove(get_turf(src)) - - for(var/obj/item/mod/module/cached in cached_modules) - if(!install(cached, user, TRUE)) - to_chat(user, span_warning("[cached] failed to return to its original place! REPORT THIS")) - stack_trace("Modsuit Unassimilate: cached module [cached] failed to return to original modsuit! [src]") - cached_modules -= cached - - theme = stored_theme - stored_theme = null - skin = initial(skin) - theme.set_up_parts(src, skin) - name = initial(name) - desc = initial(desc) - extended_desc = initial(extended_desc) - //if(forced) - // stored_modsuit.forceMove(get_turf(src)) - // stored_modsuit = null - if(user.can_put_in_hand(stored_modsuit, user.active_hand_index)) - user.put_in_hand(stored_modsuit, user.active_hand_index) - stored_modsuit = null - update_static_data_for_all_viewers() - /obj/item/mod/control/pre_equipped/protean/verb/remove_modsuit() set name = "Remove Assimilated Modsuit" - - unassimilate_modsuit(usr) + var/obj/item/mod/core/protean/p_core = core + to_chat(usr, span_notice("You begin to pry at the [stored_modsuit] to seperate it.")) + if(!do_after(usr, 5 SECONDS)) + return + p_core.linked_species.unassimilate_modsuit(usr) /obj/item/mod/control/pre_equipped/protean/examine(mob/user) . = ..() diff --git a/modular_zubbers/code/modules/customization/species/proteans/protean_modsuit_core.dm b/modular_zubbers/code/modules/customization/species/proteans/protean_modsuit_core.dm index dbc7ee05853..a0811b6a320 100644 --- a/modular_zubbers/code/modules/customization/species/proteans/protean_modsuit_core.dm +++ b/modular_zubbers/code/modules/customization/species/proteans/protean_modsuit_core.dm @@ -7,6 +7,10 @@ /// The species handles cleanup on this var/datum/species/protean/linked_species +/obj/item/mod/core/protean/Destroy() + linked_species = null + return ..() + /obj/item/mod/core/protean/charge_source() if(isnull(linked_species)) return @@ -28,10 +32,10 @@ /// We don't charge in a standard way /obj/item/mod/core/protean/add_charge(amount) - return FALSE + return TRUE /obj/item/mod/core/protean/subtract_charge(amount) - return FALSE + return TRUE /obj/item/mod/core/protean/check_charge(amount) var/obj/item/organ/stomach/protean/stomach = charge_source() diff --git a/modular_zubbers/code/modules/customization/species/proteans/protean_shapeshift.dm b/modular_zubbers/code/modules/customization/species/proteans/protean_shapeshift.dm index d7e768d3125..5bfc687a57f 100644 --- a/modular_zubbers/code/modules/customization/species/proteans/protean_shapeshift.dm +++ b/modular_zubbers/code/modules/customization/species/proteans/protean_shapeshift.dm @@ -38,4 +38,8 @@ if("Markings") alter_markings(alterer) if("Character") + var/mob/living/carbon/person = owner + var/datum/species/protean/species = person.dna.species + if(owner.loc == species.species_modsuit) + return to_chat(owner, span_notice("You must leave your suit first!")) begin_character_alteration(alterer)