Skip to content

Commit

Permalink
Merge branch 'master' into xenoarch_redux
Browse files Browse the repository at this point in the history
  • Loading branch information
DrDuckedGoose committed Aug 13, 2024
2 parents bca0a0b + 8079a4f commit 4a2f5ed
Show file tree
Hide file tree
Showing 234 changed files with 2,981 additions and 2,141 deletions.
2,268 changes: 1,137 additions & 1,131 deletions _maps/RandomZLevels/caves.dmm

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion code/__DEFINES/obj_flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@
#define SCAN_BOOZEPOWER (1<<12) //! Allows helmets and glasses to scan reagents.
#define MASKEXTENDRANGE (1<<13) //! For masks, allows you to breathe from internals on adjecent tiles
#define NOTCONSUMABLE (1<<14) //! Moths cannot eat clothing with that flag
#define HEADINTERNALS (1<<15) //! Headgear/helmet allows internals
/// Headgear/helmet allows internals
#define HEADINTERNALS (1<<18)

/// Integrity defines for clothing (not flags but close enough)
#define CLOTHING_PRISTINE 0 // We have no damage on the clothing
#define CLOTHING_DAMAGED 1 // There's some damage on the clothing but it still has at least one functioning bodypart and can be equipped
#define CLOTHING_SHREDDED 2 // The clothing is useless and cannot be equipped unless repaired first

/// Flags for the organ_flags var on /obj/item/organ

Expand Down
16 changes: 16 additions & 0 deletions code/__HELPERS/type2type.dm
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,22 @@
. = "NONE"
return .

/// For finding out what body parts a body zone covers, the inverse of the below basically
/proc/body_zone2cover_flags(def_zone)
switch(def_zone)
if(BODY_ZONE_CHEST)
return CHEST|GROIN
if(BODY_ZONE_HEAD)
return HEAD
if(BODY_ZONE_L_ARM)
return ARM_LEFT|HAND_LEFT
if(BODY_ZONE_R_ARM)
return ARM_RIGHT|HAND_RIGHT
if(BODY_ZONE_L_LEG)
return LEG_LEFT|FOOT_LEFT
if(BODY_ZONE_R_LEG)
return LEG_RIGHT|FOOT_RIGHT

/// Converts an RGB color to an HSL color
/proc/rgb2hsl(red, green, blue)
red /= 255;green /= 255;blue /= 255;
Expand Down
64 changes: 33 additions & 31 deletions code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,21 @@
return I.attack(src, user)

/**
* Called from [/mob/living/attackby]
*
* Arguments:
* * mob/living/M - The mob being hit by this item
* * mob/living/user - The mob hitting with this item
*/
/obj/item/proc/attack(mob/living/M, mob/living/user)
var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user)
* Called from [/mob/living/proc/attackby]
*
* Arguments:
* * mob/living/target_mob - The mob being hit by this item
* * mob/living/user - The mob hitting with this item
* * params - Click params of this attack
*/
/obj/item/proc/attack(mob/living/M, mob/living/user, params)
var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user, params)
if(signal_return & COMPONENT_CANCEL_ATTACK_CHAIN)
return TRUE
if(signal_return & COMPONENT_SKIP_ATTACK)
return

SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user)
SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user, params)
SEND_SIGNAL(M, COMSIG_MOB_ITEM_ATTACKBY, user, src)

var/nonharmfulhit = FALSE
Expand Down Expand Up @@ -165,17 +166,17 @@

/mob/living/attacked_by(obj/item/I, mob/living/user)
send_item_attack_message(I, user)
if(I.force)
var/armour_block = run_armor_check(null, MELEE, armour_penetration = I.armour_penetration)
apply_damage(I.force, I.damtype, blocked = armour_block)
if(I.damtype == BRUTE)
if(prob(33))
I.add_mob_blood(src)
var/turf/location = get_turf(src)
add_splatter_floor(location)
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
user.add_mob_blood(src)
return TRUE //successful attack
if(!I.force)
return FALSE
var/armour_block = run_armor_check(null, MELEE, armour_penetration = I.armour_penetration)
apply_damage(I.force, I.damtype, blocked = armour_block)
if(I.damtype == BRUTE && prob(33))
I.add_mob_blood(src)
var/turf/location = get_turf(src)
add_splatter_floor(location)
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
user.add_mob_blood(src)
return TRUE //successful attack

/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user, nonharmfulhit = FALSE)
if(I.force < force_threshold || I.damtype == STAMINA || nonharmfulhit)
Expand Down Expand Up @@ -211,23 +212,24 @@
return clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100

