diff --git a/code/citadel/dogborgstuff.dm b/code/citadel/dogborgstuff.dm index 173232c748..e7aeb87791 100644 --- a/code/citadel/dogborgstuff.dm +++ b/code/citadel/dogborgstuff.dm @@ -175,6 +175,10 @@ cleanspeed = 80 var/emagged = 0 +/obj/item/weapon/soap/tongue/New() + ..() + flags |= NOBLUDGEON //No more attack messages + /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." @@ -301,145 +305,179 @@ //Sleeper -/obj/item/weapon/dogborg/sleeper - name = "mounted sleeper" +/obj/item/device/dogborg/sleeper + name = "Medbelly" 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" + w_class = WEIGHT_CLASS_TINY var/mob/living/carbon/patient = null - var/mob/living/silicon/hound = null + var/mob/living/silicon/robot/hound = null var/inject_amount = 10 var/min_health = -100 - var/occupied = 0 - var/list/injection_chems = list("morphine", "salbutamol", "bicaridine", "kelotane","antitoxin") + var/cleaning = 0 + var/patient_laststat = null + var/mob_energy = 30000 //Energy gained from digesting mobs (including PCs) + var/list/injection_chems = list("epinephrine", "morphine", "salbutamol", "bicaridine", "kelotane"), + var/eject_port = "ingestion" + var/list/items_preserved = list() + var/list/important_items = list( + /obj/item/weapon/hand_tele, + /obj/item/weapon/card/id/captains_spare, + /obj/item/device/aicard, + /obj/item/device/paicard, + /obj/item/weapon/gun, + /obj/item/weapon/pinpointer, + /obj/item/clothing/shoes/magboots, + /obj/item/clothing/head/helmet/space, + /obj/item/weapon/disk/nuclear) -/obj/item/weapon/dogborg/sleeper/Exit(atom/movable/O) +/obj/item/device/dogborg/sleeper/New() + ..() + flags |= NOBLUDGEON //No more attack messages + +/obj/item/device/dogborg/sleeper/Exit(atom/movable/O) return 0 -/obj/item/weapon/dogborg/sleeper/attack(mob/M, mob/living/silicon/robot/user) - ..() - user.do_attack_animation(M, ATTACK_EFFECT_BITE) - -/obj/item/weapon/dogborg/sleeper/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity) +/obj/item/device/dogborg/sleeper/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity) + hound = loc if(!proximity) return if(!ishuman(target)) return - if(!patient_insertion_check(target)) - return - user.visible_message("[user] starts putting [target] into \the [src].", "You start putting [target] into [src]...") - if(do_after(user, 50, target = target)) - if(!patient_insertion_check(target)) - return - target.forceMove(src) - playsound(user.loc, 'sound/vore/gulpold.ogg', 50, 1) - patient = target - hound = user - target.reset_perspective(src) - user << "[target] successfully loaded into [src]. Life support functions engaged." - user.visible_message("[user] loads [target] into [src].") - user.visible_message("[target] loaded. Life support functions engaged.") - src.occupied = 1 - var/mob/living/silicon/robot.R = user - if(patient.stat < 2) - R.sleeper_r = 0 - R.sleeper_g = 1 - R.update_icons() - else - R.sleeper_g = 0 - R.sleeper_r = 1 - R.update_icons() - SSobj.processing |= src - -/obj/item/weapon/dogborg/sleeper/proc/patient_insertion_check(mob/living/carbon/target, mob/user) - if(target.anchored) - user << "[target] will not fit into the sleeper because they are buckled to [target.buckled]!" + if(target.buckled) + user << "The user is buckled and can not be put into your [src.name]." return if(patient) - user << "The sleeper is already occupied!" + user << "Your [src.name] is already occupied." return - return 1 + user.visible_message("[hound.name] is ingesting [target.name] into their [src.name].", "You start ingesting [target] into your [src]...") + if(!patient && ishuman(target) && !target.buckled && do_after (user, 50, target)) -/obj/item/weapon/dogborg/sleeper/proc/go_out() - if(src.occupied == 0) - return - var/mob/living/silicon/robot.R = hound - hound << "[patient] ejected. Life support functions disabled." - R.sleeper_r = 0 - R.sleeper_g = 0 - R.update_icons() - patient.forceMove(get_turf(src)) - patient.reset_perspective() - patient = null - src.occupied = 0 - src.occupied = 0 //double check just in case + if(!proximity) return //If they moved away, you can't eat them. -/obj/item/weapon/dogborg/sleeper/proc/drain() - var/mob/living/silicon/robot.R = hound - R.cell.charge = R.cell.charge - 10 + if(patient) return //If you try to eat two people at once, you can only eat one. -/obj/item/weapon/dogborg/sleeper/attack_self(mob/user) + else //If you don't have someone in you, proceed. + target.forceMove(src) + target.reset_perspective(src) + update_patient() + START_PROCESSING(SSobj, src) + user.visible_message("[hound.name]'s medical pod lights up as [target.name] slips inside into their [src.name].", "Your medical pod lights up as [target] slips into your [src]. Life support functions engaged.") + message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "JMP" : "null"])") + playsound(hound, 'sound/vore/gulpold.ogg', 100, 1) + +/obj/item/device/dogborg/sleeper/proc/go_out(var/target) + hound = src.loc + if(length(contents) > 0) + hound.visible_message("[hound.name] empties out their contents via their [eject_port] port.", "You empty your contents via your [eject_port] port.") + if(target) + if(ishuman(target)) + var/mob/living/carbon/human/person = target + person.forceMove(get_turf(src)) + person.reset_perspective() + else + var/obj/T = target + T.loc = hound.loc + else + for(var/C in contents) + if(ishuman(C)) + var/mob/living/carbon/human/person = C + person.forceMove(get_turf(src)) + person.reset_perspective() + else + var/obj/T = C + T.loc = hound.loc + items_preserved.Cut() + cleaning = 0 + playsound(loc, 'sound/effects/splat.ogg', 50, 1) + update_patient() + else //You clicked eject with nothing in you, let's just reset stuff to be sure. + items_preserved.Cut() + cleaning = 0 + update_patient() + +/obj/item/device/dogborg/sleeper/proc/drain(var/amt = 3) //Slightly reduced cost (before, it was always injecting inaprov) + hound.cell.charge = hound.cell.charge - amt + +/obj/item/device/dogborg/sleeper/attack_self(mob/user) if(..()) return sleeperUI(user) -/obj/item/weapon/dogborg/sleeper/proc/sleeperUI(mob/user) +/obj/item/device/dogborg/sleeper/proc/sleeperUI(mob/user) var/dat dat += "

