diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index c86be0af72f..ba4973fb229 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -937,7 +937,7 @@ Turf and target are seperate in case you want to teleport some distance from a t output += A return output -/proc/get_turf_loc(var/mob/M) //gets the location of the turf that the mob is on, or what the mob is in is on, etc +/proc/get_turf_loc(var/atom/movable/M) //gets the location of the turf that the atom is on, or what the atom is in is on, etc //in case they're in a closet or sleeper or something var/atom/loc = M.loc while(!istype(loc, /turf/)) diff --git a/code/modules/chemical/Chemistry-Recipes.dm b/code/modules/chemical/Chemistry-Recipes.dm index 9272c726a91..0bcdf892f47 100644 --- a/code/modules/chemical/Chemistry-Recipes.dm +++ b/code/modules/chemical/Chemistry-Recipes.dm @@ -604,6 +604,65 @@ datum return + metroidteleport + name = "Metroid Teleport" + id = "m_tele" + result = null + required_reagents = list("plasma" = 1, "acid" = 1) + result_amount = 1 + required_container = /obj/item/metroid_core + required_other = 4 + on_reaction(var/datum/reagents/holder, var/created_volume) + + // Calculate new position (searches through beacons in world) + var/obj/item/device/radio/beacon/chosen + var/list/possible = list() + for(var/obj/item/device/radio/beacon/W in world) + possible += W + + if(possible.len > 0) + chosen = pick(possible) + + if(chosen) + // Calculate previous position for transition + + var/turf/FROM = get_turf_loc(holder.my_atom) // the turf of origin we're travelling FROM + var/turf/TO = get_turf_loc(chosen) // the turf of origin we're travelling TO + + playsound(TO, 'phasein.ogg', 100, 1) + + var/list/flashers = list() + for(var/mob/living/carbon/M in viewers(TO, null)) + flick("e_flash", M.flash) // flash dose faggots + flashers += M + + var/y_distance = TO.y - FROM.y + var/x_distance = TO.x - FROM.x + for (var/atom/movable/A in range(3, FROM )) // iterate thru list of mobs in the area + if(A == chosen) continue // don't teleport the actual beacon that's just stupid as fukkkkk + + var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place + if(!A.Move(newloc)) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving + A.loc = locate(A.x + x_distance, A.y + y_distance, TO.z) + + spawn() + if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect + var/mob/M = A + if(M.client) + var/obj/blueeffect = new /obj(src) + blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH" + blueeffect.icon = 'effects.dmi' + blueeffect.icon_state = "shieldsparkles" + blueeffect.layer = 17 + blueeffect.mouse_opacity = 0 + M.client.screen += blueeffect + sleep(20) + M.client.screen -= blueeffect + del(blueeffect) + + + + metroidchloral name = "Metroid Chloral" id = "m_bunch" diff --git a/code/modules/critters/critter.dm b/code/modules/critters/critter.dm index bcbcc130216..4c2c0dfe370 100644 --- a/code/modules/critters/critter.dm +++ b/code/modules/critters/critter.dm @@ -60,6 +60,10 @@ angertext = "charges at" attacktext = "attacks" + attack_sound = null // the sound it makes when it attacks! + + attack_speed = 25 // delay of attack + proc patrol_step() @@ -71,6 +75,7 @@ TakeDamage(var/damage = 0) Target_Attacker(var/target) Harvest(var/obj/item/weapon/W, var/mob/living/user)//Controls havesting things from dead critters + AfterAttack(var/mob/living/target) diff --git a/code/modules/critters/critter_AI.dm b/code/modules/critters/critter_AI.dm index cd8d8055f2a..5fed407dea7 100644 --- a/code/modules/critters/critter_AI.dm +++ b/code/modules/critters/critter_AI.dm @@ -153,13 +153,40 @@ for(var/mob/O in viewers(src, null)) O.show_message("\red [src] [src.attacktext] [src.target]!", 1) if(ismob(src.target)) - src.target:bruteloss += rand(melee_damage_lower,melee_damage_upper) + + + var/damage = rand(melee_damage_lower, melee_damage_upper) + + if(istype(target, /mob/living/carbon/human)) + var/dam_zone = pick("head", "chest", "l_hand", "r_hand", "l_leg", "r_leg", "groin") + if (dam_zone == "chest") + if ((((target:wear_suit && target:wear_suit.body_parts_covered & UPPER_TORSO) || (target:w_uniform && target:w_uniform.body_parts_covered & LOWER_TORSO)) && prob(10))) + if(prob(20)) + target:show_message("\blue You have been protected from a hit to the chest.") + return + if (istype(target:organs[text("[]", dam_zone)], /datum/organ/external)) + var/datum/organ/external/temp = target:organs[text("[]", dam_zone)] + if (temp.take_damage(damage, 0)) + target:UpdateDamageIcon() + else + target:UpdateDamage() + target:updatehealth() + + else + target:bruteloss += damage + + if(attack_sound) + playsound(loc, attack_sound, 50, 1, -1) + + AfterAttack(target) + + if(isobj(src.target)) if(istype(target, /obj/mecha)) src.target:take_damage(rand(melee_damage_lower,melee_damage_upper)) else src.target:TakeDamage(rand(melee_damage_lower,melee_damage_upper)) - spawn(25) + spawn(attack_speed) src.attacking = 0 return diff --git a/code/modules/critters/critter_defenses.dm b/code/modules/critters/critter_defenses.dm index b31dcfdb3fd..5d944e40acb 100644 --- a/code/modules/critters/critter_defenses.dm +++ b/code/modules/critters/critter_defenses.dm @@ -34,8 +34,9 @@ Contains the procs that control attacking critters if(!target) return src.target = target src.oldtarget_name = target:name - for(var/mob/O in viewers(src, null)) - O.show_message("\red [src] [src.angertext] [target:name]!", 1) + if(task != "chasing") + for(var/mob/O in viewers(src, null)) + O.show_message("\red [src] [src.angertext] [target:name]!", 1) src.task = "chasing" return diff --git a/code/modules/critters/critters.dm b/code/modules/critters/critters.dm index ad4d215d19f..3d03574946c 100644 --- a/code/modules/critters/critters.dm +++ b/code/modules/critters/critters.dm @@ -145,9 +145,13 @@ firevuln = 2 brutevuln = 1 melee_damage_lower = 5 - melee_damage_upper = 10 - angertext = "swims at" + melee_damage_upper = 15 + angertext = "lunges at" attacktext = "bites" + attack_sound = 'bite.ogg' + attack_speed = 10 + var/stunchance = 10 // chance to tackle things down + Harvest(var/obj/item/weapon/W, var/mob/living/user) @@ -167,14 +171,24 @@ return 1 return 0 + AfterAttack(var/mob/living/target) + if(prob(stunchance)) + if(target.weakened <= 0) + target.weakened += rand(10, 15) + for(var/mob/O in viewers(src, null)) + O.show_message("\red [src] knocks down [target]!", 1) + playsound(loc, 'pierce.ogg', 25, 1, -1) + /obj/critter/spesscarp/elite - desc = "Oh shit, you're really fucked now. It has an evil gleam in it's eye." + desc = "Oh shit, you're really fucked now. It has an evil gleam in its eye." health = 50 max_health = 50 - melee_damage_lower = 10 - melee_damage_upper = 20 + melee_damage_lower = 20 + melee_damage_upper = 35 + stunchance = 15 + attack_speed = 7 // opensdoors = 1 would give all access dono if want diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index c30e399a9c3..517bfda3ca8 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -635,8 +635,8 @@ var/damage = rand(1, 3) - if(istype(src, /mob/living/carbon/metroid/adult)) - damage = rand(20, 40) + if(istype(M, /mob/living/carbon/metroid/adult)) + damage = rand(10, 40) else damage = rand(5, 35) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 5e0cd6d6d93..889aa9eb0de 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1664,10 +1664,10 @@ var/damage = rand(1, 3) - if(istype(src, /mob/living/carbon/metroid/adult)) - damage = rand(20, 40) + if(istype(M, /mob/living/carbon/metroid/adult)) + damage = rand(10, 35) else - damage = rand(5, 35) + damage = rand(5, 25) var/dam_zone = pick("head", "chest", "l_hand", "r_hand", "l_leg", "r_leg", "groin")