Fixes several bugs with AI mobs

This commit is contained in:
Neerti
2018-12-04 19:00:21 -05:00
parent 08665794e0
commit ac5fdfcd9e
5 changed files with 54 additions and 21 deletions

View File

@@ -16,9 +16,9 @@
can_flee = TRUE
violent_breakthrough = FALSE
// Won't wander away, ideal for event-spawned mobs like carp or drones.
// Won't wander away as quickly, ideal for event-spawned mobs like carp or drones.
/datum/ai_holder/simple_mob/event
wander = FALSE
base_wander_delay = 8
// Doesn't really act until told to by something on the outside.
/datum/ai_holder/simple_mob/inert
@@ -60,7 +60,7 @@
// For event-spawned malf drones.
/datum/ai_holder/simple_mob/ranged/kiting/threatening/event
wander = FALSE
base_wander_delay = 8
/datum/ai_holder/simple_mob/ranged/kiting/no_moonwalk
moonwalk = FALSE
@@ -96,6 +96,11 @@
/datum/ai_holder/simple_mob/restrained
violent_breakthrough = FALSE
conserve_ammo = TRUE
destructive = FALSE
// This does the opposite of the above subtype.
/datum/ai_holder/simple_mob/destructive
destructive = TRUE
// Melee mobs.

View File

@@ -12,13 +12,16 @@
var/always_stun = FALSE // If true, the slime will elect to attempt to permastun the target.
var/last_discipline_decay = null // Last world.time discipline was reduced from decay.
var/discipline_decay_time = 5 SECONDS // Earliest that one discipline can decay.
/datum/ai_holder/simple_mob/xenobio_slime/sapphire
always_stun = TRUE // They know that stuns are godly.
intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death.
/datum/ai_holder/simple_mob/xenobio_slime/light_pink
discipline = 5
obedience = 5
discipline = 10
obedience = 10
/datum/ai_holder/simple_mob/xenobio_slime/passive/New() // For Kendrick.
..()
@@ -89,9 +92,10 @@
// Handles decay of discipline.
/datum/ai_holder/simple_mob/xenobio_slime/proc/discipline_decay()
if(discipline > 0)
if(discipline > 0 && last_discipline_decay + discipline_decay_time < world.time)
if(!prob(75 + (obedience * 5)))
adjust_discipline(-1)
last_discipline_decay = world.time
/datum/ai_holder/simple_mob/xenobio_slime/handle_special_tactic()
evolve_and_reproduce()

View File

@@ -15,8 +15,9 @@
var/lose_target_time = 0 // world.time when a target was lost.
var/lose_target_timeout = 5 SECONDS // How long until a mob 'times out' and stops trying to find the mob that disappeared.
var/list/attackers = list() // List of strings of names of people who attacked us before in our life.
// This uses strings and not refs to allow for disguises, and to avoid needing to use weakrefs.
var/list/attackers = list() // List of strings of names of people who attacked us before in our life.
// This uses strings and not refs to allow for disguises, and to avoid needing to use weakrefs.
var/destructive = FALSE // Will target 'neutral' structures/objects and not just 'hostile' ones.
// A lot of this is based off of /TG/'s AI code.
@@ -111,6 +112,7 @@
var/obj/mecha/M = the_target
if(M.occupant)
return can_attack(M.occupant)
return destructive // Empty mechs are 'neutral'.
if(istype(the_target, /obj/machinery/porta_turret))
var/obj/machinery/porta_turret/P = the_target

View File

