Skip to content

Commit a38912a

Browse files
author
Matt Atlas
committed
a lot of stuff
1 parent 75fbfcb commit a38912a

File tree

11 files changed

+106
-59
lines changed

11 files changed

+106
-59
lines changed

code/__DEFINES/organs.dm

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,17 @@
4343
*/
4444
#define COMSIG_LIVER_FILTER_EVENT "liver_filter_event"
4545

46-
/// Raised external organ (a limb) takes damage. Used for the synthetic endoskeleton at the moment.
46+
/// Raised external organ (a limb) takes damage. Used for the synthetic endoskeleton at the moment. Must supply damage.
4747
#define COMSIG_EXTERNAL_ORGAN_DAMAGE "machine_internal_damage"
4848

4949
/// Sent when the burst damage is cleared by the posibrain.
5050
#define COMSIG_SYNTH_EMP_DAMAGE_CLEARED "emp_damage_cleared"
5151

52-
/// Sent when the synthetic enters self-preservation mode for whatever reason.
53-
#define COMSIG_SYNTH_SELF_PRESERVATION_TOGGLED "synth_self_preservation_toggle"
52+
/// Sent when the synthetic enters self-preservation mode. Must supply a TRUE/FALSE state.
53+
#define COMSIG_SYNTH_SET_SELF_PRESERVATION "synth_self_preservation_set"
5454

55-
/// Sent when endoskeleton repair is done.
55+
/// Sent when endoskeleton repair is done. Must supply a number of damage healed.
5656
#define COMSIG_SYNTH_ENDOSKELETON_REPAIR "synth_endoskeleton_repair"
57+
58+
/// Sent when a full endoskeleton repair is done. Unlike the normal one, also restores max_damage to initial state. No extra arguments.
59+
#define COMSIG_SYNTH_ENDOSKELETON_FULL_REPAIR "synth_endoskeleton_full_repair"
Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,51 @@
11
/datum/component/synthetic_endoskeleton
22
/// The synthetic that owns this component. Equivalent to `parent`, we just use this for ease of use.
33
var/mob/living/carbon/human/owner
4-
/// The posibrain of our parent.
5-
var/obj/item/organ/internal/machine/posibrain/posibrain
64
/**
75
* The synthetic endoskeleton is our answer to the eternal problem of IPCs being unable to be brainmed complaint because
86
* of a lack of mechanics to represent pain, organ breaking, or bleeding/respiration, which is how humans in brainmed are
97
* taken down nonlethally, or before they die.
108
*/
119
var/damage = 0
1210
/// The maximum damage the endoskeleton can take before triggering the safety shutdown.
13-
var/damage_maximum = 200
11+
var/max_damage = 200
12+
13+
/// Time until next message.
14+
var/message_cooldown = 10 SECONDS
15+
/// World.time of last message sent.
16+
var/last_sent_message = 0
1417

1518
/datum/component/synthetic_endoskeleton/Initialize(...)
1619
. = ..()
1720
if(isipc(parent))
1821
owner = parent
19-
var/obj/item/organ/internal/machine/posibrain/possible_brain = owner.internal_organs_by_name[BP_BRAIN]
20-
if(!istype(possible_brain))
21-
log_debug("Synthetic endoskeleton somehow could not find a brain. Deleting.")
22-
qdel_self()
23-
else
24-
posibrain = possible_brain
2522
else
2623
log_debug("Synthetic endoskeleton component spawned on non-IPC. Deleting.")
2724
qdel_self()
2825

2926
RegisterSignal(owner, COMSIG_EXTERNAL_ORGAN_DAMAGE, PROC_REF(receive_damage))
3027
RegisterSignal(owner, COMSIG_SYNTH_ENDOSKELETON_REPAIR, PROC_REF(heal_damage))
28+
RegisterSignal(owner, COMSIG_SYNTH_ENDOSKELETON_FULL_REPAIR, PROC_REF(full_repair))
3129

3230
/datum/component/synthetic_endoskeleton/Destroy(force)
3331
owner = null
34-
posibrain = null
3532
return ..()
3633

3734
/**
3835
* Signal handler called when an external synthetic limb receives damage.
3936
*/
40-
/datum/component/synthetic_endoskeleton/proc/receive_damage(amount)
37+
/datum/component/synthetic_endoskeleton/proc/receive_damage(atom/source, amount)
4138
SIGNAL_HANDLER
42-
damage = max(damage + amount, damage_maximum)
39+
damage = min(damage + amount, max_damage)
4340
handle_exoskeleton_damage()
4441

