Skip to content

Commit

Permalink
Mob stuff (#1239)
Browse files Browse the repository at this point in the history
* mobs

* somemore

* more ai

* Update stonekeep.dme

* Update bloodcrawl.dm
  • Loading branch information
NPC1314 authored Dec 12, 2024
1 parent bc5ef63 commit dcaa0fd
Show file tree
Hide file tree
Showing 19 changed files with 839 additions and 224 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/ai/hostile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
///Basic Mob Keys

///Targetting subtrees
#define BB_TARGETED_ACTION "BB_targeted_action"
#define BB_BASIC_MOB_CURRENT_TARGET "BB_basic_current_target"
#define BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION "BB_basic_current_target_hiding_location"
#define BB_TARGETTING_DATUM "targetting_datum"
Expand All @@ -50,6 +51,7 @@

/// Flag to set on or off if you want your mob to prioritise running away
#define BB_BASIC_MOB_FLEEING "BB_basic_fleeing"
#define BB_BASIC_MOB_NEXT_FLEEING "BB_nex_flee"

///List of mobs who have damaged us
#define BB_BASIC_MOB_RETALIATE_LIST "BB_basic_mob_shitlist"
51 changes: 48 additions & 3 deletions code/datums/ai/behaviours/run_from_target.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/**
* Get ranged target turf, but with direct targets as opposed to directions
*
* Starts at atom starting_atom and gets the exact angle between starting_atom and target
* Moves from starting_atom with that angle, Range amount of times, until it stops, bound to map size
* Arguments:
* * starting_atom - Initial Firer / Position
* * target - Target to aim towards
* * range - Distance of returned target turf from starting_atom
* * offset - Angle offset, 180 input would make the returned target turf be in the opposite direction
*/
/proc/get_ranged_target_turf_direct(atom/starting_atom, atom/target, range, offset)
var/angle = ATAN2(target.x - starting_atom.x, target.y - starting_atom.y)
if(offset)
angle += offset
var/turf/starting_turf = get_turf(starting_atom)
for(var/i in 1 to range)
var/turf/check = locate(starting_atom.x + cos(angle) * i, starting_atom.y + sin(angle) * i, starting_atom.z)
if(!check)
break
starting_turf = check

return starting_turf

// Move to a position further away from your current target
/datum/ai_behavior/run_away_from_target
required_distance = 0
Expand Down Expand Up @@ -29,10 +53,31 @@
plot_path_away_from(controller, target)

/datum/ai_behavior/run_away_from_target/proc/plot_path_away_from(datum/ai_controller/controller, atom/target)
var/run_direction = get_dir(controller.pawn, get_step_away(controller.pawn, target))
var/turf/target_destination = get_ranged_target_turf(controller.pawn, run_direction, run_distance)
controller.set_movement_target(target_destination)
var/turf/target_destination = get_turf(controller.pawn)
var/static/list/offset_angles = list(45, 90, 135, 180, 225, 270)
for(var/angle in offset_angles)
var/turf/test_turf = get_furthest_turf(controller.pawn, angle, target)
if(isnull(test_turf))
continue
var/distance_from_target = get_dist(target, test_turf)
if(distance_from_target <= get_dist(target, target_destination))
continue
target_destination = test_turf
if(distance_from_target == run_distance) //we already got the max running distance
break
if (target_destination == get_turf(controller.pawn))
return FALSE
set_movement_target(controller, target_destination)
return TRUE

/datum/ai_behavior/run_away_from_target/proc/get_furthest_turf(atom/source, angle, atom/target)
var/turf/return_turf
for(var/i in 1 to run_distance)
var/turf/test_destination = get_ranged_target_turf_direct(source, target, range = i, offset = angle)
if(is_blocked_turf(test_destination, exclude_mobs = !source.density))
break
return_turf = test_destination
return return_turf

/datum/ai_behavior/run_away_from_target/until_destination
until_destination = TRUE
Expand Down
50 changes: 50 additions & 0 deletions code/datums/ai/behaviours/use_targeted_ability.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* # Targeted Mob Ability
* Attempts to use a mob's cooldown ability on a target
*/
/datum/ai_behavior/targeted_mob_ability

/datum/ai_behavior/targeted_mob_ability/perform(seconds_per_tick, datum/ai_controller/controller, ability_key, target_key)
var/obj/effect/proc_holder/spell/ability = controller.blackboard[ability_key]
var/mob/living/target = controller.blackboard[target_key]
if(QDELETED(ability) || QDELETED(target))
finish_action(controller, FALSE, ability_key, target_key)
return
var/mob/pawn = controller.pawn
pawn.face_atom(target)
var/result = ability.perform(targets = list(target), user = controller.pawn)
finish_action(controller, result, ability_key, target_key)

/datum/ai_behavior/targeted_mob_ability/finish_action(datum/ai_controller/controller, succeeded, ability_key, target_key)
. = ..()
var/atom/target = controller.blackboard[target_key]
if (QDELETED(target))
controller.clear_blackboard_key(target_key)

/**
* # Try Mob Ability and clear target
* Attempts to use a mob's cooldown ability on a target and releases the target when the action completes
*/
/datum/ai_behavior/targeted_mob_ability/and_clear_target

/datum/ai_behavior/targeted_mob_ability/and_clear_target/finish_action(datum/ai_controller/controller, succeeded, ability_key, target_key)
. = ..()
controller.clear_blackboard_key(target_key)

/datum/ai_behavior/targeted_mob_ability/proc/get_ability_to_use(datum/ai_controller/controller, ability_key)
return controller.blackboard[ability_key]

/**
* Attempts to move into the provided range and then use a mob's cooldown ability on a target
*/
/datum/ai_behavior/targeted_mob_ability/min_range
required_distance = 6
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT
var/datum/ai_movement/new_movement

/datum/ai_behavior/targeted_mob_ability/min_range/setup(datum/ai_controller/controller, ability_key, target_key)
. = ..()
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target))
return FALSE
set_movement_target(controller, target, new_movement)
28 changes: 28 additions & 0 deletions code/datums/ai/subtrees/targeted_ability_use.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// Attempts to use a mob ability on a target
/datum/ai_planning_subtree/targeted_mob_ability
/// Blackboard key for the ability
var/ability_key = BB_TARGETED_ACTION
/// Blackboard key for where the target ref is stored
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
/// Behaviour to perform using ability
var/use_ability_behaviour = /datum/ai_behavior/targeted_mob_ability
/// If true we terminate planning after trying to use the ability.
var/finish_planning = TRUE

