[MIRROR] More unarmed fixes (#10485)

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-03-21 16:23:37 -07:00
committed by GitHub
parent 593396602b
commit 45a7802bc1
13 changed files with 52 additions and 114 deletions

View File

@@ -208,6 +208,9 @@
if((!can_buckle && !forced) || M.buckled || M.pinned.len || (max_buckled_mobs == 0) || (buckle_require_restraints && !M.restrained())) if((!can_buckle && !forced) || M.buckled || M.pinned.len || (max_buckled_mobs == 0) || (buckle_require_restraints && !M.restrained()))
return FALSE return FALSE
if(LAZYLEN(M.grabbed_by) && !forced)
to_chat(M, span_boldwarning("You can not buckle while grabbed!"))
return FALSE
if(has_buckled_mobs() && buckled_mobs.len >= max_buckled_mobs) //Handles trying to buckle yourself to the chair when someone is on it if(has_buckled_mobs() && buckled_mobs.len >= max_buckled_mobs) //Handles trying to buckle yourself to the chair when someone is on it
if(can_do_spont_vore && is_vore_predator(M) && M.vore_selected) if(can_do_spont_vore && is_vore_predator(M) && M.vore_selected)

View File

@@ -213,7 +213,7 @@
return return
if(istype(O, /obj/screen)) if(istype(O, /obj/screen))
return return
if(user.restrained() || user.stat || user.stunned || user.paralysis || (!user.lying && !isrobot(user))) if(user.restrained() || user.stat || user.stunned || user.paralysis || (!user.lying && !isrobot(user)) || LAZYLEN(user.grabbed_by))
return return
if((!(istype(O, /atom/movable)) || O.anchored || !Adjacent(user) || !Adjacent(O) || !user.Adjacent(O))) if((!(istype(O, /atom/movable)) || O.anchored || !Adjacent(user) || !Adjacent(O) || !user.Adjacent(O)))
return return

View File

@@ -22,8 +22,6 @@
QDEL_NULL(touching) QDEL_NULL(touching)
// We don't qdel(bloodstr) because it's the same as qdel(reagents) // We don't qdel(bloodstr) because it's the same as qdel(reagents)
bloodstr = null bloodstr = null
QDEL_NULL_LIST(internal_organs)
QDEL_NULL_LIST(stomach_contents)
return ..() return ..()
/mob/living/carbon/rejuvenate() /mob/living/carbon/rejuvenate()
@@ -45,37 +43,9 @@
// Moving around increases germ_level faster // Moving around increases germ_level faster
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8)) if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
germ_level++ germ_level++
/mob/living/carbon/relaymove(var/mob/living/user, direction)
if((user in src.stomach_contents) && istype(user))
if(user.last_special <= world.time)
user.last_special = world.time + 50
src.visible_message(span_danger("You hear something rumbling inside [src]'s stomach..."))
var/obj/item/I = user.get_active_hand()
if(I && I.force)
var/d = rand(round(I.force / 4), I.force)
if(ishuman(src))
var/mob/living/carbon/human/H = src
var/obj/item/organ/external/organ = H.get_organ(BP_TORSO)
if (istype(organ))
if(organ.take_damage(d, 0))
H.UpdateDamageIcon()
H.updatehealth()
else
src.take_organ_damage(d)
user.visible_message(span_danger("[user] attacks [src]'s stomach wall with the [I.name]!"))
playsound(user, 'sound/effects/attackblob.ogg', 50, 1)
if(prob(src.getBruteLoss() - 50))
for(var/atom/movable/A in stomach_contents)
A.loc = loc
stomach_contents.Remove(A)
src.gib()
*/ */
/mob/living/carbon/gib() /mob/living/carbon/gib()
for(var/mob/M in src) for(var/mob/M in src)
if(M in src.stomach_contents)
src.stomach_contents.Remove(M)
M.loc = src.loc M.loc = src.loc
for(var/mob/N in viewers(src, null)) for(var/mob/N in viewers(src, null))
if(N.client) if(N.client)

View File