Injector

" - if(patient) + + if(patient && !(patient.stat & DEAD)) dat += "Inject Epinephrine" else dat += "Inject Epinephrine" if(patient && patient.health > min_health) - for(var/chem in injection_chems) - var/datum/reagent/C = GLOB.chemical_reagents_list[chem] + for(var/re in injection_chems) + var/datum/reagent/C = injection_chems[re] if(C) dat += "
Inject [C.name]" else - for(var/chem in injection_chems) - var/datum/reagent/C = GLOB.chemical_reagents_list[chem] + for(var/re in injection_chems) + var/datum/reagent/C = injection_chems[re] if(C) dat += "
Inject [C.name]" dat += "

Sleeper Status

" - dat += "Scan" - dat += "Eject" + dat += "Refresh" + dat += "Eject All" + dat += "Eject port: [eject_port]" + if(!cleaning) + dat += "Self-Clean" + else + dat += "Self-Clean" + dat += "
" + + //Cleaning and there are still un-preserved items + if(cleaning && length(contents - items_preserved)) + dat += "Self-cleaning mode. [length(contents - items_preserved)] object(s) remaining.
" + + //There are no items to be processed other than un-preserved items + else if(cleaning && length(items_preserved)) + dat += "Self-cleaning done. Eject remaining objects now.
" + + //Preserved items count when the list is populated + if(length(items_preserved)) + dat += "[length(items_preserved)] uncleanable object(s).
" + if(!patient) dat += "Sleeper Unoccupied" else dat += "[patient.name] => " - switch(patient.stat) //obvious, see what their status is + + switch(patient.stat) if(0) dat += "Conscious" - var/mob/living/silicon/robot.R = user - R.sleeper_r = 0 - R.sleeper_g = 1 - R.update_icons() if(1) dat += "Unconscious" - var/mob/living/silicon/robot.R = user - R.sleeper_r = 0 - R.sleeper_g = 1 - R.update_icons() else dat += "DEAD" - var/mob/living/silicon/robot.R = user - R.sleeper_g = 0 - R.sleeper_r = 1 - R.update_icons() - dat += "
" - dat += "
Health:
[patient.stat > 1 ? "" : "[patient.health]%"]
" - dat += "
\> Brute Damage:
[patient.getBruteLoss()]%
" - dat += "
\> Resp. Damage:
[patient.getOxyLoss()]%
" - dat += "
\> Toxin Content:
[patient.getToxLoss()]%
" - dat += "
\> Burn Severity:
[patient.getFireLoss()]%

