From e0b91c53af6d42435e2b1eb5bb2c36686ba1d322 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sun, 10 May 2020 22:17:05 +0200 Subject: [PATCH] Purging unused dogborg items. --- .../objects/items/devices/dogborg_sleeper.dm | 80 +-- code/game/objects/items/robot/robot_items.dm | 45 +- .../modules/mob/living/silicon/robot/robot.dm | 115 ----- .../mob/living/silicon/robot/robot_defines.dm | 123 +++++ icons/mob/dogborg.dmi | Bin 16259 -> 0 bytes icons/mob/robot_items.dmi | Bin 1640 -> 10729 bytes .../living/silicon/robot/dogborg_equipment.dm | 459 ------------------ tgstation.dme | 2 +- 8 files changed, 169 insertions(+), 655 deletions(-) create mode 100644 code/modules/mob/living/silicon/robot/robot_defines.dm delete mode 100644 icons/mob/dogborg.dmi delete mode 100644 modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm 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 856724be1f74cca58a019cdf0b5547191c7e0228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16259 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

#$ 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 diff --git a/icons/mob/robot_items.dmi b/icons/mob/robot_items.dmi index 862e1be3843b34d4adf511bc3573996c56396461..06521f1a8483791c08e52365ad08a80d941f9012 100644 GIT binary patch literal 10729 zcmZ{KRa6~OknKf+1}^Tw2@b&t!QCx51b270;O;KLfRJan^@KP+bZ z<7&_Ir2(gq58lp)uiwHZyNPCTQ<1bQ|Gm=lsKY>*`eCH}fhoEFbtt#rlsWX3 zUI=xASTBt^f1RU{4@V~7-@Iel5Y1$K5V0CN69*Fl8LdF)g|y&qKfN8Nw)*yS{KI4f zw@SH2*VV2|DCjwtP6{>Rx+%K-cIrG!+IWYb|`@*rsZo_e+?#Oa}{}vt{ABWjEn955? zNcebY_c8HxcjO!m5dkYkU9mf!L-<%?Jy~62sMSiD(56U9=%gFmQXrK^Iy!fWxp((pWYy5Srb}?kP z*!LC6ERTtvow>tZ_f)LMVS+c@?9DR@?_&h6WRHNSnlsi+!8}s)>*_1YFX60ZUyg+R z!L5I<@}+AZ_-+HGdtLyx#ZK0nLwFmy zV+AqL4IAwjKoO*^i*kR);%z{2u}jUcv7YKXS-pW6lAy+*qk*gKA%s`@NqgSRVlL-M zY{d#H_*+B$?SlHcbfwdgmriTY%ZO;?Q93*_p-unuSL#5K4-n7M3}=O}xGbjg#}MMr z2V{d|fl#nJJGyq~E%qdR%F2dsthAL~x*=PZ->w~u_08URKsx!WV+35`w2N=_yO6tm z`-%---zZW+uMO+yiHRzbI$i|ARCKLmNA~Wg0YI39#7%Bxu`rp>QhkJhQYlT0r<7yf z>v1n(_nN2pVeXR%-0^A#m;4_$dRuUHgujC8ZWG#kYNej|7dcLs$e0aa2zWn=hKL!J-Y*(8Z!+YyT;gXe^xti~StA#0!v=MUyaU9ay-A*SM zN(_dR*HZ3tK&RASt`g!6YCc`Tt7*scgt6q&(T~? zOEKm*H>cTc_g}7goL}zz`5`VR6w#lUyYyn31zpSyuMiS;bY$*)&MR�Z-HrUcnp& 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 iZ1lCYmX?;*Z|fK3tKBr5EYckS0000You 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"