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

Separates bleeding from damage, gauze now STOPS bleeding rather than postponing it #3009

Merged
merged 41 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
a447b17
initial bleeding changes
SomeguyManperson Mar 12, 2024
2568a57
Things what cause bleeding
SomeguyManperson Mar 13, 2024
b4db414
scope 1: bandages and bandage-based healing
SomeguyManperson Mar 13, 2024
167ae2e
bandage component & blood stuff (again!)
SomeguyManperson Mar 20, 2024
d98ca60
scrapping
SomeguyManperson Mar 23, 2024
67d2c3d
starting on new structure
SomeguyManperson Mar 23, 2024
ac7d2af
Merge branch 'master' of https://github.com/shiptest-ss13/Shiptest in…
SomeguyManperson Mar 25, 2024
d231504
Merge branch 'shiptest-ss13:master' into awful
SomeguyManperson Apr 7, 2024
fc6f180
Merge branch 'awful' of https://github.com/SomeguyManperson/Shiptest …
SomeguyManperson Apr 7, 2024
dd6dfd1
fix
SomeguyManperson Apr 7, 2024
15fbb4b
Standardized proc start, tape handling, better examine stuff & surger…
SomeguyManperson Apr 29, 2024
47f3207
Mess cleaning
SomeguyManperson Apr 30, 2024
52a5c8b
cleaning
SomeguyManperson Apr 30, 2024
4d4b34c
Moves all bleeding stuff to new system, general damage procs, making …
SomeguyManperson May 3, 2024
c381e89
pretend this is in the last commit
SomeguyManperson May 3, 2024
bf948a4
removes bleed_rate because it's unnecessary
SomeguyManperson May 3, 2024
98f5ea4
Cauterization support
SomeguyManperson May 6, 2024
3c0fc45
tweaks and fix bleeding healing for bandages
SomeguyManperson May 11, 2024
da1d645
Merge branch 'master' into awful
SomeguyManperson May 20, 2024
2c566c7
minimums on bleed adjusts and rebrand heal_bodypart_bleeding to heal_…
SomeguyManperson May 20, 2024
c04cbd5
Suit storage cauterization (funny), numbers, removing bandage healing…
SomeguyManperson May 20, 2024
4deb81a
waa
SomeguyManperson May 20, 2024
70d6e0c
The last icecream sandwich is mine. Everyone else has had two and i h…
SomeguyManperson May 20, 2024
5459c27
numbers and stuff that slipped
SomeguyManperson May 20, 2024
542ab2a
Words
SomeguyManperson May 20, 2024
df16825
waa
SomeguyManperson May 20, 2024
cd97eea
Reduce bleeding from embeds since it stacks more now
SomeguyManperson May 20, 2024
72eb14d
WHOOPS
SomeguyManperson May 22, 2024
97be383
Merge branch 'awful' of https://github.com/SomeguyManperson/Shiptest …
SomeguyManperson May 22, 2024
61a7711
Merge branch 'master' into awful
SomeguyManperson May 22, 2024
0f42e6a
Improves bloodloss reduction from brute healing
SomeguyManperson May 23, 2024
49c0b8f
self help displays openly bleeding limbs
SomeguyManperson May 23, 2024
3ff3c5a
Merge branch 'awful' of https://github.com/SomeguyManperson/Shiptest …
SomeguyManperson May 23, 2024
5feeea4
Fully healed limbs will now slowly stop bleeding if any is left
SomeguyManperson May 23, 2024
715f3f4
Delimb support and some tuning
SomeguyManperson May 27, 2024
707ac6a
uogh
SomeguyManperson May 27, 2024
60b4d2b
Merge branch 'master' into awful
SomeguyManperson May 27, 2024
a32cab6
Merge branch 'awful' of https://github.com/SomeguyManperson/Shiptest …
SomeguyManperson Jun 4, 2024
bc8882a
Merge branch 'shiptest-ss13:master' into awful
SomeguyManperson Jun 4, 2024
2dd25b3
Merge branch 'master' into awful
SomeguyManperson Jun 5, 2024
2f30215
Merge branch 'master' into awful
SomeguyManperson Jun 7, 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
5 changes: 5 additions & 0 deletions code/__DEFINES/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,9 @@
/* #define SPEECH_IGNORE_SPAM 6
#define SPEECH_FORCED 7 */

