Skip to content

Commit 517505d

Browse files
authored
Pain Tweaks (#1215)
* pain stuff * fix * PUT THE FUCKING CHECK IN * traumatic shock screen alert * fix these * BRUH * buff splinting * splints + grab bug * fix throwing the upgrade message * im an idiot * impliment TRAIT_STRONG_GRABBER * fix * add grab logging * fix attacking yourself * cleaner * FUCK * redo how dropping items from pain works, add cooldowns * tweaks * fix sutures, tweak scar expirey time
1 parent f1f59a7 commit 517505d

27 files changed

+408
-266
lines changed

code/__DEFINES/inventory.dm

+4
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@
114114
//defines for the index of hands
115115
#define LEFT_HANDS 1
116116
#define RIGHT_HANDS 2
117+
/// Checks if the value is "left" - same as ISEVEN, but used primarily for hand or foot index contexts
118+
#define IS_RIGHT_INDEX(value) (value % 2 == 0)
119+
/// Checks if the value is "right" - same as ISODD, but used primarily for hand or foot index contexts
120+
#define IS_LEFT_INDEX(value) (value % 2 != 0)
117121

118122
//flags for female outfits: How much the game can safely "take off" the uniform without it looking weird
119123
/// For when there's simply no need for a female version of this uniform.

code/__DEFINES/pain.dm

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
/// Chance to drop your held item passed here
2-
#define PAIN_THRESHOLD_DROP_ITEM 50
3-
/// Chance to reduce paralysis duration passed here
4-
#define PAIN_THRESHOLD_REDUCE_PARALYSIS 10
51
/// Stage at
62
#define SHOCK_MIN_PAIN_TO_BEGIN 30
73

@@ -30,6 +26,17 @@
3026
#define PAIN_AMT_MEDIUM (PAIN_AMT_PASSOUT * 0.35)
3127
#define PAIN_AMT_AGONIZING (PAIN_AMT_PASSOUT * 0.85)
3228

29+
#define PAIN_CLASS_NONE "none"
30+
#define PAIN_CLASS_NEGLIGIBLE "negligible"
31+
#define PAIN_CLASS_LOW "low"
32+
#define PAIN_CLASS_MEDIUM "medium"
33+
#define PAIN_CLASS_AGONIZING "agonizing"
34+
35+
/// Chance to drop your held item passed here
36+
#define PAIN_THRESHOLD_DROP_ITEM 75
37+
/// Chance to reduce sleep duration passed here
38+
#define PAIN_THRESHOLD_REDUCE_SLEEP 10
39+
3340
/// max_damage * this value is the amount of pain constantly applied when the limb bone is broken
3441
#define BROKEN_BONE_PAIN_FACTOR 0.1
3542
/// max_damage * this value is the amount of pain constantly applied when the limb is dislocated

code/__DEFINES/wounds.dm

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
#define FLUIDLOSS_BURN_REQUIRED 5
1919

2020
//CONFIG STUFF
21-
///A modifier applied to wound auto healing
22-
#define WOUND_REGENERATION_MODIFIER 0.25
21+
/// How much wound damage is healed per second if the wound is able to autoheal.
22+
#define WOUND_AUTOHEAL_RATE 0.1
2323

2424
#define WOUND_BLEED_RATE(wound) (round(wound.damage / 40, DAMAGE_PRECISION))
2525

code/_onclick/hud/alert.dm

+64-59
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,42 @@
9595
/mob/proc/has_alert(category)
9696
return !isnull(alerts[category])
9797

98+
// PRIVATE = only edit, use, or override these if you're editing the system as a whole
99+
100+
// Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there
101+
/datum/hud/proc/reorganize_alerts(mob/viewmob)
102+
var/mob/screenmob = viewmob || mymob
103+
if(!screenmob.client)
104+
return
105+
var/list/alerts = mymob.alerts
106+
if(!hud_shown)
107+
for(var/i in 1 to alerts.len)
108+
screenmob.client.screen -= alerts[alerts[i]]
109+
return 1
110+
for(var/i in 1 to alerts.len)
111+
var/atom/movable/screen/alert/alert = alerts[alerts[i]]
112+
if(alert.icon_state == "template")
113+
alert.icon = ui_style
114+
switch(i)
115+
if(1)
116+
. = ui_alert1
117+
if(2)
118+
. = ui_alert2
119+
if(3)
120+
. = ui_alert3
121+
if(4)
122+
. = ui_alert4
123+
if(5)
124+
. = ui_alert5 // Right now there's 5 slots
125+
else
126+
. = ""
127+
alert.screen_loc = .
128+
screenmob.client.screen |= alert
129+
if(!viewmob)
130+
for(var/M in mymob.observers)
131+
reorganize_alerts(M)
132+
return 1
133+
98134
/atom/movable/screen/alert
99135
icon = 'icons/hud/screen_alert.dmi'
100136
icon_state = "default"
@@ -110,9 +146,33 @@
110146
/// Boolean. If TRUE, the Click() proc will attempt to Click() on the master first if there is a master.
111147
var/click_master = TRUE
112148

149+
/atom/movable/screen/alert/Destroy()
150+
severity = 0
151+
master_ref = null
152+
owner = null
153+
screen_loc = ""
154+
return ..()
155+
113156
/atom/movable/screen/alert/can_usr_use(mob/user)
114157
return owner == usr
115158

159+
/atom/movable/screen/alert/Click(location, control, params)
160+
. = ..()
161+
if(.)
162+
return FALSE
163+
164+
if(usr != owner)
165+
return FALSE
166+
var/list/modifiers = params2list(params)
167+
if(LAZYACCESS(modifiers, SHIFT_CLICK)) // screen objects don't do the normal Click() stuff so we'll cheat
168+
to_chat(usr, span_boldnotice("[name]</span> - <span class='info'>[desc]"))
169+
return FALSE
170+
var/datum/our_master = master_ref?.resolve()
171+
if(our_master && click_master)
172+
return usr.client.Click(our_master, location, control, params)
173+
174+
return TRUE
175+
116176
/atom/movable/screen/alert/MouseEntered(location,control,params)
117177
. = ..()
118178
if(!QDELETED(src))
@@ -852,62 +912,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
852912
var/mob/living/living_owner = owner
853913
living_owner.set_resting(FALSE)
854914

855-
// PRIVATE = only edit, use, or override these if you're editing the system as a whole
856-
857-
// Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there
858-
/datum/hud/proc/reorganize_alerts(mob/viewmob)
859-
var/mob/screenmob = viewmob || mymob
860-
if(!screenmob.client)
861-
return
862-
var/list/alerts = mymob.alerts
863-
if(!hud_shown)
864-
for(var/i in 1 to alerts.len)
865-
screenmob.client.screen -= alerts[alerts[i]]
866-
return 1
867-
for(var/i in 1 to alerts.len)
868-
var/atom/movable/screen/alert/alert = alerts[alerts[i]]
869-
if(alert.icon_state == "template")
870-
alert.icon = ui_style
871-
switch(i)
872-
if(1)
873-
. = ui_alert1
874-
if(2)
875-
. = ui_alert2
876-
if(3)
877-
. = ui_alert3
878-
if(4)
879-
. = ui_alert4
880-
if(5)
881-
. = ui_alert5 // Right now there's 5 slots
882-
else
883-
. = ""
884-
alert.screen_loc = .
885-
screenmob.client.screen |= alert
886-
if(!viewmob)
887-
for(var/M in mymob.observers)
888-
reorganize_alerts(M)
889-
return 1
890-
891-
/atom/movable/screen/alert/Click(location, control, params)
892-
. = ..()
893-
if(.)
894-
return FALSE
895-
896-
if(usr != owner)
897-
return FALSE
898-
var/list/modifiers = params2list(params)
899-
if(LAZYACCESS(modifiers, SHIFT_CLICK)) // screen objects don't do the normal Click() stuff so we'll cheat
900-
to_chat(usr, span_boldnotice("[name]</span> - <span class='info'>[desc]"))
901-
return FALSE
902-
var/datum/our_master = master_ref?.resolve()
903-
if(our_master && click_master)
904-
return usr.client.Click(our_master, location, control, params)
905-
906-
return TRUE
907-
908-
/atom/movable/screen/alert/Destroy()
909-
severity = 0
910-
master_ref = null
911-
owner = null
912-
screen_loc = ""
913-
return ..()
915+
/atom/movable/screen/alert/shock
916+
name = "Traumatic Shock"
917+
desc = "You've endured a significant amount of pain."
918+
icon_state = "convulsing"

code/datums/components/tackle.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@
266266
var/leg_wounds = 0 // -1 defense per 2 leg wounds
267267
var/static/list/check_areas = list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
268268
for(var/datum/wound/iterwound in target.get_wounds())
269-
if((iterwound.parent.body_zone in check_areas))
269+
if(iterwound.damage && (iterwound.parent.body_zone in check_areas))
270270
leg_wounds++
271271

272272
defense_mod -= round(leg_wounds * 0.5)

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@
241241

242242
var/wound_desc
243243
for(var/datum/wound/W as anything in shuffle(affecting.wounds))
244-
if(W.wound_type != WOUND_CUT && W.wound_type != WOUND_PIERCE)
244+
if(W.damage <= 0 || W.wound_type != WOUND_CUT && W.wound_type != WOUND_PIERCE)
245245
continue
246246
if(W.damage <= 15)
247247
wound_desc = W.desc

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@
5656
user.visible_message(span_warning("[user] fumbles [src]."))
5757
return
5858

59-
var/obj/item/stack/splint = split_stack(null, 1, null)
60-
if(!BP.apply_splint(splint))
61-
splint.merge(src)
59+
if(!BP.apply_splint(src))
6260
to_chat(user, span_warning("You fail to apply [src]."))
6361
return
6462

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
var/obj/structure/table/tableVariant // we tables now (stores table variant to be built from this stack)
6262

6363
// The following are all for medical treatment, they're here instead of /stack/medical because sticky tape can be used as a makeshift bandage or splint
64-
/// If set and this used as a splint for a broken bone wound, this is used as a multiplier for applicable slowdowns (lower = better) (also for speeding up burn recoveries)
64+
/// If set and this used as a splint for a broken bone wound, this is used as a modifier for applicable slowdowns (lower = better) (also for speeding up burn recoveries)
6565
var/splint_slowdown = null
6666
/// Like splint_factor but for burns instead of bone wounds. This is a multiplier used to speed up burn recoveries
6767
var/burn_cleanliness_bonus

code/modules/grab/grab_carbon.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// We're changing the default grab type here.
2-
/mob/living/carbon/make_grab(atom/movable/target, grab_type = /datum/grab/normal/passive)
2+
/mob/living/carbon/try_make_grab(atom/movable/target, grab_type = /datum/grab/normal/passive, use_offhand)
33
. = ..()

code/modules/grab/grab_datum.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ GLOBAL_LIST_EMPTY(all_grabstates)
198198
return FALSE
199199

200200
var/mob/living/L = G.get_affecting_mob()
201-
if(!isliving(L))
201+
if(!isliving(L) || L == G.assailant)
202202
return FALSE
203203

204204
if(!(L.status_flags & CANPUSH) || HAS_TRAIT(L, TRAIT_PUSHIMMUNE))

code/modules/grab/grab_living.dm

+8
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,18 @@
4949
/mob/living/proc/try_make_grab(atom/movable/target, grab_type, use_offhand)
5050
return canUseTopic(src, USE_IGNORE_TK|USE_CLOSE) && make_grab(target, grab_type, use_offhand)
5151

52+
/// DO NOT CALL DIRECTLY. USE THE ABOVE.
5253
/mob/living/proc/make_grab(atom/movable/target, grab_type = /datum/grab/simple, use_offhand)
54+
PRIVATE_PROC(TRUE)
55+
5356
if(SEND_SIGNAL(src, COMSIG_LIVING_TRY_GRAB, target, grab_type) & COMSIG_LIVING_CANCEL_GRAB)
5457
return
5558

59+
// REALLY SHITTY CODE TO FIX A GAMEBREAKING BUG. I HATE GRAB CODE WHY DID I PORT THIS?
60+
if(src == target)
61+
if(ispath(grab_type, /datum/grab/normal) && grab_type != /datum/grab/normal/passive)
62+
grab_type = /datum/grab/normal/passive
63+
5664
// Resolve to the 'topmost' atom in the buckle chain, as grabbing someone buckled to something tends to prevent further interaction.
5765
var/atom/movable/original_target = target
5866
if(ismob(target))

code/modules/grab/grab_object.dm

+29-10
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@
8484
current_grab.special_bodyzone_effects(src)
8585

8686
var/mob/living/L = get_affecting_mob()
87-
if(L && assailant.combat_mode)
88-
upgrade(TRUE)
87+
if(L)
88+
log_combat(assailant, L, "grabbed")
89+
if(L != assailant && assailant.combat_mode)
90+
upgrade(TRUE)
8991

9092
/// Update appearance
9193
update_appearance(UPDATE_ICON_STATE)
@@ -104,6 +106,7 @@
104106
RegisterSignal(affecting, COMSIG_PARENT_QDELETING, PROC_REF(target_or_owner_del))
105107
RegisterSignal(affecting, COMSIG_MOVABLE_PRE_THROW, PROC_REF(target_thrown))
106108
RegisterSignal(affecting, COMSIG_ATOM_ATTACK_HAND, PROC_REF(intercept_attack_hand))
109+
RegisterSignal(affecting, COMSIG_PARENT_ATTACKBY, PROC_REF(resolve_item_attack))
107110

108111
RegisterSignal(assailant, COMSIG_MOB_SELECTED_ZONE_SET, PROC_REF(on_target_change))
109112

@@ -128,6 +131,9 @@
128131
if(assailant)
129132
assailant.after_grab_release(affecting)
130133

134+
if(ismob(affecting))
135+
log_combat(assailant, affecting, "dropped a grab on")
136+
131137
//DEBUG CODE
132138
if(HAS_TRAIT_FROM(affecting, TRAIT_AGGRESSIVE_GRAB, ref(src)))
133139
stack_trace("Somehow all other safeties failed and [affecting] still is marked as grabbed from a qdeling grab, removing!")
@@ -183,7 +189,6 @@
183189
if(src != assailant.get_active_held_item())
184190
return // Note that because of this condition, there's no guarantee that target_zone = old_sel
185191

186-
new_sel = deprecise_zone(new_sel)
187192
if(target_zone == new_sel)
188193
return
189194

@@ -204,8 +209,9 @@
204209
to_chat(assailant, span_warning("You fail to grab \the [affecting] there as they do not have that bodypart!"))
205210
return
206211

207-
name = "[initial(name)] ([BP.plaintext_zone])"
208-
to_chat(assailant, span_notice("You are now holding \the [affecting] by \the [BP.plaintext_zone]."))
212+
if(old_zone != target_zone)
213+
name = "[initial(name)] ([BP.plaintext_zone])"
214+
to_chat(assailant, span_notice("You are now holding \the [affecting] by \the [BP.plaintext_zone]."))
209215

210216
if(!isbodypart(BP))
211217
qdel(src)
@@ -245,11 +251,18 @@
245251
var/mob/living/L = get_affecting_mob()
246252
return (L?.get_bodypart(deprecise_zone(target_zone)))
247253

248-
/obj/item/hand_item/grab/proc/resolve_item_attack(mob/living/M, obj/item/I, target_zone)
249-
if((M && ishuman(M)) && I)
250-
return current_grab.resolve_item_attack(src, M, I, target_zone)
251-
else
252-
return 0
254+
// Intercepts attackby() calls on our target.
255+
/obj/item/hand_item/grab/proc/resolve_item_attack(datum/source, obj/item/I, mob/attacker, params)
256+
SIGNAL_HANDLER
257+
258+
if(!ishuman(attacker))
259+
return
260+
var/mob/living/carbon/human/human_attacker = attacker
261+
if(human_attacker.combat_mode)
262+
return
263+
264+
if(current_grab.resolve_item_attack(src, attacker, I, human_attacker.zone_selected))
265+
return COMPONENT_NO_AFTERATTACK
253266

254267
/obj/item/hand_item/grab/proc/action_used()
255268
COOLDOWN_START(src, action_cd, current_grab.action_cooldown)
@@ -325,6 +338,9 @@
325338
adjust_position()
326339
update_appearance()
327340

341+
if(ismob(affecting))
342+
log_combat(assailant, affecting, "upgraded grab to [current_grab.type]")
343+
328344
SEND_SIGNAL(assailant, COMSIG_LIVING_GRAB_UPGRADE)
329345

330346
/obj/item/hand_item/grab/proc/downgrade(silent)
@@ -348,6 +364,9 @@
348364
adjust_position()
349365
update_appearance()
350366

367+
if(ismob(affecting))
368+
log_combat(assailant, affecting, "downgraded grab to [current_grab.type]")
369+
351370
SEND_SIGNAL(assailant, COMSIG_LIVING_GRAB_DOWNGRADE)
352371

353372
/// Used to prevent repeated effect application or early effect removal

code/modules/grab/grabs/grab_normal.dm

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
return
1818

1919
if(G.affecting != G.assailant)
20-
G.assailant.visible_message(span_warning("[G.assailant] has grabbed [G.affecting]'s [BP.plaintext_zone]!"))
20+
G.assailant.visible_message(span_warning("<b>[G.assailant]</b> grabs <b>[G.affecting]</b> by [G.affecting.p_their()] [BP.plaintext_zone]."))
2121
else
22-
G.assailant.visible_message(span_notice("[G.assailant] has grabbed [G.assailant.p_their()] [BP.plaintext_zone]!"))
22+
G.assailant.visible_message(span_notice("<b>[G.assailant]</b> grabs [G.assailant.p_their()] [BP.plaintext_zone]."))
2323

2424
/datum/grab/normal/on_hit_help(obj/item/hand_item/grab/G, atom/A)
2525

@@ -94,7 +94,7 @@
9494
G.action_used()
9595
BP.set_dislocated(FALSE)
9696
assailant.visible_message(span_warning("\The [affecting]'s [BP.joint_name] pops back into place!"))
97-
affecting.pain_message("AAAHHHHAAGGHHHH", 50, TRUE)
97+
affecting.pain_message("AAAHHHHAAGGHHHH", PAIN_AMT_MEDIUM, TRUE)
9898
return TRUE
9999

100100
if(BP.can_be_dislocated())
@@ -236,6 +236,9 @@
236236
return TRUE
237237

238238
/datum/grab/normal/resolve_item_attack(obj/item/hand_item/grab/G, mob/living/carbon/human/user, obj/item/I)
239+
if(damage_stage < GRAB_AGGRESSIVE)
240+
return
241+
239242
switch(G.target_zone)
240243
if(BODY_ZONE_HEAD)
241244
return attack_throat(G, I, user)

0 commit comments

Comments
 (0)