//MEDBOT //MEDBOT PATHFINDING //MEDBOT ASSEMBLY /obj/machinery/bot/medbot name = "\improper Medibot" desc = "A little medical robot. He looks somewhat underwhelmed." icon = 'icons/obj/aibots.dmi' icon_state = "medibot0" layer = 5.0 density = 0 anchored = 0 health = 20 maxhealth = 20 req_one_access =list(access_medical, access_robotics) var/stunned = 0 //It can be stunned by tasers. Delicate circuits. // var/emagged = 0 var/list/botcard_access = list(access_medical) var/obj/item/weapon/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents. var/skin = null //Set to "tox", "ointment" or "o2" for the other two firstaid kits. var/mob/living/carbon/patient = null var/mob/living/carbon/oldpatient = null var/oldloc = null var/last_found = 0 var/last_newpatient_speak = 0 //Don't spam the "HEY I'M COMING" messages var/injection_amount = 15 //How much reagent do we inject at a time? var/heal_threshold = 10 //Start healing when they have this much damage in a category var/use_beaker = 0 //Use reagents in beaker instead of default treatment agents. var/declare_crit = 1 //If active, the bot will transmit a critical patient alert to MedHUD users. var/declare_cooldown = 0 //Prevents spam of critical patient alerts. var/stationary_mode = 0 //If enabled, the Medibot will not move automatically. radio_name = "Medical" //Setting which reagents to use to treat what by default. By id. var/treatment_brute = "salglu_solution" var/treatment_oxy = "salbutamol" var/treatment_fire = "salglu_solution" var/treatment_tox = "charcoal" var/treatment_virus = "spaceacillin" var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible. var/shut_up = 0 //self explanatory :) bot_type = MED_BOT bot_type_name = "Medbot" bot_filter = RADIO_MEDBOT /obj/machinery/bot/medbot/syndicate name = "Suspicious Medibot" desc = "You'd better have insurance!" skin = "bezerk" treatment_oxy = "perfluorodecalin" treatment_brute = "styptic_powder" treatment_fire = "silver_sulfadiazine" treatment_tox = "charcoal" /obj/machinery/bot/medbot/mysterious name = "\improper Mysterious Medibot" desc = "International Medibot of mystery." skin = "bezerk" treatment_oxy = "perfluorodecalin" treatment_brute = "styptic_powder" treatment_fire = "silver_sulfadiazine" treatment_tox = "charcoal" /obj/item/weapon/firstaid_arm_assembly name = "incomplete medibot assembly." desc = "A first aid kit with a robot arm permanently grafted to it." icon = 'icons/obj/aibots.dmi' icon_state = "firstaid_arm" var/build_step = 0 var/created_name = "Medibot" //To preserve the name if it's a unique medbot I guess var/skin = null //Same as medbot, set to tox or ointment for the respective kits. w_class = 3.0 /obj/item/weapon/firstaid_arm_assembly/New() ..() spawn(5) if(skin) overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]") /obj/machinery/bot/medbot/proc/updateicon() if(!on) icon_state = "medibot0" return if(mode == BOT_HEALING) icon_state = "medibots[stationary_mode]" return else if(stationary_mode) //Bot has yellow light to indicate stationary mode. icon_state = "medibot2" else icon_state = "medibot1" /obj/machinery/bot/medbot/New() ..() updateicon() spawn(4) if(skin) overlays += image('icons/obj/aibots.dmi', "medskin_[skin]") if(isnull(botcard_access) || (botcard_access.len < 1)) var/datum/job/doctor/J = new/datum/job/doctor botcard.access = J.get_access() else botcard.access = botcard_access prev_access = botcard.access add_to_beacons(bot_filter) /obj/machinery/bot/medbot/turn_on() . = ..() updateicon() updateUsrDialog() /obj/machinery/bot/medbot/turn_off() ..() updateicon() updateUsrDialog() /obj/machinery/bot/medbot/bot_reset() ..() patient = null oldpatient = null oldloc = null last_found = world.time declare_cooldown = 0 /obj/machinery/bot/medbot/set_custom_texts() text_hack = "You corrupt [name]'s reagent processor circuits." text_dehack = "You reset [name]'s reagent processor circuits." text_dehack_fail = "[name] seems damaged and does not respond to reprogramming!" /obj/machinery/bot/medbot/attack_hand(mob/user as mob) . = ..() if (.) return usr.set_machine(src) var/dat dat += hack(user) dat += "Medical Unit Controls v1.1

