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

Merged
merged 61 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
61 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
ee200fd
Merge branch 'cmss13-devs:master' into master
HIDgamer Nov 22, 2024
e6e85bb
Merge branch 'cmss13-devs:master' into master
HIDgamer Dec 3, 2024
fb1fbf9
Temp_Christmas_Hat
HIDgamer Dec 6, 2024
ee27761
Merge branch 'cmss13-devs:master' into master
HIDgamer Dec 6, 2024
114ed52
Revert "Temp_Christmas_Hat"
HIDgamer Dec 6, 2024
8b2e95f
Merge branch 'cmss13-devs:master' into master
HIDgamer Dec 8, 2024
059c21b
Merge branch 'cmss13-devs:master' into master
HIDgamer Dec 13, 2024
4d708f5
Merge branch 'cmss13-devs:master' into master
HIDgamer Dec 19, 2024
46824dc
cleaning the code
HIDgamer Dec 21, 2024
f4f8399
more code cleaning.
HIDgamer Dec 21, 2024
140d773
Merge branch 'cmss13-devs:master' into master
HIDgamer Dec 21, 2024
6f952b3
Further code cleaning
HIDgamer Dec 22, 2024
115a5d0
more cleaning
HIDgamer Dec 22, 2024
3e0723b
Merge branch 'master' into master
HIDgamer Dec 22, 2024
095445a
Even more code cleaning.
HIDgamer Dec 23, 2024
556aeca
Merge branch 'master' into master
HIDgamer Dec 23, 2024
095d949
Merge branch 'master' into master
HIDgamer Dec 23, 2024
7c77798
Update code/game/machinery/bots/cprbot.dm
kiVts Dec 24, 2024
dcc3b97
Update code/game/machinery/bots/cprbot.dm
kiVts Dec 24, 2024
93514e1
Update code/game/machinery/bots/cprbot.dm
kiVts Dec 24, 2024
cb6f8a1
Update code/game/objects/items/cprbot.dm
kiVts Dec 24, 2024
1e8e457
Merge branch 'master' into master
kiVts Dec 24, 2024
6c9f76e
renamed file.
HIDgamer Dec 24, 2024
15385ad
renamed 2
HIDgamer Dec 24, 2024
eb4174a
renamed 3
HIDgamer Dec 24, 2024
c115453
Update code/game/machinery/bots/cprbot.dm
kiVts Dec 24, 2024
84da7f0
Merge branch 'master' into master
HIDgamer Dec 24, 2024
36095d5
removed from the coin vendor.
HIDgamer Dec 24, 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
332 changes: 332 additions & 0 deletions code/game/machinery/bots/cprbot.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
#define STATE_CPRBOT_IDLE "idle"
#define STATE_CPRBOT_MOVING "moving"
#define STATE_CPRBOT_CPR "cpr"
#define STATE_CPRBOT_FOLLOWING_OWNER "following_owner"


/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/static/search_radius = 7
/// Radius to check for nearby CPRbots
var/static/cprbot_proximity_check_radius = 2
/// Current target for CPR (using weak reference)
var/datum/weakref/human
/// Indicates whether the bot is currently healing
var/currently_healing = FALSE
var/cpr_ready = TRUE
/// 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
var/movement_delay = 4
var/owner
var/fast_processing = FALSE
COOLDOWN_DECLARE(message_cooldown)

var/state = STATE_CPRBOT_IDLE

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.",
"It's a Dyer situation it is!"
)

/// 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/Initialize(mapload, ...)
. = ..()
start_processing()
playsound(loc, 'sound/CPRbot/CPRbot_poweron.ogg', 25, 1)

/obj/structure/machinery/bot/cprbot/process()
if (health > 0)
think()

random_message()
else
stop_processing()

/obj/structure/machinery/bot/cprbot/proc/think()
switch (state)
if (STATE_CPRBOT_IDLE)
find_and_move_to_patient()
if (STATE_CPRBOT_MOVING)
move_to_target()
if (STATE_CPRBOT_CPR)
try_perform_cpr()
if (STATE_CPRBOT_FOLLOWING_OWNER)
find_and_move_to_patient()


/obj/structure/machinery/bot/cprbot/start_processing()
START_PROCESSING(SSobj, src)

/obj/structure/machinery/bot/cprbot/stop_processing()
if (fast_processing)
STOP_PROCESSING(SSfastobj, src)
else
STOP_PROCESSING(SSobj, src)

/obj/structure/machinery/bot/cprbot/Destroy()
human = null

stop_processing()
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)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
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 (!message)
return
visible_message("[src] beeps, \"[message]\"")
playsound(loc, 'sound/CPRbot/CPRbot_beep.ogg', 25, 1)

/obj/structure/machinery/bot/cprbot/proc/go_idle()
human = null
state = STATE_CPRBOT_IDLE
cpr_ready = TRUE
currently_healing = FALSE
walk_to(src, 0) // make sure we stop walking
update_icon()

/obj/structure/machinery/bot/cprbot/proc/valid_cpr_target(mob/living/carbon/human/patient)
return patient.stat == DEAD && patient.check_tod() && patient.is_revivable() && patient.get_target_lock(iff_signal)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved

