mirror of
https://github.com/Sandstorm-Station/Sandstorm-Station-13.git
synced 2026-08-26 14:48:26 +01:00
Borg belly tg UI (#125)
* Added TGUI for Dogborg sleepers again Added resist chance and help intent struggle messages (to suggest maybe a different intent is required for escape) Doubled dogborg sleepers cleaning cycle time Tweaked dogborg sleepers messages and sounds * Rebuild of TGUI (Discard if this conflicts and just rebuild TGUI) * Added game_options config ENABLE_DOGBORG_SLEEPERS to determine whether recreational sleepers or normal sleepers should be added to dogborgs * Moved ENABLE_DOGBORG_SLEEPERS flag to sandstorm config
This commit is contained in:
@@ -81,6 +81,8 @@
|
||||
|
||||
/datum/config_entry/flag/disable_peaceborg
|
||||
|
||||
/datum/config_entry/flag/enable_dogborg_sleepers // enable normal dogborg sleepers (otherwise recreational)
|
||||
|
||||
/datum/config_entry/flag/economy //money money money money money money money money money money money money
|
||||
|
||||
/datum/config_entry/number/minimum_secborg_alert //Minimum alert level for secborgs to be chosen.
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
// Dogborg Sleeper units
|
||||
|
||||
/obj/item/dogborg/sleeper
|
||||
name = "hound sleeper"
|
||||
desc = "nothing should see this."
|
||||
name = "Hound Sleeper"
|
||||
desc = "Equipment for a Medihound unit. A mounted, underslung sleeper, with a medical scanner and chemical injectors."
|
||||
icon = 'icons/mob/robot_items.dmi'
|
||||
icon_state = "sleeper"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/mob/living/carbon/patient
|
||||
var/inject_amount = 10
|
||||
var/inject_cost = 750
|
||||
var/min_health = -100
|
||||
var/cleaning = FALSE
|
||||
var/cleaning_cycles = 10
|
||||
var/medical_scanner = TRUE
|
||||
var/cleaning_cycles = 20
|
||||
var/patient_laststat = null
|
||||
var/list/injection_chems = list(/datum/reagent/medicine/antitoxin, /datum/reagent/medicine/epinephrine,
|
||||
/datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane)
|
||||
@@ -18,6 +20,8 @@
|
||||
var/escape_in_progress = FALSE
|
||||
var/message_cooldown
|
||||
var/breakout_time = 150
|
||||
var/escape_chance = 35
|
||||
var/escape_pending = FALSE
|
||||
var/tmp/last_hearcheck = 0
|
||||
var/tmp/list/hearing_mobs
|
||||
var/list/items_preserved = list()
|
||||
@@ -75,59 +79,82 @@
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(!iscarbon(target))
|
||||
if(!ishuman(target))
|
||||
return
|
||||
if(target.buckled)
|
||||
to_chat(user, "<span class='warning'>The user is buckled and can not be put into your [src.name].</span>")
|
||||
return
|
||||
if(target.anchored)
|
||||
to_chat(user, "<span class='warning'>The user is anchored and can not be put into your [src.name].</span>")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(user, "<span class='warning'>Your [src.name] is already occupied.</span>")
|
||||
return
|
||||
|
||||
if (!CHECK_BITFIELD(target.vore_flags,DEVOURABLE))
|
||||
to_chat(user, "The target registers an error code. Unable to insert into [src.name].")
|
||||
return
|
||||
|
||||
var/voracious = TRUE
|
||||
if(!target.client || !(target.client.prefs.cit_toggles & MEDIHOUND_SLEEPER) || !hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
voracious = FALSE
|
||||
if(target.buckled)
|
||||
to_chat(user, "<span class='warning'>The user is buckled and can not be put into your [src].</span>")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(user, "<span class='warning'>Your [src] is already occupied.</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is carefully inserting [target.name] into their [src].</span>", "<span class='notice'>You start placing [target] into your [src]...</span>")
|
||||
if(!patient && iscarbon(target) && !target.buckled && do_after (user, 100, target = target))
|
||||
|
||||
|
||||
user.visible_message("<span class='warning'>[hound.name] is carefully inserting [target.name] into their [src.name].</span>", "<span class='notice'>You start placing [target] into your [src.name]...</span>")
|
||||
if(do_after (user, 100, target = target) && !target.buckled && !target.anchored && !patient)
|
||||
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.
|
||||
|
||||
if(patient)
|
||||
return //If you try to eat two people at once, you can only eat one.
|
||||
//if(target.buckled)
|
||||
//to_chat(user, "<span class='warning'>The user is buckled and can not be put into your [src.name].</span>")
|
||||
//return
|
||||
//if(patient)
|
||||
//to_chat(user, "<span class='warning'>Your [src.name] is already occupied.</span>")
|
||||
//return
|
||||
|
||||
else //If you don't have someone in you, proceed.
|
||||
if(!isjellyperson(target) && ("toxin" in injection_chems))
|
||||
injection_chems -= "toxin"
|
||||
injection_chems += "antitoxin"
|
||||
if(isjellyperson(target) && !("toxin" in injection_chems))
|
||||
injection_chems -= "antitoxin"
|
||||
injection_chems += "toxin"
|
||||
target.forceMove(src)
|
||||
target.reset_perspective(src)
|
||||
target.ExtinguishMob() //The tongue already puts out fire stacks but being put into the sleeper shouldn't allow you to keep burning.
|
||||
update_gut(hound)
|
||||
user.visible_message("<span class='warning'>[voracious ? "[hound]'s [src.name] lights up and expands as [target] slips inside into their [src.name]." : "[hound]'s sleeper indicator lights up as [target] is scooped up into [hound.p_their()] [src]."]</span>", \
|
||||
"<span class='notice'>Your [voracious ? "[src.name] lights up as [target] slips into" : "sleeper indicator light shines brightly as [target] is scooped inside"] your [src]. Life support functions engaged.</span>")
|
||||
message_admins("[key_name(hound)] has sleeper'd [key_name(patient)] as a dogborg. [ADMIN_JMP(src)]")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 100, 1)
|
||||
//If you don't have someone in you, proceed.
|
||||
if(!isjellyperson(target) && ("toxin" in injection_chems))
|
||||
injection_chems -= "toxin"
|
||||
injection_chems += "antitoxin"
|
||||
if(isjellyperson(target) && !("toxin" in injection_chems))
|
||||
injection_chems -= "antitoxin"
|
||||
injection_chems += "toxin"
|
||||
target.forceMove(src)
|
||||
target.reset_perspective(src)
|
||||
target.ExtinguishMob() //The tongue already puts out fire stacks but being put into the sleeper shouldn't allow you to keep burning.
|
||||
update_gut(hound)
|
||||
user.visible_message("<span class='warning'>[voracious ? "[hound]'s [src.name] lights up and expands as [target] slips inside into their [src.name]." : "[hound]'s sleeper indicator lights up as [target] is scooped up into [hound.p_their()] [src.name]."]</span>", \
|
||||
"<span class='notice'>Your [voracious ? "[src.name] lights up as [target] slips into" : "sleeper indicator light shines brightly as [target] is scooped inside"] your [src.name]. Life support functions engaged.</span>")
|
||||
message_admins("[key_name(hound)] has sleeper'd [key_name(patient)] as a dogborg. [ADMIN_JMP(src)]")
|
||||
playsound(hound, voracious ? 'sound/vore/prey/insertion_01.ogg' : 'sound/effects/bin_close.ogg', 100, 1)
|
||||
|
||||
/obj/item/dogborg/sleeper/container_resist(mob/living/user)
|
||||
var/mob/living/silicon/robot/hound = get_host()
|
||||
if(!hound)
|
||||
go_out(user)
|
||||
return
|
||||
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
user.visible_message("<span class='warning'>[user] gently rubs the flexible confines.</span>", \
|
||||
"<span class='notice'>You gently rub [hound.name]'s flexible confines.</span>")
|
||||
return
|
||||
|
||||
var/voracious = TRUE
|
||||
if(!user.client || !(user.client.prefs.cit_toggles & MEDIHOUND_SLEEPER) || !hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
voracious = FALSE
|
||||
user.visible_message("<span class='notice'>You see [voracious ? "[user] struggling against the expanded material of [hound]'s gut!" : "and hear [user] pounding against something inside of [hound]'s [src.name]!"]</span>", \
|
||||
"<span class='notice'>[voracious ? "You start struggling inside of [src]'s tight, flexible confines," : "You start pounding against the metallic walls of [src],"] trying to trigger the release... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear a [voracious ? "couple of thumps" : "loud banging noise"] coming from within [hound].</span>")
|
||||
if(do_after(user, breakout_time, target = src))
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [hound.name]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [hound.name]!</span>")
|
||||
go_out(user, hound)
|
||||
|
||||
if(prob(escape_chance) && !escape_pending)
|
||||
user.visible_message("<span class='notice'>You see [voracious ? "[user] struggling against the expanded material of [hound]'s gut!" : "and hear [user] pounding against something inside of [hound]'s [src.name]!"]</span>", \
|
||||
"<span class='notice'>[voracious ? "You start struggling inside of [src.name]'s tight, flexible confines," : "You start pounding against the metallic walls of [src.name],"] managing to trigger a hidden emergency release... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear a [voracious ? "couple of thumps" : "loud banging noise"] coming from within [hound].</span>")
|
||||
escape_pending = TRUE
|
||||
if(do_after(user, breakout_time, target = src))
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [hound.name]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [hound.name]!</span>")
|
||||
go_out(user, hound)
|
||||
else
|
||||
user.visible_message("<span class='notice'>You see [voracious ? "[user] struggling against the expanded material of [hound]'s gut!" : "and hear [user] pounding against something inside of [hound]'s [src.name]!"]</span>", \
|
||||
"<span class='notice'>[voracious ? "You start struggling inside of [src.name]'s tight, flexible confines," : "You start pounding against the metallic walls of [src.name],"] trying to find the trigger the release...</span>", \
|
||||
"<span class='italics'>You hear a [voracious ? "couple of thumps" : "loud banging noise"] coming from within [hound].</span>")
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/go_out(atom/movable/target, mob/living/silicon/robot/hound)
|
||||
var/voracious = hound ? TRUE : FALSE
|
||||
@@ -141,7 +168,7 @@
|
||||
voracious = FALSE
|
||||
if(length(targets))
|
||||
if(hound)
|
||||
hound.visible_message("<span class='warning'>[voracious ? "[hound] empties out [hound.p_their()] contents via [hound.p_their()] release port." : "[hound]'s underside slides open with an audible clunk before [hound.p_their()] [src] flips over, carelessly dumping its contents onto the ground below [hound.p_them()] before closing right back up again."]</span>", \
|
||||
hound.visible_message("<span class='warning'>[voracious ? "[hound] empties out [hound.p_their()] contents via [hound.p_their()] release port." : "[hound]'s underside slides open with an audible clunk before [hound.p_their()] [src.name] flips over, carelessly dumping its contents onto the ground below [hound.p_them()] before closing right back up again."]</span>", \
|
||||
"<span class='notice'>[voracious ? "You empty your contents via your release port." : "You open your sleeper hatch, quickly releasing all of the contents within before closing it again."]</span>")
|
||||
for(var/a in contents)
|
||||
var/atom/movable/AM = a
|
||||
@@ -151,12 +178,13 @@
|
||||
M.reset_perspective()
|
||||
playsound(loc, voracious ? 'sound/effects/splat.ogg' : 'sound/effects/bin_close.ogg', 50, 1)
|
||||
items_preserved.Cut()
|
||||
cleaning_cycles = initial(cleaning_cycles)
|
||||
cleaning = FALSE
|
||||
patient = null
|
||||
escape_pending = FALSE
|
||||
if(hound)
|
||||
update_gut(hound)
|
||||
|
||||
|
||||
/obj/item/dogborg/sleeper/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(. || !iscyborg(user))
|
||||
@@ -169,21 +197,21 @@
|
||||
/obj/item/dogborg/sleeper/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "dogborg_sleeper", name, 375, 550) //UI DOES NOT EXIST
|
||||
ui = new(user, src, "DogborgSleeper", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/dogborg/sleeper/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = patient ? 1 : 0
|
||||
|
||||
if(cleaning && length(contents - items_preserved))
|
||||
if(cleaning)
|
||||
data["items"] = "Self-cleaning mode active: [length(contents - items_preserved)] object(s) remaining."
|
||||
data["cleaning"] = cleaning
|
||||
if(injection_chems != null)
|
||||
data["chem"] = list()
|
||||
for(var/chem in injection_chems)
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[chem]
|
||||
data["chem"] += list(list("name" = R.name, "id" = R.type))
|
||||
data["medical_scanner"] = medical_scanner
|
||||
data["chems"] = list()
|
||||
for(var/chem in injection_chems)
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[chem]
|
||||
data["chems"] += list(list("name" = R.name, "id" = R.type))
|
||||
|
||||
data["occupant"] = list()
|
||||
var/mob/living/mob_occupant = patient
|
||||
@@ -211,8 +239,9 @@
|
||||
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
data["occupant"]["is_robotic_organism"] = HAS_TRAIT(mob_occupant, TRAIT_ROBOTIC_ORGANISM)
|
||||
data["occupant"]["reagents"] = list()
|
||||
if(mob_occupant.reagents.reagent_list.len)
|
||||
if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
|
||||
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
|
||||
return data
|
||||
@@ -233,12 +262,14 @@
|
||||
inject_chem(chem, usr)
|
||||
. = TRUE
|
||||
if("cleaning")
|
||||
if(!contents)
|
||||
to_chat(src, "Your [src] is already cleaned.")
|
||||
if(!contents || length(contents) == 0)
|
||||
to_chat(usr, "Your [src.name] is already clean.")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(patient, "<span class='danger'>[usr.name]'s [src] fills with caustic enzymes around you!</span>")
|
||||
to_chat(src, "<span class='danger'>Cleaning process enabled.</span>")
|
||||
to_chat(patient, "<span class='danger'>[usr.name]'s [src.name] fills with caustic enzymes around you!</span>")
|
||||
to_chat(usr, "<span class='danger'>Cleaning process enabled.</span>")
|
||||
playsound(loc, 'sound/machines/click.ogg', 50, 1)
|
||||
cleaning = TRUE
|
||||
clean_cycle(usr)
|
||||
. = TRUE
|
||||
|
||||
@@ -270,7 +301,7 @@
|
||||
if(prociconupdate)
|
||||
hound.update_icons()
|
||||
//Return original patient
|
||||
return(patient)
|
||||
return
|
||||
//Check for a new patient
|
||||
else
|
||||
for(var/mob/living/carbon/human/C in contents)
|
||||
@@ -288,17 +319,17 @@
|
||||
hound.sleeper_nv = TRUE
|
||||
else
|
||||
hound.sleeper_nv = FALSE
|
||||
|
||||
|
||||
//Update icon and return new patient
|
||||
hound.update_icons()
|
||||
return
|
||||
|
||||
//Cleaning looks better with red on, even with nobody in it
|
||||
if(cleaning && !patient)
|
||||
if(cleaning)
|
||||
hound.sleeper_r = 1
|
||||
hound.sleeper_g = 0
|
||||
//Couldn't find anyone, and not cleaning
|
||||
else if(!cleaning && !patient)
|
||||
else
|
||||
hound.sleeper_r = 0
|
||||
hound.sleeper_g = 0
|
||||
|
||||
@@ -321,14 +352,13 @@
|
||||
var/sound/pred_death = sound(get_sfx("death_pred"))
|
||||
if(cleaning_cycles)
|
||||
cleaning_cycles--
|
||||
cleaning = TRUE
|
||||
for(var/mob/living/carbon/C in (touchable_items))
|
||||
if((C.status_flags & GODMODE) || !CHECK_BITFIELD(C.vore_flags, DIGESTABLE))
|
||||
items_preserved += C
|
||||
else
|
||||
C.adjustBruteLoss(2)
|
||||
C.adjustFireLoss(3)
|
||||
if(contents)
|
||||
if(contents && length(touchable_items) > 0)
|
||||
var/atom/target = pick(touchable_items)
|
||||
if(iscarbon(target)) //Handle the target being a mob
|
||||
var/mob/living/carbon/T = target
|
||||
@@ -360,7 +390,7 @@
|
||||
if(!T.dropItemToGround(W))
|
||||
qdel(W)
|
||||
qdel(T)
|
||||
//Handle the target being anything but a mob
|
||||
//Handle the target being anything but a mob
|
||||
else if(isobj(target))
|
||||
var/obj/T = target
|
||||
if(T.type in important_items) //If the object is in the items_preserved global list
|
||||
@@ -368,18 +398,24 @@
|
||||
//If the object is not one to preserve
|
||||
else
|
||||
qdel(T)
|
||||
update_gut()
|
||||
hound.cell.give(10)
|
||||
else
|
||||
else if(contents && length(contents) > 0)
|
||||
// Cycles complete and theres still stuff
|
||||
cleaning_cycles = initial(cleaning_cycles)
|
||||
cleaning = FALSE
|
||||
to_chat(hound, "<span class='notice'>Your [src] chimes it ends its self-cleaning cycle.</span>")//Belly is entirely empty
|
||||
|
||||
if(!length(contents))
|
||||
to_chat(hound, "<span class='notice'>Your [src] is now clean. Ending self-cleaning cycle.</span>")
|
||||
escape_pending = FALSE
|
||||
to_chat(hound, "<span class='notice'>Your [src.name] clicks as its self-cleaning cycle ends. NOTE: Foreign objects are still detected. Resume self-cleaning?</span>")
|
||||
playsound(loc, 'sound/machines/click.ogg', 50, 1)
|
||||
|
||||
if(!contents || length(contents) == 0)
|
||||
//Belly is entirely empty
|
||||
to_chat(hound, "<span class='notice'>Your [src.name] chimes as it completes its self-cleaning cycle.</span>")
|
||||
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
cleaning_cycles = initial(cleaning_cycles)
|
||||
cleaning = FALSE
|
||||
escape_pending = FALSE
|
||||
|
||||
//sound effects
|
||||
//sound effects
|
||||
if(prob(50))
|
||||
if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
|
||||
var/turf/source = get_turf(hound)
|
||||
@@ -404,18 +440,25 @@
|
||||
return is_type_in_typecache(I, important_items)
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/inject_chem(chem, mob/living/silicon/robot/hound)
|
||||
if(!hound)
|
||||
if(!hound || !patient || !patient.reagents)
|
||||
return
|
||||
if(hound.cell.charge <= 800) //This is so borgs don't kill themselves with it. Remember, 750 charge used every injection.
|
||||
if(hound.cell.charge <= inject_cost + 50) //This is so borgs don't kill themselves with it. Remember, 750 charge used every injection.
|
||||
to_chat(hound, "<span class='notice'>You don't have enough power to synthesize fluids.</span>")
|
||||
return
|
||||
if(patient.reagents.get_reagent_amount(chem) + 10 >= 20) //Preventing people from accidentally killing themselves by trying to inject too many chemicals!
|
||||
if(!chem_allowed(chem)) //Preventing people from accidentally killing themselves by trying to inject too many chemicals!
|
||||
to_chat(hound, "<span class='notice'>Your stomach is currently too full of fluids to secrete more fluids of this kind.</span>")
|
||||
return
|
||||
patient.reagents.add_reagent(chem, 10)
|
||||
hound.cell.use(750) //-750 charge per injection
|
||||
var/units = round(patient.reagents.get_reagent_amount(chem))
|
||||
to_chat(hound, "<span class='notice'>Injecting [units] unit\s of [chem] into occupant.</span>") //If they were immersed, the reagents wouldn't leave with them.
|
||||
patient.reagents.add_reagent(chem, inject_amount)
|
||||
hound.cell.use(inject_cost) //-750 charge per injection
|
||||
//var/units = round(patient.reagents.get_reagent_amount(chem))
|
||||
to_chat(hound, "<span class='notice'>Injecting [inject_amount] unit\s of [chem] into occupant.</span>") //If they were immersed, the reagents wouldn't leave with them.
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/chem_allowed(chem)
|
||||
if(!patient || !patient.reagents)
|
||||
return
|
||||
var/amount = patient.reagents.get_reagent_amount(chem) + inject_amount <= 20
|
||||
var/occ_health = patient.health > min_health || chem == /datum/reagent/medicine/epinephrine
|
||||
return amount && occ_health
|
||||
|
||||
/obj/item/dogborg/sleeper/K9 //The K9 portabrig
|
||||
name = "Mobile Brig"
|
||||
@@ -423,30 +466,56 @@
|
||||
icon_state = "sleeperb"
|
||||
inject_amount = 0
|
||||
min_health = -100
|
||||
injection_chems = null //So they don't have all the same chems as the medihound!
|
||||
injection_chems = list() //So they don't have all the same chems as the medihound!
|
||||
breakout_time = 300
|
||||
escape_chance = 15
|
||||
medical_scanner = FALSE
|
||||
|
||||
/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)
|
||||
if(!hound)
|
||||
return
|
||||
if (!CHECK_BITFIELD(target.vore_flags,DEVOURABLE))
|
||||
to_chat(user, "The target registers an error code. Unable to insert into [src].")
|
||||
if(!proximity)
|
||||
return
|
||||
if(patient)
|
||||
to_chat(user,"<span class='warning'>Your [src] is already occupied.</span>")
|
||||
if(!ishuman(target))
|
||||
return
|
||||
if(target.buckled)
|
||||
to_chat(user,"<span class='warning'>[target] is buckled and can not be put into your [src].</span>")
|
||||
to_chat(user, "<span class='warning'>The user is buckled and can not be put into your [src.name].</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [target] into their [src].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
|
||||
if(target.anchored)
|
||||
to_chat(user, "<span class='warning'>The user is anchored and can not be put into your [src.name].</span>")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(user, "<span class='warning'>Your [src.name] is already occupied.</span>")
|
||||
return
|
||||
|
||||
if(!CHECK_BITFIELD(target.vore_flags,DEVOURABLE))
|
||||
to_chat(user, "The target registers an error code. Unable to insert into [src.name].")
|
||||
return
|
||||
|
||||
var/voracious = TRUE
|
||||
if(!target.client || !(target.client.prefs.cit_toggles & MEDIHOUND_SLEEPER) || !hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
voracious = FALSE
|
||||
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [target] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
|
||||
if(do_after(user, 30, target = target) && !patient && !target.buckled)
|
||||
|
||||
//if(patient)
|
||||
//to_chat(user,"<span class='warning'>Your [src.name] is already occupied.</span>")
|
||||
//return
|
||||
//if(target.buckled)
|
||||
//to_chat(user,"<span class='warning'>[target] is buckled and can not be put into your [src.name].</span>")
|
||||
//return
|
||||
|
||||
target.forceMove(src)
|
||||
target.reset_perspective(src)
|
||||
update_gut(hound)
|
||||
user.visible_message("<span class='warning'>[hound.name]'s mobile brig clunks in series as [target] slips inside.</span>", "<span class='notice'>Your mobile brig groans lightly as [target] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
|
||||
playsound(hound, voracious ? 'sound/vore/prey/insertion_01.ogg' : '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."
|
||||
inject_amount = 0
|
||||
injection_chems = list() //So they don't have all the same chems as the medihound!
|
||||
medical_scanner = FALSE
|
||||
|
||||
@@ -143,25 +143,42 @@
|
||||
return I
|
||||
*/ //replaced by the one in sandcode
|
||||
|
||||
//Adds flavoursome dogborg items to dogborg variants without mechanical benefits
|
||||
//Adds flavoursome dogborg items to dogborg variants optionally without mechanical benefits
|
||||
/obj/item/robot_module/proc/dogborg_equip()
|
||||
has_snowflake_deadsprite = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
hat_offset = INFINITY
|
||||
basic_modules += new /obj/item/dogborg_nose(src)
|
||||
basic_modules += new /obj/item/dogborg_tongue(src)
|
||||
|
||||
var/obj/item/dogborg/sleeper/K9/flavour/I = new(src)
|
||||
|
||||
var/mechanics = CONFIG_GET(flag/enable_dogborg_sleepers)
|
||||
if (mechanics)
|
||||
// Normal sleepers
|
||||
if(istype(src, /obj/item/robot_module/security))
|
||||
basic_modules += new /obj/item/dogborg/sleeper/K9(src)
|
||||
if(istype(src, /obj/item/robot_module/medical))
|
||||
basic_modules += new /obj/item/dogborg/sleeper(src)
|
||||
else
|
||||
// Recreational sleepers
|
||||
if(istype(src, /obj/item/robot_module/security))
|
||||
I.icon_state = "sleeperb"
|
||||
basic_modules += I
|
||||
if(istype(src, /obj/item/robot_module/medical))
|
||||
I.icon_state = "sleeper"
|
||||
basic_modules += I
|
||||
|
||||
// Unimplemented sleepers
|
||||
if(istype(src, /obj/item/robot_module/engineering))
|
||||
I.icon_state = "decompiler"
|
||||
if(istype(src, /obj/item/robot_module/security))
|
||||
I.icon_state = "sleeperb"
|
||||
if(istype(src, /obj/item/robot_module/medical))
|
||||
I.icon_state = "sleeper"
|
||||
basic_modules += I
|
||||
if(istype(src, /obj/item/robot_module/butler))
|
||||
I.icon_state = "servicer"
|
||||
if(cyborg_base_icon == "scrubpup")
|
||||
I.icon_state = "compactor"
|
||||
basic_modules += I
|
||||
basic_modules += I
|
||||
|
||||
rebuild_modules()
|
||||
|
||||
/obj/item/robot_module/proc/remove_module(obj/item/I, delete_after)
|
||||
@@ -715,7 +732,7 @@
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
if("Drake")
|
||||
cyborg_base_icon = "drakepeace"
|
||||
cyborg_base_icon = "drakepeace"
|
||||
sleeper_overlay = "drakepeacesleeper"
|
||||
cyborg_icon_override = 'sandcode/icons/mob/cyborg/drakemech.dmi'
|
||||
dogborg = TRUE
|
||||
@@ -858,7 +875,7 @@
|
||||
"(Janitor) Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekjan"),
|
||||
"(Janitor) Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canjan"),
|
||||
"(Janitor) Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyjan"),
|
||||
"(Janitor) Drake" = image(icon = 'sandcode/icons/mob/cyborg/drakemech.dmi', icon_state = "drakejanitbox")
|
||||
"(Janitor) Drake" = image(icon = 'sandcode/icons/mob/cyborg/drakemech.dmi', icon_state = "drakejanitbox")
|
||||
)
|
||||
var/list/L = list("(Service) DarkK9" = "k50", "(Service) Vale" = "valeserv", "(Service) ValeDark" = "valeservdark",
|
||||
"(Janitor) Scrubpuppy" = "scrubpup")
|
||||
|
||||
@@ -7,3 +7,7 @@
|
||||
## Roundstart ping
|
||||
## Won't do anything if unset
|
||||
#NEW_ROUND_PING
|
||||
|
||||
## Dogborg Sleeper Mechanics ###
|
||||
## Uncomment to enable regular dogborg sleepers (otherwise will use recreational)
|
||||
#ENABLE_DOGBORG_SLEEPERS
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Box, Section, LabeledList, Button, ProgressBar, NoticeBox } from '../components';
|
||||
import { Fragment } from 'inferno';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
const damageTypes = [
|
||||
{
|
||||
label: 'Brute',
|
||||
type: 'bruteLoss',
|
||||
},
|
||||
{
|
||||
label: 'Burn',
|
||||
type: 'fireLoss',
|
||||
},
|
||||
{
|
||||
label: 'Toxin',
|
||||
type: 'toxLoss',
|
||||
},
|
||||
{
|
||||
label: 'Oxygen',
|
||||
type: 'oxyLoss',
|
||||
},
|
||||
];
|
||||
|
||||
export const DogborgSleeper = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
occupant = {},
|
||||
occupied,
|
||||
cleaning,
|
||||
items,
|
||||
medical_scanner,
|
||||
} = data;
|
||||
const preSortChems = data.chems || [];
|
||||
const chems = preSortChems.sort((a, b) => {
|
||||
const descA = a.name.toLowerCase();
|
||||
const descB = b.name.toLowerCase();
|
||||
if (descA < descB) {
|
||||
return -1;
|
||||
}
|
||||
if (descA > descB) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
return (
|
||||
<Window
|
||||
width={375}
|
||||
height={465}>
|
||||
<Window.Content>
|
||||
<Section
|
||||
title={occupant.name ? occupant.name : 'No Occupant'}
|
||||
minHeight="210px"
|
||||
buttons={!!occupant.stat && (
|
||||
<Box
|
||||
inline
|
||||
bold
|
||||
color={occupant.statstate}>
|
||||
{occupant.stat}
|
||||
</Box>
|
||||
)}>
|
||||
{!!cleaning && (
|
||||
<NoticeBox>
|
||||
{items}
|
||||
</NoticeBox>
|
||||
)}
|
||||
{!!occupied && (
|
||||
<Fragment>
|
||||
<ProgressBar
|
||||
value={occupant.health}
|
||||
minValue={occupant.minHealth}
|
||||
maxValue={occupant.maxHealth}
|
||||
ranges={{
|
||||
good: [50, Infinity],
|
||||
average: [0, 50],
|
||||
bad: [-Infinity, 0],
|
||||
}} />
|
||||
<Box mt={1} />
|
||||
{!!medical_scanner && (
|
||||
<LabeledList>
|
||||
{damageTypes.map(type => (
|
||||
<LabeledList.Item
|
||||
key={type.type}
|
||||
label={occupant.is_robotic_organism && type.label === 'Toxin' ? 'Corruption' : type.label}>
|
||||
<ProgressBar
|
||||
value={occupant[type.type]}
|
||||
minValue={0}
|
||||
maxValue={occupant.maxHealth}
|
||||
color="bad" />
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
<LabeledList.Item
|
||||
label="Cells"
|
||||
color={occupant.cloneLoss ? 'bad' : 'good'}>
|
||||
{occupant.cloneLoss ? 'Damaged' : 'Healthy'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item
|
||||
label="Brain"
|
||||
color={occupant.brainLoss ? 'bad' : 'good'}>
|
||||
{occupant.brainLoss ? 'Abnormal' : 'Healthy'}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</Section>
|
||||
<Section
|
||||
title="Operations"
|
||||
minHeight="205px"
|
||||
buttons={(
|
||||
<Fragment>
|
||||
{(<Button
|
||||
icon={'sign-out-alt'}
|
||||
content={'Eject Contents'}
|
||||
onClick={() => act('eject')} />)}
|
||||
{(<Button
|
||||
icon={cleaning ? 'exclamation-triangle' : 'recycle'}
|
||||
content={'Self-Clean Cycle'}
|
||||
disabled={cleaning}
|
||||
onClick={() => act('cleaning')} />)}
|
||||
</Fragment>
|
||||
)}>
|
||||
{chems.map(chem => (
|
||||
<Button
|
||||
key={chem.name}
|
||||
icon="flask"
|
||||
content={chem.name}
|
||||
disabled={!occupied}
|
||||
width="140px"
|
||||
onClick={() => act('inject', {
|
||||
chem: chem.id,
|
||||
})} />
|
||||
))}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user