diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index c3e6d3f275a..a9f5860838a 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -229,9 +229,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define SKILLCHIP_ALLOWS_MULTIPLE (1<<0) // This skillchip is incompatible with other skillchips from the incompatible_category list. #define SKILLCHIP_RESTRICTED_CATEGORIES (1<<1) -// This skillchip is incompatible with the Chameleon skillchip and cannot be copied. -// If you want to blacklist an abstract path such a /obj/item/skillchip/job then look at the blacklist in /datum/action/item_action/chameleon/change/skillchip -#define SKILLCHIP_CHAMELEON_INCOMPATIBLE (1<<2) //dir macros ///Returns true if the dir is diagonal, false otherwise diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index de4111b61f9..8e40cb933e7 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -550,4 +550,3 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE))) #define SKILLCHIP_CATEGORY_GENERAL "general" #define SKILLCHIP_CATEGORY_JOB "job" #define SKILLCHIP_CATEGORY_FIREMAN_CARRYING "fireman carrying" -#define SKILLCHIP_CATEGORY_SYNDICATE "syndicate" diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 6dd0cb5bfaf..c21806a5a47 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -751,166 +751,3 @@ /obj/item/clothing/neck/chameleon/broken/Initialize() . = ..() chameleon_action.emp_randomise(INFINITY) - -/datum/action/item_action/chameleon/change/skillchip - /// Skillchip that this chameleon action is imitating. - var/obj/item/skillchip/skillchip_mimic - /// When we can next modify this skillchip - COOLDOWN_DECLARE(usable_cooldown) - var/cooldown = 5 MINUTES - var/is_active = TRUE - -/datum/action/item_action/chameleon/change/skillchip/Destroy() - if(skillchip_mimic) - skillchip_mimic.on_removal(FALSE) - QDEL_NULL(skillchip_mimic) - return ..() - -/datum/action/item_action/chameleon/change/skillchip/proc/set_active(active = TRUE) - is_active = active - UpdateButtonIcon() - -/datum/action/item_action/chameleon/change/skillchip/Grant(mob/M) - . = ..() - - if(!COOLDOWN_FINISHED(src, usable_cooldown)) - START_PROCESSING(SSfastprocess, src) - -/datum/action/item_action/chameleon/change/skillchip/Remove(mob/M) - STOP_PROCESSING(SSfastprocess, src) - - return ..() - -/// Completely override the functionality of the initialize_disguises() proc. No longer uses chameleon_blacklist and uses skillchip flags and vars instead. -/datum/action/item_action/chameleon/change/skillchip/initialize_disguises() - if(button) - button.name = "Change [chameleon_name] Function" - - if(!ispath(chameleon_type, /obj/item/skillchip)) - CRASH("Attempted to initialise [src] disguise list with incompatible item path [chameleon_type].") - - var/obj/item/skillchip/target_chip = target - - if(!istype(target_chip)) - CRASH("Attempted to initialise [src] disguise list, but it is attached to incorrect item type [target_chip].") - - for(var/chip_type in typesof(chameleon_type)) - var/obj/item/skillchip/skillchip = chip_type - if((chip_type == initial(skillchip.abstract_parent_type)) \ - || (target_chip.slot_use < initial(skillchip.slot_use)) \ - || (initial(skillchip.skillchip_flags) & SKILLCHIP_CHAMELEON_INCOMPATIBLE) \ - || (initial(skillchip.item_flags) & ABSTRACT) \ - || !initial(skillchip.icon_state)) - continue - var/chameleon_item_name = "[initial(skillchip.name)] ([initial(skillchip.icon_state)])" - chameleon_list[chameleon_item_name] = skillchip - -/datum/action/item_action/chameleon/change/skillchip/update_item(obj/item/skillchip/picked_item) - if(istype(picked_item)) - target.name = initial(picked_item.skill_name) - target.desc = initial(picked_item.skill_description) - target.icon_state = initial(picked_item.skill_icon) - -/datum/action/item_action/chameleon/change/skillchip/update_look(mob/user, picked_item) - if(!COOLDOWN_FINISHED(src, usable_cooldown)) - to_chat(user, "Chameleon skillchip is still recharging for another [COOLDOWN_TIMELEFT(src, usable_cooldown) * 0.1] seconds!") - return ..() - - var/obj/item/skillchip/new_chip = new picked_item(target, FALSE) - - // Do a bit of a sanity check. - if(!istype(new_chip)) - stack_trace("Chameleon skillchip [src] attempted to change into non-skillchip item [picked_item].") - QDEL_NULL(new_chip) - return ..() - - // Remove the existing chip first, if it exists. - if(skillchip_mimic) - skillchip_mimic.on_removal(FALSE) - QDEL_NULL(skillchip_mimic) - - // This chip should technically have 0 slot use before doing these checks. With skillchip_mimic removed, any checks - // will probably end up using the 2-slot chameleon chip that is holding new_chip. - new_chip.slot_use = 0 - - var/incompatibility_msg = new_chip.has_mob_incompatibility(user) - if(incompatibility_msg) - to_chat(user, "The chameleon skillchip fails to load the new skillchip's data. The following thought fills your mind: [incompatibility_msg]") - QDEL_NULL(new_chip) - return ..() - - var/mob/living/carbon/target_mob = user - - // Should never happen. Our target isn't the right mob type. - if(!istype(target_mob)) - stack_trace("Chameleon skillchip [src] attempted to mimic [new_chip], but target [target_mob] is not of the correct type.") - QDEL_NULL(new_chip) - return ..() - - // Should doubly never happen, would imply the chameleon chip is in a qdel'd or null brain. - var/obj/item/organ/brain/brain = target_mob.getorganslot(ORGAN_SLOT_BRAIN) - if(QDELETED(brain)) - stack_trace("Chameleon skillchip [src] attempted to mimic [new_chip], but it appears this chip is in non-existent brain: [brain]") - QDEL_NULL(new_chip) - return ..() - - // Bypass the usual channels and directly call on_implant. - skillchip_mimic = new_chip - skillchip_mimic.on_implant(brain) - - // Let's update the slot size we deleted earlier. We're going to make it match the parent chip, as it'll end up - // feeding calls through itself to this chip. - - var/obj/item/skillchip/target_chip = target - - if(!istype(target_chip)) - CRASH("Attempted to initialise [src] disguise list, but it is attached to incorrect item type [target_chip].") - - skillchip_mimic.slot_use = target_chip.slot_use - - var/activate_msg = skillchip_mimic.try_activate_skillchip(FALSE, FALSE) - - // Couldn't activate the chip for some reason. - // Can still be activated later on, or a new chip type selected. So let's not start processing or cooldowns. - if(activate_msg) - to_chat(user, "Your skillchip can't activate! Your mind fills with the following thought: [activate_msg]") - return ..() - - // All set, start processing and cooldowns and inform the user of the recharge time. - COOLDOWN_START(src, usable_cooldown, cooldown) - START_PROCESSING(SSfastprocess, src) - - to_chat(user, "The chameleon skillchip is recharging. It will be unable to change for another [cooldown * 0.1] seconds.") - - return ..() - -/datum/action/item_action/chameleon/change/skillchip/IsAvailable() - if(!is_active) - return FALSE - - if(!COOLDOWN_FINISHED(src, usable_cooldown)) - return FALSE - - return ..() - -/datum/action/item_action/chameleon/change/skillchip/process() - if(!owner) - button.maptext = "" - STOP_PROCESSING(SSfastprocess, src) - return - - if(COOLDOWN_FINISHED(src, usable_cooldown)) - button.maptext = "" - UpdateButtonIcon() - STOP_PROCESSING(SSfastprocess, src) - return - - button.maptext = MAPTEXT("[COOLDOWN_TIMELEFT(src, usable_cooldown) * 0.1]") - -/** - * Clears the currently mimic'd skillchip, if any exists. - */ -/datum/action/item_action/chameleon/change/skillchip/proc/clear_mimic_chip() - if(skillchip_mimic) - skillchip_mimic.on_removal(FALSE) - QDEL_NULL(skillchip_mimic) diff --git a/code/modules/library/skill_learning/job_skillchips/traitor.dm b/code/modules/library/skill_learning/job_skillchips/traitor.dm deleted file mode 100644 index 4478a13d146..00000000000 --- a/code/modules/library/skill_learning/job_skillchips/traitor.dm +++ /dev/null @@ -1,173 +0,0 @@ -/obj/item/skillchip/chameleon - name = "Chameleon skillchip" - desc = "A highly advanced Syndicate skillchip that does nothing on its own. It is loaded with the data of every skillchip." - skill_name = "Imitate Skillchip" - skill_description = "Reacts to the user's thoughts, selecting a skill from a wide database of choices." - activate_message = "You feel at one with the skillchip." - deactivate_message = "The infinite mysteries of the skillchip escape your mind." - skill_icon = "microchip" - // Chip does nothing on its own, so it has 0 complexity. - complexity = 0 - // Chamelelon chips cannot mimic chips with a greater slot cost. Increasing this will potentially increase - // the pool of mimic'd chips. Decreasing it will decrease the pool of mimic'd chips. See initialize_disguises() - // in the chameleon_action#'s type for the logic block. - slot_use = 2 - removable = FALSE - skillchip_flags = SKILLCHIP_CHAMELEON_INCOMPATIBLE - /// Action for the skillchip selection. - var/datum/action/item_action/chameleon/change/skillchip/chameleon_action - -/obj/item/skillchip/chameleon/Initialize(mapload, is_removable = FALSE) - . = ..() - - // This chameleon_action uses snowflake code. Do not set the chameleon_blacklist as that is ignored. - // Instead, set the SKILLCHIP_CHAMELEON_INCOMPATIBLE flag on skillchips that should not be copyable. - // Set abstract_parent_type on skillchips that are abstract (see /obj/item/skillchip definition) - chameleon_action = new(src) - chameleon_action.chameleon_type = /obj/item/skillchip - chameleon_action.chameleon_name = "Skillchip" - chameleon_action.initialize_disguises() - -/obj/item/skillchip/chameleon/Destroy() - QDEL_NULL(chameleon_action) - return ..() - -/// We don't want this to grant the item_action automatically. -/obj/item/skillchip/chameleon/item_action_slot_check(slot, mob/user) - return FALSE - -/obj/item/skillchip/chameleon/emp_act(severity) - . = ..() - if(. & EMP_PROTECT_SELF) - return - chameleon_action.emp_randomise() - -/obj/item/skillchip/chameleon/on_implant(obj/item/organ/brain/owner_brain) - // If there's already a mimic'd skillchip available, run its implant code alongside this. - if(chameleon_action.skillchip_mimic) - chameleon_action.skillchip_mimic.on_implant(owner_brain) - - return ..() - -/// DANGEROUS - Doesn't check that the mimic'd chip can be activated. Assumes this check has been done already. -/obj/item/skillchip/chameleon/on_activate(mob/living/carbon/user, silent=TRUE) - . = ..() - - // If there's already a mimic'd skillchip available, activate it. Generally only happens with changelings. Rare interaction. - if(chameleon_action.skillchip_mimic && chameleon_action.skillchip_mimic.is_active()) - chameleon_action.skillchip_mimic.on_activate(user, silent) - - chameleon_action.Grant(user); - -/obj/item/skillchip/chameleon/on_removal(silent = FALSE) - . = ..() - - // Also call the on_removal of the mimic'd skillchip. - if(chameleon_action.skillchip_mimic) - chameleon_action.skillchip_mimic.on_removal(silent) - -/obj/item/skillchip/chameleon/on_deactivate(mob/living/carbon/user, silent = FALSE) - chameleon_action.clear_mimic_chip() - chameleon_action.Remove(user) - - return ..() - -/obj/item/skillchip/chameleon/has_skillchip_incompatibility(obj/item/skillchip/skillchip) - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.has_skillchip_incompatibility(skillchip) - - return ..() - -/obj/item/skillchip/chameleon/has_activate_incompatibility(obj/item/organ/brain/brain) - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.has_activate_incompatibility(brain) - - return ..() - -/obj/item/skillchip/chameleon/has_mob_incompatibility(mob/living/carbon/target) - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.has_mob_incompatibility(target) - - return ..() - -/obj/item/skillchip/chameleon/has_brain_incompatibility(obj/item/organ/brain/brain) - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.has_brain_incompatibility(brain) - - return ..() - -/obj/item/skillchip/chameleon/get_chip_data() - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - var/list/mimic_data = chameleon_action.skillchip_mimic.get_chip_data() - // Overwrite the ref with this chip's, as we'll want any operations to be performed through this chip and - // not through the mimic chip. - mimic_data["ref"] = REF(src) - return mimic_data - - return ..() - -/obj/item/skillchip/chameleon/try_activate_skillchip(silent = FALSE, force = FALSE) - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.try_activate_skillchip(silent, force) - - return ..() - -/obj/item/skillchip/chameleon/try_deactivate_skillchip(silent = FALSE, force = FALSE) - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.try_deactivate_skillchip(silent, force) - - return ..() -/obj/item/skillchip/chameleon/is_on_cooldown() - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.is_on_cooldown() - - return ..() - -/obj/item/skillchip/chameleon/is_active() - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.is_active() - - return ..() - -/obj/item/skillchip/chameleon/get_complexity() - // If we've selected a skillchip to mimic, we'll want to intercept this proc and forward it to the mimic chip. - if(chameleon_action.skillchip_mimic) - return chameleon_action.skillchip_mimic.get_complexity() - - return ..() - -/obj/item/skillchip/chameleon/get_metadata() - var/list/metadata = ..() - - // If we have a skillchip to mimic, create a new set of metadata for that chip. - if(chameleon_action.skillchip_mimic) - metadata["mimic_chip"] = chameleon_action.skillchip_mimic.get_metadata() - - return metadata - -/obj/item/skillchip/chameleon/set_metadata(list/metadata) - // Set base metadata first. - . = ..() - - // Get rid of the old mimic chip regardless, we're setting metadata here. If the metadata doesn't - // contain new mimic chip info, then assume we want to delete it. - chameleon_action.clear_mimic_chip() - - // If this is metadata for another chamelelon chip variant, it may have a mimic_chip set. - var/list/mimic_chip = metadata["mimic_chip"] - - // Call the mimic chip's proc to set the relevant metadata. Mimic chip activation should be handled - // through this chip's activation procs being called externally. - if(mimic_chip) - var/type = mimic_chip["type"] - chameleon_action.skillchip_mimic = new type(src) - chameleon_action.skillchip_mimic.set_metadata(mimic_chip) diff --git a/code/modules/library/skill_learning/skillchip.dm b/code/modules/library/skill_learning/skillchip.dm index 12d2da6c486..5a7233bed75 100644 --- a/code/modules/library/skill_learning/skillchip.dm +++ b/code/modules/library/skill_learning/skillchip.dm @@ -402,7 +402,7 @@ skill_icon = "plug" activate_message = "You can now activate another chip through this adapter, but you're not sure why you did this..." deactivate_message = "You no longer have the useless skillchip adapter." - skillchip_flags = SKILLCHIP_ALLOWS_MULTIPLE | SKILLCHIP_CHAMELEON_INCOMPATIBLE + skillchip_flags = SKILLCHIP_ALLOWS_MULTIPLE // Literally does nothing. complexity = 0 slot_use = 0 diff --git a/code/modules/surgery/organs/autosurgeon.dm b/code/modules/surgery/organs/autosurgeon.dm index 511e8012307..51f0f16799d 100644 --- a/code/modules/surgery/organs/autosurgeon.dm +++ b/code/modules/surgery/organs/autosurgeon.dm @@ -110,120 +110,3 @@ /obj/item/autosurgeon/organ/syndicate/reviver starting_organ = /obj/item/organ/cyberimp/chest/reviver - -/obj/item/autosurgeon/skillchip - name = "skillchip autosurgeon" - desc = "A device that automatically inserts a skillchip into the user's brain without the hassle of extensive surgery. \ - It has a slot to insert a skillchip and a screwdriver slot for removing accidentally added items." - var/skillchip_type = /obj/item/skillchip - var/starting_skillchip - var/obj/item/skillchip/stored_skillchip - -/obj/item/autosurgeon/skillchip/syndicate - name = "suspicious skillchip autosurgeon" - icon_state = "syndicate_autoimplanter" - -/obj/item/autosurgeon/skillchip/Initialize(mapload) - . = ..() - if(starting_skillchip) - insert_skillchip(new starting_skillchip(src)) - -/obj/item/autosurgeon/skillchip/proc/insert_skillchip(obj/item/skillchip/skillchip) - if(!istype(skillchip)) - return - stored_skillchip = skillchip - skillchip.forceMove(src) - name = "[initial(name)] ([stored_skillchip.name])" - -/obj/item/autosurgeon/skillchip/attack_self(mob/living/carbon/user)//when the object it used... - if(!uses) - to_chat(user, "[src] has already been used. The tools are dull and won't reactivate.") - return - - if(!stored_skillchip) - to_chat(user, "[src] currently has no skillchip stored.") - return - - if(!istype(user)) - to_chat(user, "[user]'s brain cannot accept skillchip implants.") - return - - // Try implanting. - var/implant_msg = user.implant_skillchip(stored_skillchip) - if(implant_msg) - user.visible_message("[user] presses a button on [src], but nothing happens.", "The [src] quietly beeps at you, indicating some sort of error.") - to_chat(user, "[stored_skillchip] cannot be implanted. [implant_msg]") - return - - // Clear the stored skillchip, it's technically not in this machine anymore. - var/obj/item/skillchip/implanted_chip = stored_skillchip - stored_skillchip = null - - user.visible_message("[user] presses a button on [src], and you hear a short mechanical noise.", "You feel a sharp sting as [src] plunges into your brain.") - playsound(get_turf(user), 'sound/weapons/circsawhit.ogg', 50, TRUE) - - to_chat(user,"Operation complete! [implanted_chip] successfully implanted. Attempting auto-activation...") - - // If implanting succeeded, try activating - Although activating isn't required, so don't early return if it fails. - // The user can always go activate it at a skill station. - var/activate_msg = implanted_chip.try_activate_skillchip(FALSE, FALSE) - if(activate_msg) - to_chat(user, "[implanted_chip] cannot be activated. [activate_msg]") - - name = initial(name) - - if(uses != INFINITE) - uses-- - - if(!uses) - desc = "[initial(desc)] The surgical tools look too blunt and worn to pierce a skull. Looks like it's all used up." - -/obj/item/autosurgeon/skillchip/attackby(obj/item/I, mob/user, params) - if(!istype(I, skillchip_type)) - return ..() - - if(stored_skillchip) - to_chat(user, "[src] already has a skillchip stored.") - return - - if(!uses) - to_chat(user, "[src] has already been used up.") - return - - if(!user.transferItemToLoc(I, src)) - to_chat(user, "You fail to insert the skillchip into [src]. It seems stuck to your hand.") - return - - stored_skillchip = I - to_chat(user, "You insert the [I] into [src].") - -/obj/item/autosurgeon/skillchip/screwdriver_act(mob/living/user, obj/item/I) - . = ..() - if(.) - return - - if(!stored_skillchip) - to_chat(user, "There's no skillchip in [src] for you to remove!") - return TRUE - - var/atom/drop_loc = user.drop_location() - for(var/thing in contents) - var/atom/movable/movable_content = thing - movable_content.forceMove(drop_loc) - - to_chat(user, "You remove the [stored_skillchip] from [src].") - I.play_tool_sound(src) - stored_skillchip = null - - if(uses != INFINITE) - uses-- - - if(!uses) - desc = "[initial(desc)] Looks like it's been used up." - - return TRUE - -/obj/item/autosurgeon/skillchip/syndicate/chameleon_chip - desc = "A single use autosurgeon that contains a Syndicate skillchip. A screwdriver can be used to remove it, but skillchips can't be placed back in." - uses = 1 - starting_skillchip = /obj/item/skillchip/chameleon diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index fa571a281a3..5256e12746a 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -1200,15 +1200,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 exclude_modes = list(/datum/game_mode/nuclear) //clown ops are allowed to buy this kit, since it's basically a costume -/datum/uplink_item/stealthy_tools/chameleon_skillchip - name = "Chameleon Skillchip" - desc = "A highly advanced skillchip that contains data on all available skillchips. \ - This skillchip only takes up a single skillchip slot in the user's brain. \ - Comes with a single-use Syndicate autosurgeon for immediate self-application." - item = /obj/item/autosurgeon/skillchip/syndicate/chameleon_chip - cost = 4 - exclude_modes = list(/datum/game_mode/nuclear) - /datum/uplink_item/stealthy_tools/chameleon_proj name = "Chameleon Projector" desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't \ diff --git a/tgstation.dme b/tgstation.dme index b6ceeb11e70..df3d9e561b0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2316,7 +2316,6 @@ #include "code\modules\library\skill_learning\job_skillchips\research_director.dm" #include "code\modules\library\skill_learning\job_skillchips\roboticist.dm" #include "code\modules\library\skill_learning\job_skillchips\station_engineer.dm" -#include "code\modules\library\skill_learning\job_skillchips\traitor.dm" #include "code\modules\lighting\emissive_blocker.dm" #include "code\modules\lighting\lighting_area.dm" #include "code\modules\lighting\lighting_atom.dm"