@@ -2,9 +2,7 @@
gender = MALE gender = MALE
blocks_emissive = EMISSIVE_BLOCK_UNIQUE // BLEH, this could be improved for transparent species and stuff! And blocks glowing eyes?! blocks_emissive = EMISSIVE_BLOCK_UNIQUE // BLEH, this could be improved for transparent species and stuff! And blocks glowing eyes?!
var/datum/species/species //Contains icon generation and language information, set during New(). var/datum/species/species //Contains icon generation and language information, set during New().
var/list/stomach_contents = list()
var/list/antibodies = list() var/list/antibodies = list()
var/last_eating = 0 //Not sure what this does... I found it hidden in food.dm
var/life_tick = 0 // The amount of life ticks that have processed on this mob. var/life_tick = 0 // The amount of life ticks that have processed on this mob.

View File

@@ -45,7 +45,6 @@
if(H.hand) if(H.hand)
temp = H.organs_by_name["l_hand"] temp = H.organs_by_name["l_hand"]
if(!temp || !temp.is_usable()) if(!temp || !temp.is_usable())
//to_chat(H, span_warning("You can't use your hand."))
has_hands = FALSE has_hands = FALSE
for(var/thing in GetViruses()) //This is intentionally not having a has_hands check. If you are clicking on someone next to them, you're close enough to sneeze/cough on them! for(var/thing in GetViruses()) //This is intentionally not having a has_hands check. If you are clicking on someone next to them, you're close enough to sneeze/cough on them!
var/datum/disease/D = thing var/datum/disease/D = thing
@@ -80,7 +79,13 @@
if(D.spread_flags & CONTACT_HANDS) if(D.spread_flags & CONTACT_HANDS)
ContractDisease(D) ContractDisease(D)
switch(M.a_intent) //VARS: H = The one doing the attack. || M = The mob we are targeting || TT = gender of what we are targeting. switch(M.a_intent)
//VARS: (Placed here for your convenience, because it's confusing)
// H = THE PERSON DOING THE ATTACK, BUT DEFINED AS A HUMAN. (This is for human specific interactions, such as CPR.)
// M = THE PERSON DOING THE ATTACK, AGAIN, DEFINED AS A MOB
// src = THE PERSON BEING ATTACKED
// TT = GENDER OF THE TARGET
// has_hands = Local variable. If the attacker has hands or not.
if(I_HELP) if(I_HELP)
attack_hand_help_intent(H, M, TT, has_hands) attack_hand_help_intent(H, M, TT, has_hands)
@@ -103,11 +108,15 @@
/mob/living/carbon/human/proc/attack_hand_help_intent(var/mob/living/carbon/human/H, var/mob/living/M as mob, var/datum/gender/TT, var/has_hands) /mob/living/carbon/human/proc/attack_hand_help_intent(var/mob/living/carbon/human/H, var/mob/living/M as mob, var/datum/gender/TT, var/has_hands)
PRIVATE_PROC(TRUE) PRIVATE_PROC(TRUE)
SHOULD_NOT_OVERRIDE(TRUE) SHOULD_NOT_OVERRIDE(TRUE)
if(M.restrained()) //If we're restrained, we can't help them. If you want to add snowflake stuff that you can do while restrained, add it here.
return FALSE
if(!has_hands) //This is here so if you WANT to do special code for 'if we don't have hands, do stuff' it can be done here! if(!has_hands) //This is here so if you WANT to do special code for 'if we don't have hands, do stuff' it can be done here!
return FALSE return FALSE
if (istype(H) && attempt_to_scoop(H)) if(istype(M) && attempt_to_scoop(M))
return FALSE; return FALSE;
if(istype(H) && health < CONFIG_GET(number/health_threshold_crit))
//todo: make this whole CPR check into it's own individual proc instead of hogging up attack_hand_help_intent
if(istype(H) && health < CONFIG_GET(number/health_threshold_crit)) //Only humans can do CPR.
if(!H.check_has_mouth()) if(!H.check_has_mouth())
to_chat(H, span_danger("You don't have a mouth, you cannot perform CPR!")) to_chat(H, span_danger("You don't have a mouth, you cannot perform CPR!"))
return FALSE return FALSE
@@ -148,15 +157,25 @@
/mob/living/carbon/human/proc/attack_hand_disarm_intent(var/mob/living/carbon/human/H, var/mob/living/M as mob, var/datum/gender/TT, var/has_hands) /mob/living/carbon/human/proc/attack_hand_disarm_intent(var/mob/living/carbon/human/H, var/mob/living/M as mob, var/datum/gender/TT, var/has_hands)
PRIVATE_PROC(TRUE) PRIVATE_PROC(TRUE)
SHOULD_NOT_OVERRIDE(TRUE) SHOULD_NOT_OVERRIDE(TRUE)
if(M.restrained()) //If we're restrained, we can't disarm them. If you want to add snowflake stuff that you can do while restrained, add it here.
return
if(!has_hands) //This is here so if you WANT to do special code for 'if we don't have hands, do stuff' it can be done here! if(!has_hands) //This is here so if you WANT to do special code for 'if we don't have hands, do stuff' it can be done here!
return return
add_attack_logs(H,src,"Disarmed")
M.do_attack_animation(src) M.do_attack_animation(src)
if(w_uniform) if(w_uniform)
w_uniform.add_fingerprint(M) w_uniform.add_fingerprint(M)
if(M.lying && (M.loc == src.loc)) //If we are on the ground and they're on top of us, we don't have enough space to push them! Also antispam.
if(world.time <= (last_push_time + 6 SECONDS))
return
visible_message(span_warning("[M] struggles under [src]!"))
last_push_time = world.time
return
add_attack_logs(H,src,"Disarmed")
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/list/holding = list(get_active_hand() = 40, get_inactive_hand = 20) var/list/holding = list(get_active_hand() = 40, get_inactive_hand = 20)
@@ -172,8 +191,11 @@
visible_message(span_danger("[src]'s [W] goes off during the struggle!")) visible_message(span_danger("[src]'s [W] goes off during the struggle!"))
return W.afterattack(target,src) return W.afterattack(target,src)
if(last_push_time + 30 > world.time) if(last_push_time + 30 > world.time) //The fact that we're repeatedly doing it doesn't lessen the severity of the action! Send it full blast!
visible_message(span_warning("[M] has weakly pushed [src]!")) if(M.lying)
visible_message(span_filter_combat("[span_red(span_bold("[M] attempted to sweep [src] to the floor!"))]"))
else
visible_message(span_filter_combat("[span_red(span_bold("[M] attempted to disarm [src]!"))]"))
return return
var/randn = rand(1, 100) var/randn = rand(1, 100)
@@ -187,7 +209,13 @@
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(armor_check < 60) if(armor_check < 60)
drop_both_hands() // CHOMPEdit - We've been pushed! Drop our stuff as well drop_both_hands() // CHOMPEdit - We've been pushed! Drop our stuff as well
visible_message(span_danger("[M] has pushed [src]!")) if(M.lying)
visible_message(span_danger("[M] swept [src] down onto the floor!"))
else
visible_message(span_danger("[M] has pushed [src]!"))
break_all_grabs(M)
for(var/obj/item/I in holding)
drop_from_inventory(I)
else else
visible_message(span_warning("[M] attempted to push [src]!")) visible_message(span_warning("[M] attempted to push [src]!"))
return return
@@ -207,15 +235,20 @@
return return
playsound(src, 'sound/weapons/punchmiss.ogg', 25, 1, -1) playsound(src, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message(span_filter_combat("[span_red(span_bold("[M] attempted to disarm [src]!"))]")) if(M.lying)
visible_message(span_filter_combat("[span_red(span_bold("[M] attempted to sweep [src] to the floor!"))]"))
else
visible_message(span_filter_combat("[span_red(span_bold("[M] attempted to disarm [src]!"))]"))
//Grab Intent //Grab Intent
/mob/living/carbon/human/proc/attack_hand_grab_intent(var/mob/living/carbon/human/H, var/mob/living/M as mob, var/datum/gender/TT, var/has_hands) /mob/living/carbon/human/proc/attack_hand_grab_intent(var/mob/living/carbon/human/H, var/mob/living/M as mob, var/datum/gender/TT, var/has_hands)
PRIVATE_PROC(TRUE) PRIVATE_PROC(TRUE)
SHOULD_NOT_OVERRIDE(TRUE) SHOULD_NOT_OVERRIDE(TRUE)
if(M.restrained()) //If we're restrained, we can't grab them. If you want to add snowflake stuff that you can do while restrained, add it here.
return
if(!has_hands) //This is here so if you WANT to do special code for 'if we don't have hands, do stuff' it can be done here! if(!has_hands) //This is here so if you WANT to do special code for 'if we don't have hands, do stuff' it can be done here!
return FALSE return
if(M == src || anchored) if(M == src || anchored)
return FALSE return
for(var/obj/item/grab/G in src.grabbed_by) for(var/obj/item/grab/G in src.grabbed_by)
if(G.assailant == M) if(G.assailant == M)
to_chat(M, span_notice("You already grabbed [src].")) to_chat(M, span_notice("You already grabbed [src]."))
@@ -233,7 +266,7 @@
G.synch() G.synch()
LAssailant = M LAssailant = M
H.do_attack_animation(src) M.do_attack_animation(src)
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message(span_warning("[M] has grabbed [src] [(M.zone_sel.selecting == BP_L_HAND || M.zone_sel.selecting == BP_R_HAND)? "by [(gender==FEMALE)? "her" : ((gender==MALE)? "his": "their")] hands": "passively"]!")) visible_message(span_warning("[M] has grabbed [src] [(M.zone_sel.selecting == BP_L_HAND || M.zone_sel.selecting == BP_R_HAND)? "by [(gender==FEMALE)? "her" : ((gender==MALE)? "his": "their")] hands": "passively"]!"))
//Harm Intent //Harm Intent
@@ -275,7 +308,7 @@
if(canmove && src!=H && prob(20)) if(canmove && src!=H && prob(20))
block = 1 block = 1
if (M.grabbed_by.len) if(M.grabbed_by.len)
// Someone got a good grip on them, they won't be able to do much damage // Someone got a good grip on them, they won't be able to do much damage
rand_damage = max(1, rand_damage - 2) rand_damage = max(1, rand_damage - 2)

View File

@@ -116,19 +116,6 @@
to_chat(H, span_filter_notice("[span_red("Your nose begins to bleed...")]")) to_chat(H, span_filter_notice("[span_red("Your nose begins to bleed...")]"))
H.drip(1) H.drip(1)
/mob/living/carbon/human/proc/regurgitate()
set name = "Regurgitate"
set desc = "Empties the contents of your stomach"
set category = "Abilities.General"
if(stomach_contents.len)
for(var/mob/M in src)
if(M in stomach_contents)
stomach_contents.Remove(M)
M.loc = loc
src.visible_message(span_filter_warning(span_red(span_bold("[src] hurls out the contents of their stomach!"))))
return
/mob/living/carbon/human/proc/psychic_whisper(mob/M as mob in oview()) /mob/living/carbon/human/proc/psychic_whisper(mob/M as mob in oview())
set name = "Psychic Whisper" set name = "Psychic Whisper"
set desc = "Whisper silently to someone over a distance." set desc = "Whisper silently to someone over a distance."

View File

@@ -1874,23 +1874,6 @@
*/ // CHOMPedit End */ // CHOMPedit End
playsound_local(src,pick(scarySounds),50, 1, -1) playsound_local(src,pick(scarySounds),50, 1, -1)
/mob/living/carbon/human/handle_stomach()
spawn(0)
for(var/mob/living/M in stomach_contents)
if(M.loc != src)
stomach_contents.Remove(M)
continue
if(istype(M, /mob/living/carbon) && stat != 2)
if(M.stat == 2)
M.death(1)
stomach_contents.Remove(M)
qdel(M)
continue
if(SSair.current_cycle%3==1)
if(!(M.status_flags & GODMODE))
M.adjustBruteLoss(5)
adjust_nutrition(10)
/mob/living/carbon/human/proc/handle_changeling() /mob/living/carbon/human/proc/handle_changeling()
if(mind && mind.changeling) if(mind && mind.changeling)
mind.changeling.regenerate() mind.changeling.regenerate()

View File

@@ -369,7 +369,6 @@
if(gluttonous) if(gluttonous)
if(!inherent_verbs) if(!inherent_verbs)
inherent_verbs = list() inherent_verbs = list()
inherent_verbs |= /mob/living/carbon/human/proc/regurgitate
update_sort_hint() update_sort_hint()

View File

@@ -181,7 +181,6 @@
inherent_verbs = list( inherent_verbs = list(
/mob/living/proc/ventcrawl, /mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/plant, /mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma, /mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/evolve, /mob/living/carbon/human/proc/evolve,
@@ -223,7 +222,6 @@
/mob/living/carbon/human/proc/gut, /mob/living/carbon/human/proc/gut,
/mob/living/carbon/human/proc/leap, /mob/living/carbon/human/proc/leap,
/mob/living/carbon/human/proc/psychic_whisper, /mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate
) )
/datum/species/xenos/sentinel /datum/species/xenos/sentinel
@@ -251,7 +249,6 @@
inherent_verbs = list( inherent_verbs = list(
/mob/living/proc/ventcrawl, /mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle, /mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/transfer_plasma, /mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/corrosive_acid, /mob/living/carbon/human/proc/corrosive_acid,
/mob/living/carbon/human/proc/neurotoxin, /mob/living/carbon/human/proc/neurotoxin,
@@ -290,7 +287,6 @@
inherent_verbs = list( inherent_verbs = list(
/mob/living/proc/ventcrawl, /mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/psychic_whisper, /mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/lay_egg, /mob/living/carbon/human/proc/lay_egg,
/mob/living/carbon/human/proc/plant, /mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma, /mob/living/carbon/human/proc/transfer_plasma,

View File

@@ -342,10 +342,6 @@
if(I_DISARM) if(I_DISARM)
pin_down(affecting, assailant) pin_down(affecting, assailant)
//clicking on yourself while grabbing them
if(M == assailant && state >= GRAB_AGGRESSIVE)
devour(affecting, assailant)
/obj/item/grab/dropped(mob/user) /obj/item/grab/dropped(mob/user)
..() ..()
loc = null loc = null

View File

@@ -147,27 +147,3 @@
step_to(attacker, target) step_to(attacker, target)
attacker.set_dir(EAST) //face the victim attacker.set_dir(EAST) //face the victim
target.set_dir(SOUTH) //face up target.set_dir(SOUTH) //face up
/obj/item/grab/proc/devour(mob/target, mob/user)
var/can_eat
if((FAT in user.mutations) && ismini(target))
can_eat = 1
else
var/mob/living/carbon/human/H = user
if(istype(H) && H.species.gluttonous)
if(H.species.gluttonous == 2)
can_eat = 2
else if((H.mob_size > target.mob_size) && !ishuman(target) && ismini(target))
can_eat = 1
if(can_eat)
var/mob/living/carbon/attacker = user
user.visible_message(span_vdanger("[user] is attempting to devour [target]!"))
if(can_eat == 2)
if(!do_mob(user, target)||!do_after(user, 30)) return
else
if(!do_mob(user, target)||!do_after(user, 70)) return
user.visible_message(span_vdanger("[user] devours [target]!"))
target.loc = user
attacker.stomach_contents.Add(target)
qdel(src)

View File

@@ -24,9 +24,6 @@
if(reagents.total_volume + 2 < max_acid_volume && prob(20)) if(reagents.total_volume + 2 < max_acid_volume && prob(20))
reagents.add_reagent(acidtype, rand(1,2)) reagents.add_reagent(acidtype, rand(1,2))
for(var/mob/living/L in owner.stomach_contents) // Splashes mobs inside with acid. Twice as effective as being splashed with the same acid outside the body.
reagents.trans_to(L, 2, 2, 0)
if(is_broken() && prob(1)) if(is_broken() && prob(1))
owner.custom_pain("There's a twisting pain in your abdomen!",1) owner.custom_pain("There's a twisting pain in your abdomen!",1)
owner.vomit(FALSE, TRUE) owner.vomit(FALSE, TRUE)

View File

@@ -180,7 +180,7 @@
*/ */
/** /**
* Attempt to scoop up this mob up into H's hands, if the size difference is large enough. * Attempt to scoop up this mob up into M's hands, if the size difference is large enough.
* @return false if normal code should continue, 1 to prevent normal code. * @return false if normal code should continue, 1 to prevent normal code.
*/ */
/mob/living/proc/attempt_to_scoop(mob/living/M, mob/living/G, ignore_size = FALSE) //second one is for the Grabber, only exists for animals to self-grab /mob/living/proc/attempt_to_scoop(mob/living/M, mob/living/G, ignore_size = FALSE) //second one is for the Grabber, only exists for animals to self-grab