4542
/**
4643
* Signal handler called when the endoskeleton is repaired.
4744
*/
48-
/datum/component/synthetic_endoskeleton/proc/heal_damage(amount)
45+
/datum/component/synthetic_endoskeleton/proc/heal_damage(atom/source, amount)
4946
SIGNAL_HANDLER
5047
damage = max(damage - amount, 0)
51-
var/damage_ratio = damage_maximum / damage
48+
var/damage_ratio = damage / max_damage
5249
switch(damage_ratio)
5350
if(0 to 0.3)
5451
owner.remove_movespeed_modifier(/datum/movespeed_modifier/endoskeleton)
@@ -61,42 +58,63 @@
6158
if(!damage)
6259
STOP_PROCESSING(SSprocessing, src)
6360

61+
/**
62+
* Does a full repair of the endoskeleton, also restoring max_damage to initial state.
63+
*/
64+
/datum/component/synthetic_endoskeleton/proc/full_repair(atom/source)
65+
max_damage = initial(max_damage)
66+
heal_damage(source, max_damage)
67+
6468
/**
6569
* The function that handles exoskeleton damage effects.
6670
*/
6771
/datum/component/synthetic_endoskeleton/proc/handle_exoskeleton_damage()
6872
if(damage)
6973
START_PROCESSING(SSprocessing, src)
70-
var/damage_ratio = damage_maximum / damage
74+
var/damage_ratio = damage / max_damage
7175
switch(damage_ratio)
7276
if(0.3 to 0.5)
73-
to_chat(owner, SPAN_WARNING("Your self-preservation warning system notifies you of moderate damage to your endoskeleton's supports!"))
77+
notify_owner(owner, SPAN_WARNING("Your self-preservation warning system notifies you of moderate damage to your endoskeleton's supports!"))
7478
owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/endoskeleton, multiplicative_slowdown = 1)
7579
if(0.5 to 0.75)
76-
to_chat(owner, SPAN_WARNING("Your self-preservation warning system notifies you of major damage to your endoskeleton!"))
80+
notify_owner(owner, SPAN_WARNING("Your self-preservation warning system notifies you of major damage to your endoskeleton!"))
81+
spark(owner, 2, GLOB.alldirs)
7782
owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/endoskeleton, multiplicative_slowdown = 2)
78-
if(0.75 to 1)
79-
to_chat(owner, SPAN_DANGER(FONT_LARGE("Your self-preservation routines are starting to kick in! Your endoskeleton is falling apart!")))
83+
if(0.75 to 0.99)
84+
notify_owner(owner, SPAN_DANGER("Your self-preservation routines are starting to kick in! Your endoskeleton is falling apart!"))
85+
spark(owner, 3, GLOB.alldirs)
8086
owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/endoskeleton, multiplicative_slowdown = 3)
8187
if(1 to INFINITY)
82-
owner.visible_message(SPAN_DANGER("[owner]'s limbs seize up and [owner.get_pronoun("he")] falls to the ground!"), SPAN_DANGER(FONT_LARGE("Your self-preservation routines kick in and you enter a safety shutdown mode!")))
83-
SEND_SIGNAL(owner, COMSIG_SYNTH_SELF_PRESERVATION_TOGGLED)
88+
SEND_SIGNAL(owner, COMSIG_SYNTH_SET_SELF_PRESERVATION, TRUE)
8489