@@ -102,7 +102,7 @@
return FALSE
visible_message("<span class='danger'><b>\The [src]</b> fires at \the [A]!</span>")
shoot(A, src.loc, src)
shoot(A)
if(casingtype)
new casingtype(loc)
@@ -112,21 +112,22 @@
return TRUE
//Shoot a bullet at someone (idk why user is an argument when src would fit???)
/mob/living/simple_mob/proc/shoot(atom/A, turf/start, mob/living/user, bullet = 0)
if(A == start)
// Shoot a bullet at something.
/mob/living/simple_mob/proc/shoot(atom/A)
if(A == get_turf(src))
return
face_atom(A)
var/obj/item/projectile/P = new projectiletype(user.loc)
var/obj/item/projectile/P = new projectiletype(src.loc)
if(!P)
return
// If the projectile has its own sound, use it.
// Otherwise default to the mob's firing sound.
playsound(user, P.fire_sound ? P.fire_sound : projectilesound, 80, 1)
playsound(src, P.fire_sound ? P.fire_sound : projectilesound, 80, 1)
P.firer = src // So we can't shoot ourselves.
P.launch(A)
if(needs_reload)
reload_count++

View File

@@ -20,17 +20,40 @@
var/number = 0 // This is used to make the slime semi-unique for indentification.
var/harmless = FALSE // Set to true when pacified. Makes the slime harmless, not get hungry, and not be able to grow/reproduce.
/mob/living/simple_mob/slime/xenobio/initialize()
/mob/living/simple_mob/slime/xenobio/initialize(mapload, var/mob/living/simple_mob/slime/xenobio/my_predecessor)
ASSERT(ispath(ai_holder_type, /datum/ai_holder/simple_mob/xenobio_slime))
number = rand(1, 1000)
update_name()
return ..()
. = ..() // This will make the AI and do the other mob constructor things. It will also return the default hint at the end.
if(my_predecessor)
inherit_information(my_predecessor)
/mob/living/simple_mob/slime/xenobio/Destroy()
if(victim)
stop_consumption() // Unbuckle us from our victim.
return ..()
// Called when a slime makes another slime by splitting. The predecessor slime will be deleted shortly afterwards.
/mob/living/simple_mob/slime/xenobio/proc/inherit_information(var/mob/living/simple_mob/slime/xenobio/predecessor)
if(!predecessor)
return
var/datum/ai_holder/simple_mob/xenobio_slime/AI = ai_holder
var/datum/ai_holder/simple_mob/xenobio_slime/previous_AI = predecessor.ai_holder
ASSERT(istype(AI))
ASSERT(istype(previous_AI))
// Now to transfer the information.
// Newly made slimes are bit more rebellious than their predecessors, but they also somewhat forget the atrocities the xenobiologist may have done.
AI.discipline = max(previous_AI.discipline - 1, 0)
AI.obedience = max(previous_AI.obedience - 1, 0)
AI.resentment = max(previous_AI.resentment - 1, 0)
AI.rabid = previous_AI.rabid
/mob/living/simple_mob/slime/xenobio/update_icon()
icon_living = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"][victim ? " eating" : ""]"
icon_dead = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"] dead"
@@ -212,14 +235,12 @@
t = /mob/living/simple_mob/slime/xenobio/rainbow
else if(prob(mutation_chance) && slime_mutation.len)
t = slime_mutation[rand(1, slime_mutation.len)]
var/mob/living/simple_mob/slime/xenobio/baby = new t(loc)
var/mob/living/simple_mob/slime/xenobio/baby = new t(loc, src)
// Handle 'inheriting' from parent slime.
baby.mutation_chance = mutation_chance
baby.power_charge = round(power_charge / 4)
pass_on_data(baby) // Transfer the AI stuff slowly, sadly.
if(!istype(baby, /mob/living/simple_mob/slime/xenobio/rainbow))
baby.unity = unity
baby.faction = faction
@@ -227,7 +248,7 @@
step_away(baby, src)
return baby
/*
/mob/living/simple_mob/slime/xenobio/proc/pass_on_data(mob/living/simple_mob/slime/xenobio/baby)
// This is superdumb but the AI datum won't exist until the new slime's initialize() finishes.
var/new_discipline = 0
@@ -254,7 +275,7 @@
their_AI.resentment = new_resentment
their_AI.rabid = new_rabid
*/
/mob/living/simple_mob/slime/xenobio/get_description_interaction()
var/list/results = list()