Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPR Buddy 9000 #7092

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3c82deb
CPR Buddy 9000
HIDgamer Sep 3, 2024
5cfd524
Idle message and medical facts list fix.
HIDgamer Sep 3, 2024
d135e66
Garbage Collection
HIDgamer Sep 3, 2024
d3f4404
fixed indents
HIDgamer Sep 3, 2024
682a229
Code update
HIDgamer Sep 4, 2024
ea30948
Major code refinement and updates.
HIDgamer Sep 8, 2024
b9e4ce1
Merge branch 'cmss13-devs:master' into master
HIDgamer Sep 8, 2024
642561c
Updates and Bug fixes
HIDgamer Sep 9, 2024
ded3760
CPRbot sound update.
HIDgamer Sep 9, 2024
6e5aae0
Merge branch 'master' into master
HIDgamer Sep 9, 2024
f130138
Merge branch 'master' into master
HIDgamer Sep 9, 2024
9d7f9b5
CPR warning
HIDgamer Sep 10, 2024
b917f99
Merge branch 'master' into master
HIDgamer Sep 10, 2024
ae2f9af
Merge branch 'master' into master
HIDgamer Sep 11, 2024
4aac004
Minor tweaks
HIDgamer Sep 12, 2024
90bc2cf
Merge branch 'master' into master
HIDgamer Sep 13, 2024
1ad467d
Merge branch 'master' into master
HIDgamer Sep 13, 2024
c7d9310
Merge branch 'cmss13-devs:master' into master
HIDgamer Sep 14, 2024
75e732c
Merge branch 'cmss13-devs:master' into master
HIDgamer Sep 15, 2024
d0c4f34
Merge branch 'cmss13-devs:master' into master
HIDgamer Sep 17, 2024
73b02b4
Merge branch 'cmss13-devs:master' into master
HIDgamer Sep 18, 2024
d8f0a38
Merge branch 'cmss13-devs:master' into master
HIDgamer Sep 20, 2024
0827dae
minor tweaks
HIDgamer Sep 21, 2024
7244c1e
AI pathfinding update
HIDgamer Sep 21, 2024
65903b9
fixing taps
HIDgamer Sep 21, 2024
26b3046
Merge branch 'cmss13-devs:master' into master
HIDgamer Sep 26, 2024
5a71c0a
Pathfinding tweaks
HIDgamer Sep 26, 2024
56d6159
Merge branch 'master' of https://github.com/HIDgamer/cmss13
HIDgamer Sep 26, 2024
48feafa
Merge branch 'cmss13-devs:master' into master
HIDgamer Sep 29, 2024
f970efa
Merge branch 'cmss13-devs:master' into master
HIDgamer Oct 3, 2024
b05421f
Merge branch 'cmss13-devs:master' into master
HIDgamer Oct 10, 2024
a3ada23
Merge branch 'cmss13-devs:master' into master
HIDgamer Oct 26, 2024
f880052
Merge branch 'cmss13-devs:master' into master
HIDgamer Oct 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 216 additions & 0 deletions code/game/machinery/bots/cprbot.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
/obj/structure/machinery/bot/cprbot
name = "\improper CPRbot"
desc = "Designed for urgent medical intervention, this CPRbot offers high-tech support in a compact form."
icon = 'icons/obj/structures/machinery/aibots.dmi'
icon_state = "cprbot0"
density = FALSE
anchored = FALSE
health = 100
maxhealth = 100
req_access = list(ACCESS_MARINE_MEDBAY)

/// Radius to search for patients
var/const/search_radius = 7
/// Radius to check for nearby CPRbots
var/const/cprbot_proximity_check_radius = 2
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
/// Indicates whether the bot is processing
var/processing = TRUE
/// Current target for CPR
var/mob/living/carbon/human/target = null
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
/// Time when the bot can perform CPR again
var/cpr_cooldown = 0
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
/// Path for movement logic
var/path = list()
/// Indicates whether the bot is currently healing
var/currently_healing = FALSE
/// IFF signal to check for valid targets
var/iff_signal = FACTION_MARINE
/// Cooldown for the random idle messages and medical facts
var/cooldown_time = 60 SECONDS
COOLDOWN_DECLARE(message_cooldown)