/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area)
var/message_verb = "attacked"
if(I.attack_verb && I.attack_verb.len)
message_verb = "[pick(I.attack_verb)]"
else if(!I.force)
if(!I.force && !length(I.attack_verb_simple) && !length(I.attack_verb_continuous))
return
var/message_verb_continuous = length(I.attack_verb_continuous) ? "[pick(I.attack_verb_continuous)]" : "attacks"
var/message_verb_simple = length(I.attack_verb_simple) ? "[pick(I.attack_verb_simple)]" : "attack"
var/message_hit_area = ""
if(hit_area)
message_hit_area = " in the [hit_area]"
var/attack_message = "[src] is [message_verb][message_hit_area] with [I]!"
var/attack_message_local = "You're [message_verb][message_hit_area] with [I]!"
var/attack_message_spectator = "[src] [message_verb_continuous][message_hit_area] with [I]!"
var/attack_message_victim = "You're [message_verb_continuous][message_hit_area] with [I]!"
var/attack_message_attacker = "You [message_verb_simple] [src][message_hit_area] with [I]!"
if(user in viewers(src))
attack_message = "[user] [message_verb] [src][message_hit_area] with [I]!"
attack_message_local = "[user] [message_verb] you[message_hit_area] with [I]!"
attack_message_spectator = "[user] [message_verb_continuous] [src][message_hit_area] with [I]!"
attack_message_victim = "[user] [message_verb_continuous] you[message_hit_area] with [I]!"
if(user == src)
attack_message_local = "You [message_verb] yourself[message_hit_area] with [I]!"
visible_message("<span class='danger'>[attack_message]</span>",\
"<span class='userdanger'>[attack_message_local]</span>", null, COMBAT_MESSAGE_RANGE)
attack_message_victim = "You [message_verb_simple] yourself[message_hit_area] with [I]"
visible_message("<span class='danger'>[attack_message_spectator]</span>",\
"<span class='userdanger'>[attack_message_victim]</span>", null, COMBAT_MESSAGE_RANGE, user)
to_chat(user, "<span class='danger'>[attack_message_attacker]</span>")
return 1

/mob/living/proc/send_item_poke_message(obj/item/I, mob/living/user)
Expand Down
6 changes: 4 additions & 2 deletions code/datums/martial/_martial.dm
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@
if(!damage)
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
D.visible_message("<span class='warning'>[A]'s [atk_verb] misses [D]!</span>", \
"<span class='userdanger'>[A]'s [atk_verb] misses you!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='danger'>You avoid [A]'s [atk_verb]!</span>", "<span class='hear'>You hear a swoosh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='warning'>Your [atk_verb] misses [D]!</span>")
log_combat(A, D, "attempted to [atk_verb]", important = FALSE)
return 0

Expand All @@ -66,7 +67,8 @@

playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
D.visible_message("<span class='danger'>[A] [atk_verb]ed [D]!</span>", \
"<span class='userdanger'>[A] [atk_verb]ed you!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>You're [atk_verb]ed by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You [atk_verb]ed [D]!</span>")

D.apply_damage(damage, A.dna.species.attack_type, affecting, armor_block)

