mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 09:54:52 +00:00
it continues
This commit is contained in:
@@ -25,9 +25,18 @@
|
||||
var/list/mats_per_unit //list that tells you how much is in a single unit.
|
||||
///Datum material type that this stack is made of
|
||||
var/material_type
|
||||
max_integrity = 100
|
||||
//NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind()
|
||||
var/obj/structure/table/tableVariant // we tables now (stores table variant to be built from this stack)
|
||||
|
||||
// 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
|
||||
/// 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)
|
||||
var/splint_factor
|
||||
/// How much blood flow this stack can absorb if used as a bandage on a cut wound, note that absorption is how much we lower the flow rate, not the raw amount of blood we suck up
|
||||
var/absorption_capacity
|
||||
/// How quickly we lower the blood flow on a cut wound we're bandaging. Expected lifetime of this bandage in ticks is thus absorption_capacity/absorption_rate, or until the cut heals, whichever comes first
|
||||
var/absorption_rate
|
||||
|
||||
/obj/item/stack/on_grind()
|
||||
for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists
|
||||
grind_results[grind_results[i]] *= get_amount() //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size
|
||||
|
||||
@@ -7,10 +7,13 @@
|
||||
icon = 'icons/obj/tapes.dmi'
|
||||
icon_state = "tape_w"
|
||||
var/prefix = "sticky"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
full_w_class = WEIGHT_CLASS_TINY
|
||||
item_flags = NOBLUDGEON
|
||||
amount = 5
|
||||
max_amount = 5
|
||||
resistance_flags = FLAMMABLE
|
||||
splint_factor = 0.8
|
||||
|
||||
var/list/conferred_embed = EMBED_HARMLESS
|
||||
var/overwrite_existing = FALSE
|
||||
@@ -53,6 +56,7 @@
|
||||
icon_state = "tape_y"
|
||||
prefix = "super sticky"
|
||||
conferred_embed = EMBED_HARMLESS_SUPERIOR
|
||||
splint_factor = 0.6
|
||||
|
||||
/obj/item/stack/sticky_tape/pointy
|
||||
name = "pointy tape"
|
||||
@@ -68,4 +72,14 @@
|
||||
desc = "You didn't know tape could look so sinister. Welcome to Space Station 13."
|
||||
icon_state = "tape_spikes"
|
||||
prefix = "super pointy"
|
||||
conferred_embed = EMBED_POINTY_SUPERIOR
|
||||
conferred_embed = EMBED_POINTY_SUPERIOR
|
||||
|
||||
/obj/item/stack/sticky_tape/surgical
|
||||
name = "surgical tape"
|
||||
singular_name = "surgical tape"
|
||||
desc = "Made for patching broken bones back together alongside bone gel, not for playing pranks."
|
||||
//icon_state = "tape_spikes"
|
||||
prefix = "surgical"
|
||||
conferred_embed = list("embed_chance" = 30, "pain_mult" = 0, "jostle_pain_mult" = 0, "ignore_throwspeed_threshold" = TRUE)
|
||||
splint_factor = 0.4
|
||||
custom_price = 500
|
||||
|
||||
@@ -369,6 +369,7 @@
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/surgicaldrill(src)
|
||||
new /obj/item/cautery(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/clothing/mask/surgical(src)
|
||||
new /obj/item/reagent_containers/medspray/sterilizine(src)
|
||||
@@ -391,6 +392,7 @@
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/surgicaldrill(src)
|
||||
new /obj/item/cautery(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/clothing/mask/surgical(src)
|
||||
new /obj/item/reagent_containers/medspray/sterilizine(src)
|
||||
@@ -485,6 +487,7 @@
|
||||
new /obj/item/circular_saw(src)
|
||||
new /obj/item/surgicaldrill(src)
|
||||
new /obj/item/cautery(src)
|
||||
new /obj/item/bonesetter(src)
|
||||
new /obj/item/surgical_drapes(src)
|
||||
new /obj/item/clothing/suit/straight_jacket(src)
|
||||
new /obj/item/clothing/mask/muzzle(src)
|
||||
|
||||
@@ -162,6 +162,7 @@
|
||||
/obj/item/surgical_drapes, //for true paramedics
|
||||
/obj/item/scalpel,
|
||||
/obj/item/circular_saw,
|
||||
/obj/item/bonesetter,
|
||||
/obj/item/surgicaldrill,
|
||||
/obj/item/retractor,
|
||||
/obj/item/cautery,
|
||||
@@ -181,7 +182,8 @@
|
||||
/obj/item/implant,
|
||||
/obj/item/implanter,
|
||||
/obj/item/pinpointer/crew,
|
||||
/obj/item/reagent_containers/chem_pack
|
||||
/obj/item/reagent_containers/chem_pack,
|
||||
/obj/item/stack/sticky_tape //surgical tape
|
||||
))
|
||||
|
||||
/obj/item/storage/belt/medical/surgery_belt_adv
|
||||
@@ -811,4 +813,3 @@
|
||||
attack_verb = list("bashed", "slashes", "prods", "pokes")
|
||||
fitting_swords = list(/obj/item/melee/rapier)
|
||||
starting_sword = /obj/item/melee/rapier
|
||||
|
||||
|
||||
@@ -41,9 +41,26 @@
|
||||
new /obj/item/stack/medical/suture(src)
|
||||
new /obj/item/stack/medical/mesh(src)
|
||||
new /obj/item/stack/medical/mesh(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen(src)
|
||||
new /obj/item/reagent_containers/hypospray/medipen/ekit(src)
|
||||
new /obj/item/healthanalyzer(src)
|
||||
|
||||
/obj/item/storage/firstaid/emergency
|
||||
icon_state = "medbriefcase"
|
||||
name = "emergency first-aid kit"
|
||||
desc = "A very simple first aid kit meant to secure and stabilize serious wounds for later treatment."
|
||||
|
||||
/obj/item/storage/firstaid/emergency/PopulateContents()
|
||||
if(empty)
|
||||
return
|
||||
var/static/items_inside = list(
|
||||
/obj/item/healthanalyzer/wound = 1,
|
||||
/obj/item/stack/medical/gauze = 1,
|
||||
/obj/item/stack/medical/suture/emergency = 1,
|
||||
/obj/item/stack/medical/ointment = 1,
|
||||
/obj/item/reagent_containers/hypospray/medipen/ekit = 2,
|
||||
/obj/item/storage/pill_bottle/iron = 1)
|
||||
generate_items_inside(items_inside,src)
|
||||
|
||||
/obj/item/storage/firstaid/ancient
|
||||
icon_state = "firstaid"
|
||||
desc = "A first aid kit with the ability to heal common types of injuries."
|
||||
@@ -416,6 +433,7 @@
|
||||
/obj/item/retractor,
|
||||
/obj/item/cautery,
|
||||
/obj/item/surgical_drapes,
|
||||
/obj/item/bonesetter,
|
||||
/obj/item/autosurgeon,
|
||||
/obj/item/organ,
|
||||
/obj/item/implant,
|
||||
|
||||
@@ -20,6 +20,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
var/has_latches = TRUE
|
||||
var/can_rubberify = TRUE
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //very protecc too
|
||||
wound_bonus = 5
|
||||
|
||||
/obj/item/storage/toolbox/greyscale
|
||||
icon_state = "toolbox_default"
|
||||
|
||||
@@ -574,6 +574,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
force = 10
|
||||
wound_bonus = -10
|
||||
throwforce = 12
|
||||
attack_verb = list("beat", "smacked")
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 3.5)
|
||||
@@ -626,7 +627,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
homerun_ready = 0
|
||||
return
|
||||
else if(!target.anchored)
|
||||
target.throw_at(throw_target, rand(1,2), 7, user)
|
||||
var/whack_speed = (prob(60) ? 1 : 4)
|
||||
target.throw_at(throw_target, rand(1, 2), whack_speed, user) // sorry friends, 7 speed batting caused wounds to absolutely delete whoever you knocked your target into (and said target)
|
||||
|
||||
/obj/item/melee/baseball_bat/ablative
|
||||
name = "metal baseball bat"
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
var/damtype = BRUTE
|
||||
var/force = 0
|
||||
|
||||
/// How good a given object is at causing wounds on carbons. Higher values equal better shots at creating serious wounds.
|
||||
var/wound_bonus = 0
|
||||
/// If this attacks a human with no wound armor on the affected body part, add this to the wound mod. Some attacks may be significantly worse at wounding if there's even a slight layer of armor to absorb some of it vs bare flesh
|
||||
var/bare_wound_bonus = 0
|
||||
|
||||
var/datum/armor/armor
|
||||
var/obj_integrity //defaults to max_integrity
|
||||
var/max_integrity = 500
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
if (QDELETED(head))
|
||||
return
|
||||
|
||||
playsound(src, 'sound/weapons/bladeslice.ogg', 100, 1)
|
||||
playsound(src, 'sound/weapons/guillotine.ogg', 100, TRUE)
|
||||
if (blade_sharpness >= GUILLOTINE_DECAP_MIN_SHARP || head.brute_dam >= 100)
|
||||
head.dismember()
|
||||
log_combat(user, H, "beheaded", src)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
if(user.grab_state < GRAB_AGGRESSIVE)
|
||||
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
|
||||
return
|
||||
tablepush(user, pushed_mob)
|
||||
tablelimbsmash(user, pushed_mob)
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
pushed_mob.visible_message("<span class='notice'>[user] begins to place [pushed_mob] onto [src]...</span>", \
|
||||
"<span class='userdanger'>[user] begins to place [pushed_mob] onto [src]...</span>")
|
||||
@@ -114,29 +114,17 @@
|
||||
"<span class='notice'>[user] places [pushed_mob] onto [src].</span>")
|
||||
log_combat(user, pushed_mob, "placed")
|
||||
|
||||
/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob)
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
/obj/structure/table/proc/tablelimbsmash(mob/living/user, mob/living/pushed_mob)
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM)) //this shouldnt even be possible anyway because you cant get them in an aggressive grab, but whatever
|
||||
to_chat(user, "<span class='danger'>Throwing [pushed_mob] onto the table might hurt them!</span>")
|
||||
return
|
||||
var/added_passtable = FALSE
|
||||
if(!pushed_mob.pass_flags & PASSTABLE)
|
||||
added_passtable = TRUE
|
||||
pushed_mob.pass_flags |= PASSTABLE
|
||||
pushed_mob.Move(src.loc)
|
||||
if(added_passtable)
|
||||
pushed_mob.pass_flags &= ~PASSTABLE
|
||||
if(pushed_mob.loc != loc) //Something prevented the tabling
|
||||
return
|
||||
pushed_mob.DefaultCombatKnockdown(40)
|
||||
pushed_mob.visible_message("<span class='danger'>[user] slams [pushed_mob] onto [src]!</span>", \
|
||||
"<span class='userdanger'>[user] slams you onto [src]!</span>")
|
||||
log_combat(user, pushed_mob, "tabled", null, "onto [src]")
|
||||
if(!ishuman(pushed_mob))
|
||||
return
|
||||
var/mob/living/carbon/human/H = pushed_mob
|
||||
if(iscatperson(H))
|
||||
H.emote("nya")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table)
|
||||
pushed_mob.Knockdown(30)
|
||||
var/obj/item/bodypart/banged_limb = pushed_mob.get_bodypart(user.zone_selected) || pushed_mob.get_bodypart(BODY_ZONE_HEAD)
|
||||
var/extra_wound = 0
|
||||
if(HAS_TRAIT(user, TRAIT_HULK))
|
||||
extra_wound = 20
|
||||
banged_limb.receive_damage(30, wound_bonus = extra_wound)
|
||||
pushed_mob.apply_damage(60, STAMINA)
|
||||
|
||||
/obj/structure/table/shove_act(mob/living/target, mob/living/user)
|
||||
if(CHECK_MOBILITY(target, MOBILITY_STAND))
|
||||
|
||||
@@ -1276,7 +1276,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_CUSTOM_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD)
|
||||
var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_CUSTOM_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD, ADMIN_PUNISHMENT_CRACK, ADMIN_PUNISHMENT_BLEED, ADMIN_PUNISHMENT_SCARIFY)
|
||||
|
||||
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
|
||||
|
||||
@@ -1341,7 +1341,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
if(ADMIN_PUNISHMENT_PIE)
|
||||
var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target))
|
||||
creamy.splat(target)
|
||||
if (ADMIN_PUNISHMENT_CUSTOM_PIE)
|
||||
if(ADMIN_PUNISHMENT_CUSTOM_PIE)
|
||||
var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/A = new()
|
||||
if(!A.reagents)
|
||||
var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num|null
|
||||
@@ -1354,7 +1354,33 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
if(amount)
|
||||
A.reagents.add_reagent(chosen_id, amount)
|
||||
A.splat(target)
|
||||
|
||||
if(ADMIN_PUNISHMENT_CRACK)
|
||||
if(!iscarbon(target))
|
||||
to_chat(usr,"<span class='warning'>This must be used on a carbon mob.</span>", confidential = TRUE)
|
||||
return
|
||||
var/mob/living/carbon/C = target
|
||||
for(var/obj/item/bodypart/squish_part in C.bodyparts)
|
||||
var/type_wound = pick(list(/datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/critical, /datum/wound/brute/bone/severe, /datum/wound/brute/bone/moderate))
|
||||
squish_part.force_wound_upwards(type_wound, smited=TRUE)
|
||||
if(ADMIN_PUNISHMENT_BLEED)
|
||||
if(!iscarbon(target))
|
||||
to_chat(usr,"<span class='warning'>This must be used on a carbon mob.</span>", confidential = TRUE)
|
||||
return
|
||||
var/mob/living/carbon/C = target
|
||||
for(var/obj/item/bodypart/slice_part in C.bodyparts)
|
||||
var/type_wound = pick(list(/datum/wound/brute/cut/severe, /datum/wound/brute/cut/moderate))
|
||||
slice_part.force_wound_upwards(type_wound, smited=TRUE)
|
||||
type_wound = pick(list(/datum/wound/brute/cut/critical, /datum/wound/brute/cut/severe, /datum/wound/brute/cut/moderate))
|
||||
slice_part.force_wound_upwards(type_wound, smited=TRUE)
|
||||
type_wound = pick(list(/datum/wound/brute/cut/critical, /datum/wound/brute/cut/severe))
|
||||
slice_part.force_wound_upwards(type_wound, smited=TRUE)
|
||||
if(ADMIN_PUNISHMENT_SCARIFY)
|
||||
if(!iscarbon(target))
|
||||
to_chat(usr,"<span class='warning'>This must be used on a carbon mob.</span>", confidential = TRUE)
|
||||
return
|
||||
var/mob/living/carbon/C = target
|
||||
C.generate_fake_scars(rand(1, 4))
|
||||
to_chat(C, "<span class='warning'>You feel your body grow jaded and torn...</span>")
|
||||
punish_log(target, punishment)
|
||||
|
||||
/client/proc/punish_log(var/whom, var/punishment)
|
||||
|
||||
@@ -36,6 +36,6 @@
|
||||
M.adjust_fire_stacks(round(reac_volume/10))
|
||||
M.IgniteMob()
|
||||
if(M)
|
||||
M.apply_damage(0.8*reac_volume, BURN)
|
||||
M.apply_damage(0.8*reac_volume, BURN, wound_bonus=CANT_WOUND)
|
||||
if(iscarbon(M))
|
||||
M.emote("scream")
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
M.reagents.add_reagent("frostoil", 0.3*reac_volume)
|
||||
M.reagents.add_reagent("ice", 0.3*reac_volume)
|
||||
M.reagents.add_reagent("cryogenic_poison", 0.3*reac_volume)
|
||||
M.apply_damage(0.2*reac_volume, BRUTE)
|
||||
M.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
|
||||
/datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustBruteLoss(0.3*REAGENTS_EFFECT_MULTIPLIER, 0)
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
if(prob(reac_volume*2))
|
||||
M.emp_act(EMP_LIGHT)
|
||||
if(M)
|
||||
M.apply_damage(reac_volume, BURN)
|
||||
M.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND)
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
if(ROLE_BLOB in L.faction) //no friendly fire
|
||||
continue
|
||||
var/aoe_volume = ..(L, TOUCH, initial_volume, 0, L.get_permeability_protection(), O)
|
||||
L.apply_damage(0.4*aoe_volume, BRUTE)
|
||||
L.apply_damage(0.4*aoe_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
if(M)
|
||||
M.apply_damage(0.6*reac_volume, BRUTE)
|
||||
M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
else
|
||||
M.apply_damage(0.6*reac_volume, BRUTE)
|
||||
M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
|
||||
@@ -33,6 +33,6 @@
|
||||
|
||||
/datum/reagent/blob/networked_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||
reac_volume = ..()
|
||||
M.apply_damage(0.6*reac_volume, BRUTE)
|
||||
M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
if(M)
|
||||
M.apply_damage(0.6*reac_volume, BURN)
|
||||
M.apply_damage(0.6*reac_volume, BURN, wound_bonus=CANT_WOUND)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
|
||||
M.adjust_fire_stacks(-(reac_volume / 10))
|
||||
M.ExtinguishMob()
|
||||
M.apply_damage(0.4*reac_volume, BRUTE)
|
||||
M.apply_damage(0.4*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
if(M)
|
||||
M.apply_damage(0.4*reac_volume, OXY)
|
||||
if(M)
|
||||
|
||||
@@ -31,4 +31,4 @@
|
||||
|
||||
/datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||
reac_volume = ..()
|
||||
M.apply_damage(0.7*reac_volume, BRUTE)
|
||||
M.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
|
||||
@@ -32,4 +32,4 @@
|
||||
|
||||
/datum/reagent/blob/shifting_fragments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||
reac_volume = ..()
|
||||
M.apply_damage(0.7*reac_volume, BRUTE)
|
||||
M.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
/datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
|
||||
reac_volume = ..()
|
||||
M.apply_damage(0.2*reac_volume, BRUTE)
|
||||
M.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
if(M && reac_volume)
|
||||
for(var/obj/structure/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume
|
||||
if(M)
|
||||
B.blob_attack_animation(M) //show them they're getting a bad time
|
||||
M.apply_damage(0.3*reac_volume, BRUTE)
|
||||
M.apply_damage(0.3*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/effect/proc_holder/changeling/fleshmend
|
||||
name = "Fleshmend"
|
||||
desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Functions while unconscious. This ability is loud, and might cause our blood to react violently to heat."
|
||||
desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath, as well as hiding all of our scars. Costs 20 chemicals."
|
||||
helptext = "If we are on fire, the healing effect will not function. Does not regrow limbs or restore lost blood."
|
||||
chemical_cost = 20
|
||||
loudness = 2
|
||||
|
||||
@@ -165,6 +165,8 @@
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharpness = IS_SHARP
|
||||
wound_bonus = -60
|
||||
bare_wound_bonus = 20
|
||||
var/can_drop = FALSE
|
||||
var/fake = FALSE
|
||||
total_mass = TOTAL_MASS_HAND_REPLACEMENT
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
C.emote("scream")
|
||||
C.regenerate_limbs(1)
|
||||
C.regenerate_organs()
|
||||
for(var/i in C.all_wounds)
|
||||
var/datum/wound/W = i
|
||||
W.remove_wound()
|
||||
if(!user.getorganslot(ORGAN_SLOT_BRAIN))
|
||||
var/obj/item/organ/brain/B
|
||||
if(C.has_dna() && C.dna.species.mutant_brain)
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = 15
|
||||
throwforce = 25
|
||||
wound_bonus = -30
|
||||
bare_wound_bonus = 30
|
||||
armour_penetration = 35
|
||||
actions_types = list(/datum/action/item_action/cult_dagger)
|
||||
|
||||
@@ -53,8 +55,10 @@
|
||||
flags_1 = CONDUCT_1
|
||||
sharpness = IS_SHARP
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 30
|
||||
force = 30 // whoever balanced this got beat in the head by a bible too many times good lord
|
||||
throwforce = 10
|
||||
wound_bonus = -80
|
||||
bare_wound_bonus = 30
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended")
|
||||
|
||||
|
||||
@@ -34,8 +34,11 @@
|
||||
healable = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
|
||||
obj_damage = 50
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
melee_damage_lower = 15 // reduced from 30 to 15 with wounds since they get big buffs to slicing wounds
|
||||
melee_damage_upper = 15
|
||||
wound_bonus = -10
|
||||
bare_wound_bonus = 0
|
||||
sharpness = TRUE
|
||||
see_in_dark = 8
|
||||
blood_volume = 0 //No bleeding on getting shot, for skeddadles
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
@@ -43,13 +46,25 @@
|
||||
var/playstyle_string = "<span class='big bold'>You are a slaughter demon,</span><B> a terrible creature from another realm. You have a single desire: To kill. \
|
||||
You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and disappearing from the station at will. \
|
||||
Pulling a dead or unconscious mob while you enter a pool will pull them in with you, allowing you to feast and regain your health. \
|
||||
You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. </B>"
|
||||
You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. \
|
||||
You gain strength the more attacks you land on live humanoids, though this resets when you return to the blood zone. You can also \
|
||||
launch a devastating slam attack with ctrl+shift+click, capable of smashing bones in one strike.</B>"
|
||||
|
||||
loot = list(/obj/effect/decal/cleanable/blood, \
|
||||
/obj/effect/decal/cleanable/blood/innards, \
|
||||
/obj/item/organ/heart/demon)
|
||||
del_on_death = 1
|
||||
deathmessage = "screams in anger as it collapses into a puddle of viscera!"
|
||||
// How long it takes for the alt-click slam attack to come off cooldown
|
||||
var/slam_cooldown_time = 45 SECONDS
|
||||
// The actual instance var for the cooldown
|
||||
var/slam_cooldown = 0
|
||||
// How many times we have hit humanoid targets since we last bloodcrawled, scaling wounding power
|
||||
var/current_hitstreak = 0
|
||||
// How much both our wound_bonus and bare_wound_bonus go up per hitstreak hit
|
||||
var/wound_bonus_per_hit = 5
|
||||
// How much our wound_bonus hitstreak bonus caps at (peak demonry)
|
||||
var/wound_bonus_hitstreak_max = 12
|
||||
|
||||
/mob/living/simple_animal/slaughter/Initialize()
|
||||
..()
|
||||
@@ -58,6 +73,33 @@
|
||||
if(istype(loc, /obj/effect/dummy/phased_mob/slaughter))
|
||||
bloodspell.phased = TRUE
|
||||
|
||||
/mob/living/simple_animal/slaughter/CtrlShiftClickOn(atom/A)
|
||||
if(!isliving(A))
|
||||
return ..()
|
||||
if(slam_cooldown + slam_cooldown_time > world.time)
|
||||
to_chat(src, "<span class='warning'>Your slam ability is still on cooldown!</span>")
|
||||
return
|
||||
|
||||
face_atom(A)
|
||||
var/mob/living/victim = A
|
||||
victim.take_bodypart_damage(brute=20, wound_bonus=wound_bonus) // don't worry, there's more punishment when they hit something
|
||||
visible_message("<span class='danger'>[src] slams into [victim] with monstrous strength!</span>", "<span class='danger'>You slam into [victim] with monstrous strength!</span>", ignored_mobs=victim)
|
||||
to_chat(victim, "<span class='userdanger'>[src] slams into you with monstrous strength, sending you flying like a ragdoll!</span>")
|
||||
var/turf/yeet_target = get_edge_target_turf(victim, dir)
|
||||
victim.throw_at(yeet_target, 10, 5, src)
|
||||
slam_cooldown = world.time
|
||||
log_combat(src, victim, "slaughter slammed")
|
||||
|
||||
/mob/living/simple_animal/slaughter/UnarmedAttack(atom/A, proximity)
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/target = A
|
||||
if(target.stat != DEAD && target.mind && current_hitstreak < wound_bonus_hitstreak_max)
|
||||
current_hitstreak++
|
||||
wound_bonus += wound_bonus_per_hit
|
||||
bare_wound_bonus += wound_bonus_per_hit
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/effect/decal/cleanable/blood/innards
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
name = "pile of viscera"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
/datum/antagonist/slaughter/greet()
|
||||
. = ..()
|
||||
owner.announce_objectives()
|
||||
to_chat(owner, "<span class='warning'>You have a powerful alt-attack that slams people backwards that you can activate by shift+ctrl+clicking your target!</span>")
|
||||
|
||||
/datum/antagonist/slaughter/proc/forge_objectives()
|
||||
if(summoner)
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
var/escape_in_progress = FALSE
|
||||
var/message_cooldown
|
||||
var/breakout_time = 300
|
||||
///Cryo will continue to treat people with 0 damage but existing wounds, but will sound off when damage healing is done in case doctors want to directly treat the wounds instead
|
||||
var/treating_wounds = FALSE
|
||||
|
||||
fair_market_price = 10
|
||||
payment_department = ACCOUNT_MED
|
||||
@@ -174,15 +176,27 @@
|
||||
return
|
||||
|
||||
if(mob_occupant.health >= mob_occupant.getMaxHealth()) // Don't bother with fully healed people.
|
||||
on = FALSE
|
||||
update_icon()
|
||||
playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors.
|
||||
var/msg = "Patient fully restored."
|
||||
if(autoeject) // Eject if configured.
|
||||
msg += " Auto ejecting patient now."
|
||||
open_machine()
|
||||
radio.talk_into(src, msg, radio_channel)
|
||||
return
|
||||
if(iscarbon(mob_occupant))
|
||||
var/mob/living/carbon/C = mob_occupant
|
||||
if(C.all_wounds)
|
||||
if(!treating_wounds) // if we have wounds and haven't already alerted the doctors we're only dealing with the wounds, let them know
|
||||
treating_wounds = TRUE
|
||||
playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors.
|
||||
var/msg = "Patient vitals fully recovered, continuing automated wound treatment."
|
||||
radio.talk_into(src, msg, radio_channel)
|
||||
else // otherwise if we were only treating wounds and now we don't have any, turn off treating_wounds so we can boot 'em out
|
||||
treating_wounds = FALSE
|
||||
|
||||
if(!treating_wounds)
|
||||
on = FALSE
|
||||
update_icon()
|
||||
playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors.
|
||||
var/msg = "Patient fully restored."
|
||||
if(autoeject) // Eject if configured.
|
||||
msg += " Auto ejecting patient now."
|
||||
open_machine()
|
||||
radio.talk_into(src, msg, radio_channel)
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/air1 = airs[1]
|
||||
|
||||
|
||||
@@ -75,3 +75,9 @@
|
||||
desc = "The simple beach ball is one of Nanotrasen's most popular products. 'Why do we make beach balls? Because we can! (TM)' - Nanotrasen"
|
||||
cost = 200
|
||||
contains = list(/obj/item/toy/beach_ball)
|
||||
|
||||
/datum/supply_pack/goody/hell_single
|
||||
name = "Hellgun Single-Pack"
|
||||
desc = "Contains one hellgun, an old pattern of laser gun infamous for its ability to horribly disfigure targets with burns. Technically violates the Space Geneva Convention when used on humanoids."
|
||||
cost = 1500
|
||||
contains = list(/obj/item/gun/energy/laser/hellgun)
|
||||
|
||||
@@ -114,7 +114,9 @@
|
||||
/obj/item/storage/box/medsprays,
|
||||
/obj/item/storage/box/syringes,
|
||||
/obj/item/storage/box/bodybags,
|
||||
/obj/item/storage/pill_bottle/stimulant)
|
||||
/obj/item/storage/pill_bottle/stimulant,
|
||||
/obj/item/stack/medical/bone_gel,
|
||||
/obj/item/stack/medical/bone_gel)
|
||||
crate_name = "medical supplies crate"
|
||||
|
||||
/datum/supply_pack/medical/adv_surgery_tools
|
||||
|
||||
@@ -239,6 +239,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/autostand = TRUE
|
||||
var/auto_ooc = FALSE
|
||||
|
||||
/// If we have persistent scars enabled
|
||||
var/persistent_scars = TRUE
|
||||
/// We have 5 slots for persistent scars, if enabled we pick a random one to load (empty by default) and scars at the end of the shift if we survived as our original person
|
||||
var/list/scars_list = list("1" = "", "2" = "", "3" = "", "4" = "", "5" = "")
|
||||
/// Which of the 5 persistent scar slots we randomly roll to load for this round, if enabled. Actually rolled in [/datum/preferences/proc/load_character(slot)]
|
||||
var/scars_index = 1
|
||||
|
||||
/datum/preferences/New(client/C)
|
||||
parent = C
|
||||
|
||||
@@ -825,6 +832,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Socks Color:</b> <span style='border:1px solid #161616; background-color: #[socks_color];'> </span> <a href='?_src_=prefs;preference=socks_color;task=input'>Change</a><BR>"
|
||||
dat += "<b>Backpack:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a>"
|
||||
dat += "<b>Jumpsuit:</b><BR><a href ='?_src_=prefs;preference=suit;task=input'>[jumpsuit_style]</a><BR>"
|
||||
if(CAN_SCAR in pref_species.species_traits)
|
||||
dat += "<BR><b>Temporal Scarring:</b><BR><a href='?_src_=prefs;preference=persistent_scars'>[(persistent_scars) ? "Enabled" : "Disabled"]</A>"
|
||||
dat += "<a href='?_src_=prefs;preference=clear_scars'>Clear scar slots</A>"
|
||||
dat += "<b>Uplink Location:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=uplink_loc;task=input'>[uplink_spawn_loc]</a>"
|
||||
dat += "</td>"
|
||||
|
||||
@@ -2545,6 +2555,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("hear_midis")
|
||||
toggles ^= SOUND_MIDI
|
||||
|
||||
if("persistent_scars")
|
||||
persistent_scars = !persistent_scars
|
||||
|
||||
if("clear_scars")
|
||||
to_chat(user, "<span class='notice'>All scar slots cleared. Please save character to confirm.</span>")
|
||||
scars_list["1"] = ""
|
||||
scars_list["2"] = ""
|
||||
scars_list["3"] = ""
|
||||
scars_list["4"] = ""
|
||||
scars_list["5"] = ""
|
||||
|
||||
if("lobby_music")
|
||||
toggles ^= SOUND_LOBBY
|
||||
if((toggles & SOUND_LOBBY) && user.client && isnewplayer(user))
|
||||
|
||||
@@ -453,6 +453,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(newtype)
|
||||
pref_species = new newtype
|
||||
|
||||
|
||||
scars_index = rand(1,5)
|
||||
|
||||
//Character
|
||||
S["real_name"] >> real_name
|
||||
S["nameless"] >> nameless
|
||||
@@ -497,6 +500,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["feature_insect_markings"] >> features["insect_markings"]
|
||||
S["feature_horns_color"] >> features["horns_color"]
|
||||
S["feature_wings_color"] >> features["wings_color"]
|
||||
S["persistent_scars"] >> persistent_scars
|
||||
S["scars1"] >> scars_list["1"]
|
||||
S["scars2"] >> scars_list["2"]
|
||||
S["scars3"] >> scars_list["3"]
|
||||
S["scars4"] >> scars_list["4"]
|
||||
S["scars5"] >> scars_list["5"]
|
||||
|
||||
|
||||
//Custom names
|
||||
@@ -709,6 +718,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN)
|
||||
features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN)
|
||||
|
||||
persistent_scars = sanitize_integer(persistent_scars)
|
||||
scars_list["1"] = sanitize_text(scars_list["1"])
|
||||
scars_list["2"] = sanitize_text(scars_list["2"])
|
||||
scars_list["3"] = sanitize_text(scars_list["3"])
|
||||
scars_list["4"] = sanitize_text(scars_list["4"])
|
||||
scars_list["5"] = sanitize_text(scars_list["5"])
|
||||
|
||||
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
|
||||
//Validate job prefs
|
||||
for(var/j in job_preferences)
|
||||
@@ -840,6 +856,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["vore_taste"] , vore_taste)
|
||||
WRITE_FILE(S["belly_prefs"] , belly_prefs)
|
||||
|
||||
WRITE_FILE(S["persistent_scars"] , persistent_scars)
|
||||
WRITE_FILE(S["scars1"] , scars_list["1"])
|
||||
WRITE_FILE(S["scars2"] , scars_list["2"])
|
||||
WRITE_FILE(S["scars3"] , scars_list["3"])
|
||||
WRITE_FILE(S["scars4"] , scars_list["4"])
|
||||
WRITE_FILE(S["scars5"] , scars_list["5"])
|
||||
|
||||
//gear loadout
|
||||
if(chosen_gear.len)
|
||||
var/text_to_save = chosen_gear.Join("|")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
max_integrity = 200
|
||||
integrity_failure = 0.4
|
||||
block_priority = BLOCK_PRIORITY_CLOTHING
|
||||
var/damaged_clothes = 0 //similar to machine's BROKEN stat and structure's broken var
|
||||
var/damaged_clothes = CLOTHING_PRISTINE //similar to machine's BROKEN stat and structure's broken var
|
||||
var/flash_protect = 0 //What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS
|
||||
var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect
|
||||
var/up = 0 //but separated to allow items to protect but not impair vision, like space helmets
|
||||
@@ -28,6 +28,9 @@
|
||||
|
||||
var/clothing_flags = NONE
|
||||
|
||||
// What items can be consumed to repair this clothing (must by an /obj/item/stack)
|
||||
var/repairable_by = /obj/item/stack/sheet/cloth
|
||||
|
||||
//Var modification - PLEASE be careful with this I know who you are and where you live
|
||||
var/list/user_vars_to_edit //VARNAME = VARVALUE eg: "name" = "butts"
|
||||
var/list/user_vars_remembered //Auto built by the above + dropped() + equipped()
|
||||
@@ -45,7 +48,17 @@
|
||||
var/list/species_restricted = null
|
||||
//Basically syntax is species_restricted = list("Species Name","Species Name")
|
||||
//Add a "exclude" string to do the opposite, making it only only species listed that can't wear it.
|
||||
//You append this to clothing objects.
|
||||
//You append this to clothing objects
|
||||
|
||||
|
||||
|
||||
// How much clothing damage has been dealt to each of the limbs of the clothing, assuming it covers more than one limb
|
||||
var/list/damage_by_parts
|
||||
// How much integrity is in a specific limb before that limb is disabled (for use in [/obj/item/clothing/proc/take_damage_zone], and only if we cover multiple zones.) Set to 0 to disable shredding.
|
||||
var/limb_integrity = 0
|
||||
// How many zones (body parts, not precise) we have disabled so far, for naming purposes
|
||||
var/zones_disabled
|
||||
.
|
||||
|
||||
/obj/item/clothing/Initialize()
|
||||
. = ..()
|
||||
@@ -83,15 +96,105 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/attackby(obj/item/W, mob/user, params)
|
||||
if(damaged_clothes && istype(W, /obj/item/stack/sheet/cloth))
|
||||
var/obj/item/stack/sheet/cloth/C = W
|
||||
C.use(1)
|
||||
update_clothes_damaged_state(FALSE)
|
||||
obj_integrity = max_integrity
|
||||
to_chat(user, "<span class='notice'>You fix the damage on [src] with [C].</span>")
|
||||
if(damaged_clothes && istype(W, repairable_by))
|
||||
var/obj/item/stack/S = W
|
||||
switch(damaged_clothes)
|
||||
if(CLOTHING_DAMAGED)
|
||||
S.use(1)
|
||||
repair(user, params)
|
||||
if(CLOTHING_SHREDDED)
|
||||
if(S.amount < 3)
|
||||
to_chat(user, "<span class='warning'>You require 3 [S.name] to repair [src].</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin fixing the damage to [src] with [S]...</span>")
|
||||
if(do_after(user, 6 SECONDS, TRUE, src))
|
||||
if(S.use(3))
|
||||
repair(user, params)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
// Set the clothing's integrity back to 100%, remove all damage to bodyparts, and generally fix it up
|
||||
/obj/item/clothing/proc/repair(mob/user, params)
|
||||
damaged_clothes = CLOTHING_PRISTINE
|
||||
update_clothes_damaged_state()
|
||||
obj_integrity = max_integrity
|
||||
name = initial(name) // remove "tattered" or "shredded" if there's a prefix
|
||||
body_parts_covered = initial(body_parts_covered)
|
||||
slot_flags = initial(slot_flags)
|
||||
damage_by_parts = null
|
||||
if(user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
to_chat(user, "<span class='notice'>You fix the damage on [src].</span>")
|
||||
|
||||
/**
|
||||
* take_damage_zone() is used for dealing damage to specific bodyparts on a worn piece of clothing, meant to be called from [/obj/item/bodypart/proc/check_woundings_mods()]
|
||||
*
|
||||
* This proc only matters when a bodypart that this clothing is covering is harmed by a direct attack (being on fire or in space need not apply), and only if this clothing covers
|
||||
* more than one bodypart to begin with. No point in tracking damage by zone for a hat, and I'm not cruel enough to let you fully break them in a few shots.
|
||||
* Also if limb_integrity is 0, then this clothing doesn't have bodypart damage enabled so skip it.
|
||||
*
|
||||
* Arguments:
|
||||
* * def_zone: The bodypart zone in question
|
||||
* * damage_amount: Incoming damage
|
||||
* * damage_type: BRUTE or BURN
|
||||
* * armour_penetration: If the attack had armour_penetration
|
||||
*/
|
||||
/obj/item/clothing/proc/take_damage_zone(def_zone, damage_amount, damage_type, armour_penetration)
|
||||
if(!def_zone || !limb_integrity || (initial(body_parts_covered) in GLOB.bitflags)) // the second check sees if we only cover one bodypart anyway and don't need to bother with this
|
||||
return
|
||||
var/list/covered_limbs = body_parts_covered2organ_names(body_parts_covered) // what do we actually cover?
|
||||
if(!(def_zone in covered_limbs))
|
||||
return
|
||||
|
||||
var/damage_dealt = take_damage(damage_amount * 0.1, damage_type, armour_penetration, FALSE) * 10 // only deal 10% of the damage to the general integrity damage, then multiply it by 10 so we know how much to deal to limb
|
||||
LAZYINITLIST(damage_by_parts)
|
||||
damage_by_parts[def_zone] += damage_dealt
|
||||
if(damage_by_parts[def_zone] > limb_integrity)
|
||||
disable_zone(def_zone, damage_type)
|
||||
|
||||
/**
|
||||
* disable_zone() is used to disable a given bodypart's protection on our clothing item, mainly from [/obj/item/clothing/proc/take_damage_zone()]
|
||||
*
|
||||
* This proc disables all protection on the specified bodypart for this piece of clothing: it'll be as if it doesn't cover it at all anymore (because it won't!)
|
||||
* If every possible bodypart has been disabled on the clothing, we put it out of commission entirely and mark it as shredded, whereby it will have to be repaired in
|
||||
* order to equip it again. Also note we only consider it damaged if there's more than one bodypart disabled.
|
||||
*
|
||||
* Arguments:
|
||||
* * def_zone: The bodypart zone we're disabling
|
||||
* * damage_type: Only really relevant for the verb for describing the breaking, and maybe obj_destruction()
|
||||
*/
|
||||
/obj/item/clothing/proc/disable_zone(def_zone, damage_type)
|
||||
var/list/covered_limbs = body_parts_covered2organ_names(body_parts_covered)
|
||||
if(!(def_zone in covered_limbs))
|
||||
return
|
||||
|
||||
var/zone_name = parse_zone(def_zone)
|
||||
var/break_verb = ((damage_type == BRUTE) ? "torn" : "burned")
|
||||
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/C = loc
|
||||
C.visible_message("<span class='danger'>The [zone_name] on [C]'s [src.name] is [break_verb] away!</span>", "<span class='userdanger'>The [zone_name] on your [src.name] is [break_verb] away!</span>", vision_distance = COMBAT_MESSAGE_RANGE)
|
||||
RegisterSignal(C, COMSIG_MOVABLE_MOVED, .proc/bristle)
|
||||
|
||||
zones_disabled++
|
||||
for(var/i in zone2body_parts_covered(def_zone))
|
||||
body_parts_covered &= ~i
|
||||
|
||||
if(body_parts_covered == NONE) // if there are no more parts to break then the whole thing is kaput
|
||||
obj_destruction((damage_type == BRUTE ? "melee" : "laser")) // melee/laser is good enough since this only procs from direct attacks anyway and not from fire/bombs
|
||||
return
|
||||
|
||||
damaged_clothes = CLOTHING_DAMAGED
|
||||
switch(zones_disabled)
|
||||
if(1)
|
||||
name = "damaged [initial(name)]"
|
||||
if(2)
|
||||
name = "mangy [initial(name)]"
|
||||
if(3 to INFINITY) // take better care of your shit, dude
|
||||
name = "tattered [initial(name)]"
|
||||
|
||||
update_clothes_damaged_state()
|
||||
|
||||
/obj/item/clothing/Destroy()
|
||||
user_vars_remembered = null //Oh god somebody put REFERENCES in here? not to worry, we'll clean it up
|
||||
return ..()
|
||||
@@ -100,6 +203,7 @@
|
||||
..()
|
||||
if(!istype(user))
|
||||
return
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
if(LAZYLEN(user_vars_remembered))
|
||||
for(var/variable in user_vars_remembered)
|
||||
if(variable in user.vars)
|
||||
@@ -112,7 +216,9 @@
|
||||
if (!istype(user))
|
||||
return
|
||||
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
|
||||
if (LAZYLEN(user_vars_to_edit))
|
||||
if(iscarbon(user) && LAZYLEN(zones_disabled))
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/bristle)
|
||||
if(LAZYLEN(user_vars_to_edit))
|
||||
for(var/variable in user_vars_to_edit)
|
||||
if(variable in user.vars)
|
||||
LAZYSET(user_vars_remembered, variable, user.vars[variable])
|
||||
@@ -120,8 +226,19 @@
|
||||
|
||||
/obj/item/clothing/examine(mob/user)
|
||||
. = ..()
|
||||
if(damaged_clothes)
|
||||
. += "<span class='warning'>It looks damaged!</span>"
|
||||
if(damaged_clothes == CLOTHING_SHREDDED)
|
||||
. += "<span class='warning'><b>It is completely shredded and requires mending before it can be worn again!</b></span>"
|
||||
return
|
||||
for(var/zone in damage_by_parts)
|
||||
var/pct_damage_part = damage_by_parts[zone] / limb_integrity * 100
|
||||
var/zone_name = parse_zone(zone)
|
||||
switch(pct_damage_part)
|
||||
if(100 to INFINITY)
|
||||
. += "<span class='warning'><b>The [zone_name] is useless and requires mending!</b></span>"
|
||||
if(60 to 99)
|
||||
. += "<span class='warning'>The [zone_name] is heavily shredded!</span>"
|
||||
if(30 to 59)
|
||||
. += "<span class='danger'>The [zone_name] is partially shredded.</span>"
|
||||
var/datum/component/storage/pockets = GetComponent(/datum/component/storage)
|
||||
if(pockets)
|
||||
var/list/how_cool_are_your_threads = list("<span class='notice'>")
|
||||
@@ -139,8 +256,8 @@
|
||||
. += how_cool_are_your_threads.Join()
|
||||
|
||||
/obj/item/clothing/obj_break(damage_flag)
|
||||
if(!damaged_clothes)
|
||||
update_clothes_damaged_state(TRUE)
|
||||
damaged_clothes = CLOTHING_DAMAGED
|
||||
update_clothes_damaged_state()
|
||||
if(ismob(loc)) //It's not important enough to warrant a message if nobody's wearing it
|
||||
var/mob/M = loc
|
||||
to_chat(M, "<span class='warning'>Your [name] starts to fall apart!</span>")
|
||||
@@ -222,16 +339,25 @@ BLIND // can't see anything
|
||||
|
||||
|
||||
/obj/item/clothing/obj_destruction(damage_flag)
|
||||
if(damage_flag == "bomb" || damage_flag == "melee")
|
||||
if(damage_flag == "bomb")
|
||||
var/turf/T = get_turf(src)
|
||||
spawn(1) //so the shred survives potential turf change from the explosion.
|
||||
var/obj/effect/decal/cleanable/shreds/Shreds = new(T)
|
||||
Shreds.desc = "The sad remains of what used to be [name]."
|
||||
deconstruct(FALSE)
|
||||
else if(!(damage_flag in list("acid", "fire")))
|
||||
damaged_clothes = CLOTHING_SHREDDED
|
||||
body_parts_covered = NONE
|
||||
name = "shredded [initial(name)]"
|
||||
slot_flags = NONE
|
||||
update_clothes_damaged_state()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.visible_message("<span class='danger'>[M]'s [src.name] falls off, completely shredded!</span>", "<span class='warning'><b>Your [src.name] falls off, completely shredded!</b></span>", vision_distance = COMBAT_MESSAGE_RANGE)
|
||||
M.dropItemToGround(src)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
//Species-restricted clothing check. - Thanks Oraclestation, BS13, /vg/station etc.
|
||||
/obj/item/clothing/mob_can_equip(mob/M, slot, disable_warning = TRUE)
|
||||
|
||||
@@ -265,3 +391,12 @@ BLIND // can't see anything
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/// If we're a clothing with at least 1 shredded/disabled zone, give the wearer a periodic heads up letting them know their clothes are damaged
|
||||
/obj/item/clothing/proc/bristle(mob/living/L)
|
||||
if(!istype(L))
|
||||
return
|
||||
if(prob(0.2))
|
||||
to_chat(L, "<span class='warning'>The damaged threads on your [src.name] chafe!</span>")
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
if(blood_DNA)
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color())
|
||||
|
||||
/obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE)
|
||||
/obj/item/clothing/gloves/update_clothes_damaged_state()
|
||||
..()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
if(blood_DNA)
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color())
|
||||
|
||||
/obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE)
|
||||
/obj/item/clothing/head/update_clothes_damaged_state()
|
||||
..()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
if(blood_DNA)
|
||||
. += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
|
||||
|
||||
/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE)
|
||||
/obj/item/clothing/mask/update_clothes_damaged_state()
|
||||
..()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
restore_offsets(user)
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/shoes/update_clothes_damaged_state(damaging = TRUE)
|
||||
/obj/item/clothing/shoes/update_clothes_damaged_state()
|
||||
..()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
var/blood_overlay_type = "suit"
|
||||
var/togglename = null
|
||||
var/suittoggled = FALSE
|
||||
limb_integrity = 0 // disabled for most exo-suits
|
||||
mutantrace_variation = STYLE_DIGITIGRADE
|
||||
|
||||
/obj/item/clothing/suit/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
|
||||
@@ -28,7 +29,7 @@
|
||||
if(A.above_suit)
|
||||
. += U.accessory_overlay
|
||||
|
||||
/obj/item/clothing/suit/update_clothes_damaged_state(damaging = TRUE)
|
||||
/obj/item/clothing/suit/update_clothes_damaged_state()
|
||||
..()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
equip_delay_other = 40
|
||||
max_integrity = 250
|
||||
resistance_flags = NONE
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 15)
|
||||
|
||||
|
||||
/obj/item/clothing/suit/armor/Initialize()
|
||||
. = ..()
|
||||
@@ -57,7 +58,7 @@
|
||||
icon_state = "hos"
|
||||
item_state = "greatcoat"
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90)
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90, "wound" = 20)
|
||||
cold_protection = CHEST|GROIN|LEGS|ARMS
|
||||
heat_protection = CHEST|GROIN|LEGS|ARMS
|
||||
strip_delay = 80
|
||||
@@ -123,7 +124,7 @@
|
||||
icon_state = "capcarapace"
|
||||
item_state = "armor"
|
||||
body_parts_covered = CHEST|GROIN
|
||||
armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90)
|
||||
armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90, "wound" = 10)
|
||||
dog_fashion = null
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
@@ -147,7 +148,7 @@
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80, "wound" = 30)
|
||||
blocks_shove_knockdown = TRUE
|
||||
strip_delay = 80
|
||||
equip_delay_other = 60
|
||||
@@ -158,7 +159,7 @@
|
||||
icon_state = "bonearmor"
|
||||
item_state = "bonearmor"
|
||||
blood_overlay_type = "armor"
|
||||
armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10)
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS
|
||||
|
||||
/obj/item/clothing/suit/armor/bulletproof
|
||||
@@ -167,7 +168,7 @@
|
||||
icon_state = "bulletproof"
|
||||
item_state = "armor"
|
||||
blood_overlay_type = "armor"
|
||||
armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50 "wound" = 20)
|
||||
strip_delay = 70
|
||||
equip_delay_other = 50
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
@@ -285,7 +286,7 @@
|
||||
desc = "A classic suit of armour, able to be made from many different materials."
|
||||
icon_state = "knight_greyscale"
|
||||
item_state = "knight_greyscale"
|
||||
armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40)
|
||||
armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40, "wound" = 15)
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Can change color and add prefix
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/durathread
|
||||
@@ -304,7 +305,7 @@
|
||||
desc = "A bulletproof vest with forest camo. Good thing there's plenty of forests to hide in around here, right?"
|
||||
icon_state = "rus_armor"
|
||||
item_state = "rus_armor"
|
||||
armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 15, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50)
|
||||
armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 15, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50, "wound" = 10)
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/russian_coat
|
||||
name = "russian battle coat"
|
||||
@@ -315,4 +316,4 @@
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50)
|
||||
armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50, "wound" = 10)
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
gas_transfer_coefficient = 0.01
|
||||
permeability_coefficient = 0.01
|
||||
body_parts_covered = CHEST|GROIN|ARMS|LEGS
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100)
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 20)
|
||||
allowed = list(/obj/item/teleportation_scroll)
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
strip_delay = 50
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
permeability_coefficient = 0.9
|
||||
block_priority = BLOCK_PRIORITY_UNIFORM
|
||||
slot_flags = ITEM_SLOT_ICLOTHING
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|USE_TAUR_CLIP_MASK
|
||||
limb_integrity = 30
|
||||
var/fitted = FEMALE_UNIFORM_FULL // For use in alternate clothing styles for women
|
||||
var/has_sensor = HAS_SENSORS // For the crew computer
|
||||
var/random_sensor = TRUE
|
||||
@@ -39,7 +40,7 @@
|
||||
if(!attach_accessory(I, user))
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/under/update_clothes_damaged_state(damaging = TRUE)
|
||||
/obj/item/clothing/under/update_clothes_damaged_state()
|
||||
..()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
|
||||
@@ -34,8 +34,9 @@
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/clothing/under/rank/cargo/miner
|
||||
desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty."
|
||||
name = "shaft miner's jumpsuit"
|
||||
desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty."
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 0, "wound" = 10)
|
||||
icon_state = "miner"
|
||||
item_state = "miner"
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
/obj/item/clothing/under/rank/captain/suit
|
||||
name = "captain's suit"
|
||||
desc = "A green suit and yellow necktie. Exemplifies authority."
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 15)
|
||||
icon_state = "green_suit"
|
||||
item_state = "dg_suit"
|
||||
can_adjust = FALSE
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
desc = "A tactical security jumpsuit for officers complete with Nanotrasen belt buckle."
|
||||
icon_state = "rsecurity"
|
||||
item_state = "r_suit"
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10)
|
||||
|
||||
/obj/item/clothing/under/rank/security/officer/grey
|
||||
name = "grey security jumpsuit"
|
||||
@@ -67,7 +67,7 @@
|
||||
desc = "A formal security suit for officers complete with Nanotrasen belt buckle."
|
||||
icon_state = "rwarden"
|
||||
item_state = "r_suit"
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10)
|
||||
|
||||
/obj/item/clothing/under/rank/security/warden/grey
|
||||
name = "grey security suit"
|
||||
@@ -101,7 +101,7 @@
|
||||
desc = "Someone who wears this means business."
|
||||
icon_state = "detective"
|
||||
item_state = "det"
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30)
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10)
|
||||
|
||||
/obj/item/clothing/under/rank/security/detective/skirt
|
||||
name = "detective's suitskirt"
|
||||
@@ -138,7 +138,7 @@
|
||||
desc = "A security jumpsuit decorated for those few with the dedication to achieve the position of Head of Security."
|
||||
icon_state = "rhos"
|
||||
item_state = "r_suit"
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10)
|
||||
strip_delay = 60
|
||||
|
||||
/obj/item/clothing/under/rank/security/head_of_security/skirt
|
||||
|
||||
@@ -313,6 +313,8 @@ h1.alert, h2.alert {color: #000000;}
|
||||
.rose {color: #ff5050;}
|
||||
.info {color: #0000CC;}
|
||||
.notice {color: #000099;}
|
||||
.tinynotice {color: #6685f5; font-style: italic; font-size: 85%;}
|
||||
.smallnotice {color: #6685f5; font-style: italic; font-size: 90%;}
|
||||
.boldnotice {color: #000099; font-weight: bold;}
|
||||
.adminnotice {color: #0000ff;}
|
||||
.adminhelp {color: #ff0000; font-weight: bold;}
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
icon_state = "deathnettle"
|
||||
force = 30
|
||||
throwforce = 15
|
||||
wound_bonus = CANT_WOUND
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/nettle/death/add_juice()
|
||||
..()
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
shoes = /obj/item/clothing/shoes/sneakers/brown
|
||||
suit = /obj/item/clothing/suit/toggle/labcoat/cmo
|
||||
l_hand = /obj/item/storage/firstaid/regular
|
||||
suit_store = /obj/item/flashlight/pen
|
||||
suit_store = /obj/item/flashlight/pen/paramedic
|
||||
backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1)
|
||||
|
||||
backpack = /obj/item/storage/backpack/medic
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
suit = /obj/item/clothing/suit/toggle/labcoat/paramedic
|
||||
belt = /obj/item/storage/belt/medical
|
||||
l_hand = /obj/item/storage/firstaid/regular
|
||||
suit_store = /obj/item/flashlight/pen
|
||||
suit_store = /obj/item/flashlight/pen/paramedic
|
||||
id = /obj/item/card/id
|
||||
r_pocket = /obj/item/pinpointer/crew
|
||||
l_pocket = /obj/item/pda/medical
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
cold_protection = HEAD
|
||||
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
|
||||
heat_protection = HEAD
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50, "wound" = 10)
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/clothing/suit/hooded/explorer/standard
|
||||
@@ -50,7 +50,7 @@
|
||||
visor_flags_inv = HIDEFACIALHAIR
|
||||
visor_flags_cover = MASKCOVERSMOUTH
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40)
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40, "wound" = 5)
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/clothing/mask/gas/explorer/attack_self(mob/user)
|
||||
|
||||
@@ -558,12 +558,25 @@
|
||||
client.prefs.random_character()
|
||||
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
|
||||
client.prefs.copy_to(H)
|
||||
var/cur_scar_index = client.prefs.scars_index
|
||||
if(client.prefs.persistent_scars && client.prefs.scars_list["[cur_scar_index]"])
|
||||
var/scar_string = client.prefs.scars_list["[cur_scar_index]"]
|
||||
var/valid_scars = ""
|
||||
for(var/scar_line in splittext(scar_string, ";"))
|
||||
if(H.load_scar(scar_line))
|
||||
valid_scars += "[scar_line];"
|
||||
|
||||
client.prefs.scars_list["[cur_scar_index]"] = valid_scars
|
||||
client.prefs.save_character()
|
||||
|
||||
client.prefs.copy_to(H, antagonist = is_antag)
|
||||
H.dna.update_dna_identity()
|
||||
if(mind)
|
||||
if(transfer_after)
|
||||
mind.late_joiner = TRUE
|
||||
mind.active = 0 //we wish to transfer the key manually
|
||||
mind.transfer_to(H) //won't transfer key since the mind is not active
|
||||
mind.original_character = H
|
||||
|
||||
H.name = real_name
|
||||
|
||||
|
||||
@@ -5,12 +5,27 @@
|
||||
#define EXOTIC_BLEED_MULTIPLIER 4 //Multiplies the actually bled amount by this number for the purposes of turf reaction calculations.
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/suppress_bloodloss(amount)
|
||||
if(bleedsuppress)
|
||||
return
|
||||
else
|
||||
bleedsuppress = TRUE
|
||||
addtimer(CALLBACK(src, .proc/resume_bleeding), amount)
|
||||
/mob/living/carbon/monkey/handle_blood()
|
||||
if(bodytemperature <= TCRYO || (HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
|
||||
var/temp_bleed = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
temp_bleed += BP.get_bleed_rate()
|
||||
BP.generic_bleedstacks = max(0, BP.generic_bleedstacks - 1)
|
||||
bleed(temp_bleed)
|
||||
|
||||
var/temp_bleed = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
temp_bleed += BP.get_bleed_rate()
|
||||
BP.generic_bleedstacks = max(0, BP.generic_bleedstacks - 1)
|
||||
bleed(temp_bleed)
|
||||
|
||||
//Blood regeneration if there is some space
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
blood_volume += 0.1 // regenerate blood VERY slowly
|
||||
if(blood_volume < BLOOD_VOLUME_OKAY)
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
|
||||
|
||||
/mob/living/carbon/human/proc/resume_bleeding()
|
||||
bleedsuppress = 0
|
||||
@@ -29,8 +44,7 @@
|
||||
// Takes care blood loss and regeneration
|
||||
/mob/living/carbon/human/handle_blood()
|
||||
|
||||
if(NOBLOOD in dna.species.species_traits)
|
||||
bleed_rate = 0
|
||||
if(NOBLOOD in dna.species.species_traits || bleedsuppress || (HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
return
|
||||
|
||||
if(bleed_rate < 0)
|
||||
@@ -87,24 +101,11 @@
|
||||
//Bleeding out
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
var/brutedamage = BP.brute_dam
|
||||
temp_bleed += BP.get_bleed_rate()
|
||||
BP.generic_bleedstacks = max(0, BP.generic_bleedstacks - 1)
|
||||
|
||||
if(BP.status == BODYPART_ROBOTIC) //for the moment, synth limbs won't bleed, but soon, my pretty.
|
||||
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
|
||||
|
||||
if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
bleed(bleed_rate)
|
||||
if(temp_bleed)
|
||||
bleed(temp_bleed)
|
||||
|
||||
//Makes a blood drop, leaking amt units of blood from the mob
|
||||
/mob/living/carbon/proc/bleed(amt)
|
||||
@@ -128,9 +129,11 @@
|
||||
/mob/living/proc/restore_blood()
|
||||
blood_volume = initial(blood_volume)
|
||||
|
||||
/mob/living/carbon/human/restore_blood()
|
||||
/mob/living/carbon/restore_blood()
|
||||
blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio)
|
||||
bleed_rate = 0
|
||||
for(var/i in bodyparts)
|
||||
var/obj/item/bodypart/BP = i
|
||||
BP.generic_bleedstacks = 0
|
||||
|
||||
/****************************************************
|
||||
BLOOD TRANSFERS
|
||||
|
||||
@@ -331,6 +331,8 @@
|
||||
max_traumas = TRAUMA_LIMIT_BASIC
|
||||
if(TRAUMA_RESILIENCE_SURGERY)
|
||||
max_traumas = TRAUMA_LIMIT_SURGERY
|
||||
if(TRAUMA_RESILIENCE_WOUND)
|
||||
max_traumas = TRAUMA_LIMIT_WOUND
|
||||
if(TRAUMA_RESILIENCE_LOBOTOMY)
|
||||
max_traumas = TRAUMA_LIMIT_LOBOTOMY
|
||||
if(TRAUMA_RESILIENCE_MAGIC)
|
||||
@@ -389,7 +391,7 @@
|
||||
return
|
||||
|
||||
var/trauma_type = pick(possible_traumas)
|
||||
gain_trauma(trauma_type, resilience)
|
||||
return gain_trauma(trauma_type, resilience)
|
||||
|
||||
//Cure a random trauma of a certain resilience level
|
||||
/obj/item/organ/brain/proc/cure_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience = TRAUMA_RESILIENCE_BASIC)
|
||||
|
||||
@@ -88,11 +88,32 @@
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user,user.a_intent))
|
||||
return 1
|
||||
|
||||
if(!all_wounds || !(user.a_intent == INTENT_HELP || user == src))
|
||||
return ..()
|
||||
|
||||
// The following priority/nonpriority searching is so that if we have two wounds on a limb that use the same item for treatment (gauze can bandage cuts AND splint broken bones),
|
||||
// we prefer whichever wound is not already treated (ignore the splinted broken bone for the open cut). If there's no priority wounds that this can treat, go through the
|
||||
// non-priority ones randomly.
|
||||
var/list/nonpriority_wounds = list()
|
||||
for(var/datum/wound/W in shuffle(all_wounds))
|
||||
if(!W.treat_priority)
|
||||
nonpriority_wounds += W
|
||||
else if(W.treat_priority && W.try_treating(I, user))
|
||||
return 1
|
||||
|
||||
for(var/datum/wound/W in shuffle(nonpriority_wounds))
|
||||
if(W.try_treating(I, user))
|
||||
return 1
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
. = ..()
|
||||
var/hurt = TRUE
|
||||
var/extra_speed = 0
|
||||
if(throwingdatum.thrower != src)
|
||||
extra_speed = min(max(0, throwingdatum.speed - initial(throw_speed)), 3)
|
||||
if(GetComponent(/datum/component/tackler))
|
||||
return
|
||||
if(throwingdatum?.thrower && iscyborg(throwingdatum.thrower))
|
||||
@@ -102,18 +123,18 @@
|
||||
if(hit_atom.density && isturf(hit_atom))
|
||||
if(hurt)
|
||||
DefaultCombatKnockdown(20)
|
||||
take_bodypart_damage(10)
|
||||
take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed)
|
||||
if(iscarbon(hit_atom) && hit_atom != src)
|
||||
var/mob/living/carbon/victim = hit_atom
|
||||
if(victim.movement_type & FLYING)
|
||||
return
|
||||
if(hurt)
|
||||
victim.take_bodypart_damage(10)
|
||||
take_bodypart_damage(10)
|
||||
victim.take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5)
|
||||
take_bodypart_damage(10 + 5 * extra_speed, check_armor = TRUE, wound_bonus = extra_speed * 5)
|
||||
victim.DefaultCombatKnockdown(20)
|
||||
DefaultCombatKnockdown(20)
|
||||
visible_message("<span class='danger'>[src] crashes into [victim], knocking them both over!</span>",\
|
||||
"<span class='userdanger'>You violently crash into [victim]!</span>")
|
||||
visible_message("<span class='danger'>[src] crashes into [victim] [extra_speed ? "really hard" : ""], knocking them both over!</span>",\
|
||||
"<span class='userdanger'>You violently crash into [victim] [extra_speed ? "extra hard" : ""]!</span>")
|
||||
playsound(src,'sound/weapons/punch1.ogg',50,1)
|
||||
|
||||
|
||||
@@ -196,12 +217,18 @@
|
||||
adjustStaminaLossBuffered(I.getweight(src, STAM_COST_THROW_MULT, SKILL_THROW_STAM_COST))
|
||||
|
||||
if(thrown_thing)
|
||||
visible_message("<span class='danger'>[src] has thrown [thrown_thing].</span>")
|
||||
log_message("has thrown [thrown_thing]", LOG_ATTACK)
|
||||
var/power_throw = 0
|
||||
if(HAS_TRAIT(src, TRAIT_HULK))
|
||||
power_throw++
|
||||
if(pulling && grab_state >= GRAB_NECK)
|
||||
power_throw++
|
||||
visible_message("<span class='danger'>[src] throws [thrown_thing][power_throw ? " really hard!" : "."]</span>", \
|
||||
"<span class='danger'>You throw [thrown_thing][power_throw ? " really hard!" : "."]</span>")
|
||||
log_message("has thrown [thrown_thing] [power_throw ? "really hard" : ""]", LOG_ATTACK)
|
||||
do_attack_animation(target, no_effect = 1)
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 50, 1, -1)
|
||||
newtonian_move(get_dir(target, src))
|
||||
thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force, random_turn)
|
||||
thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed + power_throw, src, null, null, null, move_force)
|
||||
|
||||
/mob/living/carbon/restrained(ignore_grab)
|
||||
. = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))
|
||||
@@ -892,6 +919,9 @@
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity != DISEASE_SEVERITY_POSITIVE)
|
||||
D.cure(FALSE)
|
||||
for(var/thing in all_wounds)
|
||||
var/datum/wound/W = thing
|
||||
W.remove_wound()
|
||||
if(admin_revive)
|
||||
regenerate_limbs()
|
||||
regenerate_organs()
|
||||
@@ -982,6 +1012,10 @@
|
||||
if(SANITY_NEUTRAL to SANITY_GREAT)
|
||||
. *= 0.90
|
||||
|
||||
for(var/i in status_effects)
|
||||
var/datum/status_effect/S = i
|
||||
. *= S.interact_speed_modifier()
|
||||
|
||||
|
||||
/mob/living/carbon/proc/create_internal_organs()
|
||||
for(var/X in internal_organs)
|
||||
@@ -1170,3 +1204,47 @@
|
||||
if(wear_mask)
|
||||
if(wear_mask.flags_inv & HIDEEYES)
|
||||
LAZYOR(., SLOT_GLASSES)
|
||||
|
||||
// if any of our bodyparts are bleeding
|
||||
/mob/living/carbon/proc/is_bleeding()
|
||||
for(var/i in bodyparts)
|
||||
var/obj/item/bodypart/BP = i
|
||||
if(BP.get_bleed_rate())
|
||||
return TRUE
|
||||
|
||||
// get our total bleedrate
|
||||
/mob/living/carbon/proc/get_total_bleed_rate()
|
||||
var/total_bleed_rate = 0
|
||||
for(var/i in bodyparts)
|
||||
var/obj/item/bodypart/BP = i
|
||||
total_bleed_rate += BP.get_bleed_rate()
|
||||
|
||||
return total_bleed_rate
|
||||
|
||||
/**
|
||||
* generate_fake_scars()- for when you want to scar someone, but you don't want to hurt them first. These scars don't count for temporal scarring (hence, fake)
|
||||
*
|
||||
* If you want a specific wound scar, pass that wound type as the second arg, otherwise you can pass a list like WOUND_LIST_CUT to generate a random cut scar.
|
||||
*
|
||||
* Arguments:
|
||||
* * num_scars- A number for how many scars you want to add
|
||||
* * forced_type- Which wound or category of wounds you want to choose from, WOUND_LIST_BONE, WOUND_LIST_CUT, or WOUND_LIST_BURN (or some combination). If passed a list, picks randomly from the listed wounds. Defaults to all 3 types
|
||||
*/
|
||||
/mob/living/carbon/proc/generate_fake_scars(num_scars, forced_type)
|
||||
for(var/i in 1 to num_scars)
|
||||
var/datum/scar/S = new
|
||||
var/obj/item/bodypart/BP = pick(bodyparts)
|
||||
|
||||
var/wound_type
|
||||
if(forced_type)
|
||||
if(islist(forced_type))
|
||||
wound_type = pick(forced_type)
|
||||
else
|
||||
wound_type = forced_type
|
||||
else
|
||||
wound_type = pick(WOUND_LIST_BONE + WOUND_LIST_CUT + WOUND_LIST_BURN)
|
||||
|
||||
var/datum/wound/W = new wound_type
|
||||
S.generate(BP, W)
|
||||
S.fake = TRUE
|
||||
QDEL_NULL(W)
|
||||
|
||||
Reference in New Issue
Block a user