var/static/list/medical_facts = list(
"Did you know? The human heart beats over 100,000 times a day.",
"Fun fact: Blood makes up about 7% of your body's weight.",
"Medical trivia: Your brain uses 20% of the oxygen you breathe.",
"Laughter really can increase your pain tolerance.",
"Did you know? The human skeleton is made up of 206 bones.",
"Fun fact: The average adult human body contains about 5 liters of blood.",
"Medical trivia: The human body has around 37.2 trillion cells.",
"The skin is the largest organ in the human body.",
"Did you know? The liver can regenerate itself if a portion is removed.",
"Fun fact: Your sense of smell is closely linked to your memory.",
"The only muscle that never tires is that heart.",
"Did you know? Not breathing can lead to a premature cessation of life!"
)

var/static/list/idle_messages = list(
"Stay still, I'm assessing the situation.",
"Just a routine check-up, don't worry.",
"Scanning the area for any casualties.",
"I’m ready to save lives, one compression at a time.",
"I hope everyone is feeling alright today!",
"It's not magic, it's CPR Buddy 9000!",
"I should have been a plastic surgeon.",
"What kind of medbay is this? Everyone’s dropping like flies.",
"Each breath a day keeps me at bay!",
"I sense a disturbance in my circuit board, as if a million people stopped breathing and were suddenly silent."
)
Comment on lines +51 to +77
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the strings system for this


/// Message to display when performing CPR
var/motivational_message = "Live! Live! Don't die on me now!"
/// List of patients who have been warned
var/list/has_said_to_patient = list()
/// Tracks the last time a message was spoken
var/last_message_time = 0

/obj/structure/machinery/bot/cprbot/New()
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
..()
src.initialize_cprbot()

/obj/structure/machinery/bot/cprbot/proc/initialize_cprbot()
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
while (processing && health > 0)
src.find_and_move_to_patient()
if (target && world.time >= cpr_cooldown)
src.perform_cpr(target)
src.random_message() // Check if it's time to send a random message
sleep(0.5 SECONDS) // Slower processing loop, moves once every 2 seconds
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved

/obj/structure/machinery/bot/cprbot/Destroy()
target = null
path = null
return ..()

/obj/structure/machinery/bot/cprbot/proc/random_message()
if (!COOLDOWN_FINISHED(src, message_cooldown))
return // Exit if the cooldown period has not elapsed yet

// Send a message based on the current state
if (currently_healing)
speak(motivational_message)
else
if (prob(50))
speak(pick(medical_facts))
else
speak(pick(idle_messages))

// Start the cooldown timer for the next message
COOLDOWN_START(src, message_cooldown, cooldown_time)

/obj/structure/machinery/bot/cprbot/proc/speak(message)
if (!processing || !message)
return
visible_message("[src] beeps, \"[message]\"")

/obj/structure/machinery/bot/cprbot/proc/find_and_move_to_patient()
var/list/humans = list()
for (var/mob/living/carbon/human/patient in range(search_radius))
if (patient.stat == DEAD && patient.check_tod() && patient.is_revivable() && patient.get_target_lock(iff_signal) && !src.has_nearby_cprbot(patient))
humans += patient

if (length(humans) > 0)
target = src.get_nearest(humans)
if (target && !has_said_to_patient.Find(target))
visible_message("[target] is injured! I'm coming!")
has_said_to_patient += target
src.move_to_target(target)
else
target = null

/obj/structure/machinery/bot/cprbot/proc/has_nearby_cprbot(mob/living/carbon/human/H)
// Check if there are any other CPRbots within a two-tile radius of the target
for (var/obj/structure/machinery/bot/cprbot/nearby_cprbot in range(H, cprbot_proximity_check_radius))
if (nearby_cprbot != src) // Ignore self
return TRUE
return FALSE

/obj/structure/machinery/bot/cprbot/proc/get_nearest(list/humans)
var/mob/living/carbon/human/nearest = null
var/distance = search_radius + 1

for (var/mob/living/carbon/human/patient in humans)
var/length = get_dist(src, patient)
if (length < distance)
nearest = patient
distance = length

return nearest