/obj/structure/machinery/bot/cprbot/proc/find_and_move_to_patient()
var/list/potential_patients = list()
has_said_to_patient = list()
for (var/mob/living/carbon/human/patient in view(search_radius, src))
if (valid_cpr_target(patient))
potential_patients += patient

for (var/obj/structure/machinery/bot/cprbot/another_cpr_bot in view(search_radius, src))
if (another_cpr_bot == src)
continue

var/mob/living/carbon/human/another_bot_patient

// sanity checks
if (another_cpr_bot.human != null)
another_bot_patient = another_cpr_bot.human.resolve()

// sanity checks
if (another_bot_patient == null)
continue

// Another CPR bot is targetting this patient, skip
if (another_bot_patient in potential_patients)
potential_patients.Remove(another_bot_patient)

if (potential_patients.len)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
var/mob/living/carbon/human/patient = potential_patients[1]
human = WEAKREF(patient)
if (patient && !(patient in has_said_to_patient))
visible_message("[patient] is injured! I'm coming!")
has_said_to_patient += patient

move_to_target()
else
// If no patients are found, check if owner is nearby and follow them if idle
if (state == STATE_CPRBOT_IDLE && (owner && (owner in view(search_radius, src))))
state = STATE_CPRBOT_FOLLOWING_OWNER
walk_to(src, owner, 0, movement_delay)
else if (state == STATE_CPRBOT_FOLLOWING_OWNER)
// Continue following the owner if no patient is in sight
walk_to(src, owner, 0, movement_delay)
else
go_idle()

/obj/structure/machinery/bot/cprbot/proc/can_still_see_patient()
if (human == null)
return FALSE

var/mob/living/carbon/human/patient = human.resolve()
if (patient == null)
return FALSE

return patient in view(search_radius, src)

/obj/structure/machinery/bot/cprbot/proc/patient_in_range()
if (human == null)
return FALSE

var/mob/living/carbon/human/patient = human.resolve()
if (patient == null)
return FALSE

return get_dist(src, patient) == 0

/obj/structure/machinery/bot/cprbot/proc/move_to_target()
var/mob/living/carbon/human/patient = human.resolve()
// If we cannot see them anymore then stop moving
if (!can_still_see_patient())
go_idle()
return

// It might not exist anymore or something
if (patient == null)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
go_idle()
return

if (!patient_in_range())
// We are already moving
if (state == STATE_CPRBOT_MOVING)
return

state = STATE_CPRBOT_MOVING
walk_to(src, patient, 0, movement_delay)
else
walk_to(src, 0) // make sure we stop walking
state = STATE_CPRBOT_CPR
switch_to_faster_processing()
try_perform_cpr()

/obj/structure/machinery/bot/cprbot/proc/perform_cpr(mob/living/carbon/human/target)
if (!cpr_ready)
return

currently_healing = TRUE

update_icon()

target.revive_grace_period += 4 SECONDS
target.visible_message(SPAN_NOTICE("<b>[src]</b> automatically performs <b>CPR</b> on <b>[target]</b>."))
target.balloon_alert_to_viewers("Performing CPR, stay clear!")
currently_healing = TRUE
playsound(loc, 'sound/CPRbot/CPR.ogg', 25, 1)
cpr_ready = FALSE
addtimer(VARSET_CALLBACK(src, cpr_ready, TRUE), 7 SECONDS)

/obj/structure/machinery/bot/cprbot/proc/try_perform_cpr()
currently_healing = TRUE
// Resolve the weak reference to check if the target still exists
var/mob/living/carbon/human/target = human.resolve()

if (!patient_in_range())
go_idle()
switch_to_slower_processing()
return

// Check if the target is valid and still needs CPR
if ((target.stat != DEAD) || (target.stat == DEAD && !target.check_tod()))
go_idle()
switch_to_slower_processing()
return

perform_cpr(target)

/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

playsound(loc, 'sound/CPRbot/CPRbot_poweroff.ogg', 25, 1)

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)
HIDgamer marked this conversation as resolved.
Show resolved Hide resolved
if (..())
return TRUE

if(!skillcheck(user, SKILL_MEDICAL, SKILL_MEDICAL_MEDIC))
visible_message(SPAN_DANGER("<B>[user] fails to undeploy [src] </B>"))
return FALSE

SEND_SIGNAL(user, COMSIG_LIVING_ATTACKHAND_HUMAN, src)

if (user != src)
visible_message(SPAN_DANGER("<B>[user] begins to undeploy [src]!</B>"))
kiVts marked this conversation as resolved.
Show resolved Hide resolved
self_destruct(user)
return TRUE

/obj/structure/machinery/bot/cprbot/update_icon()
. = ..()

switch(state)
if (STATE_CPRBOT_IDLE)
icon_state = "cprbot0"
if (STATE_CPRBOT_CPR)
icon_state = "cprbot_active"

/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)

playsound(loc, 'sound/CPRbot/CPRbot_poweroff.ogg', 25, 1)

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

/obj/structure/machinery/bot/cprbot/proc/switch_to_faster_processing()
STOP_PROCESSING(SSobj, src)
START_PROCESSING(SSfastobj, src)
fast_processing = TRUE

/obj/structure/machinery/bot/cprbot/proc/switch_to_slower_processing()
STOP_PROCESSING(SSfastobj, src)
START_PROCESSING(SSobj, src)
fast_processing = FALSE
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
Loading
Loading