/datum/ai_planning_subtree/targeted_mob_ability/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
if (!ability_key)
CRASH("You forgot to tell this mob where to find its ability")

if (!(target_key in controller.blackboard))
return

var/obj/effect/proc_holder/spell/using_action = controller.blackboard[ability_key]
if (!using_action?.recharging)
return

controller.queue_behavior(use_ability_behaviour, ability_key, target_key)
if (finish_planning)
return SUBTREE_RETURN_FINISH_PLANNING

/datum/ai_planning_subtree/targeted_mob_ability/continue_planning
finish_planning = FALSE
1 change: 1 addition & 0 deletions code/datums/outdoor_datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ Sunlight System
for(var/obj/structure/thing in src.contents) // Checks to see if weatherproof objects on the tile
if(thing.weatherproof == TRUE)
.["WEATHERPROOF"] = TRUE // returns true to block the weather
.["SKYVISIBLE"] = FALSE
return .
.["WEATHERPROOF"] = weatherproof //If we are air or space, we aren't weatherproof
else //We are open, so assume open to the elements
Expand Down
2 changes: 1 addition & 1 deletion code/game/area/roguetownareas.dm
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ GLOBAL_LIST_INIT(roguetown_areas_typecache, typecacheof(/area/rogue/indoors/town
/turf/open/floor/rogue/cobblerock)

/area/rogue/outdoors/rtfield/outlaw
ambush_mobs = list(/mob/living/carbon/human/species/human/northern/bum/outlaw = 50)
ambush_mobs = list(/mob/living/carbon/human/species/human/northern/bum/skilled/outlaw = 50)
name = "outlaw hideout"
color = "#e9baa3"
first_time_text = null
Expand Down
Loading

0 comments on commit dcaa0fd

Please sign in to comment.