/obj/structure/machinery/bot/cprbot/proc/move_to_target(mob/living/carbon/human/H)
if (H)
var/pathfinding_result = AStar(src.loc, get_turf(H), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30)
if (length(pathfinding_result) == 0)
// No reachable path to the target, so stop looking for this patient
target = null
return
path = pathfinding_result

// Begin moving towards the target if a path exists
if (get_dist(src, H) > 1)
if (length(path) > 0)
step_to(src, path[1])
path -= path[1]
sleep(0.5 SECONDS)
if (length(path))
step_to(src, path[1])
path -= path[1]
else
currently_healing = TRUE
else
target = null


/obj/structure/machinery/bot/cprbot/proc/perform_cpr(mob/living/carbon/human/H)
if (!H || H.stat != DEAD || !H.is_revivable() || !ishuman_strict(H))
target = null
icon_state = "cprbot0"
currently_healing = 0
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
return

if (get_dist(src, H) > 1)
src.move_to_target(H)
return

icon_state = "cprbot_active"
H.revive_grace_period += 4 SECONDS
cpr_cooldown = world.time + 7 SECONDS
H.visible_message(SPAN_NOTICE("<b>[src]</b> automatically performs <b>CPR</b> on <b>[H]</b>."))
H.visible_message(SPAN_DANGER("Currently performing CPR on <b>[H]</b> do not intervene!"))
currently_healing = TRUE

/obj/structure/machinery/bot/cprbot/proc/self_destruct(mob/living/carbon/human/user = null)
var/obj/item/cprbot_item/I = new /obj/item/cprbot_item(src.loc)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved

if (user)
if (!user.put_in_active_hand(I))
if (!user.put_in_inactive_hand(I))
I.forceMove(src.loc)
else
I.forceMove(src.loc)

qdel(src)

/obj/structure/machinery/bot/cprbot/attack_hand(mob/user as mob)
if (..())
return TRUE

SEND_SIGNAL(user, COMSIG_LIVING_ATTACKHAND_HUMAN, src)

if (user != src)
visible_message(SPAN_DANGER("<B>[user] begins to undeploy [src]!</B>"))
src.self_destruct(user)
return TRUE

/obj/structure/machinery/bot/cprbot/explode()
src.on = 0
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
src.visible_message(SPAN_DANGER("<B>[src] blows apart!</B>"), null, null, 1)
var/turf/Tsec = get_turf(src)

new /obj/item/cprbot_broken(Tsec)

var/datum/effect_system/spark_spread/spark = new /datum/effect_system/spark_spread
spark.set_up(3, 1, src)
spark.start()

qdel(src)
return
1 change: 1 addition & 0 deletions code/game/machinery/vending/vendor_types/crew/synthetic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ GLOBAL_LIST_INIT(cm_vending_synth_tools, list(
list("Maintenance Jack", 15, /obj/item/maintenance_jack, null, VENDOR_ITEM_REGULAR),
list("Portable Dialysis Machine", 15, /obj/item/tool/portadialysis, null, VENDOR_ITEM_REGULAR),
list("Telescopic Baton", 15, /obj/item/weapon/telebaton, null, VENDOR_ITEM_REGULAR),
list("CPR Buddy 9k", 15, /obj/item/cprbot_item, null, VENDOR_ITEM_REGULAR),
))

//------------EXPERIMENTAL TOOL KITS---------------
Expand Down
110 changes: 110 additions & 0 deletions code/game/objects/items/cprbot.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/obj/item/cprbot_item
name = "CPRbot"
desc = "A compact CPRbot 9000 asemply"
icon = 'icons/obj/structures/machinery/aibots.dmi'
icon_state = "cprbot"
w_class = SIZE_MEDIUM
var/deployment_path = /obj/structure/machinery/bot/cprbot

/obj/item/cprbot_item/proc/deploy_cprbot(mob/user, atom/location)
if(!user || !location)
return
// Attempt to delete the item first
qdel(src)
world << "Deleting item [src]. Deploying CPRbot at [location]."

// Proceed with the CPRbot deployment
var/obj/structure/machinery/bot/cprbot/R = new deployment_path(location)
if(R)
R.add_fingerprint(user)
world << "CPRbot deployed successfully at [location]."
else
world << "Failed to deploy CPRbot at [location]."

/obj/item/cprbot_item/attack_self(mob/user)
if (..())
return TRUE
if(user)
deploy_cprbot(user, user.loc)

