diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm index 480aa68984d..a27d881a437 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm @@ -1,5 +1,5 @@ /datum/ai_behavior/basic_melee_attack - action_cooldown = 2 SECONDS + action_cooldown = 0.2 SECONDS // We gotta check unfortunately often because we're in a race condition with nextmove behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION /datum/ai_behavior/basic_melee_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) @@ -16,6 +16,11 @@ set_movement_target(controller, target) /datum/ai_behavior/basic_melee_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) + if (isliving(controller.pawn)) + var/mob/living/pawn = controller.pawn + if (world.time < pawn.next_move) + return + . = ..() var/mob/living/basic/basic_mob = controller.pawn //targetting datum will kill the action if not real anymore @@ -41,9 +46,6 @@ if(!succeeded) controller.clear_blackboard_key(target_key) -/datum/ai_behavior/basic_melee_attack/average_speed - action_cooldown = 1 SECONDS - /datum/ai_behavior/basic_ranged_attack action_cooldown = 0.6 SECONDS behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM diff --git a/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm index 90379fcac0a..ed45de512ac 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/simple_attack_target.dm @@ -9,9 +9,6 @@ controller.queue_behavior(melee_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions. -/datum/ai_planning_subtree/basic_melee_attack_subtree/average_speed - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/average_speed - /datum/ai_planning_subtree/basic_ranged_attack_subtree operational_datums = list(/datum/component/ranged_attacks) var/datum/ai_behavior/basic_ranged_attack/ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack diff --git a/code/datums/ai/dog/dog_behaviors.dm b/code/datums/ai/dog/dog_behaviors.dm index 7bd0d5824a1..6c9cb779bb3 100644 --- a/code/datums/ai/dog/dog_behaviors.dm +++ b/code/datums/ai/dog/dog_behaviors.dm @@ -4,7 +4,6 @@ * Adds a floor to the melee damage of the dog, as most pet dogs don't actually have any melee strength */ /datum/ai_behavior/basic_melee_attack/dog - action_cooldown = 0.8 SECONDS behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM required_distance = 3 diff --git a/code/datums/components/basic_mob_attack_telegraph.dm b/code/datums/components/basic_mob_attack_telegraph.dm index 6467fbd7bbc..5473dbd0fa0 100644 --- a/code/datums/components/basic_mob_attack_telegraph.dm +++ b/code/datums/components/basic_mob_attack_telegraph.dm @@ -73,7 +73,7 @@ return ADD_TRAIT(source, TRAIT_BASIC_ATTACK_FORECAST, REF(src)) forget_target(target) - source.melee_attack(target) + source.melee_attack(target, ignore_cooldown = TRUE) // We already started the cooldown when we triggered the forecast /// The guy we're trying to attack moved, is he still in range? /datum/component/basic_mob_attack_telegraph/proc/target_moved(atom/target) diff --git a/code/datums/components/pet_commands/pet_commands_basic.dm b/code/datums/components/pet_commands/pet_commands_basic.dm index a07a94fff3f..ff29b8f37d2 100644 --- a/code/datums/components/pet_commands/pet_commands_basic.dm +++ b/code/datums/components/pet_commands/pet_commands_basic.dm @@ -111,7 +111,7 @@ pointed_reaction = "and growls" /// Balloon alert to display if providing an invalid target var/refuse_reaction = "shakes head" - /// Attack behaviour to use, generally you will want to override this to add some kind of cooldown + /// Attack behaviour to use var/attack_behaviour = /datum/ai_behavior/basic_melee_attack // Refuse to target things we can't target, chiefly other friends diff --git a/code/datums/elements/content_barfer.dm b/code/datums/elements/content_barfer.dm index 7e26d3f7753..e30294bc08a 100644 --- a/code/datums/elements/content_barfer.dm +++ b/code/datums/elements/content_barfer.dm @@ -4,9 +4,8 @@ * Used for morphs and bileworms! */ /datum/element/content_barfer - argument_hash_start_idx = 2 -/datum/element/content_barfer/Attach(datum/target, tally_string) +/datum/element/content_barfer/Attach(datum/target) . = ..() if(!isliving(target)) diff --git a/code/datums/elements/mob_grabber.dm b/code/datums/elements/mob_grabber.dm new file mode 100644 index 00000000000..a85c5dc48b2 --- /dev/null +++ b/code/datums/elements/mob_grabber.dm @@ -0,0 +1,30 @@ +/// Grab onto mobs we attack +/datum/element/mob_grabber + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + /// What state must the mob be in to be grabbed? + var/minimum_stat + /// If someone else is already grabbing this, will we take it? + var/steal_from_others + +/datum/element/mob_grabber/Attach(datum/target, minimum_stat = SOFT_CRIT, steal_from_others = TRUE) + . = ..() + if (!isliving(target)) + return ELEMENT_INCOMPATIBLE + src.minimum_stat = minimum_stat + src.steal_from_others = steal_from_others + RegisterSignals(target, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET), PROC_REF(grab_mob)) + +/datum/element/mob_grabber/Detach(datum/source) + UnregisterSignal(source, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET)) + . = ..() + +/// Try and grab something we attacked +/datum/element/mob_grabber/proc/grab_mob(mob/living/source, mob/living/target) + SIGNAL_HANDLER + if (!isliving(target) || !source.Adjacent(target) || target.stat < minimum_stat) + return + var/atom/currently_pulled = target.pulledby + if (!isnull(currently_pulled) && (!steal_from_others || currently_pulled == source)) + return + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob/living, grabbedby), source) diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index 44c11bdc056..155321805c6 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -35,6 +35,8 @@ var/attack_vis_effect ///Played when someone punches the creature. var/attacked_sound = SFX_PUNCH //This should be an element + /// How often can you melee attack? + var/melee_attack_cooldown = 2 SECONDS /// Variable maintained for compatibility with attack_animal procs until simple animals can be refactored away. Use element instead of setting manually. var/environment_smash = ENVIRONMENT_SMASH_STRUCTURES @@ -191,8 +193,10 @@ return . += span_deadsay("Upon closer examination, [p_they()] appear[p_s()] to be [HAS_TRAIT(user.mind, TRAIT_NAIVE) ? "asleep" : "dead"].") -/mob/living/basic/proc/melee_attack(atom/target, list/modifiers) +/mob/living/basic/proc/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) face_atom(target) + if (!ignore_cooldown) + changeNext_move(melee_attack_cooldown) if(SEND_SIGNAL(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, target) & COMPONENT_HOSTILE_NO_ATTACK) return FALSE //but more importantly return before attack_animal called var/result = target.attack_basic_mob(src, modifiers) diff --git a/code/modules/mob/living/basic/farm_animals/pony.dm b/code/modules/mob/living/basic/farm_animals/pony.dm index 434caa5ef51..4bc09391cb7 100644 --- a/code/modules/mob/living/basic/farm_animals/pony.dm +++ b/code/modules/mob/living/basic/farm_animals/pony.dm @@ -62,7 +62,7 @@ if (prob(33)) whinny_angrily() -/mob/living/basic/pony/melee_attack(atom/target, list/modifiers) +/mob/living/basic/pony/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) . = ..() if (!.) diff --git a/code/modules/mob/living/basic/heretic/star_gazer.dm b/code/modules/mob/living/basic/heretic/star_gazer.dm index 29b5f16db8f..b739da0831a 100644 --- a/code/modules/mob/living/basic/heretic/star_gazer.dm +++ b/code/modules/mob/living/basic/heretic/star_gazer.dm @@ -22,6 +22,7 @@ attack_verb_simple = "ravage" attack_vis_effect = ATTACK_EFFECT_SLASH attack_sound = 'sound/weapons/bladeslice.ogg' + melee_attack_cooldown = 0.6 SECONDS speak_emote = list("growls") damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) death_sound = 'sound/magic/cosmic_expansion.ogg' @@ -57,6 +58,24 @@ ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, INNATE_TRAIT) set_light(4, l_color = "#dcaa5b") +// Star gazer attacks everything around itself applies a spooky mark +/mob/living/basic/heretic_summon/star_gazer/melee_attack(mob/living/target, list/modifiers, ignore_cooldown) + . = ..() + if (!. || !isliving(target)) + return + + target.apply_status_effect(/datum/status_effect/star_mark) + target.apply_damage(damage = 5, damagetype = CLONE) + var/datum/targetting_datum/target_confirmer = ai_controller.blackboard[BB_TARGETTING_DATUM] + for(var/mob/living/nearby_mob in range(1, src)) + if(target == nearby_mob || !target_confirmer?.can_attack(src, nearby_mob)) + continue + nearby_mob.apply_status_effect(/datum/status_effect/star_mark) + nearby_mob.apply_damage(10) + to_chat(nearby_mob, span_userdanger("\The [src] [attack_verb_continuous] you!")) + do_attack_animation(nearby_mob, ATTACK_EFFECT_SLASH) + log_combat(src, nearby_mob, "slashed") + /datum/ai_controller/basic_controller/star_gazer blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/star_gazer(), @@ -70,39 +89,12 @@ /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path/star_gazer, - /datum/ai_planning_subtree/basic_melee_attack_subtree/star_gazer, + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) /datum/targetting_datum/basic/star_gazer stat_attack = HARD_CRIT -/datum/ai_planning_subtree/basic_melee_attack_subtree/star_gazer - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/star_gazer - -/datum/ai_behavior/basic_melee_attack/star_gazer - action_cooldown = 0.6 SECONDS - -/datum/ai_behavior/basic_melee_attack/star_gazer/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) - . = ..() - var/atom/target = controller.blackboard[target_key] - var/mob/living/living_pawn = controller.pawn - - if(!isliving(target)) - return - var/mob/living/living_target = target - living_target.apply_status_effect(/datum/status_effect/star_mark) - living_target.apply_damage_type(damage = 5, damagetype = CLONE) - if(living_target.pulledby != living_pawn) - if(living_pawn.Adjacent(living_target) && isturf(living_target.loc) && living_target.stat == SOFT_CRIT) - living_target.grabbedby(living_pawn) - for(var/mob/living/nearby_mob in range(1, living_pawn)) - if(nearby_mob.stat == DEAD || living_target == nearby_mob || faction_check(nearby_mob.faction, list(FACTION_HERETIC))) - continue - nearby_mob.apply_status_effect(/datum/status_effect/star_mark) - nearby_mob.adjustBruteLoss(10) - living_pawn.do_attack_animation(nearby_mob, ATTACK_EFFECT_SLASH) - log_combat(living_pawn, nearby_mob, "slashed") - /datum/ai_planning_subtree/attack_obstacle_in_path/star_gazer attack_behaviour = /datum/ai_behavior/attack_obstructions/star_gazer @@ -119,4 +111,4 @@ command_feedback = "stares!" pointed_reaction = "stares intensely!" refuse_reaction = "..." - attack_behaviour = /datum/ai_behavior/basic_melee_attack/star_gazer + attack_behaviour = /datum/ai_behavior/basic_melee_attack diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm index 465d724944b..292766be07b 100644 --- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm @@ -69,6 +69,7 @@ INVOKE_ASYNC(src, PROC_REF(cannibalize_victim), victim) return COMPONENT_HOSTILE_NO_ATTACK +/// Carve a stone into a beautiful self-portrait /mob/living/basic/mining/ice_whelp/proc/create_sculpture(atom/target) balloon_alert(src, "sculpting...") if(!do_after(src, 5 SECONDS, target = target)) @@ -80,7 +81,9 @@ dragon_statue.set_anchored(TRUE) qdel(target) +/// Gib and consume our fellow ice drakes /mob/living/basic/mining/ice_whelp/proc/cannibalize_victim(mob/living/target) + start_pulling(target) balloon_alert(src, "devouring...") if(!do_after(src, 5 SECONDS, target)) return diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm index 08c5fda3fd8..9885ba3da59 100644 --- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm @@ -58,7 +58,6 @@ finish_action(controller, FALSE) return - living_pawn.start_pulling(target) living_pawn.melee_attack(target) finish_action(controller, TRUE) diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm index 6463fc94979..18cd7321936 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm @@ -18,6 +18,7 @@ attack_verb_simple = "snip" attack_sound = 'sound/weapons/bite.ogg' attack_vis_effect = ATTACK_EFFECT_BITE // Closer than a scratch to a crustacean pinching effect + melee_attack_cooldown = 1 SECONDS butcher_results = list( /obj/item/food/meat/crab = 2, /obj/item/stack/sheet/bone = 2, @@ -35,6 +36,7 @@ /mob/living/basic/mining/lobstrosity/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_SNOWSTORM_IMMUNE, INNATE_TRAIT) + AddElement(/datum/element/mob_grabber) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) AddElement(/datum/element/basic_eating, food_types = target_foods) AddElement(\ @@ -73,7 +75,7 @@ return var/mob/living/basic/basic_source = source var/mob/living/living_target = target - basic_source.melee_attack(living_target) + basic_source.melee_attack(living_target, ignore_cooldown = TRUE) basic_source.ai_controller?.set_blackboard_key(BB_BASIC_MOB_FLEEING, FALSE) basic_source.start_pulling(living_target) diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm index dcbeb1e670c..8e4dfe9e294 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm @@ -36,7 +36,6 @@ return ..() /datum/ai_behavior/basic_melee_attack/lobster - action_cooldown = 1 SECONDS /datum/ai_behavior/basic_melee_attack/lobster/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) var/mob/living/target = controller.blackboard[target_key] @@ -53,9 +52,6 @@ if (controller.blackboard[BB_BASIC_MOB_FLEEING]) finish_action(controller = controller, succeeded = TRUE, target_key = target_key) // We don't want to clear our target return - var/mob/living/living_pawn = controller.pawn - if (target.stat != CONSCIOUS) - living_pawn.start_pulling(target) // No crawling away return ..() /datum/ai_planning_subtree/flee_target/lobster @@ -75,6 +71,10 @@ finish_action(controller, succeeded = FALSE) return + var/mob/living/us = controller.pawn + if (us.pulling == target) + us.stop_pulling() // If we're running away from someone, best not to bring them with us + return ..() /// Don't use charge ability on an adjacent target, and make sure you're visible before you start diff --git a/code/modules/mob/living/basic/pets/dog/_dog.dm b/code/modules/mob/living/basic/pets/dog/_dog.dm index 93947173cd9..dd3b3b3a463 100644 --- a/code/modules/mob/living/basic/pets/dog/_dog.dm +++ b/code/modules/mob/living/basic/pets/dog/_dog.dm @@ -33,6 +33,7 @@ attack_verb_simple = "bite" attack_sound = 'sound/weapons/bite.ogg' attack_vis_effect = ATTACK_EFFECT_BITE + melee_attack_cooldown = 0.8 SECONDS /// Instructions you can give to dogs var/static/list/pet_commands = list( /datum/pet_command/idle, diff --git a/code/modules/mob/living/basic/ruin_defender/stickman.dm b/code/modules/mob/living/basic/ruin_defender/stickman.dm index 8d0a5ab0cde..107973135c7 100644 --- a/code/modules/mob/living/basic/ruin_defender/stickman.dm +++ b/code/modules/mob/living/basic/ruin_defender/stickman.dm @@ -13,6 +13,7 @@ attack_verb_simple = "punch" melee_damage_lower = 10 melee_damage_upper = 10 + melee_attack_cooldown = 1.5 SECONDS attack_sound = 'sound/weapons/punch1.ogg' combat_mode = TRUE faction = list(FACTION_STICKMAN) @@ -39,15 +40,9 @@ idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/stickman + /datum/ai_planning_subtree/basic_melee_attack_subtree ) -/datum/ai_planning_subtree/basic_melee_attack_subtree/stickman - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/stickman - -/datum/ai_behavior/basic_melee_attack/stickman - action_cooldown = 1.5 SECONDS - /mob/living/basic/stickman/dog name = "Angry Stick Dog" desc = "Stickman's best friend, if he could see him at least." diff --git a/code/modules/mob/living/basic/space_fauna/bear/bear_ai_behavior.dm b/code/modules/mob/living/basic/space_fauna/bear/bear_ai_behavior.dm index 6e716ddf411..7c57349524f 100644 --- a/code/modules/mob/living/basic/space_fauna/bear/bear_ai_behavior.dm +++ b/code/modules/mob/living/basic/space_fauna/bear/bear_ai_behavior.dm @@ -1,6 +1,3 @@ -/datum/ai_behavior/basic_melee_attack/bear - action_cooldown = 2 SECONDS - /datum/ai_behavior/find_hunt_target/find_hive /datum/ai_behavior/find_hunt_target/find_hive/valid_dinner(mob/living/source, obj/structure/beebox/hive, radius) diff --git a/code/modules/mob/living/basic/space_fauna/bear/bear_ai_subtree.dm b/code/modules/mob/living/basic/space_fauna/bear/bear_ai_subtree.dm index 244c600d89f..851c0bb8029 100644 --- a/code/modules/mob/living/basic/space_fauna/bear/bear_ai_subtree.dm +++ b/code/modules/mob/living/basic/space_fauna/bear/bear_ai_subtree.dm @@ -8,16 +8,13 @@ planning_subtrees = list( /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/bear, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/climb_trees, /datum/ai_planning_subtree/find_and_hunt_target/find_hive, /datum/ai_planning_subtree/find_and_hunt_target/find_honeycomb, /datum/ai_planning_subtree/random_speech/bear, ) -/datum/ai_planning_subtree/basic_melee_attack_subtree/bear - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/bear - /datum/ai_planning_subtree/find_and_hunt_target/find_hive target_key = BB_FOUND_HONEY hunting_behavior = /datum/ai_behavior/hunt_target/find_hive diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm index 6ce40d8c1a3..9a4b149fd1a 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm @@ -32,6 +32,7 @@ attack_vis_effect = ATTACK_EFFECT_BITE attack_verb_continuous = "bites" attack_verb_simple = "bite" + melee_attack_cooldown = 1.5 SECONDS response_help_continuous = "pets" response_help_simple = "pet" response_disarm_continuous = "gently pushes aside" @@ -57,7 +58,7 @@ /datum/pet_command/idle, /datum/pet_command/free, /datum/pet_command/follow, - /datum/pet_command/point_targetting/attack/carp + /datum/pet_command/point_targetting/attack ) /// Carp want to eat raw meat var/static/list/desired_food = list(/obj/item/food/meat/slab, /obj/item/food/meat/rawcutlet) diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm index c0f5143f18c..b2dc866ce7c 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm @@ -1,17 +1,8 @@ #define MAGICARP_SPELL_TARGET_SEEK_RANGE 4 -/datum/pet_command/point_targetting/attack/carp - attack_behaviour = /datum/ai_behavior/basic_melee_attack/carp - /datum/pet_command/point_targetting/use_ability/magicarp pet_ability_key = BB_MAGICARP_SPELL -/datum/ai_planning_subtree/basic_melee_attack_subtree/carp - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/carp - -/datum/ai_behavior/basic_melee_attack/carp - action_cooldown = 1.5 SECONDS - /datum/ai_planning_subtree/attack_obstacle_in_path/carp attack_behaviour = /datum/ai_behavior/attack_obstructions/carp @@ -20,12 +11,12 @@ /// As basic attack tree but interrupt if your health gets low or if your spell is off cooldown /datum/ai_planning_subtree/basic_melee_attack_subtree/magicarp - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/carp/magic + melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/magicarp /// Interrupt your attack chain if: you have a spell, it's not on cooldown, and it has a target -/datum/ai_behavior/basic_melee_attack/carp/magic +/datum/ai_behavior/basic_melee_attack/magicarp -/datum/ai_behavior/basic_melee_attack/carp/magic/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, health_ratio_key) +/datum/ai_behavior/basic_melee_attack/magicarp/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, health_ratio_key) var/datum/action/cooldown/using_action = controller.blackboard[BB_MAGICARP_SPELL] if (QDELETED(using_action)) return ..() diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm index f4c446d088b..b3097014535 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm @@ -25,7 +25,7 @@ /datum/ai_planning_subtree/attack_obstacle_in_path/carp, /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift, /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport, - /datum/ai_planning_subtree/basic_melee_attack_subtree/carp, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/carp_migration, ) @@ -48,7 +48,7 @@ /datum/ai_planning_subtree/attack_obstacle_in_path/carp, /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift, /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport, - /datum/ai_planning_subtree/basic_melee_attack_subtree/carp, + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) /** @@ -91,6 +91,6 @@ /datum/ai_planning_subtree/attack_obstacle_in_path/carp, /datum/ai_planning_subtree/shortcut_to_target_through_carp_rift, /datum/ai_planning_subtree/make_carp_rift/aggressive_teleport, - /datum/ai_planning_subtree/basic_melee_attack_subtree/carp, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/carp_migration, ) diff --git a/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm b/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm index 5051335a557..32f02b880db 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm @@ -56,7 +56,7 @@ GLOBAL_LIST_INIT(magicarp_spell_colours, list( /datum/pet_command/idle, /datum/pet_command/free, /datum/pet_command/follow, - /datum/pet_command/point_targetting/attack/carp, + /datum/pet_command/point_targetting/attack, /datum/pet_command/point_targetting/use_ability/magicarp, ) /// List of all projectiles we can fire. diff --git a/code/modules/mob/living/basic/space_fauna/faithless.dm b/code/modules/mob/living/basic/space_fauna/faithless.dm index b279856412c..c1dc297ea46 100644 --- a/code/modules/mob/living/basic/space_fauna/faithless.dm +++ b/code/modules/mob/living/basic/space_fauna/faithless.dm @@ -18,6 +18,7 @@ attack_verb_continuous = "grips" attack_verb_simple = "grip" attack_sound = 'sound/hallucinations/growl1.ogg' + melee_attack_cooldown = 1 SECONDS speak_emote = list("growls") unsuitable_atmos_damage = 0 @@ -29,12 +30,29 @@ ai_controller = /datum/ai_controller/basic_controller/faithless + /// What are the odds we paralyze a target on attack + var/paralyze_chance = 12 + /// How long do we paralyze a target for if we attack them + var/paralyze_duration = 2 SECONDS + /mob/living/basic/faithless/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT) AddElement(/datum/element/footstep, FOOTSTEP_MOB_SHOE) + AddElement(/datum/element/mob_grabber, steal_from_others = FALSE) AddComponent(/datum/component/pry_open_door) +/mob/living/basic/faithless/melee_attack(atom/target, list/modifiers, ignore_cooldown) + . = ..() + if (!. || !isliving(target)) + return + + var/mob/living/living_target = target + if (prob(paralyze_chance)) + living_target.Paralyze(paralyze_duration) + living_target.visible_message(span_danger("\The [src] knocks \the [target] down!"), \ + span_userdanger("\The [src] knocks you down!")) + /datum/ai_controller/basic_controller/faithless blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/faithless(), @@ -47,37 +65,10 @@ /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path, /datum/ai_planning_subtree/attack_obstacle_in_path/low_priority_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/faithless, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/find_and_hunt_target/look_for_light_fixtures, /datum/ai_planning_subtree/random_speech/faithless, ) /datum/targetting_datum/basic/faithless stat_attack = UNCONSCIOUS - -/datum/ai_planning_subtree/basic_melee_attack_subtree/faithless - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/faithless - -/datum/ai_behavior/basic_melee_attack/faithless - action_cooldown = 1 SECONDS - /// What are the odds we paralyze a target - var/paralyze_chance = 12 - /// How long do we paralyze a target for if we attack them - var/paralyze_duration = 2 SECONDS - -/datum/ai_behavior/basic_melee_attack/faithless/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) - . = ..() - var/atom/target = controller.blackboard[target_key] - var/mob/living/living_pawn = controller.pawn - - if(!isliving(target)) - return - var/mob/living/living_target = target - if(living_target.pulledby != living_pawn && !HAS_AI_CONTROLLER_TYPE(living_target.pulledby, /datum/ai_controller/basic_controller/faithless)) //Dont steal from my fellow faithless. - if(living_pawn.Adjacent(living_target) && isturf(living_target.loc) && living_target.stat == SOFT_CRIT) - living_target.grabbedby(living_pawn) //Drag their bodies around as a menace. - if(prob(paralyze_chance) && iscarbon(target)) - var/mob/living/carbon/carbon_target = target - carbon_target.Paralyze(paralyze_duration) - carbon_target.visible_message(span_danger("\The [living_pawn] knocks down \the [carbon_target]!"), \ - span_userdanger("\The [living_pawn] knocks you down!")) diff --git a/code/modules/mob/living/basic/space_fauna/garden_gnome.dm b/code/modules/mob/living/basic/space_fauna/garden_gnome.dm index 9b57eba8fe2..d9dfc3c5343 100644 --- a/code/modules/mob/living/basic/space_fauna/garden_gnome.dm +++ b/code/modules/mob/living/basic/space_fauna/garden_gnome.dm @@ -17,6 +17,7 @@ attack_verb_continuous = "punches" attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' + melee_attack_cooldown = 1.2 SECONDS damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) speak_emote = list("announces") @@ -132,12 +133,6 @@ planning_subtrees = list( /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree/garden_gnome, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/random_speech/garden_gnome, ) - -/datum/ai_planning_subtree/basic_melee_attack_subtree/garden_gnome - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/garden_gnome - -/datum/ai_behavior/basic_melee_attack/garden_gnome - action_cooldown = 1.2 SECONDS diff --git a/code/modules/mob/living/basic/space_fauna/lightgeist.dm b/code/modules/mob/living/basic/space_fauna/lightgeist.dm index 28debb6c0a1..c70588f4502 100644 --- a/code/modules/mob/living/basic/space_fauna/lightgeist.dm +++ b/code/modules/mob/living/basic/space_fauna/lightgeist.dm @@ -21,6 +21,7 @@ health = 2 melee_damage_lower = 5 melee_damage_upper = 5 + melee_attack_cooldown = 5 SECONDS friendly_verb_continuous = "taps" friendly_verb_simple = "tap" density = FALSE @@ -65,10 +66,10 @@ complete_text = "%TARGET%'s wounds mend together.",\ ) -/mob/living/basic/lightgeist/melee_attack(atom/target, list/modifiers) - if (isliving(target)) +/mob/living/basic/lightgeist/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) + . = ..() + if (. && isliving(target)) faction |= REF(target) // Anyone we heal will treat us as a friend - return ..() /mob/living/basic/lightgeist/ghost() . = ..() @@ -86,7 +87,7 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/lightgeist, // We heal things by attacking them + /datum/ai_planning_subtree/basic_melee_attack_subtree, // We heal things by attacking them ) /// Attack only mobs who have damage that we can heal, I think this is specific enough not to be a generic type @@ -111,9 +112,3 @@ continue return TRUE return FALSE - -/datum/ai_planning_subtree/basic_melee_attack_subtree/lightgeist - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/lightgeist - -/datum/ai_behavior/basic_melee_attack/lightgeist - action_cooldown = 5 SECONDS diff --git a/code/modules/mob/living/basic/space_fauna/mushroom.dm b/code/modules/mob/living/basic/space_fauna/mushroom.dm index 5e52dabae75..e6d47e2db5c 100644 --- a/code/modules/mob/living/basic/space_fauna/mushroom.dm +++ b/code/modules/mob/living/basic/space_fauna/mushroom.dm @@ -64,7 +64,7 @@ idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/mushroom, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/find_and_hunt_target/mushroom_food, ) @@ -76,13 +76,6 @@ /datum/targetting_datum/basic/mushroom/faction_check(mob/living/living_mob, mob/living/the_target) return !living_mob.faction_check_mob(the_target, exact_match = check_factions_exactly) - -/datum/ai_planning_subtree/basic_melee_attack_subtree/mushroom - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/mushroom - -/datum/ai_behavior/basic_melee_attack/mushroom - action_cooldown = 2 SECONDS - /datum/ai_planning_subtree/find_and_hunt_target/mushroom_food target_key = BB_LOW_PRIORITY_HUNTING_TARGET hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/mushroom_food diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm index 35d597e53ca..5a7bb075f19 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm @@ -14,6 +14,7 @@ attack_verb_simple = "punch" attack_sound = 'sound/weapons/bladeslice.ogg' attack_vis_effect = ATTACK_EFFECT_SLASH + melee_attack_cooldown = 1 SECONDS faction = list(FACTION_NETHER) speak_emote = list("screams") death_message = "falls apart into a fine dust." @@ -42,5 +43,5 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree/average_speed, + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm index 5fabbf2afb2..b38ada0f6e1 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm @@ -15,6 +15,7 @@ gold_core_spawnable = HOSTILE_SPAWN attack_sound = 'sound/weapons/bite.ogg' attack_vis_effect = ATTACK_EFFECT_BITE + melee_attack_cooldown = 1 SECONDS faction = list(FACTION_NETHER) speak_emote = list("screams") death_message = "gets his head split open." @@ -111,5 +112,5 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree/average_speed, + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm index 57d90da264a..18dca95013e 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm @@ -12,6 +12,7 @@ speed = 1 attack_verb_continuous = "lacerates" attack_verb_simple = "lacerate" + melee_attack_cooldown = 1 SECONDS gold_core_spawnable = HOSTILE_SPAWN attack_sound = 'sound/weapons/bladeslice.ogg' attack_vis_effect = ATTACK_EFFECT_SLASH @@ -81,5 +82,5 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree/average_speed, + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm index 1c36ed151a7..7a30f88b4c2 100644 --- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm +++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm @@ -161,6 +161,7 @@ nearby_roach.melee_damage_upper += 4 nearby_roach.obj_damage += 5 nearby_roach.ai_controller = new /datum/ai_controller/basic_controller/cockroach/sewer(nearby_roach) + nearby_roach.melee_attack_cooldown = 0.8 SECONDS nearby_roach.icon_state += "_sewer" nearby_roach.maxHealth += 1 diff --git a/code/modules/mob/living/basic/space_fauna/statue/statue.dm b/code/modules/mob/living/basic/space_fauna/statue/statue.dm index 7d13ee9a1ab..bce35146ecf 100644 --- a/code/modules/mob/living/basic/space_fauna/statue/statue.dm +++ b/code/modules/mob/living/basic/space_fauna/statue/statue.dm @@ -27,6 +27,7 @@ attack_verb_simple = "claw" attack_sound = 'sound/hallucinations/growl1.ogg' attack_vis_effect = ATTACK_EFFECT_CLAW + melee_attack_cooldown = 1 SECONDS faction = list(FACTION_STATUE) speak_emote = list("screams") @@ -147,16 +148,10 @@ ai_movement = /datum/ai_movement/basic_avoidance planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/statue, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/find_and_hunt_target/look_for_light_fixtures, ) -/datum/ai_planning_subtree/basic_melee_attack_subtree/statue - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/statue - -/datum/ai_behavior/basic_melee_attack/statue - action_cooldown = 1 SECONDS - /mob/living/basic/statue/frosty name = "Frosty" desc = "Just a snowman. Just a snowman. Oh god, it's just a snowman." diff --git a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm index f632a38dc1b..9d3a09c5348 100644 --- a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm +++ b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm @@ -1,5 +1,3 @@ -#define WUMBO_ATTACK_COOLDOWN 2.5 SECONDS - /// Cowardly when small, aggressive when big. Tries to transform whenever possible. /datum/ai_controller/basic_controller/wumborian_fugu blackboard = list( @@ -15,23 +13,15 @@ /datum/ai_planning_subtree/targeted_mob_ability/inflate, /datum/ai_planning_subtree/flee_target, /datum/ai_planning_subtree/attack_obstacle_in_path/wumborian_fugu, - /datum/ai_planning_subtree/basic_melee_attack_subtree/wumborian_fugu, + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) -/datum/ai_planning_subtree/basic_melee_attack_subtree/wumborian_fugu - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/wumborian_fugu - -/datum/ai_behavior/basic_melee_attack/wumborian_fugu - action_cooldown = WUMBO_ATTACK_COOLDOWN - /datum/ai_planning_subtree/attack_obstacle_in_path/wumborian_fugu attack_behaviour = /datum/ai_behavior/attack_obstructions/wumborian_fugu /datum/ai_behavior/attack_obstructions/wumborian_fugu can_attack_turfs = TRUE - action_cooldown = WUMBO_ATTACK_COOLDOWN + action_cooldown = 2.5 SECONDS /datum/ai_planning_subtree/targeted_mob_ability/inflate ability_key = BB_FUGU_INFLATE - -#undef WUMBO_ATTACK_COOLDOWN diff --git a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm index e13bef35482..bf8be2051d8 100644 --- a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm +++ b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm @@ -29,6 +29,7 @@ melee_damage_upper = 0 attack_sound = 'sound/weapons/punch1.ogg' attack_vis_effect = ATTACK_EFFECT_BITE + melee_attack_cooldown = 2.5 SECONDS attack_verb_continuous = "chomps" attack_verb_simple = "chomp" friendly_verb_continuous = "floats near" diff --git a/code/modules/mob/living/basic/syndicate/syndicate.dm b/code/modules/mob/living/basic/syndicate/syndicate.dm index c11d592cd3b..a4fd0981198 100644 --- a/code/modules/mob/living/basic/syndicate/syndicate.dm +++ b/code/modules/mob/living/basic/syndicate/syndicate.dm @@ -15,6 +15,7 @@ attack_verb_continuous = "punches" attack_verb_simple = "punch" attack_sound = 'sound/weapons/punch1.ogg' + melee_attack_cooldown = 1.2 SECONDS combat_mode = TRUE unsuitable_atmos_damage = 7.5 unsuitable_cold_damage = 7.5 diff --git a/code/modules/mob/living/basic/syndicate/syndicate_ai.dm b/code/modules/mob/living/basic/syndicate/syndicate_ai.dm index be24b37441a..393ef19287e 100644 --- a/code/modules/mob/living/basic/syndicate/syndicate_ai.dm +++ b/code/modules/mob/living/basic/syndicate/syndicate_ai.dm @@ -8,18 +8,12 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path/syndicate, - /datum/ai_planning_subtree/basic_melee_attack_subtree/syndicate + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) /datum/targetting_datum/basic/syndicate stat_attack = HARD_CRIT -/datum/ai_planning_subtree/basic_melee_attack_subtree/syndicate - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/syndicate - -/datum/ai_behavior/basic_melee_attack/syndicate - action_cooldown = 1.2 SECONDS - /datum/ai_planning_subtree/attack_obstacle_in_path/syndicate attack_behaviour = /datum/ai_behavior/attack_obstructions/syndicate diff --git a/code/modules/mob/living/basic/tree.dm b/code/modules/mob/living/basic/tree.dm index f93ab14a37f..2a0806b105c 100644 --- a/code/modules/mob/living/basic/tree.dm +++ b/code/modules/mob/living/basic/tree.dm @@ -74,7 +74,7 @@ our_turf.air.gases[/datum/gas/carbon_dioxide][MOLES] -= amt our_turf.atmos_spawn_air("[GAS_O2]=[amt]") -/mob/living/basic/tree/melee_attack(atom/target, list/modifiers) +/mob/living/basic/tree/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) . = ..() if(!.) @@ -107,12 +107,6 @@ idle_behavior = /datum/idle_behavior/idle_random_walk/less_walking planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/tree, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/random_speech/tree, ) - -/datum/ai_planning_subtree/basic_melee_attack_subtree/tree - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/tree - -/datum/ai_behavior/basic_melee_attack/tree - action_cooldown = 2 SECONDS diff --git a/code/modules/mob/living/basic/vermin/cockroach.dm b/code/modules/mob/living/basic/vermin/cockroach.dm index 7aff4a844d3..5c69ad90447 100644 --- a/code/modules/mob/living/basic/vermin/cockroach.dm +++ b/code/modules/mob/living/basic/vermin/cockroach.dm @@ -131,6 +131,7 @@ melee_damage_lower = 2.5 melee_damage_upper = 10 obj_damage = 10 + melee_attack_cooldown = 1 SECONDS gold_core_spawnable = HOSTILE_SPAWN attack_sound = 'sound/weapons/bladeslice.ogg' attack_vis_effect = ATTACK_EFFECT_SLASH @@ -165,31 +166,19 @@ /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/random_speech/insect, /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/hauberoach, //If we are attacking someone, this will prevent us from hunting + /datum/ai_planning_subtree/basic_melee_attack_subtree, //If we are attacking someone, this will prevent us from hunting /datum/ai_planning_subtree/find_and_hunt_target/roach, ) -/datum/ai_planning_subtree/basic_melee_attack_subtree/hauberoach - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/hauberoach - -/datum/ai_behavior/basic_melee_attack/hauberoach //Slightly slower, as this is being made in feature freeze ;) - action_cooldown = 1 SECONDS - /datum/ai_controller/basic_controller/cockroach/sewer planning_subtrees = list( /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/random_speech/insect, /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/sewer, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/find_and_hunt_target/roach, ) -/datum/ai_planning_subtree/basic_melee_attack_subtree/sewer - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/sewer - -/datum/ai_behavior/basic_melee_attack/sewer - action_cooldown = 0.8 SECONDS - /mob/living/basic/cockroach/glockroach/mobroach name = "mobroach" desc = "WE'RE FUCKED, THAT GLOCKROACH HAS A TOMMYGUN!" diff --git a/code/modules/mob/living/basic/vermin/frog.dm b/code/modules/mob/living/basic/vermin/frog.dm index 282ed17b00c..191ea12b4df 100644 --- a/code/modules/mob/living/basic/vermin/frog.dm +++ b/code/modules/mob/living/basic/vermin/frog.dm @@ -17,6 +17,7 @@ obj_damage = 10 attack_verb_continuous = "bites" attack_verb_simple = "bite" + melee_attack_cooldown = 2.5 SECONDS response_help_continuous = "pets" response_help_simple = "pet" response_disarm_continuous = "pokes" @@ -85,19 +86,13 @@ planning_subtrees = list( /datum/ai_planning_subtree/target_retaliate, /datum/ai_planning_subtree/random_speech/frog, - /datum/ai_planning_subtree/basic_melee_attack_subtree/frog, + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) -/datum/ai_planning_subtree/basic_melee_attack_subtree/frog - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/frog - -/datum/ai_behavior/basic_melee_attack/frog - action_cooldown = 2.5 SECONDS - /datum/ai_controller/basic_controller/frog/trash planning_subtrees = list( /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/random_speech/frog, /datum/ai_planning_subtree/simple_find_target, - /datum/ai_planning_subtree/basic_melee_attack_subtree/frog, + /datum/ai_planning_subtree/basic_melee_attack_subtree, ) diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index 98827ae3ce3..01551ac0743 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -1,4 +1,4 @@ -/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item) +/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item) SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage, damagetype, def_zone) var/hit_percent = (100-blocked)/100 if(!damage || (!forced && hit_percent <= 0)) diff --git a/code/modules/mob/living/carbon/human/damage_procs.dm b/code/modules/mob/living/carbon/human/damage_procs.dm index 47cbbe12188..d4fc0b40365 100644 --- a/code/modules/mob/living/carbon/human/damage_procs.dm +++ b/code/modules/mob/living/carbon/human/damage_procs.dm @@ -1,4 +1,4 @@ /// depending on the species, it will run the corresponding apply_damage code there -/mob/living/carbon/human/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item) +/mob/living/carbon/human/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item) return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item) diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 439101151c6..786e781a584 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -14,7 +14,7 @@ * * Returns TRUE if damage applied */ -/mob/living/proc/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item) +/mob/living/proc/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item) SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMAGE, damage, damagetype, def_zone) var/hit_percent = (100-blocked)/100 if(!damage || (!forced && hit_percent <= 0)) diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm index 59db1264a30..8ee146508a4 100644 --- a/code/modules/mob/living/silicon/damage_procs.dm +++ b/code/modules/mob/living/silicon/damage_procs.dm @@ -1,5 +1,5 @@ -/mob/living/silicon/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item) +/mob/living/silicon/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, attacking_item) var/hit_percent = (100-blocked)/100 if((!damage || (!forced && hit_percent <= 0))) return 0 diff --git a/tgstation.dme b/tgstation.dme index c8782fe7bb6..80dc1a478f6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1391,6 +1391,7 @@ #include "code\datums\elements\light_eater.dm" #include "code\datums\elements\loomable.dm" #include "code\datums\elements\mirage_border.dm" +#include "code\datums\elements\mob_grabber.dm" #include "code\datums\elements\mob_killed_tally.dm" #include "code\datums\elements\movement_turf_changer.dm" #include "code\datums\elements\movetype_handler.dm"