///from /mob/living/life()
#define COMSIG_MOB_LIFE "mob_life"

///from /mob/say_dead(): (mob/speaker, message)
#define COMSIG_MOB_DEADSAY "mob_deadsay"
#define MOB_DEADSAY_SIGNAL_INTERCEPT (1<<0)
Expand Down Expand Up @@ -420,6 +423,8 @@
///from base of /obj/item/bodypart/proc/attach_limb(): (new_limb, special) allows you to fail limb attachment
#define COMSIG_LIVING_ATTACH_LIMB "living_attach_limb"
#define COMPONENT_NO_ATTACH 1
///from base of /obj/item/bodypart/proc/drop_limb(): (special)
#define COMSIG_LIVING_DROP_LIMB "living_drop_limb"
///from base of mob/living/set_buckled(): (new_buckled)
#define COMSIG_LIVING_SET_BUCKLED "living_set_buckled"

Expand Down
7 changes: 7 additions & 0 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@
#define BLOOD_VOLUME_BAD 224
#define BLOOD_VOLUME_SURVIVE 122

// Bloodloss
#define BLOOD_LOSS_MAXIMUM 30
#define BLOOD_LOSS_DAMAGE_MAXIMUM 2
#define BLOOD_LOSS_DAMAGE_BASE 0.013
#define BLOOD_CAUTERIZATION_RATIO 10
#define BLOOD_CAUTERIZATION_DAMAGE_RATIO 300

//Sizes of mobs, used by mob/living/var/mob_size
#define MOB_SIZE_TINY 0
#define MOB_SIZE_SMALL 1
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
var/armor_value = run_armor_check(attack_flag = "melee", armour_penetration = I.armour_penetration) //WS Edit - Simplemobs can have armor
send_item_attack_message(I, user)
if(I.force)
apply_damage(I.force, I.damtype, break_modifier = I.force, blocked = armor_value) //Bone break modifier = item force
apply_damage(I.force, I.damtype, break_modifier = I.force, blocked = armor_value, sharpness = I.get_sharpness()) //Bone break modifier = item force
if(I.damtype == BRUTE)
if(prob(33))
I.add_mob_blood(src)
Expand Down
60 changes: 60 additions & 0 deletions code/datums/components/bandage.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#define TREATMENT_DAMAGE_MOD 2

/datum/component/bandage
/// How fast do we stop bleeding?
var/bleed_reduction = 0
/// How many healing ticks will this bandage apply? Reduced by incoming damage and current bleeding
var/lifespan = 300
var/bandage_name = "gauze"
/// The person this bandage is applied to
var/mob/living/mummy

/datum/component/bandage/Initialize(_bleed_reduction, _lifespan, _bandage_name)
if(!istype(parent, /obj/item/bodypart))
return COMPONENT_INCOMPATIBLE
var/obj/item/bodypart/BP = parent
mummy = BP.owner
if(!mummy)
return COMPONENT_INCOMPATIBLE
if(_bleed_reduction)
bleed_reduction = _bleed_reduction
if(_lifespan)
lifespan = _lifespan
if(_bandage_name)
bandage_name = _bandage_name
RegisterSignal(mummy, COMSIG_MOB_APPLY_DAMGE, PROC_REF(check_damage))
RegisterSignal(mummy, COMSIG_MOB_LIFE, PROC_REF(bandage_effects))
RegisterSignal(parent, COMSIG_LIVING_DROP_LIMB, PROC_REF(drop_bandage))

/// Checks if damage to the owner is applied to this limb and reduces lifespan (perforated bandages dont work as well)
/datum/component/bandage/proc/check_damage(attacker, damage, damagetype = BRUTE, def_zone = null)
SIGNAL_HANDLER

if(parent != mummy.get_bodypart(check_zone(def_zone)))
return
lifespan -= damage / 100 * initial(lifespan) * TREATMENT_DAMAGE_MOD //take incoming damage as a % of durability
if(lifespan <= 0)
drop_bandage()

/// Handles healing effects and passive lifespan usage
/datum/component/bandage/proc/bandage_effects()
SIGNAL_HANDLER

var/obj/item/bodypart/heal_target = parent
lifespan -= 1 + heal_target.bleeding // particularly nasty bleeding can burn through dressing faster
heal_target.adjust_bleeding(-bleed_reduction)
if(lifespan <= 0 || !heal_target.bleeding) //remove treatment once it's no longer able to treat
drop_bandage(TRUE)

