diff --git a/code/modules/mob/living/carbon/alien/alien_defenses.dm b/code/modules/mob/living/carbon/alien/alien_defenses.dm index 95ed75f18a0..16b7a17721c 100644 --- a/code/modules/mob/living/carbon/alien/alien_defenses.dm +++ b/code/modules/mob/living/carbon/alien/alien_defenses.dm @@ -49,6 +49,8 @@ In all, this is a lot like the monkey code. /N /mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M as mob) if(..()) //to allow surgery to return properly. return 0 + if(istype(src,/mob/living/carbon/alien/humanoid)) + return 0 //this is horrible but 100% necessary switch(M.a_intent) if("help") diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 3d346f83941..c054f766dac 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -254,18 +254,7 @@ help_shake_act(M) if ("grab") - if (M == src || anchored) - return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) - - M.put_in_active_hand(G) - - G.synch() - - LAssailant = M - - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message("[M] has grabbed [src] passively!") + grabbedby(M) if ("harm") M.do_attack_animation(src) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 925636dbba5..73244f1a6c5 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -27,34 +27,47 @@ mob/living if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8)) germ_level++ +#define STOMACH_ATTACK_DELAY 4 + +/mob/living/carbon/var/last_stomach_attack //defining this here because no one would look in carbon_defines for it + /mob/living/carbon/relaymove(var/mob/user, direction) if(user in src.stomach_contents) - if(prob(40)) - for(var/mob/M in hearers(4, src)) - if(M.client) - M.show_message(text("\red You hear something rumbling inside [src]'s stomach..."), 2) - var/obj/item/I = user.get_active_hand() - if(I && I.force) - var/d = rand(round(I.force / 4), I.force) - if(istype(src, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = src - var/obj/item/organ/external/organ = H.get_organ("chest") - if (istype(organ)) - if(organ.take_damage(d, 0)) - H.UpdateDamageIcon() - H.updatehealth() - else - src.take_organ_damage(d) - for(var/mob/M in viewers(user, null)) - if(M.client) - M.show_message(text("\red [user] attacks [src]'s stomach wall with the [I.name]!"), 2) - playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1) + if(last_stomach_attack + STOMACH_ATTACK_DELAY > world.time) return - if(prob(src.getBruteLoss() - 50)) - for(var/atom/movable/A in stomach_contents) - A.loc = loc - stomach_contents.Remove(A) - src.gib() + last_stomach_attack = world.time + for(var/mob/M in hearers(4, src)) + if(M.client) + M.show_message(text("\red You hear something rumbling inside [src]'s stomach..."), 2) + + var/obj/item/I = user.get_active_hand() + if(I && I.force) + var/d = rand(round(I.force / 4), I.force) + + if(istype(src, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = src + var/obj/item/organ/external/organ = H.get_organ("chest") + if (istype(organ)) + if(organ.take_damage(d, 0)) + H.UpdateDamageIcon() + + H.updatehealth() + + else + src.take_organ_damage(d) + + for(var/mob/M in viewers(user, null)) + if(M.client) + M.show_message(text("\red [user] attacks [src]'s stomach wall with the [I.name]!"), 2) + playsound(user.loc, '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() + +#undef STOMACH_ATTACK_DELAY /mob/living/carbon/gib() for(var/mob/M in src) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index b04c0832350..a15cf352e25 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -1,6 +1,13 @@ #define UPGRADE_COOLDOWN 40 #define UPGRADE_KILL_TIMER 100 +//times it takes for a mob to eat +#define EAT_TIME_XENO 30 +#define EAT_TIME_FAT 100 + +//time it takes for a mob to be eaten (in deciseconds) (overrides mob eat time) +#define EAT_TIME_MOUSE 30 + /obj/item/weapon/grab name = "grab" flags = NOBLUDGEON | ABSTRACT @@ -187,22 +194,47 @@ if(!affecting) return - if(M == affecting) + if(M == affecting) //what the actual fuck is this s_click(hud) return - if(M == assailant && state >= GRAB_AGGRESSIVE) - if( (ishuman(user) && (FAT in user.mutations) && iscarbon(affecting) ) || ( isalien(user) && iscarbon(affecting) ) || ( istype(user,/mob/living/carbon/human/kidan) && istype(affecting,/mob/living/carbon/monkey/diona) ) || ( ishuman(user) && user.get_species() == "Tajaran" && istype(affecting,/mob/living/simple_animal/mouse) ) ) + + if(M == assailant && state >= GRAB_AGGRESSIVE) //no eatin unless you have an agressive grab + if(checkvalid(user, affecting)) //wut var/mob/living/carbon/attacker = user user.visible_message("[user] is attempting to devour \the [affecting]!") - if(istype(user, /mob/living/carbon/alien/humanoid/hunter) || istype(affecting, /mob/living/simple_animal/mouse)) //mice are easy to eat - if(!do_mob(user, affecting)||!do_after(user, 30)) return - else - if(!do_mob(user, affecting)||!do_after(user, 100)) return + + if(!do_mob(user, affecting) || !do_after(user, checktime(user, affecting))) return + user.visible_message("[user] devours \the [affecting]!") - affecting.loc = user - attacker.stomach_contents.Add(affecting) + + affecting.loc = user //add the mob to the user + attacker.stomach_contents.Add(affecting) //list keeping + del(src) +/obj/item/weapon/grab/proc/checkvalid(var/mob/attacker, var/mob/prey) //does all the checking for the attack proc to see if a mob can eat another with the grab + if(ishuman(attacker) && (FAT in attacker.mutations) && iscarbon(prey)) //Fat people eating carbon mobs + return 1 + + if(isalien(attacker) && iscarbon(prey)) //Xenomorphs eating carbon mobs + return 1 + + if(ishuman(attacker) && attacker.get_species() == "Kidan" && istype(prey,/mob/living/carbon/monkey/diona)) //Kidan eating nymphs + return 1 + + if(ishuman(attacker) && attacker.get_species() == "Tajaran" && istype(prey,/mob/living/simple_animal/mouse)) //Tajaran eating mice. Meow! + return 1 + + return 0 + +/obj/item/weapon/grab/proc/checktime(var/mob/attacker, var/mob/prey) //Returns the time the attacker has to wait before they eat the prey + if(isalien(attacker)) + return EAT_TIME_XENO //xenos get a speed boost + + if(istype(prey,/mob/living/simple_animal/mouse)) //mice get eaten at xeno-eating-speed regardless + return EAT_TIME_MOUSE + + return EAT_TIME_FAT //if it doesn't fit into the above, it's probably a fat guy, take EAT_TIME_FAT to do it /obj/item/weapon/grab/dropped() del(src) @@ -211,3 +243,8 @@ /obj/item/weapon/grab/Destroy() del(hud) ..() + +#undef EAT_TIME_XENO +#undef EAT_TIME_FAT + +#undef EAT_TIME_MOUSE \ No newline at end of file