mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 12:35:33 +01:00
ice demon basic mobs (#78539)
## About The Pull Request ice demons are now basic mobs. they still have their behavior where they can teleport around the player, run away from him and shoot him. they now also have a new ability they will only use when they are on their last legs, they will spawn weak and slow afterimage clones of theirselves to attack the player. damaging these clones will also damage the original ice demons. ice demons can also now be very easily countered as they are very afraid of fires. they will run away from you if they see u holding a lit torch/flare/welding tool and while running away they will freeze the floors around them to try to slip u to stop u from chasing them. ice demons now also get a new unique trophy! this trophy will summon 2 friendly spirits that will help you kill ur target, but these spirits will dissappear after a very short while. https://github.com/tgstation/tgstation/assets/138636438/6a48fb15-f447-441a-91c6-48ca120dc22c ## Why It's Good For The Game ## Changelog 🆑 refactor: ice demons have been refactored into basic mbos. please report any bugs add: ice demons now have a unique trophy /🆑
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
var/maximum_distance = 6
|
||||
/// How far do we look for our target?
|
||||
var/view_distance = 10
|
||||
/// the run away behavior we will use
|
||||
var/run_away_behavior = /datum/ai_behavior/step_away
|
||||
|
||||
/datum/ai_planning_subtree/maintain_distance/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
@@ -16,12 +18,15 @@
|
||||
return // Don't run away from cucumbers, they're not snakes
|
||||
var/range = get_dist(controller.pawn, target)
|
||||
if (range < minimum_distance)
|
||||
controller.queue_behavior(/datum/ai_behavior/step_away, target_key)
|
||||
controller.queue_behavior(run_away_behavior, target_key, minimum_distance)
|
||||
return
|
||||
if (range > maximum_distance)
|
||||
controller.queue_behavior(/datum/ai_behavior/pursue_to_range, target_key, maximum_distance)
|
||||
return
|
||||
|
||||
/datum/ai_planning_subtree/maintain_distance/cover_minimum_distance
|
||||
run_away_behavior = /datum/ai_behavior/cover_minimum_distance
|
||||
|
||||
/// Take one step away
|
||||
/datum/ai_behavior/step_away
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
@@ -80,3 +85,32 @@
|
||||
if (!QDELETED(current_target) && get_dist(controller.pawn, current_target) > range)
|
||||
return
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
|
||||
///instead of taking a single step, we cover the entire distance
|
||||
/datum/ai_behavior/cover_minimum_distance
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
required_distance = 0
|
||||
action_cooldown = 0.2 SECONDS
|
||||
|
||||
/datum/ai_behavior/cover_minimum_distance/setup(datum/ai_controller/controller, target_key, minimum_distance)
|
||||
. = ..()
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
if(QDELETED(target))
|
||||
return FALSE
|
||||
var/required_distance = minimum_distance - get_dist(controller.pawn, target) //the distance we need to move
|
||||
var/distance = 0
|
||||
var/turf/chosen_turf
|
||||
for(var/turf/open/potential_turf in oview(required_distance, controller.pawn))
|
||||
var/new_distance_from_target = get_dist(potential_turf, target)
|
||||
if(potential_turf.is_blocked_turf())
|
||||
continue
|
||||
if(new_distance_from_target > distance)
|
||||
chosen_turf = potential_turf
|
||||
distance = new_distance_from_target
|
||||
if(isnull(chosen_turf))
|
||||
return FALSE
|
||||
set_movement_target(controller, target = chosen_turf)
|
||||
|
||||
/datum/ai_behavior/cover_minimum_distance/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
finish_action(controller, succeeded = TRUE)
|
||||
|
||||
@@ -4,28 +4,28 @@
|
||||
/// Blackboard key holding target atom
|
||||
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
|
||||
/// What AI behaviour do we actually run?
|
||||
var/datum/ai_behavior/ranged_skirmish/attack_behavior = /datum/ai_behavior/ranged_skirmish
|
||||
|
||||
/datum/ai_planning_subtree/ranged_skirmish/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
if(!controller.blackboard_key_exists(target_key))
|
||||
return
|
||||
controller.queue_behavior(attack_behavior, target_key, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
|
||||
/// How often will we try to perform our ranged attack?
|
||||
/datum/ai_behavior/ranged_skirmish
|
||||
action_cooldown = 1 SECONDS
|
||||
var/attack_behavior = /datum/ai_behavior/ranged_skirmish
|
||||
/// If target is further away than this we don't fire
|
||||
var/max_range = 9
|
||||
/// If target is closer than this we don't fire
|
||||
var/min_range = 2
|
||||
|
||||
/datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_planning_subtree/ranged_skirmish/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
if(!controller.blackboard_key_exists(target_key))
|
||||
return
|
||||
controller.queue_behavior(attack_behavior, target_key, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION, max_range, min_range)
|
||||
|
||||
/// How often will we try to perform our ranged attack?
|
||||
/datum/ai_behavior/ranged_skirmish
|
||||
action_cooldown = 1 SECONDS
|
||||
|
||||
/datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, max_range, min_range)
|
||||
. = ..()
|
||||
var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key]
|
||||
return !QDELETED(target)
|
||||
|
||||
/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, max_range, min_range)
|
||||
. = ..()
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
if (QDELETED(target))
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
///behavior to activate ability to escape from target
|
||||
/datum/ai_planning_subtree/teleport_away_from_target
|
||||
///minimum distance away from the target before we execute behavior
|
||||
var/minimum_distance = 2
|
||||
///the ability we will execute
|
||||
var/ability_key
|
||||
|
||||
/datum/ai_planning_subtree/teleport_away_from_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
|
||||
return
|
||||
var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
|
||||
var/distance_from_target = get_dist(target, controller.pawn)
|
||||
if(distance_from_target >= minimum_distance)
|
||||
controller.clear_blackboard_key(BB_ESCAPE_DESTINATION)
|
||||
return
|
||||
var/datum/action/cooldown/ability = controller.blackboard[ability_key]
|
||||
if(!ability?.IsAvailable())
|
||||
return
|
||||
var/turf/location_turf = controller.blackboard[BB_ESCAPE_DESTINATION]
|
||||
|
||||
if(isnull(location_turf))
|
||||
controller.queue_behavior(/datum/ai_behavior/find_furthest_turf_from_target, BB_BASIC_MOB_CURRENT_TARGET, BB_ESCAPE_DESTINATION, minimum_distance)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
if(get_dist(location_turf, target) < minimum_distance || !can_see(controller.pawn, location_turf)) //target moved close too close or we moved too far since finding the target turf
|
||||
controller.clear_blackboard_key(BB_ESCAPE_DESTINATION)
|
||||
return
|
||||
|
||||
controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_clear_target, ability_key, BB_ESCAPE_DESTINATION)
|
||||
|
||||
///find furtherst turf target so we may teleport to it
|
||||
/datum/ai_behavior/find_furthest_turf_from_target
|
||||
|
||||
/datum/ai_behavior/find_furthest_turf_from_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key, set_key, range)
|
||||
var/mob/living/living_target = controller.blackboard[target_key]
|
||||
if(QDELETED(living_target))
|
||||
return
|
||||
|
||||
var/distance = 0
|
||||
var/turf/chosen_turf
|
||||
for(var/turf/open/potential_destination in oview(range, living_target))
|
||||
if(potential_destination.is_blocked_turf())
|
||||
continue
|
||||
var/new_distance_to_target = get_dist(potential_destination, living_target)
|
||||
if(new_distance_to_target > distance)
|
||||
chosen_turf = potential_destination
|
||||
distance = new_distance_to_target
|
||||
if(distance == range)
|
||||
break //we have already found the max distance
|
||||
|
||||
if(isnull(chosen_turf))
|
||||
finish_action(controller, FALSE)
|
||||
return
|
||||
|
||||
controller.set_blackboard_key(set_key, chosen_turf)
|
||||
finish_action(controller, TRUE)
|
||||
Reference in New Issue
Block a user