Slime Update

Pink Slime Aura and Mend Synthetic (technomancer) should now fix FBPs again.
Adds procs to get the 'real' number of damage from humans, including limb damage on prosthetic limbs.
Slime following made a bit more robust, slimes (and other simple animals) stop wandering when following.
Slimes following a leader that passes the can_command() check will refrain from attacking things if not attacked first.
Slime kill command implemented, requires the slime to be in your faction or be the slime's friend, and not just obedient.  This can be accomplished with end-game slime agents.
Slimes require three 'free' tiles to split, which should prevent super overcrowed cells and by extension avoid Amber Tide from crashing the mob controller.
Dark Blue Cold Aura now properly adjusts temperature based on protection gradually instead of instantly setting to the lowest value.
This commit is contained in:
Neerti
2017-09-17 13:18:16 -04:00
parent aa6866bf44
commit d741b0e987
9 changed files with 106 additions and 48 deletions
@@ -80,6 +80,12 @@
amount += O.brute_dam
return amount
/mob/living/carbon/human/getActualBruteLoss()
var/amount = 0
for(var/obj/item/organ/external/O in organs) // Unlike the above, robolimbs DO count.
amount += O.brute_dam
return amount
/mob/living/carbon/human/getFireLoss()
var/amount = 0
for(var/obj/item/organ/external/O in organs)
@@ -96,6 +102,12 @@
amount += O.burn_dam
return amount
/mob/living/carbon/human/getActualFireLoss()
var/amount = 0
for(var/obj/item/organ/external/O in organs) // Unlike the above, robolimbs DO count.
amount += O.burn_dam
return amount
/mob/living/carbon/human/adjustBruteLoss(var/amount)
amount = amount*species.brute_mod
if(amount > 0)
+6
View File
@@ -218,6 +218,9 @@ default behaviour is:
/mob/living/proc/getShockBruteLoss() //Only checks for things that'll actually hurt (not robolimbs)
return bruteloss
/mob/living/proc/getActualBruteLoss() // Mostly for humans with robolimbs.
return getBruteLoss()
/mob/living/proc/adjustBruteLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -286,6 +289,9 @@ default behaviour is:
/mob/living/proc/getShockFireLoss() //Only checks for things that'll actually hurt (not robolimbs)
return fireloss
/mob/living/proc/getActualFireLoss() // Mostly for humans with robolimbs.
return getBruteLoss()
/mob/living/proc/adjustFireLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
if(amount > 0)
@@ -994,6 +994,7 @@
//Follow a target (and don't attempt to murder it horribly)
/mob/living/simple_animal/proc/FollowTarget()
ai_log("FollowTarget() [follow_mob]",1)
stop_automated_movement = 1
//If we were chasing someone and we can't anymore, give up.
if(!follow_mob || follow_mob.stat)
ai_log("FollowTarget() Losing follow at top",2)
@@ -1324,6 +1325,7 @@
//Forget a follow mode
/mob/living/simple_animal/proc/LoseFollow()
ai_log("LoseFollow() [target_mob]",2)
stop_automated_movement = 0
follow_mob = null
handle_stance(STANCE_IDLE)
GiveUpMoving()
@@ -1,11 +1,16 @@
/mob/living/simple_animal/slime/FindTarget()
if(victim) // Don't worry about finding another target if we're eatting someone.
return
// if(!will_hunt())
// return
if(follow_mob && can_command(follow_mob)) // If following someone, don't attack until the leader says so, something hits you, or the leader is no longer worthy.
return
..()
/mob/living/simple_animal/slime/special_target_check(mob/living/L)
if(L.faction == faction && !attack_same)
return FALSE
if(L in friends)
return FALSE
if(istype(L, /mob/living/simple_animal/slime))
var/mob/living/simple_animal/slime/buddy = L
if(buddy.slime_color == src.slime_color || discipline || unity || buddy.unity)
@@ -47,12 +52,3 @@
return
else
..()
/*
/mob/living/simple_animal/slime/proc/will_hunt() // Check for being stopped from feeding and chasing
if(nutrition <= get_starve_nutrition() || rabid)
return TRUE
if(nutrition <= get_hunger_nutrition() || prob(25))
return TRUE
return FALSE
*/
@@ -97,16 +97,21 @@
// This is to make slime responses feel a bit more natural and not instant.
/mob/living/simple_animal/slime/proc/delayed_say(var/message, var/mob/target)
sleep(rand(1 SECOND, 2 SECONDS))
if(target)
face_atom(target)
say(message)
spawn(rand(1 SECOND, 2 SECONDS))
if(target)
face_atom(target)
say(message)
//Commands, reactions, etc
/mob/living/simple_animal/slime/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
..()
if((findtext(message, num2text(number)) || findtext(message, name) || findtext(message, "slimes"))) // Talking to us
// First make sure it's not just another slime repeating things.
if(istype(speaker, /mob/living/simple_animal/slime))
if(!speaker.client)
return
// Say hello back.
if(findtext(message, "hello") || findtext(message, "hi") || findtext(message, "greetings"))
delayed_say(pick("Hello...", "Hi..."), speaker)
@@ -142,33 +147,31 @@
adjust_discipline(1, TRUE)
if(follow_mob) // We're being asked to stop following someone.
if(follow_mob == speaker)
if(can_command(speaker) == SLIME_COMMAND_FRIEND || follow_mob == speaker)
delayed_say("Yes... I'll stop...", speaker)
LoseFollow()
else
delayed_say("No... I'll keep following \the [follow_mob]...", speaker)
// Help request
if(findtext(message, "help"))
if(!can_command(speaker))
delayed_say("No...", speaker)
return
else
delayed_say("I will protect \the [speaker].", speaker)
// Murder request
if(findtext(message, "harm") || findtext(message, "kill") || findtext(message, "murder") || findtext(message, "eat") || findtext(message, "consume"))
if(!can_command(speaker))
if(can_command(speaker) < SLIME_COMMAND_FACTION)
delayed_say("No...", speaker)
return
//LoseFollow()
/*
if(reacts && speaker && (message in reactions) && (!hostile || isliving(speaker)) && say_understands(speaker,language))
var/mob/living/L = speaker
if(L.faction == faction)
spawn(10)
face_atom(speaker)
say(reactions[message])
*/
for(var/mob/living/L in view(7, src) - list(src, speaker))
if(L == src)
continue // Don't target ourselves.
var/list/valid_names = splittext(L.name, " ") // Should output list("John", "Doe") as an example.
for(var/line in valid_names) // Check each part of someone's name.
if(findtext(message, lowertext(line))) // If part of someone's name is in the command, the slime targets them if allowed to.
if(special_target_check(L))
delayed_say("Okay... I attack \the [L]...", speaker)
LoseFollow()
set_target(L)
return
else
delayed_say("No... I won't attack \the [L].", speaker)
return
// If we're here, it couldn't find anyone with that name.
delayed_say("No... I don't know who to attack...", speaker)
@@ -297,6 +297,24 @@
if(is_adult)
if(amount_grown >= 10)
// Check if there's enough 'room' to split.
var/list/nearby_things = orange(1, src)
var/free_tiles = 0
for(var/turf/T in nearby_things)
var/free = TRUE
if(T.density) // No walls.
continue
for(var/atom/movable/AM in T)
if(AM.density)
free = FALSE
break
if(free)
free_tiles++
if(free_tiles < 3) // Three free tiles are needed, as four slimes are made and the 4th tile is from the center tile that the current slime occupies.
to_chat(src, "<span class='warning'>It is too cramped here to reproduce...</span>")
return
var/list/babies = list()
for(var/i = 1 to 4)
@@ -352,13 +370,13 @@
if(rabid)
return FALSE
if(docile)
return TRUE
return SLIME_COMMAND_OBEY
if(commander in friends)
return TRUE
return SLIME_COMMAND_FRIEND
if(faction == commander.faction)
return TRUE
return SLIME_COMMAND_FACTION
if(discipline > resentment && obedience >= 5)
return TRUE
return SLIME_COMMAND_OBEY
return FALSE
/mob/living/simple_animal/slime/proc/give_hat(var/obj/item/clothing/head/new_hat, var/mob/living/user)
@@ -200,12 +200,15 @@
var/cold_factor = abs(protection - 1)
var/delta = -20
delta *= cold_factor
L.bodytemperature = max(50, delta)
L.bodytemperature = max(50, L.bodytemperature + delta)
var/turf/T = get_turf(src)
var/datum/gas_mixture/env = T.return_air()
if(env)
env.add_thermal_energy(-10 * 1000)
/mob/living/simple_animal/slime/dark_blue/get_cold_protection()
return 1 // This slime is immune to cold.
/mob/living/simple_animal/slime/silver
desc = "This slime is shiny, and can deflect lasers or other energy weapons directed at it."
@@ -513,8 +516,16 @@
/datum/modifier/slime_heal/tick()
if(holder.stat == DEAD) // Required or else simple animals become immortal.
expire()
holder.adjustBruteLoss(-2)
holder.adjustFireLoss(-2)
if(ishuman(holder)) // Robolimbs need this code sadly.
var/mob/living/carbon/human/H = holder
for(var/obj/item/organ/external/E in H.organs)
var/obj/item/organ/external/O = E
O.heal_damage(2, 2, 0, 1)
else
holder.adjustBruteLoss(-2)
holder.adjustFireLoss(-2)
holder.adjustToxLoss(-2)
holder.adjustOxyLoss(-2)
holder.adjustCloneLoss(-1)