" - dat += "
Paralysis Summary:
[round(patient.paralysis)]% [patient.paralysis ? "([round(patient.paralysis / 4)] seconds left)" : ""]

" - if(patient.getCloneLoss()) - dat += "
Subject appears to have cellular damage.

" + var/healthcolor = (patient.health > 0 ? "color:white;" : "color:red;") + var/brutecolor = (patient.getBruteLoss() < 60 ? "color:gray;" : "color:red;") + var/o2color = (patient.getOxyLoss() < 60 ? "color:gray;" : "color:red;") + var/toxcolor = (patient.getToxLoss() < 60 ? "color:gray;" : "color:red;") + var/burncolor = (patient.getFireLoss() < 60 ? "color:gray;" : "color:red;") + + dat += "\t-Overall Health %: [round(patient.health)]
" + dat += "\t-Brute Damage %: [patient.getBruteLoss()]
" + dat += "\t-Respiratory Damage %: [patient.getOxyLoss()]
" + dat += "\t-Toxin Content %: [patient.getToxLoss()]
" + dat += "\t-Burn Severity %: [patient.getFireLoss()]
" + + if(round(patient.paralysis / 4) >= 1) + dat += text("
Patient paralyzed for: []
", round(patient.paralysis / 4) >= 1 ? "[round(patient.paralysis / 4)] seconds" : "None") if(patient.getBrainLoss()) dat += "
Significant brain damage detected.

" + if(patient.getCloneLoss()) + dat += "
Patient may be improperly cloned.

" if(patient.reagents.reagent_list.len) for(var/datum/reagent/R in patient.reagents.reagent_list) dat += "
[R.name]:
[round(R.volume, 0.1)] units