/// Handles deleting the component when the bandage runs out of lifespan or finishes healing. Special = bandage didn't get torn off
/datum/component/bandage/proc/drop_bandage(special = FALSE)
SIGNAL_HANDLER

var/obj/item/bodypart/BP = parent
if(special)
to_chat(mummy, span_notice("The [bandage_name] on your [parse_zone(BP.body_zone)] has [BP.bleeding ? "done what it can" : "stopped the bleeding"]."))
else
to_chat(mummy, span_warning("The [bandage_name] on your [parse_zone(BP.body_zone)] is damaged beyond use!"))
qdel(src)

#undef TREATMENT_DAMAGE_MOD
8 changes: 7 additions & 1 deletion code/datums/components/butchering.dm
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,17 @@
"<span class='warning'>Their neck has already been already cut, you can't make the bleeding any worse!</span>")
return

var/obj/item/bodypart/throat_in_question = H.get_bodypart(BODY_ZONE_HEAD)
if(!throat_in_question)
user.show_message("<span class='warning'>[H]... doesn't have a neck.</span>", MSG_VISUAL, \
"<span class='warning'>They don't seem to have a neck to cut.</span>")
return

H.visible_message("<span class='danger'>[user] slits [H]'s throat!</span>", \
"<span class='userdanger'>[user] slits your throat...</span>")
log_combat(user, H, "finishes slicing the throat of")
H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD)
H.bleed_rate = clamp(H.bleed_rate + 20, 0, 30)
throat_in_question.adjust_bleeding(20)
H.apply_status_effect(/datum/status_effect/neck_slice)

/datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat)
Expand Down
2 changes: 1 addition & 1 deletion code/datums/diseases/advance/symptoms/flesh_eating.dm
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Bonus
if(bleed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate += 5 * power
H.cause_bleeding(5 * power)
return 1

/*
Expand Down
3 changes: 2 additions & 1 deletion code/datums/status_effects/debuffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,8 @@

/datum/status_effect/neck_slice/tick()
var/mob/living/carbon/human/H = owner
if(H.stat == DEAD || H.bleed_rate <= 8)
var/obj/item/bodypart/throat_in_question = H.get_bodypart(BODY_ZONE_HEAD)
if(H.stat == DEAD || throat_in_question?.bleeding <= 8)
H.remove_status_effect(/datum/status_effect/neck_slice)
if(prob(10))
H.emote(pick("gasp", "gag", "choke"))
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/medical_kiosk.dm
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@
sickness_data = "\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]"

if(altPatient.has_dna()) //Blood levels Information
if(altPatient.bleed_rate)
if(LAZYLEN(altPatient.get_bleeding_parts()))
bleed_status = "Patient is currently bleeding!"
if(blood_percent <= 80)
blood_warning = " Patient has low blood levels. Seek a large meal, or iron supplements."
Expand Down
6 changes: 6 additions & 0 deletions code/game/machinery/suit_storage_unit.dm
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,12 @@
else
visible_message(span_warning("[src]'s door slides open, barraging you with the nauseating smell of charred flesh."))
mob_occupant.radiation = 0
if(iscarbon(mob_occupant))
var/mob/living/carbon/bacon = mob_occupant
for(var/obj/item/bodypart/grilling as anything in bacon.get_bleeding_parts(TRUE))
if(!grilling.can_bandage())
continue
grilling.apply_bandage(0.005, 600, "cauterization")
playsound(src, 'sound/machines/airlocks/standard/close.ogg', 25, TRUE)
var/list/things_to_clear = list() //Done this way since using GetAllContents on the SSU itself would include circuitry and such.
if(suit)
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/devices/scanners.dm
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ GENE SCANNER
if(blood_id)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.bleed_rate)
if(LAZYLEN(H.get_bleeding_parts()))
render_list += "<span class='alert ml-1'><b>Subject is bleeding!</b></span>\n"
var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
var/blood_type = C.dna.blood_type.name
Expand Down
24 changes: 14 additions & 10 deletions code/game/objects/items/stacks/medical.dm
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,13 @@

/obj/item/stack/medical/gauze
name = "medical gauze"
desc = "A roll of elastic cloth that is extremely effective at stopping bleeding, but does not heal wounds."
desc = "A roll of elastic cloth that is extremely effective at stopping bleeding and slowly heals wounds."
gender = PLURAL
singular_name = "medical gauze"
icon_state = "gauze"
apply_sounds = list('sound/effects/rip1.ogg', 'sound/effects/rip2.ogg')
var/stop_bleeding = 1800
var/bleed_reduction = 0.02
var/lifespan = 150
self_delay = 20
max_amount = 12
grind_results = list(/datum/reagent/cellulose = 2)
Expand All @@ -152,13 +153,16 @@
amount = 12

/obj/item/stack/medical/gauze/heal(mob/living/target, mob/user)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(!H.bleedsuppress && H.bleed_rate) //so you can't stack bleed suppression
H.suppress_bloodloss(stop_bleeding)
to_chat(user, "<span class='notice'>You stop the bleeding of [target]!</span>")
if(iscarbon(target))
var/mob/living/carbon/C = target
var/obj/item/bodypart/BP = C.get_bodypart(check_zone(user.zone_selected))
if(!BP)
to_chat(user, span_warning("[C] doesn't have \a [parse_zone(user.zone_selected)]!"))
return
if(BP.can_bandage(user))
BP.apply_bandage(bleed_reduction, lifespan, name)
user.visible_message(span_notice("[user] wraps [C]'s [parse_zone(BP.body_zone)] with [src]."), span_notice("You wrap [C]'s [parse_zone(check_zone(user.zone_selected))] with [src]."), span_hear("You hear ruffling cloth."))
return TRUE
to_chat(user, "<span class='warning'>You can not use \the [src] on [target]!</span>")

/obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_WIRECUTTER || I.get_sharpness())
Expand All @@ -178,8 +182,8 @@
/obj/item/stack/medical/gauze/improvised
name = "improvised gauze"
singular_name = "improvised gauze"
desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds."
stop_bleeding = 900
desc = "A roll of cloth roughly cut from something that can stop bleeding and slowly heal wounds."
bleed_reduction = 0.005

/obj/item/stack/medical/gauze/cyborg
custom_materials = null
Expand Down
24 changes: 10 additions & 14 deletions code/game/objects/items/stacks/tape.dm
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@
grind_results = list(/datum/reagent/cellulose = 5)
usesound = 'sound/items/tape.ogg'

var/stop_bleed = 600
var/lifespan = 300
var/bleed_reduction = 0.002
var/nonorganic_heal = 5
var/self_delay = 30 //! Also used for the tapecuff delay
var/other_delay = 10
Expand Down Expand Up @@ -173,21 +174,17 @@
if(!affecting) //Missing limb?
to_chat(user, "<span class='warning'>[C] doesn't have \a [parse_zone(user.zone_selected)]!</span>")
return
if(!IS_ORGANIC_LIMB(affecting))
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(!H.bleedsuppress && H.bleed_rate)
H.suppress_bloodloss(stop_bleed)
to_chat(user, "<span class='notice'>You tape up the bleeding of [C]!</span>")
return TRUE
to_chat(user, "<span class='warning'>[C] has a problem \the [src] won't fix!</span>")
else //Robotic patch-up
if(IS_ROBOTIC_LIMB(affecting)) //Robotic patch-up
if(affecting.brute_dam)
user.visible_message("<span class='notice'>[user] applies \the [src] on [C]'s [affecting.name].</span>", "<span class='green'>You apply \the [src] on [C]'s [affecting.name].</span>")
if(affecting.heal_damage(nonorganic_heal))
C.update_damage_overlays()
return TRUE
to_chat(user, "<span class='warning'>[src] can't patch what [C] has...</span>")
if(affecting.can_bandage(user))
affecting.apply_bandage(bleed_reduction, lifespan, name)
to_chat(user, "<span class='notice'>You tape up [C]'s [parse_zone(affecting.body_zone)]!</span>")
return TRUE
to_chat(user, "<span class='warning'>[src] can't patch what [C] has...</span>")

/obj/item/stack/tape/proc/apply_gag(mob/living/carbon/target, mob/user)
if(target.is_muzzled() || target.is_mouth_covered())
Expand Down Expand Up @@ -272,7 +269,7 @@
desc = "This roll of silver sorcery can fix just about anything."
icon_state = "tape_d"

stop_bleed = 800
lifespan = 400
nonorganic_heal = 20
prefix = "super sticky"
conferred_embed = EMBED_HARMLESS_SUPERIOR
Expand All @@ -297,7 +294,6 @@
desc = "Specialty insulated strips of adhesive plastic. Made for securing cables."
icon_state = "tape_e"

stop_bleed = 400
nonorganic_heal = 10
prefix = "insulated sticky"
siemens_coefficient = 0
Expand All @@ -321,6 +317,6 @@
desc = "Now THIS is engineering."
icon_state = "tape_y"

stop_bleed = 1000
lifespan = 500
nonorganic_heal = 30
prefix = "industry-standard sticky"
5 changes: 4 additions & 1 deletion code/game/objects/structures/petrified_statue.dm
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@

if(petrified_mob)
petrified_mob.status_flags &= ~GODMODE
if(ishuman(petrified_mob))
var/mob/living/carbon/human/H = petrified_mob
H.bleedsuppress = FALSE
petrified_mob.forceMove(loc)
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE)
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
Expand All @@ -80,7 +83,7 @@
return 0
var/obj/structure/statue/petrified/S = new(loc, src, statue_timer)
S.name = "statue of [name]"
bleedsuppress = 1
bleedsuppress = TRUE
S.copy_overlays(src)
var/newcolor = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
S.add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
Expand Down
6 changes: 6 additions & 0 deletions code/modules/food_and_drinks/kitchen_machinery/microwave.dm
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,12 @@
playsound(src, 'sound/items/cig_light.ogg', 50, 1)
moveToNullspace()


/obj/item/ration_heater/get_temperature()
if(!uses)
return 0
. = ..()

Comment on lines +388 to +393
Copy link
Member

Choose a reason for hiding this comment

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

i looked at the attackby and it looks like you would be use this infinity to cauterize is that correct?
it also SHOULD qdel itself after it has no uses left so this shouldn't realllly matter

/obj/item/ration_heater/proc/clear_cooking(datum/source)
SIGNAL_HANDLER
UnregisterSignal(tocook, COMSIG_PARENT_QDELETING)
Expand Down
35 changes: 9 additions & 26 deletions code/modules/mob/living/blood.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,6 @@
BLOOD SYSTEM
****************************************************/

/mob/living/carbon/human/proc/suppress_bloodloss(amount)
if(bleedsuppress)
return
else
bleedsuppress = TRUE
addtimer(CALLBACK(src, PROC_REF(resume_bleeding)), amount)

/mob/living/carbon/human/proc/resume_bleeding()
bleedsuppress = 0
if(stat != DEAD && bleed_rate)
to_chat(src, "<span class='warning'>The blood soaks through your bandage.</span>")


/mob/living/carbon/monkey/handle_blood()
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
Expand All @@ -29,7 +16,6 @@
/mob/living/carbon/human/handle_blood()

if(NOBLOOD in dna.species.species_traits)
bleed_rate = 0
return

if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
Expand Down Expand Up @@ -83,24 +69,20 @@
if(!HAS_TRAIT(src, TRAIT_NODEATH))
death()

var/temp_bleed = 0
//Bleeding out
var/limb_bleed = 0
for(var/obj/item/bodypart/BP as anything in bodyparts)
var/brutedamage = BP.brute_dam

if(BP.GetComponent(/datum/component/bandage))
continue
//We want an accurate reading of .len
listclearnulls(BP.embedded_objects)
for(var/obj/item/embeddies in BP.embedded_objects)
if(!embeddies.isEmbedHarmless())
temp_bleed += 0.5

if(brutedamage >= 20)
temp_bleed += (brutedamage * 0.013)

bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
BP.adjust_bleeding(0.1, BLOOD_LOSS_DAMAGE_MAXIMUM)
limb_bleed += BP.bleeding

if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
bleed(bleed_rate)
if(limb_bleed && !bleedsuppress && !HAS_TRAIT(src, TRAIT_FAKEDEATH))
bleed(limb_bleed)

//Makes a blood drop, leaking amt units of blood from the mob
/mob/living/carbon/proc/bleed(amt)
Expand All @@ -125,7 +107,8 @@

/mob/living/carbon/human/restore_blood()
blood_volume = BLOOD_VOLUME_NORMAL
bleed_rate = 0
for(var/obj/item/bodypart/BP as anything in get_bleeding_parts())
BP.bleeding = 0

/****************************************************
BLOOD TRANSFERS
Expand Down
Loading
Loading