Expand Down
3 changes: 2 additions & 1 deletion code/datums/martial/boxing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
var/knockout_prob = D.getStaminaLoss() + rand(-15,15)
if((D.stat != DEAD) && prob(knockout_prob))
D.visible_message("<span class='danger'>[A] knocks [D] out with a haymaker!</span>", \
"<span class='userdanger'>[A] knocks you out with a haymaker!</span>")
"<span class='userdanger'>You're knocked unconscious by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You knock [D] out with a haymaker!</span>")
D.apply_effect(200,EFFECT_KNOCKDOWN,armor_block)
D.SetSleeping(100)
D.force_say(A)
Expand Down
57 changes: 35 additions & 22 deletions code/datums/martial/cqc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@
if(!can_use(A))
return FALSE
if(D.body_position == STANDING_UP)
D.visible_message("<span class='warning'>[A] slams [D] into the ground!</span>", \
"<span class='userdanger'>[A] slams you into the ground!</span>")
D.visible_message("<span class='danger'>[A] slams [D] into the ground!</span>", \
"<span class='userdanger'>You're slammed into the ground by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", null, A)
to_chat(A, "<span class='danger'>You slam [D] into the ground!</span>")
playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE, blocked = def_check)
D.Paralyze(120)
Expand All @@ -67,17 +68,19 @@
if(!can_use(A))
return FALSE
if(!D.stat || !D.IsParalyzed())
D.visible_message("<span class='warning'>[A] kicks [D] back!</span>", \
"<span class='userdanger'>[A] kicks you back!</span>", null, COMBAT_MESSAGE_RANGE)
D.visible_message("<span class='danger'>[A] kicks [D] back!</span>", \
"<span class='userdanger'>You're kicked back by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You kick [D] back!</span>")
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
var/atom/throw_target = get_edge_target_turf(D, A.dir)
D.throw_at(throw_target, 1, 14, A)
D.apply_damage(10, A.dna.species.attack_type, blocked = def_check)
log_combat(A, D, "kicked (CQC)", name)
if(D.IsParalyzed() && !D.stat)
log_combat(A, D, "knocked out (Head kick)(CQC)", name)
D.visible_message("<span class='warning'>[A] kicks [D]'s head, knocking [D.p_them()] out!</span>", \
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
D.visible_message("<span class='danger'>[A] kicks [D]'s head, knocking [D.p_them()] out!</span>", \
"<span class='userdanger'>You're knocked unconscious by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", null, A)
to_chat(A, "<span class='danger'>You kick [D]'s head, knocking [D.p_them()] out!</span>")
playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
D.SetSleeping(300)
D.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150)
Expand All @@ -88,7 +91,8 @@
return FALSE
log_combat(A, D, "pressured (CQC)", name)
D.visible_message("<span class='danger'>[A] punches [D]'s neck!</span>", \
"<span class='userdanger'>[A] punches your neck!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>Your neck is punched by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You punch [D]'s neck!</span>")
D.adjustStaminaLoss(60)
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
return TRUE
Expand All @@ -101,7 +105,8 @@
if(!D.stat)
log_combat(A, D, "restrained (CQC)", name)
D.visible_message("<span class='warning'>[A] locks [D] into a restraining position!</span>", \
"<span class='userdanger'>[A] locks you into a restraining position!</span>")
"<span class='userdanger'>You're locked into a restraining position by [A]!</span>", "<span class='hear'>You hear shuffling and a muffled groan!</span>", null, A)
to_chat(A, "<span class='danger'>You lock [D] into a restraining position!</span>")
D.adjustStaminaLoss(20)
D.Stun(100)
restraining = TRUE
Expand All @@ -114,8 +119,9 @@
return FALSE
if(!D.stat)
log_combat(A, D, "consecutive CQC'd (CQC)", name)
D.visible_message("<span class='warning'>[A] strikes [D]'s abdomen, neck and back consecutively.</span>", \
"<span class='userdanger'>[A] strikes your abdomen, neck and back consecutively!</span>", null, COMBAT_MESSAGE_RANGE)
D.visible_message("<span class='danger'>[A] strikes [D]'s abdomen, neck and back consecutively</span>", \
"<span class='userdanger'>Your abdomen, neck and back are struck consecutively by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You strike [D]'s abdomen, neck and back consecutively!</span>")
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
var/obj/item/I = D.get_active_held_item()
if(I && D.temporarilyRemoveItemFromInventory(I))
Expand All @@ -139,7 +145,8 @@
A.setGrabState(GRAB_AGGRESSIVE) //Instant aggressive grab if on grab intent
log_combat(A, D, "grabbed", name, addition="aggressively")
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
"<span class='userdanger'>[A] violently grabs you!</span>")
"<span class='userdanger'>You're grabbed violently by [A]!</span>", "<span class='hear'>You hear sounds of aggressive fondling!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You violently grab [D]!</span>")
else
D.grabbedby(A, 1)
return TRUE
Expand All @@ -153,22 +160,25 @@
return TRUE
log_combat(A, D, "attacked (CQC)", name)
A.do_attack_animation(D)
var/picked_hit_type = pick("CQC'd", "Big Bossed")
var/picked_hit_type = pick("CQC", "Big Boss")
var/bonus_damage = 13
if(D.body_position == LYING_DOWN)
bonus_damage += 5
picked_hit_type = "stomps on"
picked_hit_type = "stomp"
D.apply_damage(bonus_damage, BRUTE, blocked = def_check)
if(picked_hit_type == "kicks" || picked_hit_type == "stomps on")
if(picked_hit_type == "kick" || picked_hit_type == "stomp")
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
else
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
"<span class='userdanger'>[A] [picked_hit_type] you!</span>", null, COMBAT_MESSAGE_RANGE)
D.visible_message("<span class='danger'>[A] [picked_hit_type]ed [D]!</span>", \
"<span class='userdanger'>You're [picked_hit_type]ed by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You [picked_hit_type] [D]!</span>")
log_combat(A, D, "[picked_hit_type]s (CQC)")
log_combat(A, D, "[picked_hit_type] (CQC)", name)
if(A.resting && !D.stat && !D.IsParalyzed())
D.visible_message("<span class='warning'>[A] leg sweeps [D]!", \
"<span class='userdanger'>[A] leg sweeps you!</span>")
D.visible_message("<span class='danger'>[A] leg sweeps [D]!", \
"<span class='userdanger'>Your legs are sweeped by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", null, A)
to_chat(A, "<span class='danger'>You leg sweep [D]!</span>")
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE, blocked = def_check)
D.Paralyze(60)
Expand All @@ -186,22 +196,25 @@
if(prob(65))
if(!D.stat || !D.IsParalyzed() || !restraining)
I = D.get_active_held_item()
D.visible_message("<span class='warning'>[A] strikes [D]'s jaw with their hand!</span>", \
"<span class='userdanger'>[A] strikes your jaw, disorienting you!</span>", null, COMBAT_MESSAGE_RANGE)
D.visible_message("<span class='danger'>[A] strikes [D]'s jaw with their hand!</span>", \
"<span class='userdanger'>Your jaw is struck by [A], you feel disoriented!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You strike [D]'s jaw, leaving [D.p_them()] disoriented!</span>")
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
if(I && D.temporarilyRemoveItemFromInventory(I))
A.put_in_hands(I)
D.Jitter(2)
D.apply_damage(5, A.dna.species.attack_type, blocked = def_check)
else
D.visible_message("<span class='danger'>[A] fails to disarm [D]!</span>", \
"<span class='userdanger'>[A] fails to disarm you!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>You're nearly disarmed by [A]!</span>", "<span class='hear'>You hear a swoosh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='warning'>You fail to disarm [D]!</span>")
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
log_combat(A, D, "disarmed (CQC)[I ? " grabbing \the [I]" : ""]", name)
if(restraining && A.pulling == D)
log_combat(A, D, "knocked out (Chokehold)(CQC)", name)
D.visible_message("<span class='danger'>[A] puts [D] into a chokehold!</span>", \
"<span class='userdanger'>[A] puts you into a chokehold!</span>")
"<span class='userdanger'>You're put into a chokehold by [A]!</span>", "<span class='hear'>You hear shuffling and a muffled groan!</span>", null, A)
to_chat(A, "<span class='danger'>You put [D] into a chokehold!</span>")
D.SetSleeping(400)
restraining = FALSE
if(A.grab_state < GRAB_NECK)
Expand Down
17 changes: 10 additions & 7 deletions code/datums/martial/krav_maga.dm
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@