/obj/item/cprbot_item/afterattack(atom/target, mob/user, proximity)
if(proximity && isturf(target))
var/turf/T = target
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
if(!T.density)
deploy_cprbot(user, T)

/obj/item/cprbot_broken
name = "CPRbot"
desc = "A compact CPRbot 9000 asemply it appears to be in bad shape"
icon = 'icons/obj/structures/machinery/aibots.dmi'
icon_state = "cprbot_broken"
w_class = SIZE_MEDIUM

/obj/item/cprbot_broken/attackby(obj/item/W, mob/living/user)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
if(iswelder(W))
if(!HAS_TRAIT(W, TRAIT_TOOL_BLOWTORCH))
to_chat(user, SPAN_WARNING("You need a stronger blowtorch!"))
return

var/obj/item/tool/weldingtool/WT = W
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
if(!WT.isOn())
to_chat(user, SPAN_WARNING("\The [WT] needs to be on!"))
return

if(!WT.remove_fuel(5, user)) // Ensure the welder has enough fuel to operate
to_chat(user, SPAN_NOTICE("You need more welding fuel to complete this task."))
return

playsound(src, 'sound/items/Welder.ogg', 25, 1)

if(!do_after(user, 10 * user.get_skill_duration_multiplier(SKILL_CONSTRUCTION), INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

var/obj/item/cprbot_item/I = new /obj/item/cprbot_item(src.loc)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved

if(user)
if(!user.put_in_active_hand(I))
if(!user.put_in_inactive_hand(I))
I.forceMove(src.loc)
else
I.forceMove(src.loc)

/obj/item/cprbot_broken/attackby(obj/item/W, mob/living/user)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
if(iswelder(W))
if(!HAS_TRAIT(W, TRAIT_TOOL_BLOWTORCH))
to_chat(user, SPAN_WARNING("You need a stronger blowtorch!"))
return

var/obj/item/tool/weldingtool/WT = W
if(!WT.isOn())
to_chat(user, SPAN_WARNING("\The [WT] needs to be on!"))
return

if(!WT.remove_fuel(5, user)) // Ensure enough fuel is available
to_chat(user, SPAN_NOTICE("You need more welding fuel to complete this task."))
return

playsound(src, 'sound/items/Welder.ogg', 25, 1)

if(!do_after(user, 10 * user.get_skill_duration_multiplier(SKILL_CONSTRUCTION), INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

// Create the repaired item
var/obj/item/cprbot_item/I = new /obj/item/cprbot_item(src.loc)

// Check if the broken item is in the user's hand
var/hand_was_active = user.get_active_hand() == src
var/hand_was_inactive = user.get_inactive_hand() == src

// Remove the broken item
qdel(src)

// Attempt to place the new item into the user's hands
if (hand_was_active)
if (!user.put_in_active_hand(I))
I.forceMove(user.loc) // Place it at user's location if hands are full
else if (hand_was_inactive)
if (!user.put_in_inactive_hand(I))
I.forceMove(user.loc) // Place it at user's location if hands are full
else
I.forceMove(user.loc) // Place at the original location if not in hand
2 changes: 2 additions & 0 deletions colonialmarines.dme
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,7 @@
#include "code\game\machinery\atmoalter\scrubber.dm"
#include "code\game\machinery\bots\bots.dm"
#include "code\game\machinery\bots\cleanbot.dm"
#include "code\game\machinery\bots\cprbot.dm"
#include "code\game\machinery\bots\floorbot.dm"
#include "code\game\machinery\bots\medbot.dm"
#include "code\game\machinery\bots\mulebot.dm"
Expand Down Expand Up @@ -1088,6 +1089,7 @@
#include "code\game\objects\items\contraband.dm"
#include "code\game\objects\items\cosmetics.dm"
#include "code\game\objects\items\cpr_dummy.dm"
#include "code\game\objects\items\cprbot.dm"
#include "code\game\objects\items\disks.dm"
#include "code\game\objects\items\fulton.dm"
#include "code\game\objects\items\gift_wrappaper.dm"
Expand Down
Binary file modified icons/obj/structures/machinery/aibots.dmi
Binary file not shown.
Loading