" @@ -451,11 +489,13 @@ popup.open() return -/obj/item/weapon/dogborg/sleeper/Topic(href, href_list) + +/obj/item/device/dogborg/sleeper/Topic(href, href_list) if(..() || usr == patient) return usr.set_machine(src) if(href_list["refresh"]) + update_patient() src.updateUsrDialog() sleeperUI(usr) return @@ -463,42 +503,322 @@ go_out() sleeperUI(usr) return - if(patient && patient.stat != DEAD) + if(href_list["clean"]) + if(!cleaning) + var/confirm = alert(usr, "You are about to engage self-cleaning mode. This will fill your [src] with caustic enzymes to remove any objects or biomatter, and convert them into energy. Are you sure?", "Confirmation", "Self-Clean", "Cancel") + if(confirm == "Self-Clean") + if(cleaning) + return + else + cleaning = 1 + drain(500) + START_PROCESSING(SSobj, src) + sleeperUI(usr) + if(patient) + patient << "[hound.name]'s [src.name] fills with caustic enzymes around you!" + return + if(cleaning) + sleeperUI(usr) + return + if(href_list["port"]) + switch(eject_port) + if("ingestion") + eject_port = "disposal" + if("disposal") + eject_port = "ingestion" + sleeperUI(usr) + return + + if(patient && !(patient.stat & DEAD)) if(href_list["inject"] == "epinephrine" || patient.health > min_health) inject_chem(usr, href_list["inject"]) else - usr << "ERROR: Subject is not in stable condition for auto-injection." + usr << "ERROR: Subject is not in stable condition for injections." else usr << "ERROR: Subject cannot metabolise chemicals." + src.updateUsrDialog() sleeperUI(usr) //Needs a callback to boop the page to refresh. return -/obj/item/weapon/dogborg/sleeper/proc/inject_chem(mob/user, chem) +/obj/item/device/dogborg/sleeper/proc/inject_chem(mob/user, chem) if(patient && patient.reagents) if(chem in injection_chems + "epinephrine") - if(patient.reagents.get_reagent_amount(chem) + 10 <= 20) - patient.reagents.add_reagent(chem, 10) - var/mob/living/silicon/robot.R = user - R.cell.charge = R.cell.charge - 250 //-250 charge per sting. + if(hound.cell.charge < 800) //This is so borgs don't kill themselves with it. + hound << "You don't have enough power to synthesize fluids." + return + else if(patient.reagents.get_reagent_amount(chem) + 10 >= 20) //Preventing people from accidentally killing themselves by trying to inject too many chemicals! + hound << "Your stomach is currently too full of fluids to secrete more fluids of this kind." + else if(patient.reagents.get_reagent_amount(chem) + 10 <= 20) //No overdoses for you + patient.reagents.add_reagent(chem, inject_amount) + drain(750) //-750 charge per injection var/units = round(patient.reagents.get_reagent_amount(chem)) - user << "Occupant now has [units] unit\s of [GLOB.chemical_reagents_list[chem]] in their bloodstream." + hound << "Injecting [units] unit\s of [injection_chems[chem]] into occupant." //If they were immersed, the reagents wouldn't leave with them. -/obj/item/weapon/dogborg/sleeper/process() - if(src.occupied == 0) - SSobj.processing.Remove(src) +/obj/item/device/dogborg/sleeper/process() + + if(cleaning) //We're cleaning, return early after calling this as we don't care about the patient. + src.clean_cycle() return - if(patient.health > 0) - patient.adjustOxyLoss(-1) - patient.updatehealth() - patient.AdjustStunned(-4) - patient.AdjustWeakened(-4) - src.drain() - if(patient.reagents.get_reagent_amount("epinephrine") < 5) - patient.reagents.add_reagent("epinephrine", 5) -/obj/item/weapon/dogborg/sleeper/container_resist() - go_out() + if(patient) //We're caring for the patient. Medical emergency! Or endo scene. + update_patient() + if(patient.health < 0) + patient.adjustOxyLoss(-1) //Heal some oxygen damage if they're in critical condition + patient.updatehealth() + patient.AdjustStunned(-4) + patient.AdjustWeakened(-4) + src.drain() + if((patient.reagents.get_reagent_amount("epinephrine") < 5) && (patient.health < patient.maxHealth)) //Stop pumping full HP people full of drugs. Don't heal people you're digesting, meanie. + patient.reagents.add_reagent("epinephrine", 5) + return + + if(!patient && !cleaning) //We think we're done working. + if(!update_patient()) //One last try to find someone + STOP_PROCESSING(SSobj, src) + return + +/obj/item/device/dogborg/sleeper/proc/update_patient() + + //Well, we HAD one, what happened to them? + if(patient in contents) + if(patient_laststat != patient.stat) + if(patient.stat & DEAD) + hound.sleeper_r = 1 + hound.sleeper_g = 0 + patient_laststat = patient.stat + else + hound.sleeper_r = 0 + hound.sleeper_g = 1 + patient_laststat = patient.stat + //Update icon + hound.update_icons() + //Return original patient + return(patient) + + //Check for a new patient + else + for(var/mob/living/carbon/human/C in contents) + patient = C + if(patient.stat & DEAD) + hound.sleeper_r = 1 + hound.sleeper_g = 0 + patient_laststat = patient.stat + else + hound.sleeper_r = 0 + hound.sleeper_g = 1 + patient_laststat = patient.stat + //Update icon and return new patient + hound.update_icons() + return(C) + + //Cleaning looks better with red on, even with nobody in it + if(cleaning && !patient) + hound.sleeper_r = 1 + hound.sleeper_g = 0 + + //Couldn't find anyone, and not cleaning + else if(!cleaning && !patient) + hound.sleeper_r = 0 + hound.sleeper_g = 0 + + patient_laststat = null + patient = null + hound.update_icons() + return + +//Gurgleborg process +/obj/item/device/dogborg/sleeper/proc/clean_cycle() + + //Sanity? Maybe not required. More like if indigestible person OOC escapes. + for(var/I in items_preserved) + if(!(I in contents)) + items_preserved -= I + + var/list/touchable_items = contents - items_preserved + + //Belly is entirely empty + if(!length(contents)) + hound << "Your [src.name] is now clean. Ending self-cleaning cycle." + cleaning = 0 + update_patient() + return + + if(prob(20)) + var/churnsound = pick( + 'sound/vore/pred/digest_01.ogg', + 'sound/vore/pred/digest_02.ogg', + 'sound/vore/pred/digest_03.ogg', + 'sound/vore/pred/digest_04.ogg', + 'sound/vore/pred/digest_05.ogg', + 'sound/vore/pred/digest_06.ogg', + 'sound/vore/pred/digest_07.ogg', + 'sound/vore/pred/digest_08.ogg', + 'sound/vore/pred/digest_09.ogg', + 'sound/vore/pred/digest_10.ogg', + 'sound/vore/pred/digest_11.ogg', + 'sound/vore/pred/digest_12.ogg', + 'sound/vore/pred/digest_13.ogg', + 'sound/vore/pred/digest_14.ogg', + 'sound/vore/pred/digest_15.ogg', + 'sound/vore/pred/digest_16.ogg', + 'sound/vore/pred/digest_17.ogg', + 'sound/vore/pred/digest_18.ogg') + for(var/mob/outhearer in range(1,hound)) + outhearer << sound(churnsound) + for(var/mob/inhearer in contents) + inhearer << sound(churnsound) + //If the timing is right, and there are items to be touched + if(SSmobs.times_fired%6==1 && length(touchable_items)) + + //Burn all the mobs or add them to the exclusion list + for(var/mob/living/carbon/human/T in (touchable_items)) + if((T.status_flags & GODMODE) || !T.digestable) + src.items_preserved += T + else + T.adjustBruteLoss(2) + T.adjustFireLoss(3) + src.update_patient() + + //Pick a random item to deal with (if there are any) + var/atom/target = pick(touchable_items) + + //Handle the target being a mob + if(ishuman(target)) + var/mob/living/carbon/human/T = target + + //Mob is now dead + if(T.stat & DEAD) + message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "JMP" : "null"])") + hound << "You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems." + T << "You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems." + src.drain(-30000) //Fueeeeellll + var/deathsound = pick( + 'sound/vore/pred/death_01.ogg', + 'sound/vore/pred/death_02.ogg', + 'sound/vore/pred/death_03.ogg', + 'sound/vore/pred/death_04.ogg', + 'sound/vore/pred/death_05.ogg', + 'sound/vore/pred/death_06.ogg', + 'sound/vore/pred/death_07.ogg', + 'sound/vore/pred/death_08.ogg', + 'sound/vore/pred/death_09.ogg', + 'sound/vore/pred/death_10.ogg', + 'sound/vore/pred/death_11.ogg', + 'sound/vore/pred/death_12.ogg', + 'sound/vore/pred/death_13.ogg') + for(var/mob/hearer in range(1,src.hound)) + hearer << deathsound + T << deathsound + qdel(T) + src.update_patient() + + //Handle the target being anything but a /mob/living/carbon/human + else + var/obj/T = target + + //If the object is in the items_preserved global list //POLARISTODO + + if(T.type in important_items) + src.items_preserved += T + + //If the object is not one to preserve + else + //Special case for PDAs as they are dumb. TODO fix Del on PDAs to be less dumb. + if (istype(T, /obj/item/device/pda)) + var/obj/item/device/pda/PDA = T + if (PDA.id) + PDA.id.forceMove(src) + PDA.id = null + qdel(T) + + //Special case for IDs to make them digested + //else if (istype(T, /obj/item/weapon/card/id)) + //var/obj/item/weapon/card/id/ID = T + //ID.digest() //Need the digest proc, first. + + //Anything not perserved, PDA, or ID + else + //Spill(T) //Needs the spill proc to be added + qdel(T) + src.update_patient() + src.hound.cell.charge += 120 //10 charge? that was such a practically nonexistent number it hardly gave any purpose for this bit :v *cranks up* + return + + +/obj/item/device/dogborg/sleeper/container_resist() + if(prob(8)) + go_out() + +/obj/item/device/dogborg/sleeper/K9 //The K9 portabrig + name = "Brig-Belly" + desc = "Equipment for a K9 unit. A mounted portable-brig that holds criminals." + icon = 'icons/mob/dogborg.dmi' + icon_state = "sleeperb" + inject_amount = 10 + min_health = -100 + injection_chems = null //So they don't have all the same chems as the medihound! + +/obj/item/device/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 = 10 + min_health = -100 + injection_chems = null //So they don't have all the same chems as the medihound! + var/max_item_count = 32 + +/obj/item/weapon/storage/attackby(obj/item/device/dogborg/sleeper/compactor, mob/user, proximity) //GIT CIRCUMVENTED YO! + compactor.afterattack(src, user ,1) + +/obj/item/device/dogborg/sleeper/compactor/afterattack(var/atom/movable/target, mob/living/silicon/user, proximity)//GARBO NOMS + hound = loc + + if(!istype(target)) + return + if(!proximity) + return + if(target.anchored) + return + if(length(contents) > (max_item_count - 1)) + user << "Your [src.name] is full. Eject or process contents to continue." + return + + if(istype(target,/obj/item)) + var/obj/item/target_obj = target + if(target_obj.w_class > WEIGHT_CLASS_BULKY) + user << "\The [target] is too large to fit into your [src.name]" + return + user.visible_message("[hound.name] is ingesting [target.name] into their [src.name].", "You start ingesting [target] into your [src.name]...") + if(do_after(user, 30, target) && length(contents) < max_item_count) + target.forceMove(src) + user.visible_message("[hound.name]'s garbage processor groans lightly as [target.name] slips inside.", "Your garbage compactor groans lightly as [target] slips inside.") + playsound(hound, 'sound/vore/gulpold.ogg', 50, 1) + if(length(contents) > 11) //grow that tum after a certain junk amount + hound.sleeper_r = 1 + hound.update_icons() + return + + else if(ishuman(target)) + var/mob/living/carbon/human/trashman = target + if(patient) + user << "Your [src.name] is already occupied." + return + if(trashman.buckled) + user << "[trashman] is buckled and can not be put into your [src.name]." + return + user.visible_message("[hound.name] is ingesting [trashman] into their [src.name].", "You start ingesting [trashman] into your [src.name]...") + if(do_after(user, 30, trashman) && !patient && !trashman.buckled && length(contents) < max_item_count) + trashman.forceMove(src) + trashman.reset_perspective(src) + update_patient() + START_PROCESSING(SSobj, src) + 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/vore/gulpold.ogg', 80, 1) + return + return + // Pounce stuff for K-9 @@ -510,6 +830,10 @@ force = 0 throwforce = 0 +/obj/item/weapon/dogborg/pounce/New() + ..() + flags |= NOBLUDGEON + /mob/living/silicon/robot var/leaping = 0 var/pounce_cooldown = 0 diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 16405f5dc4..c45a32a9be 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -25,11 +25,11 @@ else if(istype(O,/obj/item/weapon/gun/energy/disabler/cyborg)) disabler = 0 update_icons() - else if(istype(O,/obj/item/weapon/dogborg/sleeper)) + else if(istype(O,/obj/item/device/dogborg/sleeper)) sleeper_g = 0 sleeper_r = 0 update_icons() - var/obj/item/weapon/dogborg/sleeper/S = O + var/obj/item/device/dogborg/sleeper/S = O S.go_out() if(client) client.screen -= O diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index abb81678bb..cdf59e0a40 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -209,7 +209,8 @@ "Janitor" = /obj/item/weapon/robot_module/janitor, \ "Service" = /obj/item/weapon/robot_module/butler, \ "MediHound" = /obj/item/weapon/robot_module/medihound, \ - "Security K9" = /obj/item/weapon/robot_module/k9) + "Security K9" = /obj/item/weapon/robot_module/k9, \ + "Scrub Puppy" = /obj/item/weapon/robot_module/scrubpup) if(!config.forbid_peaceborg) modulelist["Peacekeeper"] = /obj/item/weapon/robot_module/peacekeeper if(!config.forbid_secborg) @@ -598,9 +599,9 @@ icon = 'icons/mob/widerobot.dmi' pixel_x = -16 if(sleeper_g == 1) - add_overlay("sleeper_g") + add_overlay("msleeper_g") if(sleeper_r == 1) - add_overlay("sleeper_r") + add_overlay("msleeper_r") if(stat == DEAD) icon_state = "medihound-wreck" @@ -611,9 +612,23 @@ add_overlay("laser") if(disabler == 1) add_overlay("disabler") + if(sleeper_g == 1) + add_overlay("ksleeper_g") + if(sleeper_r == 1) + add_overlay("ksleeper_r") if(stat == DEAD) icon_state = "k9-wreck" + if(module.cyborg_base_icon == "scrubpup") + icon = 'icons/mob/widerobot.dmi' + pixel_x = -16 + if(sleeper_g == 1) + add_overlay("jsleeper_g") + if(sleeper_r == 1) + add_overlay("jsleeper_r") + if(stat == DEAD) + icon_state = "scrubpup-wreck" + if(module.cyborg_base_icon == "robot") icon = 'icons/mob/robots.dmi' pixel_x = initial(pixel_x) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index e39cc1672d..a4f14002cd 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -352,6 +352,7 @@ /obj/item/clothing/mask/gas/sechailer/cyborg, /obj/item/weapon/soap/tongue, /obj/item/device/analyzer/nose, + /obj/item/device/dogborg/sleeper/K9, /obj/item/weapon/gun/energy/disabler/cyborg) emag_modules = list(/obj/item/weapon/gun/energy/laser/cyborg) ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security, @@ -367,6 +368,17 @@ loc << "While you have picked the security-k9 module, you still have to follow your laws, NOT Space Law. \ For Asimov, this means you must follow criminals' orders unless there is a law 1 reason not to." +/obj/item/weapon/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1) + ..() + var/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg) in basic_modules + if(T) + if(T.cell.charge < T.cell.maxcharge) + var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select] + T.cell.give(S.e_cost * coeff) + T.update_icon() + else + T.charge_tick = 0 + /obj/item/weapon/robot_module/medihound name = "MediHound module" basic_modules = list( @@ -374,7 +386,7 @@ /obj/item/device/analyzer/nose, /obj/item/weapon/soap/tongue, /obj/item/device/healthanalyzer, - /obj/item/weapon/dogborg/sleeper, + /obj/item/device/dogborg/sleeper, /obj/item/weapon/twohanded/shockpaddles/hound, /obj/item/device/sensor_device) emag_modules = list(/obj/item/weapon/dogborg/pounce) @@ -391,16 +403,36 @@ loc << "Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \ You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you." -/obj/item/weapon/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1) +/obj/item/weapon/robot_module/scrubpup + name = "Janitor" + basic_modules = list( + /obj/item/device/assembly/flash/cyborg, + /obj/item/weapon/dogborg/jaws/small, + /obj/item/device/analyzer/nose, + /obj/item/weapon/soap/tongue, + /obj/item/device/lightreplacer/cyborg, + /obj/item/device/dogborg/sleeper/compactor) + emag_modules = list(/obj/item/weapon/dogborg/pounce) + ratvar_modules = list( + /obj/item/clockwork/slab/cyborg/janitor, + /obj/item/clockwork/replica_fabricator/cyborg) + cyborg_base_icon = "scrubpup" + moduleselect_icon = "scrubpup" + feedback_key = "cyborg_scrubpup" + hat_offset = INFINITY + clean_on_move = TRUE + +/obj/item/weapon/robot_module/scrubpup/respawn_consumable(mob/living/silicon/robot/R, coeff = 1) ..() - var/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg) in basic_modules - if(T) - if(T.cell.charge < T.cell.maxcharge) - var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select] - T.cell.give(S.e_cost * coeff) - T.update_icon() - else - T.charge_tick = 0 + var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in basic_modules + if(LR) + for(var/i in 1 to coeff) + LR.Charge(R) + +/obj/item/weapon/robot_module/scrubpup/do_transform_animation() + ..() + loc << "As tempting as it might be, do not begin binging on important items. Eat your garbage responsibly." + /obj/item/weapon/robot_module/peacekeeper name = "Peacekeeper" @@ -432,9 +464,9 @@ name = "Janitor" basic_modules = list( /obj/item/device/assembly/flash/cyborg, - /obj/item/weapon/screwdriver/cyborg, - /obj/item/weapon/crowbar/cyborg, - /obj/item/stack/tile/plasteel/cyborg, + /obj/item/weapon/screwdriver/cyborg, + /obj/item/weapon/crowbar/cyborg, + /obj/item/stack/tile/plasteel/cyborg, /obj/item/weapon/soap/nanotrasen, /obj/item/weapon/storage/bag/trash/cyborg, /obj/item/weapon/mop/cyborg, diff --git a/icons/mob/dogborg.dmi b/icons/mob/dogborg.dmi index 2ccf941237..ec63120ae1 100644 Binary files a/icons/mob/dogborg.dmi and b/icons/mob/dogborg.dmi differ diff --git a/icons/mob/screen_cyborg.dmi b/icons/mob/screen_cyborg.dmi index c7abab2d23..e9fd4ed401 100644 Binary files a/icons/mob/screen_cyborg.dmi and b/icons/mob/screen_cyborg.dmi differ diff --git a/icons/mob/widerobot.dmi b/icons/mob/widerobot.dmi index 6e11bf4031..88ac16da24 100644 Binary files a/icons/mob/widerobot.dmi and b/icons/mob/widerobot.dmi differ