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)