diff --git a/code/game/objects/items/devices/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm
index 2614775906..41a12136ef 100644
--- a/code/game/objects/items/devices/dogborg_sleeper.dm
+++ b/code/game/objects/items/devices/dogborg_sleeper.dm
@@ -3,7 +3,7 @@
/obj/item/dogborg/sleeper
name = "hound sleeper"
desc = "nothing should see this."
- icon = 'icons/mob/dogborg.dmi'
+ icon = 'icons/mob/robot_items.dmi'
icon_state = "sleeper"
w_class = WEIGHT_CLASS_TINY
var/mob/living/carbon/patient
@@ -418,29 +418,15 @@
var/units = round(patient.reagents.get_reagent_amount(chem))
to_chat(hound, "Injecting [units] unit\s of [chem] into occupant.") //If they were immersed, the reagents wouldn't leave with them.
-/obj/item/dogborg/sleeper/medihound //Medihound sleeper
- name = "Mobile Sleeper"
- desc = "Equipment for medical hound. A mounted sleeper that stabilizes patients and can inject reagents in the borg's reserves."
- icon = 'icons/mob/dogborg.dmi'
- icon_state = "sleeper"
- breakout_time = 30 //Medical sleepers should be designed to be as easy as possible to get out of.
-
/obj/item/dogborg/sleeper/K9 //The K9 portabrig
name = "Mobile Brig"
desc = "Equipment for a K9 unit. A mounted portable-brig that holds criminals."
- icon = 'icons/mob/dogborg.dmi'
icon_state = "sleeperb"
inject_amount = 0
min_health = -100
injection_chems = null //So they don't have all the same chems as the medihound!
breakout_time = 300
-/obj/item/storage/attackby(obj/item/dogborg/sleeper/K9, mob/user, proximity)
- if(istype(K9))
- K9.afterattack(src, user ,1)
- else
- . = ..()
-
/obj/item/dogborg/sleeper/K9/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity)
var/mob/living/silicon/robot/hound = get_host()
if(!hound || !istype(target) || !proximity || target.anchored)
@@ -462,70 +448,6 @@
user.visible_message("[hound.name]'s mobile brig clunks in series as [target] slips inside.", "Your mobile brig groans lightly as [target] slips inside.")
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
-
-/obj/item/dogborg/sleeper/compactor //Janihound gut.
- name = "garbage processor"
- desc = "A mounted garbage compactor unit with fuel processor."
- icon = 'icons/mob/dogborg.dmi'
- icon_state = "compactor"
- inject_amount = 0
- min_health = -100
- injection_chems = null //So they don't have all the same chems as the medihound!
- var/max_item_count = 30
-
-/obj/item/storage/attackby(obj/item/dogborg/sleeper/compactor, mob/user, proximity) //GIT CIRCUMVENTED YO!
- if(istype(compactor))
- compactor.afterattack(src, user ,1)
- else
- . = ..()
-
-/obj/item/dogborg/sleeper/compactor/afterattack(atom/movable/target, mob/living/silicon/user, proximity)//GARBO NOMS
- var/mob/living/silicon/robot/hound = get_host()
- if(!hound || !istype(target) || !proximity || target.anchored)
- return
- if(length(contents) > (max_item_count - 1))
- to_chat(user,"Your [src] is full. Eject or process contents to continue.")
- return
- if(isitem(target))
- var/obj/item/I = target
- if(CheckAccepted(I))
- to_chat(user,"[I] registers an error code to your [src]")
- return
- if(I.w_class > WEIGHT_CLASS_NORMAL)
- to_chat(user,"[I] is too large to fit into your [src]")
- return
- user.visible_message("[hound.name] is ingesting [I] into their [src.name].", "You start ingesting [target] into your [src.name]...")
- if(do_after(user, 15, target = target) && length(contents) < max_item_count)
- I.forceMove(src)
- I.visible_message("[hound.name]'s garbage processor groans lightly as [I] slips inside.", "Your garbage compactor groans lightly as [I] slips inside.")
- playsound(hound, 'sound/machines/disposalflush.ogg', 50, 1)
- if(length(contents) > 11) //grow that tum after a certain junk amount
- hound.sleeper_r = 1
- hound.update_icons()
- else
- hound.sleeper_r = 0
- hound.update_icons()
- return
-
- if(iscarbon(target) || issilicon(target))
- var/mob/living/trashman = target
- if(!CHECK_BITFIELD(trashman.vore_flags,DEVOURABLE))
- to_chat(user, "[target] registers an error code to your [src]")
- return
- if(patient)
- to_chat(user,"Your [src] is already occupied.")
- return
- if(trashman.buckled)
- to_chat(user,"[trashman] is buckled and can not be put into your [src].")
- return
- user.visible_message("[hound.name] is ingesting [trashman] into their [src].", "You start ingesting [trashman] into your [src.name]...")
- if(do_after(user, 30, target = trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
- trashman.forceMove(src)
- trashman.reset_perspective(src)
- update_gut()
- user.visible_message("[hound.name]'s garbage processor groans lightly as [trashman] slips inside.", "Your garbage compactor groans lightly as [trashman] slips inside.")
- playsound(hound, 'sound/effects/bin_close.ogg', 80, 1)
-
/obj/item/dogborg/sleeper/K9/flavour
name = "Recreational Sleeper"
desc = "A mounted, underslung sleeper, intended for holding willing occupants for leisurely purposes."
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index abb2d12a1f..9700d8e6cd 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -902,4 +902,47 @@
name = "mining point card"
desc = "A robotic ID strip used for claiming and transferring mining points. Must be held in an active slot to transfer points."
access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
- icon_state = "data_1"
\ No newline at end of file
+ icon_state = "data_1"
+
+
+///Mere cosmetic dogborg items, remnants of what were once the most annoying cyborg modules.
+/obj/item/dogborg_tongue
+ name = "synthetic tongue"
+ desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
+ icon = 'icons/mob/robot_items.dmi'
+ icon_state = "synthtongue"
+ hitsound = 'sound/effects/attackblob.ogg'
+ desc = "For giving affectionate kisses."
+ item_flags = NOBLUDGEON
+
+/obj/item/dogborg_tongue/afterattack(atom/target, mob/user, proximity)
+ . = ..()
+ if(!proximity || !isliving(target))
+ return
+ var/mob/living/silicon/robot/R = user
+ var/mob/living/L = target
+ if(L.ckey && !(L.client?.prefs.vore_flags & LICKABLE))
+ to_chat(R, "ERROR ERROR: Target not lickable. Aborting display-of-affection subroutine.")
+ return
+
+ if(check_zone(R.zone_selected) == "head")
+ R.visible_message("\the [R] affectionally licks \the [L]'s face!", "You affectionally lick \the [L]'s face!")
+ playsound(R, 'sound/effects/attackblob.ogg', 50, 1)
+ else
+ R.visible_message("\the [R] affectionally licks \the [L]!", "You affectionally lick \the [L]!")
+ playsound(R, 'sound/effects/attackblob.ogg', 50, 1)
+
+/obj/item/dogborg_nose
+ name = "boop module"
+ desc = "The BOOP module"
+ icon = 'icons/mob/robot_items.dmi'
+ icon_state = "nose"
+ flags_1 = CONDUCT_1|NOBLUDGEON
+ force = 0
+
+/obj/item/dogborg_nose/afterattack(atom/target, mob/user, proximity)
+ . = ..()
+ if(!proximity)
+ return
+ do_attack_animation(target, null, src)
+ user.visible_message("[user] [pick("nuzzles", "pushes", "boops")] \the [target.name] with their nose!")
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 508dc67dd7..98a5f0f234 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -3,122 +3,7 @@
real_name = "Cyborg"
icon = 'icons/mob/robots.dmi'
icon_state = "robot"
- maxHealth = 100
- health = 100
bubble_icon = "robot"
- designation = "Default" //used for displaying the prefix & getting the current module of cyborg
- has_limbs = 1
- hud_type = /datum/hud/robot
-
- blocks_emissive = EMISSIVE_BLOCK_UNIQUE
-
- var/custom_name = ""
- var/braintype = "Cyborg"
- var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
- var/obj/item/mmi/mmi = null
-
- var/shell = FALSE
- var/deployed = FALSE
- var/mob/living/silicon/ai/mainframe = null
- var/datum/action/innate/undeployment/undeployment_action = new
-
-//Hud stuff
-
- var/obj/screen/inv1 = null
- var/obj/screen/inv2 = null
- var/obj/screen/inv3 = null
- var/obj/screen/lamp_button = null
- var/obj/screen/thruster_button = null
- var/obj/screen/hands = null
-
- var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
- var/obj/screen/robot_modules_background
-
-//3 Modules can be activated at any one time.
- var/obj/item/robot_module/module = null
- var/obj/item/module_active = null
- held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do!
-
- var/mutable_appearance/eye_lights
-
- var/mob/living/silicon/ai/connected_ai = null
- var/obj/item/stock_parts/cell/cell = null
-
- var/opened = 0
- var/emagged = FALSE
- var/emag_cooldown = 0
- var/wiresexposed = 0
-
- var/ident = 0
- var/locked = TRUE
- var/list/req_access = list(ACCESS_ROBOTICS)
-
- var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
-
- var/speed = 0 // VTEC speed boost.
- var/magpulse = FALSE // Magboot-like effect.
- var/ionpulse = FALSE // Jetpack-like effect.
- var/ionpulse_on = FALSE // Jetpack-like effect.
- var/datum/effect_system/trail_follow/ion/ion_trail // Ionpulse effect.
-
- var/low_power_mode = 0 //whether the robot has no charge left.
- var/datum/effect_system/spark_spread/spark_system // So they can initialize sparks whenever/N
-
- var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
- var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
- var/locked_down //Boolean of whether the borg is locked down or not
-
- var/toner = 0
- var/tonermax = 40
-
- var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting.
- var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power.
- light_color = "#FFCC66"
- light_power = 0.8
- var/lamp_cooldown = 0 //Flag for if the lamp is on cooldown after being forcibly disabled.
-
- var/sight_mode = 0
- hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD)
-
- var/list/upgrades = list()
-
- var/hasExpanded = FALSE
- var/obj/item/hat
- var/hat_offset = -3
- var/list/equippable_hats = list(/obj/item/clothing/head/caphat,
- /obj/item/clothing/head/hardhat,
- /obj/item/clothing/head/centhat,
- /obj/item/clothing/head/HoS,
- /obj/item/clothing/head/beret,
- /obj/item/clothing/head/kitty,
- /obj/item/clothing/head/hopcap,
- /obj/item/clothing/head/wizard,
- /obj/item/clothing/head/nursehat,
- /obj/item/clothing/head/sombrero,
- /obj/item/clothing/head/helmet/chaplain/witchunter_hat,
- /obj/item/clothing/head/soft/, //All baseball caps
- /obj/item/clothing/head/that, //top hat
- /obj/item/clothing/head/collectable/tophat, //Not sure where this one is found, but it looks the same so might as well include
- /obj/item/clothing/mask/bandana/, //All bandanas (which only work in hat mode)
- /obj/item/clothing/head/fedora,
- /obj/item/clothing/head/beanie/, //All beanies
- /obj/item/clothing/ears/headphones,
- /obj/item/clothing/head/helmet/skull,
- /obj/item/clothing/head/crown/fancy)
-
- can_buckle = TRUE
- buckle_lying = FALSE
- var/static/list/can_ride_typecache = typecacheof(/mob/living/carbon/human)
-
- var/sitting = 0
- var/bellyup = 0
- var/dogborg = FALSE
-
- var/cansprint = 1
-
- var/orebox = null
-
-/mob/living/silicon/robot
/mob/living/silicon/robot/get_cell()
return cell
diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm
new file mode 100644
index 0000000000..860d531608
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/robot_defines.dm
@@ -0,0 +1,123 @@
+
+/mob/living/silicon/robot
+ designation = "Default" //used for displaying the prefix & getting the current module of cyborg
+ has_limbs = TRUE
+ hud_type = /datum/hud/robot
+
+ blocks_emissive = EMISSIVE_BLOCK_UNIQUE
+
+ maxHealth = 100
+ health = 100
+
+ var/custom_name = ""
+ var/braintype = "Cyborg"
+ var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
+ var/obj/item/mmi/mmi = null
+
+ var/shell = FALSE
+ var/deployed = FALSE
+ var/mob/living/silicon/ai/mainframe = null
+ var/datum/action/innate/undeployment/undeployment_action = new
+
+//Hud stuff
+
+ var/obj/screen/inv1 = null
+ var/obj/screen/inv2 = null
+ var/obj/screen/inv3 = null
+ var/obj/screen/lamp_button = null
+ var/obj/screen/thruster_button = null
+ var/obj/screen/hands = null
+
+ var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
+ var/obj/screen/robot_modules_background
+
+//3 Modules can be activated at any one time.
+ var/obj/item/robot_module/module = null
+ var/obj/item/module_active = null
+ held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do!
+
+ var/mutable_appearance/eye_lights
+
+ var/mob/living/silicon/ai/connected_ai = null
+ var/obj/item/stock_parts/cell/cell = null
+
+ var/opened = 0
+ var/emagged = FALSE
+ var/emag_cooldown = 0
+ var/wiresexposed = 0
+
+ var/ident = 0
+ var/locked = TRUE
+ var/list/req_access = list(ACCESS_ROBOTICS)
+
+ var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
+
+ var/speed = 0 // VTEC speed boost.
+ var/magpulse = FALSE // Magboot-like effect.
+ var/ionpulse = FALSE // Jetpack-like effect.
+ var/ionpulse_on = FALSE // Jetpack-like effect.
+ var/datum/effect_system/trail_follow/ion/ion_trail // Ionpulse effect.
+
+ var/low_power_mode = 0 //whether the robot has no charge left.
+ var/datum/effect_system/spark_spread/spark_system // So they can initialize sparks whenever/N
+
+ var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
+ var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
+ var/locked_down //Boolean of whether the borg is locked down or not
+
+ var/toner = 0
+ var/tonermax = 40
+
+ var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting.
+ var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power.
+ light_color = "#FFCC66"
+ light_power = 0.8
+ var/lamp_cooldown = 0 //Flag for if the lamp is on cooldown after being forcibly disabled.
+
+ var/sight_mode = 0
+ hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD)
+
+ var/list/upgrades = list()
+
+ var/hasExpanded = FALSE
+ var/obj/item/hat
+ var/hat_offset = -3
+ var/list/equippable_hats = list(/obj/item/clothing/head/caphat,
+ /obj/item/clothing/head/hardhat,
+ /obj/item/clothing/head/centhat,
+ /obj/item/clothing/head/HoS,
+ /obj/item/clothing/head/beret,
+ /obj/item/clothing/head/kitty,
+ /obj/item/clothing/head/hopcap,
+ /obj/item/clothing/head/wizard,
+ /obj/item/clothing/head/nursehat,
+ /obj/item/clothing/head/sombrero,
+ /obj/item/clothing/head/helmet/chaplain/witchunter_hat,
+ /obj/item/clothing/head/soft/, //All baseball caps
+ /obj/item/clothing/head/that, //top hat
+ /obj/item/clothing/head/collectable/tophat, //Not sure where this one is found, but it looks the same so might as well include
+ /obj/item/clothing/mask/bandana/, //All bandanas (which only work in hat mode)
+ /obj/item/clothing/head/fedora,
+ /obj/item/clothing/head/beanie/, //All beanies
+ /obj/item/clothing/ears/headphones,
+ /obj/item/clothing/head/helmet/skull,
+ /obj/item/clothing/head/crown/fancy)
+
+ can_buckle = TRUE
+ buckle_lying = FALSE
+ var/static/list/can_ride_typecache = typecacheof(/mob/living/carbon/human)
+
+ var/sitting = 0
+ var/bellyup = 0
+ var/dogborg = FALSE
+
+ var/cansprint = 1
+
+ var/orebox = null
+
+ //doggie borg stuff.
+ var/disabler
+ var/laser
+ var/sleeper_g
+ var/sleeper_r
+ var/sleeper_nv
\ No newline at end of file
diff --git a/icons/mob/dogborg.dmi b/icons/mob/dogborg.dmi
deleted file mode 100644
index 856724be1f..0000000000
Binary files a/icons/mob/dogborg.dmi and /dev/null differ
diff --git a/icons/mob/robot_items.dmi b/icons/mob/robot_items.dmi
index 862e1be384..06521f1a84 100644
Binary files a/icons/mob/robot_items.dmi and b/icons/mob/robot_items.dmi differ
diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm
deleted file mode 100644
index f59d18686a..0000000000
--- a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
-DOG BORG EQUIPMENT HERE
-SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
-*/
-
-/obj/item/dogborg/jaws
- name = "Dogborg jaws"
- desc = "The jaws of the debug errors oh god."
- icon = 'icons/mob/dogborg.dmi'
- flags_1 = CONDUCT_1
- force = 1
- throwforce = 0
- w_class = 3
- hitsound = 'sound/weapons/bite.ogg'
- sharpness = IS_SHARP
- var/stamtostunconversion = 0.1 //Total stamloss gets multiplied by this value for the help intent hard stun. Resting adds an additional 2x multiplier on top. Keep this low or so help me god.
- var/stuncooldown = 4 SECONDS //How long it takes before you're able to attempt to stun a target again
- var/nextstuntime
-
-/obj/item/dogborg/jaws/examine(mob/user)
- . = ..()
- if(!CONFIG_GET(flag/weaken_secborg))
- . += "Use help intent to attempt to non-lethally incapacitate the target by latching on with your maw. This is more effective against exhausted and resting targets."
-
-/obj/item/dogborg/jaws/big
- name = "combat jaws"
- desc = "The jaws of the law. Very sharp."
- icon_state = "jaws"
- force = 15 //Chomp chomp. Crew harm.
- attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
- stamtostunconversion = 0.2 // 100*0.2*2=40. Stun's just long enough to slap on cuffs with click delay if the target is near hard stamcrit.
- stuncooldown = 6 SECONDS
-
-
-/obj/item/dogborg/jaws/small
- name = "puppy jaws"
- desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however."
- icon_state = "smalljaws"
- force = 6
- attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
- var/status = 0
-
-/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
- if(!istype(user))
- return
- if(!CONFIG_GET(flag/weaken_secborg) && user.a_intent != INTENT_HARM && istype(A, /mob/living))
- if(A == user.pulling)
- to_chat(user, "You already have [A] in your jaws.")
- return
- if(nextstuntime >= world.time)
- to_chat(user, "Your jaw servos are still recharging.")
- return
- nextstuntime = world.time + stuncooldown
- var/mob/living/M = A
- var/cachedstam = M.getStaminaLoss()
- var/totalstuntime = cachedstam * stamtostunconversion * (M.lying ? 2 : 1)
- if(CHECK_MOBILITY(M, MOBILITY_STAND))
- M.DefaultCombatKnockdown(cachedstam*2) //BORK BORK. GET DOWN.
- M.Stun(totalstuntime)
- user.do_attack_animation(A, ATTACK_EFFECT_BITE)
- user.start_pulling(M, TRUE) //Yip yip. Come with.
- user.changeNext_move(CLICK_CD_MELEE)
- M.visible_message("[user] clamps [user.p_their()] [src] onto [M] and latches on!", "[user] clamps [user.p_their()] [src] onto you and latches on!")
- if(totalstuntime >= 4 SECONDS)
- playsound(usr, 'sound/effects/k9_jaw_strong.ogg', 75, FALSE, 2) //Wuff wuff. Big stun.
- else
- playsound(usr, 'sound/effects/k9_jaw_weak.ogg', 50, TRUE, -1) //Arf arf. Pls buff.
- else
- . = ..()
- user.do_attack_animation(A, ATTACK_EFFECT_BITE)
-
-/obj/item/dogborg/jaws/small/attack_self(mob/user)
- var/mob/living/silicon/robot/R = user
- if(R.cell && R.cell.charge > 100)
- if(R.emagged && status == 0)
- name = "combat jaws"
- icon_state = "jaws"
- desc = "The jaws of the law."
- force = 12
- attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
- stamtostunconversion = 0.15
- stuncooldown = 5 SECONDS
- status = 1
- to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"].")
- else
- name = "puppy jaws"
- icon_state = "smalljaws"
- desc = "The jaws of a small dog."
- force = initial(force)
- attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
- stamtostunconversion = initial(stamtostunconversion)
- stuncooldown = initial(stuncooldown)
- status = 0
- if(R.emagged)
- to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"].")
- update_icon()
-
-//Boop
-
-/obj/item/analyzer/nose
- name = "boop module"
- icon = 'icons/mob/dogborg.dmi'
- icon_state = "nose"
- desc = "The BOOP module"
- flags_1 = CONDUCT_1
- force = 0
- throwforce = 0
- attack_verb = list("nuzzles", "pushes", "boops")
- w_class = 1
-
-/obj/item/analyzer/nose/attack_self(mob/user)
- user.visible_message("[user] sniffs around the air.", "You sniff the air for gas traces.")
-
- var/turf/location = user.loc
- if(!istype(location))
- return
-
- var/datum/gas_mixture/environment = location.return_air()
-
- var/pressure = environment.return_pressure()
- var/total_moles = environment.total_moles()
-
- to_chat(user, "Results:")
- if(abs(pressure - ONE_ATMOSPHERE) < 10)
- to_chat(user, "Pressure: [round(pressure,0.1)] kPa")
- else
- to_chat(user, "Pressure: [round(pressure,0.1)] kPa")
- if(total_moles)
- var/list/env_gases = environment.gases
-
- var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles
- var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles
- var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles
- var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles
- GAS_GARBAGE_COLLECT(environment.gases)
-
- if(abs(n2_concentration - N2STANDARD) < 20)
- to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %")
- else
- to_chat(user, "Nitrogen: [round(n2_concentration*100, 0.01)] %")
-
- if(abs(o2_concentration - O2STANDARD) < 2)
- to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %")
- else
- to_chat(user, "Oxygen: [round(o2_concentration*100, 0.01)] %")
-
- if(co2_concentration > 0.01)
- to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %")
- else
- to_chat(user, "CO2: [round(co2_concentration*100, 0.01)] %")
-
- if(plasma_concentration > 0.005)
- to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %")
- else
- to_chat(user, "Plasma: [round(plasma_concentration*100, 0.01)] %")
-
-
- for(var/id in env_gases)
- if(id in GLOB.hardcoded_gases)
- continue
- var/gas_concentration = env_gases[id]/total_moles
- to_chat(user, "[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] %")
- to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C")
-
-/obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity)
- . = ..()
- if(!proximity)
- return
- do_attack_animation(target, null, src)
- user.visible_message("[user] [pick(attack_verb)] \the [target.name] with their nose!")
-
-//Delivery
-/obj/item/storage/bag/borgdelivery
- name = "fetching storage"
- desc = "Fetch the thing!"
- icon = 'icons/mob/dogborg.dmi'
- icon_state = "dbag"
- w_class = WEIGHT_CLASS_BULKY
-
-/obj/item/storage/bag/borgdelivery/ComponentInitialize()
- . = ..()
- var/datum/component/storage/STR = GetComponent(/datum/component/storage)
- STR.max_w_class = WEIGHT_CLASS_BULKY
- STR.max_combined_w_class = 5
- STR.max_items = 1
- STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom))
-
-//Tongue stuff
-/obj/item/soap/tongue
- name = "synthetic tongue"
- desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
- icon = 'icons/mob/dogborg.dmi'
- icon_state = "synthtongue"
- hitsound = 'sound/effects/attackblob.ogg'
- cleanspeed = 80
- var/status = 0
-
-/obj/item/soap/tongue/scrubpup
- cleanspeed = 25 //slightly faster than a mop.
-
-/obj/item/soap/tongue/New()
- ..()
- item_flags |= NOBLUDGEON //No more attack messages
-
-/obj/item/soap/tongue/attack_self(mob/user)
- var/mob/living/silicon/robot/R = user
- if(R.cell && R.cell.charge > 100)
- if(R.emagged && status == 0)
- status = !status
- name = "energized tongue"
- desc = "Your tongue is energized for dangerously maximum efficency."
- icon_state = "syndietongue"
- to_chat(user, "Your tongue is now [status ? "Energized" : "Normal"].")
- cleanspeed = 10 //(nerf'd)tator soap stat
- else
- status = 0
- name = "synthetic tongue"
- desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
- icon_state = "synthtongue"
- cleanspeed = initial(cleanspeed)
- if(R.emagged)
- to_chat(user, "Your tongue is now [status ? "Energized" : "Normal"].")
- update_icon()
-
-/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
- var/mob/living/silicon/robot/R = user
- if(!proximity || !check_allowed_items(target))
- return
- if(R.client && (target in R.client.screen))
- to_chat(R, "You need to take that [target.name] off before cleaning it!")
- else if(is_cleanable(target))
- R.visible_message("[R] begins to lick off \the [target.name].", "You begin to lick off \the [target.name]...")
- if(do_after(R, src.cleanspeed, target = target))
- if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
- return //If they moved away, you can't eat them.
- to_chat(R, "You finish licking off \the [target.name].")
- qdel(target)
- R.cell.give(50)
- else if(isobj(target)) //hoo boy. danger zone man
- if(istype(target,/obj/item/trash))
- R.visible_message("[R] nibbles away at \the [target.name].", "You begin to nibble away at \the [target.name]...")
- if(!do_after(R, src.cleanspeed, target = target))
- return //If they moved away, you can't eat them.
- to_chat(R, "You finish off \the [target.name].")
- qdel(target)
- R.cell.give(250)
- return
- if(istype(target,/obj/item/stock_parts/cell))
- R.visible_message("[R] begins cramming \the [target.name] down its throat.", "You begin cramming \the [target.name] down your throat...")
- if(!do_after(R, 50, target = target))
- return //If they moved away, you can't eat them.
- to_chat(R, "You finish off \the [target.name].")
- var/obj/item/stock_parts/cell/C = target
- R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf
- qdel(target)
- return
- var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT
- if(!I.anchored && R.emagged)
- R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "You begin chewing up \the [target.name]...")
- if(!do_after(R, 100, target = I)) //Nerf dat time yo
- return //If they moved away, you can't eat them.
- visible_message("[R] chews up \the [target.name] and cleans off the debris!")
- to_chat(R, "You finish off \the [target.name].")
- qdel(I)
- R.cell.give(500)
- return
- R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...")
- else if(isliving(target))
- var/mob/living/L = target
- if(!status)
- if(L.ckey && !(L.client?.prefs.vore_flags & LICKABLE))
- to_chat(R, "ERROR ERROR: Target not lickable. Aborting display-of-affection subroutine.")
- return
- if(check_zone(R.zone_selected) == "head")
- R.visible_message("\the [R] affectionally licks \the [L]'s face!", "You affectionally lick \the [L]'s face!")
- playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
- if(istype(L) && L.fire_stacks > 0)
- L.adjust_fire_stacks(-10)
- else
- R.visible_message("\the [R] affectionally licks \the [L]!", "You affectionally lick \the [L]!")
- playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
- if(istype(L) && L.fire_stacks > 0)
- L.adjust_fire_stacks(-10)
- else
- if(R.cell.charge <= 800)
- to_chat(R, "Insufficent Power!")
- return
- L.Stun(4) // normal stunbaton is force 7 gimme a break good sir!
- L.DefaultCombatKnockdown(80)
- L.apply_effect(EFFECT_STUTTER, 4)
- L.visible_message("[R] has shocked [L] with its tongue!", \
- "[R] has shocked you with its tongue!")
- playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
- R.cell.use(666)
- log_combat(R, L, "tongue stunned")
-
- else if(istype(target, /obj/structure/window))
- R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...")
- if(do_after(user, src.cleanspeed, target = target))
- to_chat(user, "You clean \the [target.name].")
- target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- target.set_opacity(initial(target.opacity))
- else
- R.visible_message("[R] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...")
- if(do_after(user, src.cleanspeed, target = target))
- to_chat(user, "You clean \the [target.name].")
- var/obj/effect/decal/cleanable/C = locate() in target
- qdel(C)
- target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
- target.wash_cream()
- return
-
-//Nerfed tongue for flavour reasons (haha geddit?). Used for aux skins for regular borgs
-/obj/item/dogborg_tongue
- name = "synthetic tongue"
- desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
- icon = 'icons/mob/dogborg.dmi'
- icon_state = "synthtongue"
- hitsound = 'sound/effects/attackblob.ogg'
- desc = "For giving affectionate kisses."
- item_flags = NOBLUDGEON
-
-/obj/item/dogborg_tongue/afterattack(atom/target, mob/user, proximity)
- . = ..()
- if(!proximity || !isliving(target))
- return
- var/mob/living/silicon/robot/R = user
- var/mob/living/L = target
- if(L.ckey && !(L.client?.prefs.vore_flags & LICKABLE))
- to_chat(R, "ERROR ERROR: Target not lickable. Aborting display-of-affection subroutine.")
- return
-
- if(check_zone(R.zone_selected) == "head")
- R.visible_message("\the [R] affectionally licks \the [L]'s face!", "You affectionally lick \the [L]'s face!")
- playsound(R, 'sound/effects/attackblob.ogg', 50, 1)
- else
- R.visible_message("\the [R] affectionally licks \the [L]!", "You affectionally lick \the [L]!")
- playsound(R, 'sound/effects/attackblob.ogg', 50, 1)
-
-
-/obj/item/dogborg_nose
- name = "boop module"
- icon = 'icons/mob/dogborg.dmi'
- icon_state = "nose"
- desc = "The BOOP module"
- flags_1 = CONDUCT_1|NOBLUDGEON
- force = 0
-
-/obj/item/dogborg_nose/afterattack(atom/target, mob/user, proximity)
- . = ..()
- if(!proximity)
- return
- do_attack_animation(target, null, src)
- user.visible_message("[user] [pick(attack_verb)] \the [target.name] with their nose!")
-
-
-//Dogfood
-
-/obj/item/trash/rkibble
- name = "robo kibble"
- desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge."
- icon = 'icons/mob/dogborg.dmi'
- icon_state= "kibble"
-
-// Pounce stuff for K-9
-
-/obj/item/dogborg/pounce
- name = "pounce"
- icon = 'icons/mob/dogborg.dmi'
- icon_state = "pounce"
- desc = "Leap at your target to momentarily stun them."
- force = 0
- throwforce = 0
-
-/obj/item/dogborg/pounce/New()
- ..()
- item_flags |= NOBLUDGEON
-
-/mob/living/silicon/robot
- var/leaping = 0
- var/pounce_cooldown = 0
- var/pounce_cooldown_time = 30 //Time in deciseconds between pounces
- var/pounce_spoolup = 5 //Time in deciseconds for the pounce to happen after clicking
- var/pounce_stamloss_cap = 120 //How much staminaloss pounces alone are capable of bringing a spaceman to
- var/pounce_stamloss = 80 //Base staminaloss value of the pounce
- var/leap_at
- var/disabler
- var/laser
- var/sleeper_g
- var/sleeper_r
- var/sleeper_nv
-
-#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance.
-
-/obj/item/dogborg/pounce/afterattack(atom/A, mob/user)
- var/mob/living/silicon/robot/R = user
- if(R && (world.time >= R.pounce_cooldown))
- R.pounce_cooldown = world.time + R.pounce_cooldown_time
- to_chat(R, "Your targeting systems lock on to [A]...")
- playsound(R, 'sound/effects/servostep.ogg', 100, TRUE)
- addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup)
- else if(R && (world.time < R.pounce_cooldown))
- to_chat(R, "Your leg actuators are still recharging!")
-
-/mob/living/silicon/robot/proc/leap_at(atom/A)
- if(leaping || stat || buckled || lying)
- return
-
- if(!has_gravity(src) || !has_gravity(A))
- to_chat(src,"It is unsafe to leap without gravity!")
- //It's also extremely buggy visually, so it's balance+bugfix
- return
-
- if(cell.charge <= 750)
- to_chat(src,"Insufficent reserves for jump actuators!")
- return
-
- else
- leaping = 1
- weather_immunities += "lava"
- pixel_y = 10
- update_icons()
- throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1)
- cell.use(750) //Less than a stunbaton since stunbatons hit everytime.
- playsound(src, 'sound/effects/stealthoff.ogg', 25, TRUE, -1)
- weather_immunities -= "lava"
-
-/mob/living/silicon/robot/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
-
- if(!leaping)
- return ..()
-
- if(hit_atom)
- if(isliving(hit_atom))
- var/mob/living/L = hit_atom
- if(L.run_block(0, "the [name]", src, ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
- DefaultCombatKnockdown(15, 1, 1)
- else
- L.visible_message("[src] pounces on [L]!", "[src] pounces on you!")
- L.DefaultCombatKnockdown(iscarbon(L) ? 60 : 45, override_stamdmg = clamp(pounce_stamloss, 0, pounce_stamloss_cap-L.getStaminaLoss())) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
- playsound(src, 'sound/weapons/Egloves.ogg', 50, 1)
- sleep(2)//Runtime prevention (infinite bump() calls on hulks)
- step_towards(src,L)
- log_combat(src, L, "borg pounced")
-
- pounce_cooldown = !pounce_cooldown
- spawn(pounce_cooldown_time) //3s by default
- pounce_cooldown = !pounce_cooldown
- else if(hit_atom.density && !hit_atom.CanPass(src))
- visible_message("[src] smashes into [hit_atom]!", "You smash into [hit_atom]!")
- playsound(src, 'sound/items/trayhit1.ogg', 50, 1)
- DefaultCombatKnockdown(15, 1, 1)
-
- if(leaping)
- leaping = 0
- pixel_y = initial(pixel_y)
- update_icons()
- update_mobility()
diff --git a/tgstation.dme b/tgstation.dme
index bb27ca021c..d115bac2d1 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2432,6 +2432,7 @@
#include "code\modules\mob\living\silicon\robot\login.dm"
#include "code\modules\mob\living\silicon\robot\robot.dm"
#include "code\modules\mob\living\silicon\robot\robot_defense.dm"
+#include "code\modules\mob\living\silicon\robot\robot_defines.dm"
#include "code\modules\mob\living\silicon\robot\robot_mobility.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
@@ -3360,7 +3361,6 @@
#include "modular_citadel\code\modules\mob\living\carbon\reindex_screams.dm"
#include "modular_citadel\code\modules\mob\living\carbon\human\human.dm"
#include "modular_citadel\code\modules\mob\living\carbon\human\human_defense.dm"
-#include "modular_citadel\code\modules\mob\living\silicon\robot\dogborg_equipment.dm"
#include "modular_citadel\code\modules\projectiles\gun.dm"
#include "modular_citadel\code\modules\projectiles\ammunition\caseless.dm"
#include "modular_citadel\code\modules\projectiles\ammunition\ballistic\smg\smg.dm"