8590
/datum/component/synthetic_endoskeleton/process()
86-
var/damage_ratio = damage_maximum / damage
91+
if(owner.stat)
92+
return
93+
94+
var/damage_ratio = damage / max_damage
8795
switch(damage_ratio)
8896
if(0.3 to 0.5)
8997
if(prob(5))
90-
to_chat(owner, SPAN_MACHINE_WARNING("Warning: Endoskeleton integrity at [100 - (damage_ratio * 100)]%."))
98+
notify_owner(owner, SPAN_MACHINE_WARNING("Warning: Endoskeleton integrity at [100 - (damage_ratio * 100)]%."))
9199
if(0.5 to 0.75)
92100
if(prob(10))
93-
to_chat(owner, SPAN_MACHINE_WARNING("WARNING: Endoskeleton integrity at [100 - (damage_ratio * 100)]%!"))
94-
to_chat(owner, SPAN_WARNING("The mangled and exposed wires in your endoskeleton spark!"))
101+
notify_owner(owner, SPAN_MACHINE_WARNING("WARNING: Endoskeleton integrity at [100 - (damage_ratio * 100)]%!"))
102+
notify_owner(owner, SPAN_WARNING("The mangled and exposed wires in your endoskeleton spark!"))
95103
spark(owner, 3, GLOB.alldirs)
96104
owner.bodytemperature += 10
97105
if(0.75 to 1)
98-
if(prob(20))
99-
to_chat(owner, SPAN_MACHINE_DANGER("ENDOSKELETON INTEGRITY CRITICAL. Your self preservation blares at you to return to safety!"))
100-
to_chat(owner, SPAN_WARNING("Your frame creaks and groans, threatening to break apart at the metallic seams!"))
106+
if(prob(15))
107+
notify_owner(owner, SPAN_MACHINE_DANGER(FONT_LARGE("ENDOSKELETON INTEGRITY CRITICAL. Your self preservation blares at you to return to safety!")))
108+
notify_owner(owner, SPAN_DANGER("Your frame creaks and groans, threatening to break apart at the metallic seams!"))
101109
spark(owner, 4, GLOB.alldirs)
102110
owner.bodytemperature += 20
111+
112+
/**
113+
* Wrapper to_chat proc with a stat check.
114+
*/
115+
/datum/component/synthetic_endoskeleton/proc/notify_owner(mob/living/carbon/human/user, message)
116+
if(user.is_asystole() || (last_sent_message + message_cooldown > world.time))
117+
return
118+
119+
to_chat(user, message)
120+
last_sent_message = world.time

code/game/objects/items/stacks/nanopaste.dm

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,25 @@
8383
var/obj/item/organ/external/S = H.get_organ(target_zone)
8484

