diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index f390f930ea7..90d61e403dd 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -337,3 +337,23 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list(
#define HUNTER_PACK_RUSSIAN "Russian Fugitive Hunters"
#define HUNTER_PACK_BOUNTY "Bounty Fugitive Hunters"
#define HUNTER_PACK_PSYKER "Psyker Fugitive Hunters"
+
+// Various abductor equipment modes.
+
+#define VEST_STEALTH 1
+#define VEST_COMBAT 2
+
+#define GIZMO_SCAN 1
+#define GIZMO_MARK 2
+
+#define MIND_DEVICE_MESSAGE 1
+#define MIND_DEVICE_CONTROL 2
+
+#define TOOLSET_MEDICAL 1
+#define TOOLSET_HACKING 2
+
+#define BATON_STUN 0
+#define BATON_SLEEP 1
+#define BATON_CUFF 2
+#define BATON_PROBE 3
+#define BATON_MODES 4
diff --git a/code/game/objects/effects/posters/poster.dm b/code/game/objects/effects/posters/poster.dm
index 7aa4eebd278..0313311ed37 100644
--- a/code/game/objects/effects/posters/poster.dm
+++ b/code/game/objects/effects/posters/poster.dm
@@ -193,16 +193,7 @@
return
if(ruined)
return
-
- visible_message(span_notice("[user] rips [src] in a single, decisive motion!") )
- playsound(src.loc, 'sound/items/poster_ripped.ogg', 100, TRUE)
- spring_trap(user)
-
- var/obj/structure/sign/poster/ripped/R = new(loc)
- R.pixel_y = pixel_y
- R.pixel_x = pixel_x
- R.add_fingerprint(user)
- qdel(src)
+ tear_poster(user)
/obj/structure/sign/poster/proc/spring_trap(mob/user)
var/obj/item/shard/payload = trap?.resolve()
@@ -229,7 +220,7 @@
return rolled_poster
//separated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby()
-/turf/closed/wall/proc/place_poster(obj/item/poster/rolled_poster, mob/user)
+/turf/closed/proc/place_poster(obj/item/poster/rolled_poster, mob/user)
if(!rolled_poster.poster_structure)
to_chat(user, span_warning("[rolled_poster] has no poster... inside it? Inform a coder!"))
return
@@ -259,19 +250,30 @@
playsound(src, 'sound/items/poster_being_created.ogg', 100, TRUE)
var/turf/user_drop_location = get_turf(user) //cache this so it just falls to the ground if they move. also no tk memes allowed.
- if(!do_after(user, PLACE_SPEED, placed_poster, extra_checks = CALLBACK(placed_poster, TYPE_PROC_REF(/obj/structure/sign/poster, snowflake_wall_turf_check), src)))
+ if(!do_after(user, PLACE_SPEED, placed_poster, extra_checks = CALLBACK(placed_poster, TYPE_PROC_REF(/obj/structure/sign/poster, snowflake_closed_turf_check), src)))
placed_poster.roll_and_drop(user_drop_location)
return
placed_poster.on_placed_poster(user)
return TRUE
-/obj/structure/sign/poster/proc/snowflake_wall_turf_check(atom/hopefully_still_a_wall_turf) //since turfs never get deleted but instead change type, make sure we're still being placed on a wall.
- return iswallturf(hopefully_still_a_wall_turf)
+/obj/structure/sign/poster/proc/snowflake_closed_turf_check(atom/hopefully_still_a_closed_turf) //since turfs never get deleted but instead change type, make sure we're still being placed on a wall.
+ return isclosedturf(hopefully_still_a_closed_turf)
/obj/structure/sign/poster/proc/on_placed_poster(mob/user)
to_chat(user, span_notice("You place the poster!"))
+/obj/structure/sign/poster/proc/tear_poster(mob/user)
+ visible_message(span_notice("[user] rips [src] in a single, decisive motion!") )
+ playsound(src.loc, 'sound/items/poster_ripped.ogg', 100, TRUE)
+ spring_trap(user)
+
+ var/obj/structure/sign/poster/ripped/R = new(loc)
+ R.pixel_y = pixel_y
+ R.pixel_x = pixel_x
+ R.add_fingerprint(user)
+ qdel(src)
+
// Various possible posters follow
/obj/structure/sign/poster/ripped
diff --git a/code/game/turfs/closed/_closed.dm b/code/game/turfs/closed/_closed.dm
index 6b517507c45..5d913f19601 100644
--- a/code/game/turfs/closed/_closed.dm
+++ b/code/game/turfs/closed/_closed.dm
@@ -38,6 +38,12 @@
/turf/closed/indestructible/singularity_act()
return
+/turf/closed/indestructible/attackby(obj/item/attacking_item, mob/user, params)
+ if(istype(attacking_item, /obj/item/poster) && Adjacent(user))
+ return place_poster(attacking_item, user)
+
+ return ..()
+
/turf/closed/indestructible/oldshuttle
name = "strange shuttle wall"
icon = 'icons/turf/shuttleold.dmi'
diff --git a/code/modules/antagonists/abductor/abductor_structures.dm b/code/modules/antagonists/abductor/abductor_structures.dm
new file mode 100644
index 00000000000..2de390ad4de
--- /dev/null
+++ b/code/modules/antagonists/abductor/abductor_structures.dm
@@ -0,0 +1,124 @@
+
+// Operating Table / Beds / Lockers
+
+/obj/structure/bed/abductor
+ name = "resting contraption"
+ desc = "This looks similar to contraptions from Earth. Could aliens be stealing our technology?"
+ icon = 'icons/obj/abductor.dmi'
+ buildstacktype = /obj/item/stack/sheet/mineral/abductor
+ icon_state = "bed"
+
+/obj/structure/table_frame/abductor
+ name = "alien table frame"
+ desc = "A sturdy table frame made from alien alloy."
+ icon_state = "alien_frame"
+ framestack = /obj/item/stack/sheet/mineral/abductor
+ framestackamount = 1
+
+/obj/structure/table_frame/abductor/attackby(obj/item/attacking_item, mob/user, params)
+ if(attacking_item.tool_behaviour == TOOL_WRENCH)
+ to_chat(user, span_notice("You start disassembling [src]..."))
+ attacking_item.play_tool_sound(src)
+ if(attacking_item.use_tool(src, user, 30))
+ playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
+ for(var/i in 0 to framestackamount)
+ new framestack(get_turf(src))
+ qdel(src)
+ return
+ if(istype(attacking_item, /obj/item/stack/sheet/mineral/abductor))
+ var/obj/item/stack/sheet/stacked_sheets = attacking_item
+ if(stacked_sheets.get_amount() < 1)
+ to_chat(user, span_warning("You need one alien alloy sheet to do this!"))
+ return
+ to_chat(user, span_notice("You start adding [stacked_sheets] to [src]..."))
+ if(do_after(user, 50, target = src))
+ stacked_sheets.use(1)
+ new /obj/structure/table/abductor(src.loc)
+ qdel(src)
+ return
+ if(istype(attacking_item, /obj/item/stack/sheet/mineral/silver))
+ var/obj/item/stack/sheet/stacked_sheets = attacking_item
+ if(stacked_sheets.get_amount() < 1)
+ to_chat(user, span_warning("You need one sheet of silver to do this!"))
+ return
+ to_chat(user, span_notice("You start adding [stacked_sheets] to [src]..."))
+ if(do_after(user, 50, target = src))
+ stacked_sheets.use(1)
+ new /obj/structure/table/optable/abductor(src.loc)
+ qdel(src)
+
+/obj/structure/table/abductor
+ name = "alien table"
+ desc = "Advanced flat surface technology at work!"
+ icon = 'icons/obj/smooth_structures/alien_table.dmi'
+ icon_state = "alien_table-0"
+ base_icon_state = "alien_table"
+ buildstack = /obj/item/stack/sheet/mineral/abductor
+ framestack = /obj/item/stack/sheet/mineral/abductor
+ buildstackamount = 1
+ framestackamount = 1
+ smoothing_groups = SMOOTH_GROUP_ABDUCTOR_TABLES
+ canSmoothWith = SMOOTH_GROUP_ABDUCTOR_TABLES
+ frame = /obj/structure/table_frame/abductor
+ custom_materials = list(/datum/material/silver =SHEET_MATERIAL_AMOUNT)
+
+/obj/structure/table/optable/abductor
+ name = "alien operating table"
+ desc = "Used for alien medical procedures. The surface is covered in tiny spines."
+ frame = /obj/structure/table_frame/abductor
+ buildstack = /obj/item/stack/sheet/mineral/silver
+ framestack = /obj/item/stack/sheet/mineral/abductor
+ buildstackamount = 1
+ framestackamount = 1
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "bed"
+ can_buckle = TRUE
+ buckle_lying = 90
+ /// Amount to inject per second
+ var/inject_amount = 0.5
+
+ var/static/list/injected_reagents = list(/datum/reagent/medicine/cordiolis_hepatico)
+
+/obj/structure/table/optable/abductor/Initialize(mapload)
+ . = ..()
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+
+/obj/structure/table/optable/abductor/proc/on_entered(datum/source, atom/movable/AM)
+ SIGNAL_HANDLER
+ if(iscarbon(AM))
+ START_PROCESSING(SSobj, src)
+ to_chat(AM, span_danger("You feel a series of tiny pricks!"))
+
+/obj/structure/table/optable/abductor/process(seconds_per_tick)
+ . = PROCESS_KILL
+ for(var/mob/living/carbon/victim in get_turf(src))
+ . = TRUE
+ for(var/chemical in injected_reagents)
+ if(victim.reagents.get_reagent_amount(chemical) < inject_amount * seconds_per_tick)
+ victim.reagents.add_reagent(chemical, inject_amount * seconds_per_tick)
+ return .
+
+/obj/structure/table/optable/abductor/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/structure/closet/abductor
+ name = "alien locker"
+ desc = "Contains secrets of the universe."
+ icon_state = "abductor"
+ icon_door = "abductor"
+ can_weld_shut = FALSE
+ door_anim_time = 0
+ material_drop = /obj/item/stack/sheet/mineral/abductor
+
+/obj/structure/door_assembly/door_assembly_abductor
+ name = "alien airlock assembly"
+ icon = 'icons/obj/doors/airlocks/abductor/abductor_airlock.dmi'
+ base_name = "alien airlock"
+ overlays_file = 'icons/obj/doors/airlocks/abductor/overlays.dmi'
+ airlock_type = /obj/machinery/door/airlock/abductor
+ material_type = /obj/item/stack/sheet/mineral/abductor
+ noglass = TRUE
diff --git a/code/modules/antagonists/abductor/equipment/gear/abductor_clothing.dm b/code/modules/antagonists/abductor/equipment/gear/abductor_clothing.dm
new file mode 100644
index 00000000000..5bd7c0a02c7
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/gear/abductor_clothing.dm
@@ -0,0 +1,159 @@
+/obj/item/clothing/under/abductor
+ desc = "The most advanced form of jumpsuit known to reality, looks uncomfortable."
+ name = "alien jumpsuit"
+ icon = 'icons/obj/clothing/under/syndicate.dmi'
+ icon_state = "abductor"
+ inhand_icon_state = "bl_suit"
+ worn_icon = 'icons/mob/clothing/under/syndicate.dmi'
+ armor_type = /datum/armor/under_abductor
+ can_adjust = FALSE
+
+/datum/armor/under_abductor
+ bomb = 10
+ bio = 10
+ wound = 5
+
+//AGENT VEST
+/obj/item/clothing/suit/armor/abductor/vest
+ name = "agent vest"
+ desc = "A vest outfitted with advanced stealth technology. It has two modes - combat and stealth."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "vest_stealth"
+ inhand_icon_state = "armor"
+ blood_overlay_type = "armor"
+ armor_type = /datum/armor/abductor_vest
+ actions_types = list(/datum/action/item_action/hands_free/activate)
+ allowed = list(
+ /obj/item/abductor,
+ /obj/item/melee/baton,
+ /obj/item/gun/energy,
+ /obj/item/restraints/handcuffs,
+ )
+ /// What operation mode is our vest in?
+ var/mode = VEST_STEALTH
+ /// Do we have a disguise active?
+ var/stealth_active = FALSE
+ /// Cooldown in seconds for the combat mode activation stimulant.
+ var/combat_cooldown = 20
+ /// The visual of our suit's disguise.
+ var/datum/icon_snapshot/disguise
+
+/datum/armor/abductor_combat
+ melee = 50
+ bullet = 50
+ laser = 50
+ energy = 50
+ bomb = 50
+ bio = 50
+ fire = 90
+ acid = 90
+
+/datum/armor/abductor_vest
+ melee = 15
+ bullet = 15
+ laser = 15
+ energy = 25
+ bomb = 15
+ bio = 15
+ fire = 70
+ acid = 70
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop()
+ if(HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT))
+ REMOVE_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)
+ else
+ ADD_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)
+ if(ismob(loc))
+ to_chat(loc, span_notice("Your vest is now [HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "locked" : "unlocked"]."))
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode()
+ switch(mode)
+ if(VEST_STEALTH)
+ mode = VEST_COMBAT
+ DeactivateStealth()
+ set_armor(/datum/armor/abductor_combat)
+ icon_state = "vest_combat"
+ if(VEST_COMBAT)// TO STEALTH
+ mode = VEST_STEALTH
+ set_armor(/datum/armor/abductor_vest)
+ icon_state = "vest_stealth"
+ if(ishuman(loc))
+ var/mob/living/carbon/human/human_target = loc
+ human_target.update_worn_oversuit()
+ update_item_action_buttons()
+
+/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user)
+ if(slot & ITEM_SLOT_OCLOTHING) //we only give the mob the ability to activate the vest if he's actually wearing it.
+ return TRUE
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/SetDisguise(datum/icon_snapshot/entry)
+ disguise = entry
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/ActivateStealth()
+ if(disguise == null)
+ return
+ stealth_active = TRUE
+ if(ishuman(loc))
+ var/mob/living/carbon/human/wearer = loc
+ new /obj/effect/temp_visual/dir_setting/ninja/cloak(get_turf(wearer), wearer.dir)
+ wearer.name_override = disguise.name
+ wearer.icon = disguise.icon
+ wearer.icon_state = disguise.icon_state
+ wearer.cut_overlays()
+ wearer.add_overlay(disguise.overlays)
+ wearer.update_held_items()
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/DeactivateStealth()
+ if(!stealth_active)
+ return
+ stealth_active = FALSE
+ if(ishuman(loc))
+ var/mob/living/carbon/human/wearer = loc
+ new /obj/effect/temp_visual/dir_setting/ninja(get_turf(wearer), wearer.dir)
+ wearer.name_override = null
+ wearer.cut_overlays()
+ wearer.regenerate_icons()
+
+/obj/item/clothing/suit/armor/abductor/vest/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE)
+ DeactivateStealth()
+
+/obj/item/clothing/suit/armor/abductor/vest/IsReflect()
+ DeactivateStealth()
+
+/obj/item/clothing/suit/armor/abductor/vest/ui_action_click()
+ switch(mode)
+ if(VEST_COMBAT)
+ Adrenaline()
+ if(VEST_STEALTH)
+ if(stealth_active)
+ DeactivateStealth()
+ else
+ ActivateStealth()
+
+/obj/item/clothing/suit/armor/abductor/vest/proc/Adrenaline()
+ if(ishuman(loc))
+ if(combat_cooldown < initial(combat_cooldown))
+ to_chat(loc, span_warning("Combat injection is still recharging."))
+ return
+ var/mob/living/carbon/human/wearer = loc
+ wearer.adjustStaminaLoss(-75)
+ wearer.SetUnconscious(0)
+ wearer.SetStun(0)
+ wearer.SetKnockdown(0)
+ wearer.SetImmobilized(0)
+ wearer.SetParalyzed(0)
+ combat_cooldown = 0
+ START_PROCESSING(SSobj, src)
+
+/obj/item/clothing/suit/armor/abductor/vest/process(seconds_per_tick)
+ combat_cooldown += seconds_per_tick
+ if(combat_cooldown >= initial(combat_cooldown))
+ STOP_PROCESSING(SSobj, src)
+
+/obj/item/clothing/suit/armor/abductor/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ for(var/obj/machinery/abductor/console/mothership_console in GLOB.machines)
+ if(mothership_console.vest == src)
+ mothership_console.vest = null
+ break
+ return ..()
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
similarity index 60%
rename from code/modules/antagonists/abductor/equipment/abduction_gear.dm
rename to code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
index f81e7130665..bd5e49e807c 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
@@ -1,153 +1,3 @@
-#define VEST_STEALTH 1
-#define VEST_COMBAT 2
-#define GIZMO_SCAN 1
-#define GIZMO_MARK 2
-#define MIND_DEVICE_MESSAGE 1
-#define MIND_DEVICE_CONTROL 2
-
-//AGENT VEST
-/obj/item/clothing/suit/armor/abductor/vest
- name = "agent vest"
- desc = "A vest outfitted with advanced stealth technology. It has two modes - combat and stealth."
- icon = 'icons/obj/abductor.dmi'
- icon_state = "vest_stealth"
- inhand_icon_state = "armor"
- blood_overlay_type = "armor"
- armor_type = /datum/armor/abductor_vest
- actions_types = list(/datum/action/item_action/hands_free/activate)
- allowed = list(
- /obj/item/abductor,
- /obj/item/melee/baton,
- /obj/item/gun/energy,
- /obj/item/restraints/handcuffs
- )
- var/mode = VEST_STEALTH
- var/stealth_active = FALSE
- /// Cooldown in seconds
- var/combat_cooldown = 20
- var/datum/icon_snapshot/disguise
-
-/datum/armor/abductor_combat
- melee = 50
- bullet = 50
- laser = 50
- energy = 50
- bomb = 50
- bio = 50
- fire = 90
- acid = 90
-
-/datum/armor/abductor_vest
- melee = 15
- bullet = 15
- laser = 15
- energy = 25
- bomb = 15
- bio = 15
- fire = 70
- acid = 70
-
-/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop()
- if(HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT))
- REMOVE_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)
- else
- ADD_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)
- if(ismob(loc))
- to_chat(loc, span_notice("Your vest is now [HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "locked" : "unlocked"]."))
-
-/obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode()
- switch(mode)
- if(VEST_STEALTH)
- mode = VEST_COMBAT
- DeactivateStealth()
- set_armor(/datum/armor/abductor_combat)
- icon_state = "vest_combat"
- if(VEST_COMBAT)// TO STEALTH
- mode = VEST_STEALTH
- set_armor(/datum/armor/abductor_vest)
- icon_state = "vest_stealth"
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- H.update_worn_oversuit()
- update_item_action_buttons()
-
-/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user)
- if(slot & ITEM_SLOT_OCLOTHING) //we only give the mob the ability to activate the vest if he's actually wearing it.
- return TRUE
-
-/obj/item/clothing/suit/armor/abductor/vest/proc/SetDisguise(datum/icon_snapshot/entry)
- disguise = entry
-
-/obj/item/clothing/suit/armor/abductor/vest/proc/ActivateStealth()
- if(disguise == null)
- return
- stealth_active = TRUE
- if(ishuman(loc))
- var/mob/living/carbon/human/M = loc
- new /obj/effect/temp_visual/dir_setting/ninja/cloak(get_turf(M), M.dir)
- M.name_override = disguise.name
- M.icon = disguise.icon
- M.icon_state = disguise.icon_state
- M.cut_overlays()
- M.add_overlay(disguise.overlays)
- M.update_held_items()
-
-/obj/item/clothing/suit/armor/abductor/vest/proc/DeactivateStealth()
- if(!stealth_active)
- return
- stealth_active = FALSE
- if(ishuman(loc))
- var/mob/living/carbon/human/M = loc
- new /obj/effect/temp_visual/dir_setting/ninja(get_turf(M), M.dir)
- M.name_override = null
- M.cut_overlays()
- M.regenerate_icons()
-
-/obj/item/clothing/suit/armor/abductor/vest/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE)
- DeactivateStealth()
-
-/obj/item/clothing/suit/armor/abductor/vest/IsReflect()
- DeactivateStealth()
-
-/obj/item/clothing/suit/armor/abductor/vest/ui_action_click()
- switch(mode)
- if(VEST_COMBAT)
- Adrenaline()
- if(VEST_STEALTH)
- if(stealth_active)
- DeactivateStealth()
- else
- ActivateStealth()
-
-/obj/item/clothing/suit/armor/abductor/vest/proc/Adrenaline()
- if(ishuman(loc))
- if(combat_cooldown < initial(combat_cooldown))
- to_chat(loc, span_warning("Combat injection is still recharging."))
- return
- var/mob/living/carbon/human/M = loc
- M.adjustStaminaLoss(-75)
- M.SetUnconscious(0)
- M.SetStun(0)
- M.SetKnockdown(0)
- M.SetImmobilized(0)
- M.SetParalyzed(0)
- combat_cooldown = 0
- START_PROCESSING(SSobj, src)
-
-/obj/item/clothing/suit/armor/abductor/vest/process(seconds_per_tick)
- combat_cooldown += seconds_per_tick
- if(combat_cooldown >= initial(combat_cooldown))
- STOP_PROCESSING(SSobj, src)
-
-/obj/item/clothing/suit/armor/abductor/Destroy()
- STOP_PROCESSING(SSobj, src)
- for(var/obj/machinery/abductor/console/C in GLOB.machines)
- if(C.vest == src)
- C.vest = null
- break
- . = ..()
-
-
/obj/item/abductor
icon = 'icons/obj/abductor.dmi'
lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi'
@@ -198,7 +48,7 @@
icon_state = "gizmo_scan"
to_chat(user, span_notice("You switch the device to [mode == GIZMO_SCAN? "SCAN": "MARK"] MODE"))
-/obj/item/abductor/gizmo/attack(mob/living/M, mob/user)
+/obj/item/abductor/gizmo/attack(mob/living/target, mob/user)
if(!ScientistCheck(user))
return
if(!console)
@@ -207,9 +57,9 @@
switch(mode)
if(GIZMO_SCAN)
- scan(M, user)
+ scan(target, user)
if(GIZMO_MARK)
- mark(M, user)
+ mark(target, user)
/obj/item/abductor/gizmo/afterattack(atom/target, mob/living/user, flag, params)
@@ -268,10 +118,10 @@
icon_state = "silencer"
inhand_icon_state = "gizmo"
-/obj/item/abductor/silencer/attack(mob/living/M, mob/user)
+/obj/item/abductor/silencer/attack(mob/living/target, mob/user)
if(!AbductorCheck(user))
return
- radio_off(M, user)
+ radio_off(target, user)
/obj/item/abductor/silencer/afterattack(atom/target, mob/living/user, flag, params)
. = ..()
@@ -289,15 +139,15 @@
var/turf/targloc = get_turf(target)
- var/mob/living/carbon/human/M
- for(M in view(2,targloc))
- if(M == user)
+ var/mob/living/carbon/human/human_target
+ for(human_target in view(2,targloc))
+ if(human_target == user)
continue
- to_chat(user, span_notice("You silence [M]'s radio devices."))
- radio_off_mob(M)
+ to_chat(user, span_notice("You silence [human_target]'s radio devices."))
+ radio_off_mob(human_target)
-/obj/item/abductor/silencer/proc/radio_off_mob(mob/living/carbon/human/M)
- var/list/all_items = M.get_all_contents()
+/obj/item/abductor/silencer/proc/radio_off_mob(mob/living/carbon/human/target)
+ var/list/all_items = target.get_all_contents()
for(var/obj/item/radio/radio in all_items)
radio.set_listening(FALSE)
@@ -338,20 +188,20 @@
/obj/item/abductor/mind_device/proc/mind_control(atom/target, mob/living/user)
if(iscarbon(target))
- var/mob/living/carbon/C = target
- var/obj/item/organ/internal/heart/gland/G = C.get_organ_slot("heart")
- if(!istype(G))
+ var/mob/living/carbon/carbon_target = target
+ var/obj/item/organ/internal/heart/gland/target_gland = carbon_target.get_organ_slot("heart")
+ if(!istype(target_gland))
to_chat(user, span_warning("Your target does not have an experimental gland!"))
return
- if(!G.mind_control_uses)
+ if(!target_gland.mind_control_uses)
to_chat(user, span_warning("Your target's gland is spent!"))
return
- if(G.active_mind_control)
+ if(target_gland.active_mind_control)
to_chat(user, span_warning("Your target is already under a mind-controlling influence!"))
return
var/command = tgui_input_text(user, "Enter the command for your target to follow.\
- Uses Left: [G.mind_control_uses], Duration: [DisplayTimeText(G.mind_control_duration)]", "Enter command")
+ Uses Left: [target_gland.mind_control_uses], Duration: [DisplayTimeText(target_gland.mind_control_duration)]", "Enter command")
if(!command)
return
@@ -359,33 +209,33 @@
if(QDELETED(user) || user.get_active_held_item() != src || loc != user)
return
- if(QDELETED(G))
+ if(QDELETED(target_gland))
return
- if(C.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
+ if(carbon_target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
user.balloon_alert(user, "foiled!")
to_chat(user, span_warning("Your target seems to have some sort of mental blockage, preventing the message from being sent! It seems you've been foiled."))
return
- G.mind_control(command, user)
+ target_gland.mind_control(command, user)
to_chat(user, span_notice("You send the command to your target."))
/obj/item/abductor/mind_device/proc/mind_message(atom/target, mob/living/user)
if(isliving(target))
- var/mob/living/L = target
- if(L.stat == DEAD)
+ var/mob/living/living_target = target
+ if(living_target.stat == DEAD)
to_chat(user, span_warning("Your target is dead!"))
return
var/message = tgui_input_text(user, "Message to send to your target's brain", "Enter message")
if(!message)
return
- if(QDELETED(L) || L.stat == DEAD)
+ if(QDELETED(living_target) || living_target.stat == DEAD)
return
- L.balloon_alert(L, "you hear a voice")
- to_chat(L, span_hear("You hear a voice in your head saying: [message]"))
+ living_target.balloon_alert(living_target, "you hear a voice")
+ to_chat(living_target, span_hear("You hear a voice in your head saying: [message]"))
to_chat(user, span_notice("You send the message to your target."))
- log_directed_talk(user, L, message, LOG_SAY, "abductor whisper")
+ log_directed_talk(user, living_target, message, LOG_SAY, "abductor whisper")
/obj/item/firing_pin/abductor
@@ -445,12 +295,6 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/paper/guides/antag/abductor/AltClick()
return //otherwise it would fold into a paperplane.
-#define BATON_STUN 0
-#define BATON_SLEEP 1
-#define BATON_CUFF 2
-#define BATON_PROBE 3
-#define BATON_MODES 4
-
/obj/item/melee/baton/abductor
name = "advanced baton"
desc = "A quad-mode baton used for incapacitation and restraining of specimens."
@@ -555,67 +399,67 @@ Congratulations! You are now trained for invasive xenobiology research!"}
. = ..()
toggle(user)
-/obj/item/melee/baton/abductor/proc/SleepAttack(mob/living/L,mob/living/user)
+/obj/item/melee/baton/abductor/proc/SleepAttack(mob/living/target, mob/living/user)
playsound(src, on_stun_sound, 50, TRUE, -1)
- if(L.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB))
- if(L.can_block_magic(MAGIC_RESISTANCE_MIND))
+ if(target.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB))
+ if(target.can_block_magic(MAGIC_RESISTANCE_MIND))
to_chat(user, span_warning("The specimen has some kind of mental protection that is interfering with the sleep inducement! It seems you've been foiled."))
- L.visible_message(span_danger("[user] tried to induced sleep in [L] with [src], but is unsuccessful!"), \
+ target.visible_message(span_danger("[user] tried to induced sleep in [target] with [src], but is unsuccessful!"), \
span_userdanger("You feel a strange wave of heavy drowsiness wash over you!"))
- L.adjust_drowsiness(4 SECONDS)
+ target.adjust_drowsiness(4 SECONDS)
return
- L.visible_message(span_danger("[user] induces sleep in [L] with [src]!"), \
+ target.visible_message(span_danger("[user] induces sleep in [target] with [src]!"), \
span_userdanger("You suddenly feel very drowsy!"))
- L.Sleeping(sleep_time)
- log_combat(user, L, "put to sleep")
+ target.Sleeping(sleep_time)
+ log_combat(user, target, "put to sleep")
else
- if(L.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
+ if(target.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
to_chat(user, span_warning("The specimen has some kind of mental protection that is completely blocking our sleep inducement methods! It seems you've been foiled."))
- L.visible_message(span_danger("[user] tried to induce sleep in [L] with [src], but is unsuccessful!"), \
+ target.visible_message(span_danger("[user] tried to induce sleep in [target] with [src], but is unsuccessful!"), \
span_userdanger("Any sense of drowsiness is quickly diminished!"))
return
- L.adjust_drowsiness(2 SECONDS)
+ target.adjust_drowsiness(2 SECONDS)
to_chat(user, span_warning("Sleep inducement works fully only on stunned specimens! "))
- L.visible_message(span_danger("[user] tried to induce sleep in [L] with [src]!"), \
+ target.visible_message(span_danger("[user] tried to induce sleep in [target] with [src]!"), \
span_userdanger("You suddenly feel drowsy!"))
-/obj/item/melee/baton/abductor/proc/CuffAttack(mob/living/L,mob/living/user)
- if(!iscarbon(L))
+/obj/item/melee/baton/abductor/proc/CuffAttack(mob/living/victim, mob/living/user)
+ if(!iscarbon(victim))
return
- var/mob/living/carbon/C = L
- if(!C.handcuffed)
- if(C.canBeHandcuffed())
+ var/mob/living/carbon/carbon_victim = victim
+ if(!carbon_victim.handcuffed)
+ if(carbon_victim.canBeHandcuffed())
playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
- C.visible_message(span_danger("[user] begins restraining [C] with [src]!"), \
+ carbon_victim.visible_message(span_danger("[user] begins restraining [carbon_victim] with [src]!"), \
span_userdanger("[user] begins shaping an energy field around your hands!"))
- if(do_after(user, time_to_cuff, C) && C.canBeHandcuffed())
- if(!C.handcuffed)
- C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(C))
- C.update_handcuffed()
- to_chat(user, span_notice("You restrain [C]."))
- log_combat(user, C, "handcuffed")
+ if(do_after(user, time_to_cuff, carbon_victim) && carbon_victim.canBeHandcuffed())
+ if(!carbon_victim.handcuffed)
+ carbon_victim.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(carbon_victim))
+ carbon_victim.update_handcuffed()
+ to_chat(user, span_notice("You restrain [carbon_victim]."))
+ log_combat(user, carbon_victim, "handcuffed")
else
- to_chat(user, span_warning("You fail to restrain [C]."))
+ to_chat(user, span_warning("You fail to restrain [carbon_victim]."))
else
- to_chat(user, span_warning("[C] doesn't have two hands..."))
+ to_chat(user, span_warning("[carbon_victim] doesn't have two hands..."))
-/obj/item/melee/baton/abductor/proc/ProbeAttack(mob/living/L,mob/living/user)
- L.visible_message(span_danger("[user] probes [L] with [src]!"), \
+/obj/item/melee/baton/abductor/proc/ProbeAttack(mob/living/victim, mob/living/user)
+ victim.visible_message(span_danger("[user] probes [victim] with [src]!"), \
span_userdanger("[user] probes you!"))
var/species = span_warning("Unknown species")
var/helptext = span_warning("Species unsuitable for experiments.")
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- species = span_notice("[H.dna.species.name]")
- if(L.mind && L.mind.has_antag_datum(/datum/antagonist/changeling))
+ if(ishuman(victim))
+ var/mob/living/carbon/human/human_victim = victim
+ species = span_notice("[human_victim.dna.species.name]")
+ if(human_victim.mind && human_victim.mind.has_antag_datum(/datum/antagonist/changeling))
species = span_warning("Changeling lifeform")
- var/obj/item/organ/internal/heart/gland/temp = locate() in H.organs
+ var/obj/item/organ/internal/heart/gland/temp = locate() in human_victim.organs
if(temp)
helptext = span_warning("Experimental gland detected!")
else
- if (L.get_organ_slot(ORGAN_SLOT_HEART))
+ if (human_victim.get_organ_slot(ORGAN_SLOT_HEART))
helptext = span_notice("Subject suitable for experiments.")
else
helptext = span_warning("Subject unsuitable for experiments.")
@@ -639,9 +483,9 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/restraints/handcuffs/energy/used/dropped(mob/user)
user.visible_message(span_danger("[user]'s [name] breaks in a discharge of energy!"), \
span_userdanger("[user]'s [name] breaks in a discharge of energy!"))
- var/datum/effect_system/spark_spread/S = new
- S.set_up(4,0,user.loc)
- S.start()
+ var/datum/effect_system/spark_spread/sparks = new
+ sparks.set_up(4,0,user.loc)
+ sparks.start()
. = ..()
/obj/item/melee/baton/abductor/examine(mob/user)
@@ -768,152 +612,104 @@ Congratulations! You are now trained for invasive xenobiology research!"}
return COMPONENT_CANT_TRACK
-// Operating Table / Beds / Lockers
+/obj/item/abductor/alien_omnitool
+ name = "quizzandric interfacer"
+ desc = "Effectively just a Space Swiss Army Knife. Contains a multitude of integrated tools. Right-click it to switch which toolset is active."
+ icon_state = "omnitool"
+ inhand_icon_state = "silencer"
+ toolspeed = 0.25
+ tool_behaviour = null
+ usesound = 'sound/items/pshoom.ogg'
+ ///A list of all the tools we offer. Stored as "Tool" for the key, and the icon/icon_state as the value.
+ var/list/tool_list = list()
+ ///Which toolset do we have active currently?
+ var/active_toolset = TOOLSET_MEDICAL
-/obj/structure/bed/abductor
- name = "resting contraption"
- desc = "This looks similar to contraptions from Earth. Could aliens be stealing our technology?"
- icon = 'icons/obj/abductor.dmi'
- buildstacktype = /obj/item/stack/sheet/mineral/abductor
- icon_state = "bed"
+/obj/item/abductor/alien_omnitool/Initialize(mapload)
+ . = ..()
+ set_toolset() //This populates the tool list, and sets it to the hacking configuration.
-/obj/structure/table_frame/abductor
- name = "alien table frame"
- desc = "A sturdy table frame made from alien alloy."
- icon_state = "alien_frame"
- framestack = /obj/item/stack/sheet/mineral/abductor
- framestackamount = 1
+/obj/item/abductor/alien_omnitool/examine()
+ . = ..()
+ . += " The mode is: [tool_behaviour]"
-/obj/structure/table_frame/abductor/attackby(obj/item/I, mob/user, params)
- if(I.tool_behaviour == TOOL_WRENCH)
- to_chat(user, span_notice("You start disassembling [src]..."))
- I.play_tool_sound(src)
- if(I.use_tool(src, user, 30))
- playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
- for(var/i in 0 to framestackamount)
- new framestack(get_turf(src))
- qdel(src)
- return
- if(istype(I, /obj/item/stack/sheet/mineral/abductor))
- var/obj/item/stack/sheet/P = I
- if(P.get_amount() < 1)
- to_chat(user, span_warning("You need one alien alloy sheet to do this!"))
- return
- to_chat(user, span_notice("You start adding [P] to [src]..."))
- if(do_after(user, 50, target = src))
- P.use(1)
- new /obj/structure/table/abductor(src.loc)
- qdel(src)
+/obj/item/abductor/alien_omnitool/attack_self(mob/user)
+ if(!user)
return
- if(istype(I, /obj/item/stack/sheet/mineral/silver))
- var/obj/item/stack/sheet/P = I
- if(P.get_amount() < 1)
- to_chat(user, span_warning("You need one sheet of silver to do this!"))
- return
- to_chat(user, span_notice("You start adding [P] to [src]..."))
- if(do_after(user, 50, target = src))
- P.use(1)
- new /obj/structure/table/optable/abductor(src.loc)
- qdel(src)
-/obj/structure/table/abductor
- name = "alien table"
- desc = "Advanced flat surface technology at work!"
- icon = 'icons/obj/smooth_structures/alien_table.dmi'
- icon_state = "alien_table-0"
- base_icon_state = "alien_table"
- buildstack = /obj/item/stack/sheet/mineral/abductor
- framestack = /obj/item/stack/sheet/mineral/abductor
- buildstackamount = 1
- framestackamount = 1
- smoothing_groups = SMOOTH_GROUP_ABDUCTOR_TABLES
- canSmoothWith = SMOOTH_GROUP_ABDUCTOR_TABLES
- frame = /obj/structure/table_frame/abductor
- custom_materials = list(/datum/material/silver =SHEET_MATERIAL_AMOUNT)
+ var/tool_result = show_radial_menu(user, src, tool_list, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE)
+ if(!check_menu(user))
+ return
+ switch(tool_result)
+ if("Retractor")
+ tool_behaviour = TOOL_RETRACTOR
+ if("Hemostat")
+ tool_behaviour = TOOL_HEMOSTAT
+ if("Cautery")
+ tool_behaviour = TOOL_CAUTERY
+ if("Drill")
+ tool_behaviour = TOOL_DRILL
+ if("Scalpel")
+ tool_behaviour = TOOL_SCALPEL
+ if("Saw")
+ tool_behaviour = TOOL_SAW
+ if("Bonesetter")
+ tool_behaviour = TOOL_BONESET
+ if("Blood Filter")
+ tool_behaviour = TOOL_BLOODFILTER
+ if("Crowbar")
+ tool_behaviour = TOOL_CROWBAR
+ if("Multitool")
+ tool_behaviour = TOOL_MULTITOOL
+ if("Screwdriver")
+ tool_behaviour = TOOL_SCREWDRIVER
+ if("Wirecutters")
+ tool_behaviour = TOOL_WIRECUTTER
+ if("Wrench")
+ tool_behaviour = TOOL_WRENCH
+ if("Welding Tool")
+ tool_behaviour = TOOL_WELDER
-/obj/structure/table/optable/abductor
- name = "alien operating table"
- desc = "Used for alien medical procedures. The surface is covered in tiny spines."
- frame = /obj/structure/table_frame/abductor
- buildstack = /obj/item/stack/sheet/mineral/silver
- framestack = /obj/item/stack/sheet/mineral/abductor
- buildstackamount = 1
- framestackamount = 1
- icon = 'icons/obj/abductor.dmi'
- icon_state = "bed"
- can_buckle = TRUE
- buckle_lying = 90
- /// Amount to inject per second
- var/inject_am = 0.5
+ playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
- var/static/list/injected_reagents = list(/datum/reagent/medicine/cordiolis_hepatico)
+/obj/item/abductor/alien_omnitool/attack_self_secondary(mob/user, modifiers) //ADD SFX FOR USING THE TOOL
+ if(!user)
+ return
-/obj/structure/table/optable/abductor/Initialize(mapload)
- . = ..()
- var/static/list/loc_connections = list(
- COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
- )
- AddElement(/datum/element/connect_loc, loc_connections)
+ set_toolset(user)
+ playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
-/obj/structure/table/optable/abductor/proc/on_entered(datum/source, atom/movable/AM)
- SIGNAL_HANDLER
- if(iscarbon(AM))
- START_PROCESSING(SSobj, src)
- to_chat(AM, span_danger("You feel a series of tiny pricks!"))
+/obj/item/abductor/alien_omnitool/proc/check_menu(mob/user)
+ if(!istype(user))
+ return FALSE
+ if(user.incapacitated() || !user.Adjacent(src))
+ return FALSE
+ return TRUE
-/obj/structure/table/optable/abductor/process(seconds_per_tick)
- . = PROCESS_KILL
- for(var/mob/living/carbon/C in get_turf(src))
- . = TRUE
- for(var/chemical in injected_reagents)
- if(C.reagents.get_reagent_amount(chemical) < inject_am * seconds_per_tick)
- C.reagents.add_reagent(chemical, inject_am * seconds_per_tick)
-
-/obj/structure/table/optable/abductor/Destroy()
- STOP_PROCESSING(SSobj, src)
- . = ..()
-
-/obj/structure/closet/abductor
- name = "alien locker"
- desc = "Contains secrets of the universe."
- icon_state = "abductor"
- icon_door = "abductor"
- can_weld_shut = FALSE
- door_anim_time = 0
- material_drop = /obj/item/stack/sheet/mineral/abductor
-
-/obj/structure/door_assembly/door_assembly_abductor
- name = "alien airlock assembly"
- icon = 'icons/obj/doors/airlocks/abductor/abductor_airlock.dmi'
- base_name = "alien airlock"
- overlays_file = 'icons/obj/doors/airlocks/abductor/overlays.dmi'
- airlock_type = /obj/machinery/door/airlock/abductor
- material_type = /obj/item/stack/sheet/mineral/abductor
- noglass = TRUE
-
-/obj/item/clothing/under/abductor
- desc = "The most advanced form of jumpsuit known to reality, looks uncomfortable."
- name = "alien jumpsuit"
- icon = 'icons/obj/clothing/under/syndicate.dmi'
- icon_state = "abductor"
- inhand_icon_state = "bl_suit"
- worn_icon = 'icons/mob/clothing/under/syndicate.dmi'
- armor_type = /datum/armor/under_abductor
- can_adjust = FALSE
-
-/datum/armor/under_abductor
- bomb = 10
- bio = 10
- wound = 5
-
-#undef BATON_CUFF
-#undef BATON_MODES
-#undef BATON_PROBE
-#undef BATON_SLEEP
-#undef BATON_STUN
-#undef GIZMO_MARK
-#undef GIZMO_SCAN
-#undef MIND_DEVICE_CONTROL
-#undef MIND_DEVICE_MESSAGE
-#undef VEST_COMBAT
-#undef VEST_STEALTH
+/obj/item/abductor/alien_omnitool/proc/set_toolset(mob/user)
+ if(active_toolset == TOOLSET_MEDICAL)
+ tool_list = list(
+ "Crowbar" = image(icon = 'icons/obj/abductor.dmi', icon_state = "crowbar"),
+ "Multitool" = image(icon = 'icons/obj/abductor.dmi', icon_state = "multitool"),
+ "Screwdriver" = image(icon = 'icons/obj/abductor.dmi', icon_state = "screwdriver_a"),
+ "Wirecutters" = image(icon = 'icons/obj/abductor.dmi', icon_state = "cutters"),
+ "Wrench" = image(icon = 'icons/obj/abductor.dmi', icon_state = "wrench"),
+ "Welding Tool" = image(icon = 'icons/obj/abductor.dmi', icon_state = "welder"),
+ )
+ active_toolset = TOOLSET_HACKING
+ if(user)
+ balloon_alert(user, "hacking toolset selected")
+ else
+ tool_list = list(
+ "Retractor" = image(icon = 'icons/obj/abductor.dmi', icon_state = "retractor"),
+ "Hemostat" = image(icon = 'icons/obj/abductor.dmi', icon_state = "hemostat"),
+ "Cautery" = image(icon = 'icons/obj/abductor.dmi', icon_state = "cautery"),
+ "Drill" = image(icon = 'icons/obj/abductor.dmi', icon_state = "drill"),
+ "Scalpel" = image(icon = 'icons/obj/abductor.dmi', icon_state = "scalpel"),
+ "Saw" = image(icon = 'icons/obj/abductor.dmi', icon_state = "saw"),
+ "Bonesetter" = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "bonesetter"),
+ "Blood Filter" = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "bloodfilter"),
+ )
+ active_toolset = TOOLSET_MEDICAL
+ if(user)
+ balloon_alert(user, "medical toolset selected")
diff --git a/code/modules/antagonists/abductor/equipment/gear/abductor_posters.dm b/code/modules/antagonists/abductor/equipment/gear/abductor_posters.dm
new file mode 100644
index 00000000000..9d97b3a5568
--- /dev/null
+++ b/code/modules/antagonists/abductor/equipment/gear/abductor_posters.dm
@@ -0,0 +1,82 @@
+
+/obj/item/poster/random_abductor
+ name = "random abductor poster"
+ poster_type = /obj/structure/sign/poster/abductor/random
+ icon = 'icons/obj/poster.dmi'
+ icon_state = "rolled_abductor"
+
+/obj/structure/sign/poster/abductor
+ icon = 'icons/obj/abductor_posters.dmi'
+ poster_item_name = "abductor poster"
+ poster_item_desc = "A sheet of holofiber resin, with a nanospike perforation on the back end for maximum adhesion."
+ poster_item_icon_state = "rolled_abductor"
+
+/obj/structure/sign/poster/abductor/tear_poster(mob/user)
+ if(!isabductor(user))
+ balloon_alert(user, "it won't budge!")
+ return
+ return ..()
+
+/obj/structure/sign/poster/abductor/random
+ name = "random abductor poster"
+ icon_state = "random_abductor"
+ never_random = TRUE
+ random_basetype = /obj/structure/sign/poster/abductor
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/random, 32)
+
+/obj/structure/sign/poster/abductor/ayylian
+ name = "Ayylian"
+ desc = "Man, Ian sure is looking strange these days."
+ icon_state = "ayylian"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/ayylian, 32)
+
+/obj/structure/sign/poster/abductor/ayy
+ name = "Abductor"
+ desc = "Hey, that's not a lizard!"
+ icon_state = "ayy"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/ayy, 32)
+
+/obj/structure/sign/poster/abductor/ayy_over_tizira
+ name = "Abductors Over Tizira"
+ desc = "A poster for an experimental adaptation of a movie about the Human-Lizard war. Production was greatly hindered by the leading pair's refusal to speak any lines."
+ icon_state = "ayy_over_tizira"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/ayy_over_tizira, 32)
+
+/obj/structure/sign/poster/abductor/ayy_recruitment
+ name = "Abductor Recruitment"
+ desc = "Enlist in the Mothership Probing Division today!"
+ icon_state = "ayy_recruitment"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/ayy_recruitment, 32)
+
+/obj/structure/sign/poster/abductor/ayy_cops
+ name = "Abductor Cops"
+ desc = "A poster advertising the polarizing 'Abductor Cops' series. Some critics claimed that it stunned them, while others said it put them to sleep."
+ icon_state = "ayyce_cops"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/ayy_cops, 32)
+
+/obj/structure/sign/poster/abductor/ayy_no
+ name = "Uayy No"
+ desc = "This thing is all in Japanese, AND they got rid of the anime girl on the poster. Outrageous."
+ icon_state = "ayy_no"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/ayy_no, 32)
+
+/obj/structure/sign/poster/abductor/ayy_piping
+ name = "Safety Abductor - Piping"
+ desc = "Safety Abductor has nothing to say. Not because it cannot speak, but because Abductors don't have to deal with atmos stuff."
+ icon_state = "ayy_piping"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/ayy_piping, 32)
+
+/obj/structure/sign/poster/abductor/ayy_fancy
+ name = "Abductor Fancy"
+ desc = "Abductors are the best at doing everything. That includes looking good!"
+ icon_state = "ayy_fancy"
+
+MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/abductor/ayy_fancy, 32)
diff --git a/code/modules/antagonists/abductor/equipment/orderable_gear.dm b/code/modules/antagonists/abductor/equipment/orderable_gear.dm
index 4d0562ca35b..b133bf3f8a5 100644
--- a/code/modules/antagonists/abductor/equipment/orderable_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/orderable_gear.dm
@@ -1,5 +1,9 @@
GLOBAL_LIST_INIT(abductor_gear, subtypesof(/datum/abductor_gear))
+#define CATEGORY_BASIC_GEAR "Basic Gear"
+#define CATEGORY_ADVANCED_GEAR "Advanced Gear"
+#define CATEGORY_MISC_GEAR "Miscellaneous Gear"
+
/datum/abductor_gear
/// Name of the gear
var/name = "Generic Abductor Gear"
@@ -12,45 +16,45 @@ GLOBAL_LIST_INIT(abductor_gear, subtypesof(/datum/abductor_gear))
/// Build path of the gear itself
var/build_path = null
/// Category of the gear
- var/category = "Basic Gear"
+ var/category = CATEGORY_BASIC_GEAR
/datum/abductor_gear/agent_helmet
name = "Agent Helmet"
description = "Abduct with style - spiky style. Prevents digital tracking."
id = "agent_helmet"
- build_path = /obj/item/clothing/head/helmet/abductor
+ build_path = list(/obj/item/clothing/head/helmet/abductor = 1)
/datum/abductor_gear/agent_vest
name = "Agent Vest"
description = "A vest outfitted with advanced stealth technology. It has two modes - combat and stealth."
id = "agent_vest"
- build_path = /obj/item/clothing/suit/armor/abductor/vest
+ build_path = list(/obj/item/clothing/suit/armor/abductor/vest = 1)
/datum/abductor_gear/radio_silencer
name = "Radio Silencer"
description = "A compact device used to shut down communications equipment."
id = "radio_silencer"
- build_path = /obj/item/abductor/silencer
+ build_path = list(/obj/item/abductor/silencer = 1)
/datum/abductor_gear/science_tool
name = "Science Tool"
description = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
id = "science_tool"
- build_path = /obj/item/abductor/gizmo
+ build_path = list(/obj/item/abductor/gizmo = 1)
/datum/abductor_gear/advanced_baton
name = "Advanced Baton"
description = "A quad-mode baton used for incapacitation and restraining of specimens."
id = "advanced_baton"
cost = 2
- build_path = /obj/item/melee/baton/abductor
+ build_path = list(/obj/item/melee/baton/abductor = 1)
/datum/abductor_gear/superlingual_matrix
name = "Superlingual Matrix"
description = "A mysterious structure that allows for instant communication between users. Using it inhand will attune it to your mothership's channel. Pretty impressive until you need to eat something."
id = "superlingual_matrix"
- build_path = /obj/item/organ/internal/tongue/abductor
- category = "Advanced Gear"
+ build_path = list(/obj/item/organ/internal/tongue/abductor = 1)
+ category = CATEGORY_MISC_GEAR
/datum/abductor_gear/mental_interface
name = "Mental Interface Device"
@@ -58,16 +62,16 @@ GLOBAL_LIST_INIT(abductor_gear, subtypesof(/datum/abductor_gear))
or to send a command to a test subject with a charged gland."
id = "mental_interface"
cost = 2
- build_path = /obj/item/abductor/mind_device
- category = "Advanced Gear"
+ build_path = list(/obj/item/abductor/mind_device = 1)
+ category = CATEGORY_ADVANCED_GEAR
/datum/abductor_gear/reagent_synthesizer
name = "Reagent Synthesizer"
description = "Synthesizes a variety of reagents using proto-matter."
id = "reagent_synthesizer"
cost = 2
- build_path = /obj/item/abductor_machine_beacon/chem_dispenser
- category = "Advanced Gear"
+ build_path = list(/obj/item/abductor_machine_beacon/chem_dispenser = 1)
+ category = CATEGORY_ADVANCED_GEAR
/datum/abductor_gear/shrink_ray
name = "Shrink Ray Blaster"
@@ -75,5 +79,32 @@ GLOBAL_LIST_INIT(abductor_gear, subtypesof(/datum/abductor_gear))
That or it's just space magic. Either way, it shrinks stuff."
id = "shrink_ray"
cost = 2
- build_path = /obj/item/gun/energy/shrink_ray
- category = "Advanced Gear"
+ build_path = list(/obj/item/gun/energy/shrink_ray = 1)
+ category = CATEGORY_ADVANCED_GEAR
+
+/datum/abductor_gear/omnitool
+ name = "Alien Omnitool"
+ description = "A handheld device with an absurd number of integrated tools. Can be used as a convenient tool replacement for either role. \
+ Right-click it to switch between medical and hacking toolsets."
+ id = "omnitool"
+ cost = 2
+ build_path = list(/obj/item/abductor/alien_omnitool = 1)
+ category = CATEGORY_ADVANCED_GEAR
+
+/datum/abductor_gear/cow
+ name = "Spare Cow"
+ description = "Delivers a leftover specimen from an earlier abduction operation."
+ id = "cow"
+ build_path = list(/mob/living/basic/cow = 1, /obj/item/food/grown/wheat = 3)
+ category = CATEGORY_MISC_GEAR
+
+/datum/abductor_gear/posters
+ name = "Decorative Posters"
+ description = "Some posters, to decorate the walls of the Mothership (or even the station) with."
+ id = "poster"
+ build_path = list(/obj/item/poster/random_abductor = 2)
+ category = CATEGORY_MISC_GEAR
+
+#undef CATEGORY_BASIC_GEAR
+#undef CATEGORY_ADVANCED_GEAR
+#undef CATEGORY_MISC_GEAR
diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm
index c73a735f4fa..494491ab9fd 100644
--- a/code/modules/antagonists/abductor/machinery/console.dm
+++ b/code/modules/antagonists/abductor/machinery/console.dm
@@ -268,7 +268,7 @@
else
return ..()
-/obj/machinery/abductor/console/proc/Dispense(item,cost=1)
+/obj/machinery/abductor/console/proc/Dispense(items_list, cost=1)
if(experiment && experiment.credits >= cost)
experiment.credits -=cost
say("Incoming supply!")
@@ -276,7 +276,8 @@
if(pad)
flick("alien-pad", pad)
drop_location = pad.loc
- new item(drop_location)
-
+ for(var/each_item in items_list)
+ for(var/i in 1 to items_list[each_item])
+ new each_item(drop_location)
else
say("Insufficent data!")
diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm
index 8fab6d289b7..0989ef25004 100644
--- a/code/modules/antagonists/abductor/machinery/experiment.dm
+++ b/code/modules/antagonists/abductor/machinery/experiment.dm
@@ -120,6 +120,9 @@
LAZYINITLIST(history)
var/mob/living/carbon/human/H = occupant
+ if(istype(H)) //We shouldn't be processing anything other than humans, and if we do we runtime.
+ return
+
var/datum/antagonist/abductor/user_abductor = user.mind.has_antag_datum(/datum/antagonist/abductor)
if(!user_abductor)
return "Authorization failure. Contact mothership immediately."
diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi
index 98792bfeb5d..0045d4b2398 100644
Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ
diff --git a/icons/obj/abductor_posters.dmi b/icons/obj/abductor_posters.dmi
new file mode 100644
index 00000000000..bcd2c0200a2
Binary files /dev/null and b/icons/obj/abductor_posters.dmi differ
diff --git a/icons/obj/poster.dmi b/icons/obj/poster.dmi
index 788c61152d0..d1b425d31b4 100644
Binary files a/icons/obj/poster.dmi and b/icons/obj/poster.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 640936e95c5..02b8c696601 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2563,14 +2563,17 @@
#include "code\modules\antagonists\_common\antag_spawner.dm"
#include "code\modules\antagonists\_common\antag_team.dm"
#include "code\modules\antagonists\abductor\abductor.dm"
+#include "code\modules\antagonists\abductor\abductor_structures.dm"
#include "code\modules\antagonists\abductor\ice_abductor.dm"
#include "code\modules\antagonists\abductor\abductee\abductee.dm"
#include "code\modules\antagonists\abductor\abductee\abductee_objectives.dm"
-#include "code\modules\antagonists\abductor\equipment\abduction_gear.dm"
#include "code\modules\antagonists\abductor\equipment\abduction_outfits.dm"
#include "code\modules\antagonists\abductor\equipment\abduction_surgery.dm"
#include "code\modules\antagonists\abductor\equipment\gland.dm"
#include "code\modules\antagonists\abductor\equipment\orderable_gear.dm"
+#include "code\modules\antagonists\abductor\equipment\gear\abductor_clothing.dm"
+#include "code\modules\antagonists\abductor\equipment\gear\abductor_items.dm"
+#include "code\modules\antagonists\abductor\equipment\gear\abductor_posters.dm"
#include "code\modules\antagonists\abductor\equipment\glands\access.dm"
#include "code\modules\antagonists\abductor\equipment\glands\blood.dm"
#include "code\modules\antagonists\abductor\equipment\glands\chem.dm"