/datum/martial_art/krav_maga/proc/quick_choke(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)//is actually lung punch
D.visible_message("<span class='warning'>[A] pounds [D] on the chest!</span>", \
"<span class='userdanger'>[A] slams your chest! You can't breathe!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>Your chest is slammed by [A]! You can't breathe!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You pound [D] on the chest!</span>")
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
if(D.losebreath <= 10)
D.losebreath = clamp(D.losebreath + 5, 0, 10)
Expand All @@ -112,7 +113,8 @@

/datum/martial_art/krav_maga/proc/neck_chop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
D.visible_message("<span class='warning'>[A] karate chops [D]'s neck!</span>", \
"<span class='userdanger'>[A] karate chops your neck, rendering you unable to speak!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>Your neck is karate chopped by [A], rendering you unable to speak!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You karate chop [D]'s neck, rendering [D.p_them()] unable to speak!</span>")
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
D.apply_damage(5, A.dna.species.attack_type)
if(D.silent <= 10)
Expand All @@ -131,20 +133,21 @@
return 1
var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.get_combat_bodyzone(D)))
var/armor_block = D.run_armor_check(affecting, MELEE)
var/picked_hit_type = pick("punched", "kicked")
var/picked_hit_type = pick("punch", "kick")
var/bonus_damage = 0
if(D.body_position == LYING_DOWN)
bonus_damage += 5
picked_hit_type = "stomped"
picked_hit_type = "stomp"
D.apply_damage(rand(5,10) + bonus_damage, A.dna.species.attack_type, affecting, armor_block)
if(picked_hit_type == "kicked" || picked_hit_type == "stomped")
if(picked_hit_type == "kick" || picked_hit_type == "stomp")
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
playsound(get_turf(D), 'sound/effects/hit_kick.ogg', 50, 1, -1)
else
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
playsound(get_turf(D), 'sound/effects/hit_punch.ogg', 50, 1, -1)
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
"<span class='userdanger'>[A] [picked_hit_type] you!</span>", null, COMBAT_MESSAGE_RANGE)
D.visible_message("<span class='danger'>[A] [picked_hit_type]s [D]!</span>", \
"<span class='userdanger'>You're [picked_hit_type]ed by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
to_chat(A, "<span class='danger'>You [picked_hit_type] [D]!</span>")
log_combat(A, D, "[picked_hit_type] with [name]", name)
return 1

Expand Down
Loading

0 comments on commit 4a2f5ed

Please sign in to comment.