8585
if (S && (S.status & ORGAN_ASSISTED))
86+
var/datum/component/synthetic_endoskeleton/endoskeleton = H.GetComponent(/datum/component/synthetic_endoskeleton)
87+
if(istype(endoskeleton) && endoskeleton.damage)
88+
if(target_mob == user)
89+
if(endoskeleton.damage >= endoskeleton.max_damage * 0.5)
90+
to_chat(user, SPAN_WARNING("Your control over your limbs is too damaged to apply the nanopaste precisely!"))
91+
return
92+
application_time *= application_multiplier // It takes longer to apply nanopaste to yourself than to someone else.
93+
94+
if (application_in_progress == FALSE)
95+
application_in_progress = TRUE
96+
user.visible_message(SPAN_NOTICE("\The [user] begins to apply nanite past to the broken support systems of [user != target_mob ? " \the [target_mob]'s" : "\the [user]'s"] endoskeleton..."), \
97+
SPAN_NOTICE("You begin to apply nanite paste to the broken support systems of [user != target_mob ? " \the [target_mob]'s" : "your"] [endoskeleton]..."))
98+
if(do_mob(user, target_mob, application_time))
99+
SEND_SIGNAL(target_mob, COMSIG_SYNTH_ENDOSKELETON_REPAIR, rand(15, 30))
100+
user.visible_message(SPAN_NOTICE("\The [user] mends the broken links in [user != target_mob ? " \the [target_mob]'s" : "\the [user]'s"] endoskeleton with \the [src]."),\
101+
SPAN_NOTICE("You successfully mend the broken links in[user == target_mob ? "your" : "[target_mob]'s"] endoskeleton with \the [src]."))
102+
use(1)
103+
application_in_progress = FALSE
104+
86105
if(S.get_damage())
87106
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
88107

code/modules/mob/living/carbon/human/human_organs.dm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,11 @@
198198
if(isSynthetic())
199199
var/obj/item/organ/internal/machine/power_core/C = internal_organs_by_name[BP_CELL]
200200
if(istype(C) && C.is_usable() && C.percent())
201-
return FALSE
202-
var/obj/item/organ/internal/machine/posibrain/posi = internal_organs_by_name[BP_BRAIN]
203-
if(istype(posi) && !posi.self_preservation_activated)
204-
return FALSE
201+
var/obj/item/organ/internal/machine/posibrain/posi = internal_organs_by_name[BP_BRAIN]
202+
if(istype(posi) && !posi.self_preservation_activated)
203+
return FALSE
205204
return TRUE
205+
206206
else if(should_have_organ(BP_HEART))
207207
var/obj/item/organ/internal/heart/heart = internal_organs_by_name[BP_HEART]
208208
if(!istype(heart) || !heart.is_working())

code/modules/mob/living/carbon/human/species/station/ipc/ipc.dm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@
200200
if(!endoskeleton)
201201
return 6 //how?
202202

203-
var/damage_ratio = endoskeleton.damage_maximum / endoskeleton.damage
203+
var/damage_ratio = endoskeleton.damage / endoskeleton.max_damage
204204
switch(damage_ratio)
205205
if(0.3 to 0.5)
206206
stance_damage += 1

code/modules/organs/internal/species/machine/posibrain.dm

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
/// Stores the current status of EMP damage.
3838
var/emp_damage_counter = 0
3939
/// Maximum EMP damage points we can have.
40-
var/emp_damage_maximum = 3
40+
var/emp_max_damage = 3
4141
/// The amount of seconds the brain should be scrambled for, while this is above 0, it'll add a flat 2 evaluate_damage()'s damage points
4242
var/brain_scrambling = 0
4343
/// Whether or not the positronic's self-preservation is toggled. Basically knocks the IPC out.
@@ -53,7 +53,7 @@
5353
set_max_damage(species.total_health)
5454
else
5555
set_max_damage(200)
56-
RegisterSignal(owner, COMSIG_SYNTH_SELF_PRESERVATION_TOGGLED, PROC_REF(toggle_self_preservation))
56+
RegisterSignal(owner, COMSIG_SYNTH_SET_SELF_PRESERVATION, PROC_REF(set_self_preservation))
5757
sizzle = new(owner)
5858

5959
/obj/item/organ/internal/machine/posibrain/Destroy()
@@ -63,9 +63,7 @@
6363

6464
/obj/item/organ/internal/machine/posibrain/rejuvenate()
6565
. = ..()
66-
var/datum/component/synthetic_endoskeleton/endoskeleton = owner.GetComponent(/datum/component/synthetic_endoskeleton)
67-
if(endoskeleton)
68-
endoskeleton.heal_damage(endoskeleton.damage_maximum)
66+
SEND_SIGNAL(owner, COMSIG_SYNTH_ENDOSKELETON_FULL_REPAIR)
6967
emp_damage_counter = 0
7068
brain_scrambling = 0
7169
remove_fragmentation(max_damage)
@@ -176,7 +174,7 @@
176174
* This proc adds to the EMP damage counter, and automatically starts a unique/override timer to clear it.
177175
*/
178176
/obj/item/organ/internal/machine/posibrain/proc/add_emp_damage_counter()
179-
emp_damage_counter = min(emp_damage_counter + 1, emp_damage_maximum)
177+
emp_damage_counter = min(emp_damage_counter + 1, emp_max_damage)
180178
handle_emp_damage()
181179
addtimer(CALLBACK(src, PROC_REF(clear_emp_damage_counter)), emp_damage_counter * 20, TIMER_OVERRIDE | TIMER_UNIQUE)
182180

@@ -350,14 +348,16 @@
350348

351349
var/datum/component/synthetic_endoskeleton/endoskeleton = owner.GetComponent(/datum/component/synthetic_endoskeleton)
352350
if(endoskeleton && endoskeleton.damage)
353-
var/damage_ratio = endoskeleton.damage_maximum / endoskeleton.damage
351+
var/damage_ratio = endoskeleton.damage / endoskeleton.max_damage
354352
switch(damage_ratio)
355353
if(0.3 to 0.5)
356354
damage_points++
357355
if(0.5 to 0.75)
358356
damage_points += 2
359-
if(0.75 to INFINITY)
360-
damage_points += 3
357+
if(0.75 to 0.85)
358+
damage_points += 4
359+
if(0.85 to INFINITY)
360+
damage_points += 5
361361

362362
if(damage_points)
363363
damage_points = min(6, damage_points)
@@ -457,15 +457,21 @@
457457
cooling_unit.locked_thermostat = FALSE
458458
cooling_unit.take_internal_damage(20)
459459

460-
/obj/item/organ/internal/machine/posibrain/proc/toggle_self_preservation()
460+
/obj/item/organ/internal/machine/posibrain/proc/set_self_preservation(atom/source, state)
461461
SIGNAL_HANDLER
462-
if(self_preservation_activated)
462+
if(state == self_preservation_activated)
463+
return
464+
465+
self_preservation_activated = state
466+
if(!self_preservation_activated)
463467
owner.visible_message(SPAN_WARNING("A crackle of electricity is heard as [owner]'s limbs twitch almost imperceptibly."), SPAN_MACHINE_WARNING("Your control is restored to you as your self-preservation protocols ease up."))
464-
playsound(owner, 'sound/species/synthetic/synthetic_restart.ogg', 100)
468+
if(!is_broken())
469+
playsound(owner, 'sound/species/synthetic/synthetic_restart.ogg', 100)
465470
self_preservation_activated = FALSE
466471
else
467-
owner.visible_message(SPAN_DANGER("[owner]'s limbs seize up as the light from [owner.get_pronoun("his")] eyes fades."), SPAN_MACHINE_DANGER("You lose control over your limbs as your self-preservation protocols take over!"))
468-
playsound(owner, 'sound/species/synthetic/synthetic_stun.ogg', 100)
472+
owner.visible_message(SPAN_DANGER("[owner]'s limbs seize up as the light from [owner.get_pronoun("his")] eyes fades."), FONT_LARGE(SPAN_MACHINE_DANGER("You lose control over your limbs as your self-preservation protocols take over!")))
473+
if(!is_broken())
474+
playsound(owner, 'sound/species/synthetic/synthetic_stun.ogg', 100)
469475
self_preservation_activated = TRUE
470476

471477
/obj/item/organ/internal/machine/posibrain/Topic(href, href_list)

code/modules/organs/internal/species/machine/targeting_core.dm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
if(magazine)
6767
do_reload(user, gun, magazine)
6868
else
69-
to_chat(owner, SPAN_DANGER("Your targeting core can't locate any applicable magazines!"))
69+
to_chat(owner, SPAN_DANGER("Your hands come up empty!"))
7070

7171
/**
7272
* Reloads the gun itself.
@@ -82,4 +82,5 @@
8282
if(istype(storage))
8383
for(var/obj/item/item in storage.contents)
8484
if(item.type == magazine_type)
85+
storage.remove_from_storage(item)
8586
return item

code/modules/surgery/robotics.dm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,12 +761,12 @@
761761
user.visible_message(SPAN_WARNING("[user]'s [tool] shut off before the procedure was finished."), \
762762
SPAN_WARNING("Your [tool] is shut off!"))
763763
return
764-
var/obj/item/organ/external/affected = target.get_organ(target_zone)
765764
user.visible_message("<b>[user]</b> finishes repairing damage to [target]'s endoskeleton with \the [tool].", \
766765
SPAN_NOTICE("You finish repairing damage to [target]'s endoskeleton with \the [tool]."))
767766
SEND_SIGNAL(target, COMSIG_SYNTH_ENDOSKELETON_REPAIR, rand(30, 50))
768767

769768
/singleton/surgery_step/robotics/repair_endoskeleton/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
769+
var/obj/item/organ/external/affected = target.get_organ(target_zone)
770770
user.visible_message(SPAN_WARNING("[user]'s [tool.name] slips, damaging some of the support structure of [target]'s endoskeleton!"),
771-
SPAN_WARNING("Your [tool.name] slips, damaging some of the support structure of [target]'s [affected.name]!"))
771+
SPAN_WARNING("Your [tool.name] slips, damaging some of the support structure of [target]'s endoskeleton!"))
772772
target.apply_damage(rand(5,10), DAMAGE_BURN, affected)

code/modules/tgui/modules/ipc_diagnostic.dm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
var/datum/component/synthetic_endoskeleton/endoskeleton = ipc.GetComponent(/datum/component/synthetic_endoskeleton)
6868
if(istype(endoskeleton))
6969
data["endoskeleton_damage"] = endoskeleton.damage
70-
data["endoskeleton_damage_maximum"] = endoskeleton.damage_maximum
70+
data["endoskeleton_max_damage"] = endoskeleton.max_damage
7171

7272
var/datum/component/armor/synthetic/synth_armor = ipc.GetComponent(/datum/component/armor/synthetic)
7373
if(istype(synth_armor))

tgui/packages/tgui/interfaces/IPCDiagnostics.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export type DiagnosticsData = {
2020
armor_data: ArmorDamage[];
2121

2222
endoskeleton_damage: number;
23-
endoskeleton_damage_maximum: number;
23+
endoskeleton_max_damage: number;
2424
};
2525

2626
type ArmorDamage = {
@@ -110,12 +110,12 @@ export const DiagnosticsWindow = (props, context) => {
110110
bold
111111
textColor={endoskeletonDamageLabel(
112112
data.endoskeleton_damage,
113-
data.endoskeleton_damage_maximum
113+
data.endoskeleton_max_damage
114114
)}>
115115
{capitalize(
116116
describeEndoskeletonIntegrity(
117117
data.endoskeleton_damage,
118-
data.endoskeleton_damage_maximum
118+
data.endoskeleton_max_damage
119119
)
120120
)}
121121
</Box>

0 commit comments

Comments
 (0)