" dat += "Status: [on ? "On" : "Off"]
" dat += "Maintenance panel panel is [open ? "opened" : "closed"]
" dat += "Beaker: " if (reagent_glass) dat += "Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]" else dat += "None Loaded" dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]
" if(!locked || issilicon(user)) dat += "Healing Threshold: " dat += "-- " dat += "- " dat += "[heal_threshold] " dat += "+ " dat += "++" dat += "
" dat += "Injection Level: " dat += "- " dat += "[injection_amount] " dat += "+ " dat += "
" dat += "Reagent Source: " dat += "[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]
" dat += "Treat Viral Infections: [treat_virus ? "Yes" : "No"]
" dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle
" dat += "Critical Patient Alerts: [declare_crit ? "Yes" : "No"]
" dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
" dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
" var/datum/browser/popup = new(user, "automed", "Automatic Medical Unit v1.1") popup.set_content(dat) popup.open() return /obj/machinery/bot/medbot/Topic(href, href_list) ..() if(href_list["adj_threshold"]) var/adjust_num = text2num(href_list["adj_threshold"]) heal_threshold += adjust_num if(heal_threshold < 5) heal_threshold = 5 if(heal_threshold > 75) heal_threshold = 75 else if(href_list["adj_inject"]) var/adjust_num = text2num(href_list["adj_inject"]) injection_amount += adjust_num if(injection_amount < 5) injection_amount = 5 if(injection_amount > 15) injection_amount = 15 else if(href_list["use_beaker"]) use_beaker = !use_beaker else if (href_list["eject"] && (!isnull(reagent_glass))) reagent_glass.loc = get_turf(src) reagent_glass = null else if (href_list["togglevoice"]) shut_up = !shut_up else if (href_list["critalerts"]) declare_crit = !declare_crit else if (href_list["stationary"]) stationary_mode = !stationary_mode path = list() updateicon() else if (href_list["virus"]) treat_virus = !treat_virus updateUsrDialog() return /obj/machinery/bot/medbot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if (allowed(user) && !open && !emagged) locked = !locked user << "Controls are now [locked ? "locked." : "unlocked."]" updateUsrDialog() else if(emagged) user << "ERROR" if(open) user << "Please close the access panel before locking it." else user << "Access denied." else if (istype(W, /obj/item/weapon/reagent_containers/glass)) if(locked) user << "You cannot insert a beaker because the panel is locked." return if(!isnull(reagent_glass)) user << "There is already a beaker loaded." return user.drop_item() W.loc = src reagent_glass = W user << "You insert [W]." updateUsrDialog() return else var/current_health = health ..() if (health < current_health) //if medbot took some damage step_to(src, (get_step_away(src,user))) /obj/machinery/bot/medbot/Emag(mob/user as mob) ..() if(emagged == 2) declare_crit = 0 if(user) user << "You short out [src]'s reagent synthesis circuits." spawn(0) visible_message("[src] buzzes oddly!") flick("medibot_spark", src) if(user) oldpatient = user /obj/machinery/bot/medbot/process_scan(var/mob/living/carbon/human/H) if (H.stat == 2) return if ((H == oldpatient) && (world.time < last_found + 100)) return if(assess_patient(H)) last_found = world.time if((last_newpatient_speak + 300) < world.time) //Don't spam these messages! var/message = pick("Hey, [H.name]! Hold on, I'm coming.","Wait [H.name]! I want to help!","[H.name], you appear to be injured!") speak(message) last_newpatient_speak = world.time return H else return /obj/machinery/bot/medbot/bot_process() if (!..()) return if(mode == BOT_HEALING) return if(stunned) icon_state = "medibota" stunned-- oldpatient = patient patient = null mode = BOT_IDLE if(stunned <= 0) updateicon() stunned = 0 return if(frustration > 8) oldpatient = patient patient = null mode = BOT_IDLE last_found = world.time path = list() if(!patient) if(!shut_up && prob(1)) var/message = pick("Radar, put a mask on!","There's always a catch, and it's the best there is.","I knew it, I should've been a plastic surgeon.","What kind of medbay is this? Everyone's dropping like dead flies.","Delicious!") speak(message) var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) //If in stationary mode, scan range is limited to adjacent patients. patient = scan(/mob/living/carbon/human, oldpatient, scan_range) oldpatient = patient if(patient && (get_dist(src,patient) <= 1)) //Patient is next to us, begin treatment! if(mode != BOT_HEALING) mode = BOT_HEALING updateicon() frustration = 0 medicate_patient(patient) return //Patient has moved away from us! else if(patient && path.len && (get_dist(patient,path[path.len]) > 2)) path = list() mode = BOT_IDLE last_found = world.time else if(stationary_mode && patient) patient = null mode = BOT_IDLE last_found = world.time return if(patient && path.len == 0 && (get_dist(src,patient) > 1)) spawn(0) path = AStar(loc, get_turf(patient), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_cardinal, 0, 30,id=botcard) if(!path) path = list() if(path.len > 0 && patient) if(!bot_move(patient)) oldpatient = patient patient = null mode = BOT_IDLE last_found = world.time return if(path.len > 8 && patient) frustration++ if(auto_patrol && !stationary_mode && !patient) if(mode == BOT_IDLE || mode == BOT_START_PATROL) start_patrol() if(mode == BOT_PATROL) bot_patrol() return /obj/machinery/bot/medbot/proc/assess_patient(mob/living/carbon/C as mob) //Time to see if they need medical help! if(C.stat == 2) return 0 //welp too late for them! if(C.suiciding) return 0 //Kevorkian school of robotic medical assistants. if(emagged == 2) //Everyone needs our medicine. (Our medicine is toxins) return 1 if((skin == "bezerk") && (!("syndicate" in C.faction))) return 0 if(declare_crit && C.health <= 0) //Critical condition! Call for help! declare(C) //If they're injured, we're using a beaker, and don't have one of our WONDERCHEMS. if((reagent_glass) && (use_beaker) && ((C.getBruteLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getToxLoss() >= heal_threshold) || (C.getOxyLoss() >= (heal_threshold + 15)))) for(var/datum/reagent/R in reagent_glass.reagents.reagent_list) if(!C.reagents.has_reagent(R.id)) return 1 //They're injured enough for it! if((C.getBruteLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_brute))) return 1 //If they're already medicated don't bother! if((C.getOxyLoss() >= (15 + heal_threshold)) && (!C.reagents.has_reagent(treatment_oxy))) return 1 if((C.getFireLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_fire))) return 1 if((C.getToxLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_tox))) return 1 if((C.virus2.len) && (!C.reagents.has_reagent(treatment_virus))) for (var/ID in C.virus2) if (ID in virusDB) // If the virus is known, the medbot is aware of it return 1 return 0 /obj/machinery/bot/medbot/proc/medicate_patient(mob/living/carbon/C as mob) if(!on) return if(!istype(C)) oldpatient = patient patient = null mode = BOT_IDLE last_found = world.time return if(C.stat == 2) var/death_message = pick("No! NO!","Live, damnit! LIVE!","I...I've never lost a patient before. Not today, I mean.") speak(death_message) oldpatient = patient patient = null mode = BOT_IDLE last_found = world.time return var/reagent_id = null if(emagged == 2) //Emagged! Time to poison everybody. reagent_id = "pancuronium" else if(treat_virus) var/virus = 0 if(C:virus2.len) for (var/ID in C.virus2) if (ID in virusDB) // If the virus is known, the medbot is aware of it and will try to cure it virus = 1 if (!reagent_id && (virus)) if(!C.reagents.has_reagent(treatment_virus)) reagent_id = treatment_virus if (!reagent_id && (C.getBruteLoss() >= heal_threshold)) if(!C.reagents.has_reagent(treatment_brute)) reagent_id = treatment_brute if (!reagent_id && (C.getOxyLoss() >= (15 + heal_threshold))) if(!C.reagents.has_reagent(treatment_oxy)) reagent_id = treatment_oxy if (!reagent_id && (C.getFireLoss() >= heal_threshold)) if(!C.reagents.has_reagent(treatment_fire)) reagent_id = treatment_fire if (!reagent_id && (C.getToxLoss() >= heal_threshold)) if(!C.reagents.has_reagent(treatment_tox)) reagent_id = treatment_tox //If the patient is injured but doesn't have our special reagent in them then we should give it to them first if(reagent_id && use_beaker && reagent_glass && reagent_glass.reagents.total_volume) for(var/datum/reagent/R in reagent_glass.reagents.reagent_list) if(!C.reagents.has_reagent(R.id)) reagent_id = "internal_beaker" break if(!reagent_id) //If they don't need any of that they're probably cured! oldpatient = patient patient = null mode = BOT_IDLE last_found = world.time var/message = pick("All patched up!","An apple a day keeps me away.","Feel better soon!") speak(message) updateicon() return else C.visible_message("[src] is trying to inject [patient]!", \ "[src] is trying to inject [patient]!") spawn(30) if ((get_dist(src, patient) <= 1) && (on)) if(reagent_id == "internal_beaker") if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume) reagent_glass.reagents.trans_to(patient,injection_amount) //Inject from beaker instead. reagent_glass.reagents.reaction(patient, 2) else patient.reagents.add_reagent(reagent_id,injection_amount) C.visible_message("[src] injects [patient] with the syringe!", \ "[src] injects [patient] with the syringe!") mode = BOT_IDLE updateicon() return reagent_id = null return /obj/machinery/bot/medbot/bullet_act(var/obj/item/projectile/Proj) if(Proj.flag == "taser") stunned = min(stunned+10,20) ..() /obj/machinery/bot/medbot/explode() on = 0 visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) new /obj/item/weapon/storage/firstaid(Tsec) new /obj/item/device/assembly/prox_sensor(Tsec) new /obj/item/device/healthanalyzer(Tsec) if(reagent_glass) reagent_glass.loc = Tsec reagent_glass = null if (prob(50)) new /obj/item/robot_parts/l_arm(Tsec) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() qdel(src) return /obj/machinery/bot/medbot/proc/declare(var/crit_patient) if(declare_cooldown) return if((skin == "bezerk")) return var/area/location = get_area(src) speak("Medical emergency! [crit_patient ? "[crit_patient]" : "A patient"] is in critical condition at [location]!", radio_name) declare_cooldown = 1 spawn(200) //Twenty seconds declare_cooldown = 0 /* * Medbot Assembly -- Can be made out of all three medkits. */ /obj/item/weapon/storage/firstaid/attackby(var/obj/item/robot_parts/S, mob/user as mob, params) if ((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm))) ..() return //Making a medibot! if(contents.len >= 1) user << "You need to empty [src] out first." return var/obj/item/weapon/firstaid_arm_assembly/A = new /obj/item/weapon/firstaid_arm_assembly if(istype(src,/obj/item/weapon/storage/firstaid/fire)) A.skin = "ointment" else if(istype(src,/obj/item/weapon/storage/firstaid/toxin)) A.skin = "tox" else if(istype(src,/obj/item/weapon/storage/firstaid/o2)) A.skin = "o2" qdel(S) user.put_in_hands(A) user << "You add the robot arm to the first aid kit." user.unEquip(src, 1) qdel(src) /obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/pen)) var/t = stripped_input(user, "Enter new robot name", name, created_name,MAX_NAME_LEN) if (!t) return if (!in_range(src, usr) && loc != usr) return created_name = t else switch(build_step) if(0) if(istype(W, /obj/item/device/healthanalyzer)) user.drop_item() qdel(W) build_step++ user << "You add the health sensor to [src]." name = "First aid/robot arm/health analyzer assembly" overlays += image('icons/obj/aibots.dmi', "na_scanner") if(1) if(isprox(W)) user.drop_item() qdel(W) build_step++ user << "You complete the Medibot! Beep boop." var/turf/T = get_turf(src) var/obj/machinery/bot/medbot/S = new /obj/machinery/bot/medbot(T) S.skin = skin S.name = created_name user.unEquip(src, 1) qdel(src)