mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-25 13:07:46 +01:00
Converts hivebots to basic mob AI (#29849)
* Converts hivebots to basic mob AI * Updatepaths * Linters * Hivebot beacon * New linters --------- Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
co-authored by
Burzah
parent
8976c80adc
commit
3a03e29187
@@ -154,6 +154,17 @@ RESTRICT_TYPE(/mob/living/basic)
|
||||
/// Footsteps
|
||||
var/step_type
|
||||
|
||||
/// Does this type do range attacks?
|
||||
var/is_ranged = FALSE
|
||||
/// How many shots in a burst?
|
||||
var/ranged_burst_count = 1
|
||||
/// How fast do we fire between bursts?
|
||||
var/ranged_burst_interval = 0.2 SECONDS
|
||||
/// What projectile do we shoot?
|
||||
var/projectile_type
|
||||
/// What sound does it make when firing?
|
||||
var/projectile_sound
|
||||
|
||||
/mob/living/basic/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -164,6 +175,8 @@ RESTRICT_TYPE(/mob/living/basic)
|
||||
apply_temperature_requirements()
|
||||
if(step_type)
|
||||
AddComponent(/datum/component/footstep, step_type)
|
||||
if(is_ranged)
|
||||
AddComponent(/datum/component/ranged_attacks, projectile_type = projectile_type, projectile_sound = projectile_sound, burst_shots = ranged_burst_count, burst_intervals = ranged_burst_interval)
|
||||
|
||||
/mob/living/basic/Destroy()
|
||||
if(nest)
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/obj/item/projectile/hivebotbullet
|
||||
|
||||
/mob/living/basic/hivebot
|
||||
name = "Hivebot"
|
||||
desc = "A small robot."
|
||||
icon = 'icons/mob/hivebot.dmi'
|
||||
icon_state = "basic"
|
||||
icon_living = "basic"
|
||||
icon_dead = "basic"
|
||||
mob_biotypes = MOB_ROBOTIC
|
||||
health = 15
|
||||
maxHealth = 15
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 3
|
||||
melee_attack_cooldown_min = 1.5 SECONDS
|
||||
melee_attack_cooldown_max = 2.5 SECONDS
|
||||
attack_verb_continuous = "claws"
|
||||
attack_verb_simple = "claw"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
faction = list("hivebot")
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minimum_survivable_temperature = 0
|
||||
speak_emote = list("states")
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
loot = list(/obj/effect/decal/cleanable/blood/gibs/robot)
|
||||
death_message = "blows apart!"
|
||||
bubble_icon = "machine"
|
||||
basic_mob_flags = DEL_ON_DEATH
|
||||
step_type = FOOTSTEP_MOB_CLAW
|
||||
ai_controller = /datum/ai_controller/basic_controller/hivebot
|
||||
projectile_type = /obj/item/projectile/hivebotbullet
|
||||
projectile_sound = 'sound/weapons/gunshots/gunshot.ogg'
|
||||
|
||||
/mob/living/basic/hivebot/range
|
||||
desc = "A smallish robot, this one is armed!"
|
||||
is_ranged = TRUE
|
||||
ai_controller = /datum/ai_controller/basic_controller/hivebot/ranged
|
||||
|
||||
/mob/living/basic/hivebot/rapid
|
||||
is_ranged = TRUE
|
||||
ranged_burst_count = 3
|
||||
ai_controller = /datum/ai_controller/basic_controller/hivebot/ranged/rapid
|
||||
|
||||
/mob/living/basic/hivebot/strong
|
||||
name = "Strong Hivebot"
|
||||
desc = "A robot, this one is armed and looks tough!"
|
||||
health = 80
|
||||
maxHealth = 80
|
||||
is_ranged = TRUE
|
||||
ai_controller = /datum/ai_controller/basic_controller/hivebot/ranged
|
||||
|
||||
/mob/living/basic/hivebot/death(gibbed)
|
||||
// Only execute the below if we successfully died
|
||||
. = ..(gibbed)
|
||||
if(!.)
|
||||
return FALSE
|
||||
do_sparks(3, 1, src)
|
||||
|
||||
/mob/living/basic/hivebot/tele // Hivebot Telebeacon
|
||||
name = "Beacon"
|
||||
desc = "Some odd beacon thing."
|
||||
icon_state = "def_radar-off"
|
||||
icon_living = "def_radar-off"
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
status_flags = 0
|
||||
anchored = TRUE
|
||||
ai_controller = /datum/ai_controller/basic_controller/beacon
|
||||
/// The total number of hivebots to spawn
|
||||
var/bot_amt = 10
|
||||
|
||||
/mob/living/basic/hivebot/tele/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.set_up(5, FALSE, loc)
|
||||
smoke.start()
|
||||
visible_message("<span class='danger'>[src] warps in!</span>")
|
||||
playsound(src.loc, 'sound/effects/empulse.ogg', 25, 1)
|
||||
|
||||
/mob/living/basic/hivebot/tele/proc/warpbots()
|
||||
icon_state = "def_radar"
|
||||
visible_message("<span class='warning'>[src] turns on!</span>")
|
||||
while(bot_amt > 0)
|
||||
bot_amt--
|
||||
if(bot_amt > 3)
|
||||
var/mob/living/basic/hivebot/H = new /mob/living/basic/hivebot(get_turf(src))
|
||||
H.faction = faction
|
||||
else if(bot_amt > 0)
|
||||
var/mob/living/basic/hivebot/range/R = new /mob/living/basic/hivebot/range(get_turf(src))
|
||||
R.faction = faction
|
||||
else
|
||||
var/mob/living/basic/hivebot/rapid/F = new /mob/living/basic/hivebot/rapid(get_turf(src))
|
||||
F.faction = faction
|
||||
spawn(100)
|
||||
qdel(src)
|
||||
return
|
||||
@@ -0,0 +1,128 @@
|
||||
/datum/ai_controller/basic_controller/hivebot
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
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,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/hive_communicate,
|
||||
)
|
||||
|
||||
/datum/ai_controller/basic_controller/hivebot/ranged
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/hivebot,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/hive_communicate,
|
||||
)
|
||||
|
||||
/datum/ai_controller/basic_controller/hivebot/ranged/rapid
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/hivebot_rapid,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/hive_communicate,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/hivebot_rapid
|
||||
ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack/hivebot_rapid
|
||||
|
||||
/datum/ai_planning_subtree/basic_ranged_attack_subtree/hivebot
|
||||
ranged_attack_behavior = /datum/ai_behavior/basic_ranged_attack/hivebot
|
||||
|
||||
/datum/ai_planning_subtree/hive_communicate
|
||||
/// chance to go and relay message
|
||||
var/relay_chance = 10
|
||||
|
||||
/datum/ai_planning_subtree/hive_communicate/select_behaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
|
||||
if(!SPT_PROB(relay_chance, seconds_per_tick))
|
||||
return
|
||||
|
||||
if(controller.blackboard_key_exists(BB_HIVE_PARTNER))
|
||||
controller.queue_behavior(/datum/ai_behavior/relay_message, BB_HIVE_PARTNER)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
controller.queue_behavior(/datum/ai_behavior/find_and_set/hive_partner, BB_HIVE_PARTNER, /mob/living/basic/hivebot)
|
||||
|
||||
/datum/ai_behavior/find_and_set/hive_partner
|
||||
|
||||
/datum/ai_behavior/find_and_set/hive_partner/search_tactic(datum/ai_controller/controller, locate_path, search_range)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
var/list/hive_partners = list()
|
||||
for(var/mob/living/target in oview(10, living_pawn))
|
||||
if(!istype(target, locate_path))
|
||||
continue
|
||||
if(target.stat == DEAD)
|
||||
continue
|
||||
hive_partners += target
|
||||
|
||||
if(length(hive_partners))
|
||||
return pick(hive_partners)
|
||||
|
||||
/// behavior that allow us to go communicate with other hivebots
|
||||
/datum/ai_behavior/relay_message
|
||||
/// length of the message we will relay
|
||||
var/length_of_message = 4
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT| AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/relay_message/setup(datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
var/mob/living/target = controller.blackboard[target_key]
|
||||
// It stopped existing
|
||||
if(QDELETED(target))
|
||||
return FALSE
|
||||
set_movement_target(controller, target)
|
||||
|
||||
/datum/ai_behavior/relay_message/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
var/mob/living/target = controller.blackboard[target_key]
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
|
||||
if(QDELETED(target))
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
var/message_relayed = ""
|
||||
for(var/i in 1 to length_of_message)
|
||||
message_relayed += prob(50) ? "1" : "0"
|
||||
living_pawn.say(message_relayed)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
/datum/ai_behavior/relay_message/finish_action(datum/ai_controller/controller, succeeded, target_key)
|
||||
. = ..()
|
||||
controller.clear_blackboard_key(target_key)
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/hivebot
|
||||
action_cooldown = 3 SECONDS
|
||||
avoid_friendly_fire = TRUE
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/hivebot_rapid
|
||||
action_cooldown = 1 SECONDS
|
||||
avoid_friendly_fire = TRUE
|
||||
|
||||
/datum/ai_controller/basic_controller/beacon
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = null
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/warpbots,
|
||||
/datum/ai_planning_subtree/hive_communicate,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/warpbots
|
||||
/// chance to summon hivebots
|
||||
var/warp_chance = 2
|
||||
|
||||
/datum/ai_planning_subtree/warpbots/select_behaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
|
||||
if(!SPT_PROB(warp_chance, seconds_per_tick))
|
||||
return
|
||||
|
||||
if(controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
|
||||
var/mob/living/basic/hivebot/tele/beacon = controller.pawn
|
||||
beacon.warpbots()
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
Reference in New Issue
Block a user