|
|
|
@@ -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("<span class='warning'>[user] starts putting [target] into \the [src].</span>", "<span class='notice'>You start putting [target] into [src]...</span>")
|
|
|
|
|
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 << "<span class='notice'>[target] successfully loaded into [src]. Life support functions engaged.</span>"
|
|
|
|
|
user.visible_message("<span class='warning'>[user] loads [target] into [src].</span>")
|
|
|
|
|
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 << "<span class='warning'>[target] will not fit into the sleeper because they are buckled to [target.buckled]!</span>"
|
|
|
|
|
if(target.buckled)
|
|
|
|
|
user << "<span class='warning'>The user is buckled and can not be put into your [src.name].</span>"
|
|
|
|
|
return
|
|
|
|
|
if(patient)
|
|
|
|
|
user << "<span class='warning'>The sleeper is already occupied!</span>"
|
|
|
|
|
user << "<span class='warning'>Your [src.name] is already occupied.</span>"
|
|
|
|
|
return
|
|
|
|
|
return 1
|
|
|
|
|
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src]...</span>")
|
|
|
|
|
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 << "<span class='notice'>[patient] ejected. Life support functions disabled.</span>"
|
|
|
|
|
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("<span class='warning'>[hound.name]'s medical pod lights up as [target.name] slips inside into their [src.name].</span>", "<span class='notice'>Your medical pod lights up as [target] slips into your [src]. Life support functions engaged.</span>")
|
|
|
|
|
message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "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("<span class='warning'>[hound.name] empties out their contents via their [eject_port] port.</span>", "<span class='notice'>You empty your contents via your [eject_port] port.</span>")
|
|
|
|
|
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 += "<h3>Injector</h3>"
|
|
|
|
|
if(patient)
|
|
|
|
|
|
|
|
|
|
if(patient && !(patient.stat & DEAD))
|
|
|
|
|
dat += "<A href='?src=\ref[src];inject=epinephrine'>Inject Epinephrine</A>"
|
|
|
|
|
else
|
|
|
|
|
dat += "<span class='linkOff'>Inject Epinephrine</span>"
|
|
|
|
|
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 += "<BR><A href='?src=\ref[src];inject=[C.id]'>Inject [C.name]</A>"
|
|
|
|
|
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 += "<BR><span class='linkOff'>Inject [C.name]</span>"
|
|
|
|
|
|
|
|
|
|
dat += "<h3>Sleeper Status</h3>"
|
|
|
|
|
dat += "<A href='?src=\ref[src];refresh=1'>Scan</A>"
|
|
|
|
|
dat += "<A href='?src=\ref[src];eject=1'>Eject</A>"
|
|
|
|
|
dat += "<A id='refbutton' href='?src=\ref[src];refresh=1'>Refresh</A>"
|
|
|
|
|
dat += "<A href='?src=\ref[src];eject=1'>Eject All</A>"
|
|
|
|
|
dat += "<A href='?src=\ref[src];port=1'>Eject port: [eject_port]</A>"
|
|
|
|
|
if(!cleaning)
|
|
|
|
|
dat += "<A href='?src=\ref[src];clean=1'>Self-Clean</A>"
|
|
|
|
|
else
|
|
|
|
|
dat += "<span class='linkOff'>Self-Clean</span>"
|
|
|
|
|
|
|
|
|
|
dat += "<div class='statusDisplay'>"
|
|
|
|
|
|
|
|
|
|
//Cleaning and there are still un-preserved items
|
|
|
|
|
if(cleaning && length(contents - items_preserved))
|
|
|
|
|
dat += "<font color='red'><B>Self-cleaning mode.</B> [length(contents - items_preserved)] object(s) remaining.</font><BR>"
|
|
|
|
|
|
|
|
|
|
//There are no items to be processed other than un-preserved items
|
|
|
|
|
else if(cleaning && length(items_preserved))
|
|
|
|
|
dat += "<font color='red'><B>Self-cleaning done. Eject remaining objects now.</B></font><BR>"
|
|
|
|
|
|
|
|
|
|
//Preserved items count when the list is populated
|
|
|
|
|
if(length(items_preserved))
|
|
|
|
|
dat += "<font color='red'>[length(items_preserved)] uncleanable object(s).</font><BR>"
|
|
|
|
|
|
|
|
|
|
if(!patient)
|
|
|
|
|
dat += "Sleeper Unoccupied"
|
|
|
|
|
else
|
|
|
|
|
dat += "[patient.name] => "
|
|
|
|
|
switch(patient.stat) //obvious, see what their status is
|
|
|
|
|
|
|
|
|
|
switch(patient.stat)
|
|
|
|
|
if(0)
|
|
|
|
|
dat += "<span class='good'>Conscious</span>"
|
|
|
|
|
var/mob/living/silicon/robot.R = user
|
|
|
|
|
R.sleeper_r = 0
|
|
|
|
|
R.sleeper_g = 1
|
|
|
|
|
R.update_icons()
|
|
|
|
|
if(1)
|
|
|
|
|
dat += "<span class='average'>Unconscious</span>"
|
|
|
|
|
var/mob/living/silicon/robot.R = user
|
|
|
|
|
R.sleeper_r = 0
|
|
|
|
|
R.sleeper_g = 1
|
|
|
|
|
R.update_icons()
|
|
|
|
|
else
|
|
|
|
|
dat += "<span class='bad'>DEAD</span>"
|
|
|
|
|
var/mob/living/silicon/robot.R = user
|
|
|
|
|
R.sleeper_g = 0
|
|
|
|
|
R.sleeper_r = 1
|
|
|
|
|
R.update_icons()
|
|
|
|
|
dat += "<br />"
|
|
|
|
|
dat += "<div class='line'><div class='statusLabel'>Health:</div><div class='progressBar'><div style='width: [patient.health < 0 ? "0" : "[patient.health]"]%;' class='progressFill good'></div></div><div class='statusValue'>[patient.stat > 1 ? "" : "[patient.health]%"]</div></div>"
|
|
|
|
|
dat += "<div class='line'><div class='statusLabel'>\> Brute Damage:</div><div class='progressBar'><div style='width: [patient.getBruteLoss()]%;' class='progressFill bad'></div></div><div class='statusValue'>[patient.getBruteLoss()]%</div></div>"
|
|
|
|
|
dat += "<div class='line'><div class='statusLabel'>\> Resp. Damage:</div><div class='progressBar'><div style='width: [patient.getOxyLoss()]%;' class='progressFill bad'></div></div><div class='statusValue'>[patient.getOxyLoss()]%</div></div>"
|
|
|
|
|
dat += "<div class='line'><div class='statusLabel'>\> Toxin Content:</div><div class='progressBar'><div style='width: [patient.getToxLoss()]%;' class='progressFill bad'></div></div><div class='statusValue'>[patient.getToxLoss()]%</div></div>"
|
|
|
|
|
dat += "<div class='line'><div class='statusLabel'>\> Burn Severity:</div><div class='progressBar'><div style='width: [patient.getFireLoss()]%;' class='progressFill bad'></div></div><div class='statusValue'>[patient.getFireLoss()]%</div></div><br>"
|
|
|
|
|
|
|
|
|
|
dat += "<HR><div class='line'><div style='width: 170px;' class='statusLabel'>Paralysis Summary:</div><div class='statusValue'>[round(patient.paralysis)]% [patient.paralysis ? "([round(patient.paralysis / 4)] seconds left)" : ""]</div></div><br>"
|
|
|
|
|
if(patient.getCloneLoss())
|
|
|
|
|
dat += "<div class='line'><span class='average'>Subject appears to have cellular damage.</span></div><br>"
|
|
|
|
|
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 += "<span style='[healthcolor]'>\t-Overall Health %: [round(patient.health)]</span><BR>"
|
|
|
|
|
dat += "<span style='[brutecolor]'>\t-Brute Damage %: [patient.getBruteLoss()]</span><BR>"
|
|
|
|
|
dat += "<span style='[o2color]'>\t-Respiratory Damage %: [patient.getOxyLoss()]</span><BR>"
|
|
|
|
|
dat += "<span style='[toxcolor]'>\t-Toxin Content %: [patient.getToxLoss()]</span><BR>"
|
|
|
|
|
dat += "<span style='[burncolor]'>\t-Burn Severity %: [patient.getFireLoss()]</span><BR>"
|
|
|
|
|
|
|
|
|
|
if(round(patient.paralysis / 4) >= 1)
|
|
|
|
|
dat += text("<HR>Patient paralyzed for: []<BR>", round(patient.paralysis / 4) >= 1 ? "[round(patient.paralysis / 4)] seconds" : "None")
|
|
|
|
|
if(patient.getBrainLoss())
|
|
|
|
|
dat += "<div class='line'><span class='average'>Significant brain damage detected.</span></div><br>"
|
|
|
|
|
if(patient.getCloneLoss())
|
|
|
|
|
dat += "<div class='line'><span class='average'>Patient may be improperly cloned.</span></div><br>"
|
|
|
|
|
if(patient.reagents.reagent_list.len)
|
|
|
|
|
for(var/datum/reagent/R in patient.reagents.reagent_list)
|
|
|
|
|
dat += "<div class='line'><div style='width: 170px;' class='statusLabel'>[R.name]:</div><div class='statusValue'>[round(R.volume, 0.1)] units</div></div><br>"
|
|
|
|
@@ -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 << "<span class='danger'>[hound.name]'s [src.name] fills with caustic enzymes around you!</span>"
|
|
|
|
|
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 << "<span class='notice'>ERROR: Subject is not in stable condition for auto-injection.</span>"
|
|
|
|
|
usr << "<span class='notice'>ERROR: Subject is not in stable condition for injections.</span>"
|
|
|
|
|
else
|
|
|
|
|
usr << "<span class='notice'>ERROR: Subject cannot metabolise chemicals.</span>"
|
|
|
|
|
|
|
|
|
|
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 << "<span class='notice'>You don't have enough power to synthesize fluids.</span>"
|
|
|
|
|
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 << "<span class='notice'>Your stomach is currently too full of fluids to secrete more fluids of this kind.</span>"
|
|
|
|
|
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 << "<span class='notice'>Occupant now has [units] unit\s of [GLOB.chemical_reagents_list[chem]] in their bloodstream.</span>"
|
|
|
|
|
hound << "<span class='notice'>Injecting [units] unit\s of [injection_chems[chem]] into occupant.</span>" //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 << "<span class='notice'>Your [src.name] is now clean. Ending self-cleaning cycle.</span>"
|
|
|
|
|
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 ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
|
|
|
|
|
hound << "<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>"
|
|
|
|
|
T << "<span class='notice'>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.</span>"
|
|
|
|
|
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 << "<span class='warning'>Your [src.name] is full. Eject or process contents to continue.</span>"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(istype(target,/obj/item))
|
|
|
|
|
var/obj/item/target_obj = target
|
|
|
|
|
if(target_obj.w_class > WEIGHT_CLASS_BULKY)
|
|
|
|
|
user << "<span class='warning'>\The [target] is too large to fit into your [src.name]</span>"
|
|
|
|
|
return
|
|
|
|
|
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
|
|
|
|
|
if(do_after(user, 30, target) && length(contents) < max_item_count)
|
|
|
|
|
target.forceMove(src)
|
|
|
|
|
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [target] slips inside.</span>")
|
|
|
|
|
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 << "<span class='warning'>Your [src.name] is already occupied.</span>"
|
|
|
|
|
return
|
|
|
|
|
if(trashman.buckled)
|
|
|
|
|
user << "<span class='warning'>[trashman] is buckled and can not be put into your [src.name].</span>"
|
|
|
|
|
return
|
|
|
|
|
user.visible_message("<span class='warning'>[hound.name] is ingesting [trashman] into their [src.name].</span>", "<span class='notice'>You start ingesting [trashman] into your [src.name]...</span>")
|
|
|
|
|
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("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashman] slips inside.</span>")
|
|
|
|
|
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
|
|
|
|
|