diff --git a/baystation12.dme b/baystation12.dme
index afcec78b11..d8cb9e31e8 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -981,6 +981,7 @@
#include "code\modules\mob\living\carbon\metroid\login.dm"
#include "code\modules\mob\living\carbon\metroid\metroid.dm"
#include "code\modules\mob\living\carbon\metroid\powers.dm"
+#include "code\modules\mob\living\carbon\metroid\say.dm"
#include "code\modules\mob\living\carbon\metroid\subtypes.dm"
#include "code\modules\mob\living\carbon\metroid\update_icons.dm"
#include "code\modules\mob\living\carbon\monkey\death.dm"
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 90a68b02b6..22c8a11300 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -63,7 +63,7 @@
slime.Discipline = 0
if(power >= 3)
- if(istype(slime, /mob/living/carbon/slime/adult))
+ if(slime.is_adult)
if(prob(5 + round(power/2)))
if(slime.Victim)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 61d26340a5..44d374b85c 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -173,7 +173,7 @@
return src.attack_hand(user)
/obj/machinery/door/window/attack_paw(mob/user as mob)
- if(istype(user, /mob/living/carbon/alien/humanoid) || istype(user, /mob/living/carbon/slime/adult))
+ if(istype(user, /mob/living/carbon/alien/humanoid))
if(src.operating)
return
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
@@ -346,4 +346,4 @@
/obj/machinery/door/window/brigdoor/southright
dir = SOUTH
icon_state = "rightsecure"
- base_state = "rightsecure"
+ base_state = "rightsecure"
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 441dee233a..6bc605a9c9 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -425,4 +425,47 @@ REAGENT SCANNER
name = "advanced reagent scanner"
icon_state = "adv_spectrometer"
details = 1
- origin_tech = "magnets=4;biotech=2"
\ No newline at end of file
+ origin_tech = "magnets=4;biotech=2"
+
+/obj/item/device/slime_scanner
+ name = "slime scanner"
+ icon_state = "adv_spectrometer"
+ item_state = "analyzer"
+ origin_tech = "biotech=1"
+ w_class = 2.0
+ flags = CONDUCT
+ throwforce = 0
+ throw_speed = 3
+ throw_range = 7
+ matter = list("metal" = 30,"glass" = 20)
+
+/obj/item/device/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob)
+ if (!isslime(M))
+ user << "This device can only scan slimes!"
+ return
+ var/mob/living/carbon/slime/T = M
+ user.show_message("Slime scan results:")
+ user.show_message(text("[T.colour] [] slime", T.is_adult ? "adult" : "baby"))
+ user.show_message(text("Nutrition: [T.nutrition]/[]", T.get_max_nutrition()))
+ if (T.nutrition < T.get_starve_nutrition())
+ user.show_message("Warning: slime is starving!")
+ else if (T.nutrition < T.get_hunger_nutrition())
+ user.show_message("Warning: slime is hungry")
+ user.show_message("Electric change strength: [T.powerlevel]")
+ user.show_message("Health: [T.health]")
+ if (T.slime_mutation[4] == T.colour)
+ user.show_message("This slime does not evolve any further")
+ else
+ if (T.slime_mutation[3] == T.slime_mutation[4])
+ if (T.slime_mutation[2] == T.slime_mutation[1])
+ user.show_message(text("Possible mutation: []", T.slime_mutation[3]))
+ user.show_message("Genetic destability: [T.mutation_chance/2]% chance of mutation on splitting")
+ else
+ user.show_message(text("Possible mutations: [], [], [] (x2)", T.slime_mutation[1], T.slime_mutation[2], T.slime_mutation[3]))
+ user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting")
+ else
+ user.show_message(text("Possible mutations: [], [], [], []", T.slime_mutation[1], T.slime_mutation[2], T.slime_mutation[3], T.slime_mutation[4]))
+ user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting")
+ if (T.cores > 1)
+ user.show_message("Anomalious slime core amount detected")
+ user.show_message("Growth progress: [T.amount_grown]/10")
\ No newline at end of file
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index bb50f1d63d..595a7d903b 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -58,7 +58,9 @@
return
/obj/structure/grille/attack_slime(mob/user as mob)
- if(!istype(user, /mob/living/carbon/slime/adult)) return
+ var/mob/living/carbon/slime/S = user
+ if (!S.is_adult)
+ return
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
user.visible_message("[user] smashes against [src].", \
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index 3d21a3a2b2..cd9dfd3e8a 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -103,7 +103,9 @@
attack_slime(mob/user as mob)
- if(!isslimeadult(user)) return
+ var/mob/living/carbon/slime/S = user
+ if (!S.is_adult)
+ return
attack_generic(user, rand(10, 15))
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index 0937e72d84..5977121973 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -105,7 +105,9 @@
/obj/structure/mirror/attack_slime(mob/user as mob)
- if(!isslimeadult(user)) return
+ var/mob/living/carbon/slime/S = user
+ if (!S.is_adult)
+ return
if(shattered)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index bc4d5fd25e..4977da7f4d 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -155,7 +155,9 @@
/obj/structure/window/attack_slime(mob/user as mob)
- if(!isslimeadult(user)) return
+ var/mob/living/carbon/slime/S = user
+ if (!S.is_adult)
+ return
attack_generic(user, rand(10, 15))
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 5990b64ceb..6b1e1d2b01 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -228,7 +228,7 @@
emergency_shuttle.call_evac()
log_admin("[key_name(usr)] called the Emergency Shuttle")
message_admins("\blue [key_name_admin(usr)] called the Emergency Shuttle to the station", 1)
-
+
else if (emergency_shuttle.can_recall())
emergency_shuttle.recall()
log_admin("[key_name(usr)] sent the Emergency Shuttle back")
@@ -247,7 +247,7 @@
log_admin("[key_name(usr)] edited the Emergency Shuttle's launch time to [new_time_left]")
message_admins("\blue [key_name_admin(usr)] edited the Emergency Shuttle's launch time to [new_time_left*10]", 1)
else if (emergency_shuttle.shuttle.has_arrive_time())
-
+
var/new_time_left = input("Enter new shuttle arrival time (seconds):","Edit Shuttle Arrival Time", emergency_shuttle.estimate_arrival_time() ) as num
emergency_shuttle.shuttle.arrive_time = world.time + new_time_left*10
@@ -255,7 +255,7 @@
message_admins("\blue [key_name_admin(usr)] edited the Emergency Shuttle's arrival time to [new_time_left*10]", 1)
else
alert("The shuttle is neither counting down to launch nor is it in transit. Please try again when it is.")
-
+
href_list["secretsadmin"] = "check_antagonist"
else if(href_list["delay_round_end"])
@@ -291,7 +291,6 @@
if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob )
if("human") M.change_mob_type( /mob/living/carbon/human , null, null, delmob )
if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob )
- if("adultslime") M.change_mob_type( /mob/living/carbon/slime/adult , null, null, delmob )
if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob )
if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob )
if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob )
@@ -1935,20 +1934,20 @@
if("launchshuttle")
if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created.
-
+
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","ShL")
-
+
var/list/valid_shuttles = list()
for (var/shuttle_tag in shuttle_controller.shuttles)
if (istype(shuttle_controller.shuttles[shuttle_tag], /datum/shuttle/ferry))
valid_shuttles += shuttle_tag
-
+
var/shuttle_tag = input("Which shuttle do you want to launch?") as null|anything in valid_shuttles
-
+
if (!shuttle_tag)
return
-
+
var/datum/shuttle/ferry/S = shuttle_controller.shuttles[shuttle_tag]
if (S.can_launch())
S.launch(usr)
@@ -1956,23 +1955,23 @@
log_admin("[key_name(usr)] launched the [shuttle_tag] shuttle")
else
alert("The [shuttle_tag] shuttle cannot be launched at this time. It's probably busy.")
-
+
if("forcelaunchshuttle")
if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created.
-
+
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","ShFL")
-
+
var/list/valid_shuttles = list()
for (var/shuttle_tag in shuttle_controller.shuttles)
if (istype(shuttle_controller.shuttles[shuttle_tag], /datum/shuttle/ferry))
valid_shuttles += shuttle_tag
-
+
var/shuttle_tag = input("Which shuttle's launch do you want to force?") as null|anything in valid_shuttles
-
+
if (!shuttle_tag)
return
-
+
var/datum/shuttle/ferry/S = shuttle_controller.shuttles[shuttle_tag]
if (S.can_force())
S.force_launch(usr)
@@ -1980,31 +1979,31 @@
log_admin("[key_name(usr)] has forced the [shuttle_tag] shuttle launch")
else
alert("The [shuttle_tag] shuttle launch cannot be forced at this time. It's busy, or hasn't been launched yet.")
-
+
if("jumpshuttle")
if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created.
-
+
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","ShJ")
-
+
var/shuttle_tag = input("Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles
if (!shuttle_tag) return
-
+
var/datum/shuttle/S = shuttle_controller.shuttles[shuttle_tag]
-
+
var/origin_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world
if (!origin_area) return
-
+
var/destination_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world
if (!destination_area) return
-
+
var/long_jump = alert("Is there a transition area for this jump?","", "Yes", "No")
if (long_jump == "Yes")
var/transition_area = input("Which area is the transition area? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world
if (!transition_area) return
-
+
var/move_duration = input("How many seconds will this jump take?") as num
-
+
S.long_jump(origin_area, destination_area, transition_area, move_duration)
message_admins("\blue [key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle", 1)
log_admin("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle")
@@ -2012,29 +2011,29 @@
S.short_jump(origin_area, destination_area)
message_admins("\blue [key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle", 1)
log_admin("[key_name_admin(usr)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle")
-
+
if("moveshuttle")
if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created.
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","ShM")
-
+
var/confirm = alert("This command directly moves a shuttle from one area to another. DO NOT USE THIS UNLESS YOU ARE DEBUGGING A SHUTTLE AND YOU KNOW WHAT YOU ARE DOING.", "Are you sure?", "Ok", "Cancel")
if (confirm == "Cancel")
return
var/shuttle_tag = input("Which shuttle do you want to jump?") as null|anything in shuttle_controller.shuttles
if (!shuttle_tag) return
-
+
var/datum/shuttle/S = shuttle_controller.shuttles[shuttle_tag]
-
+
var/origin_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world
if (!origin_area) return
-
+
var/destination_area = input("Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)") as null|area in world
if (!destination_area) return
-
+
S.move(origin_area, destination_area)
message_admins("\blue [key_name_admin(usr)] moved the [shuttle_tag] shuttle", 1)
log_admin("[key_name(usr)] moved the [shuttle_tag] shuttle")
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index d419a7cf70..03e590f036 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -177,7 +177,7 @@
var/damage = rand(1, 3)
- if(istype(M, /mob/living/carbon/slime/adult))
+ if(M.is_adult)
damage = rand(10, 40)
else
damage = rand(5, 35)
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 043b60bae2..9f5640c69b 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -198,7 +198,7 @@
var/damage = rand(1, 3)
- if(istype(src, /mob/living/carbon/slime/adult))
+ if(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 4f6368ad6f..56374bcd0f 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -336,7 +336,7 @@
var/damage = rand(1, 3)
- if(istype(M, /mob/living/carbon/slime/adult))
+ if(M.is_adult)
damage = rand(10, 35)
else
damage = rand(5, 25)
diff --git a/code/modules/mob/living/carbon/metroid/death.dm b/code/modules/mob/living/carbon/metroid/death.dm
index e37f3d2368..b8e004e201 100644
--- a/code/modules/mob/living/carbon/metroid/death.dm
+++ b/code/modules/mob/living/carbon/metroid/death.dm
@@ -1,23 +1,28 @@
/mob/living/carbon/slime/death(gibbed)
+ if(!gibbed)
+ if(is_adult)
+ var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc)
+ M.colour = colour
+ M.rabid = 1
+ is_adult = 0
+ maxHealth = 150
+ revive()
+ regenerate_icons()
+ number = rand(1, 1000)
+ name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
+ return
+
if(stat == DEAD) return
stat = DEAD
icon_state = "[colour] baby slime dead"
-
- if(!gibbed)
- if(istype(src, /mob/living/carbon/slime/adult))
- ghostize()
- var/mob/living/carbon/slime/M1 = new primarytype(loc)
- M1.rabid = 1
- var/mob/living/carbon/slime/M2 = new primarytype(loc)
- M2.rabid = 1
- if(src) del(src)
- else
- for(var/mob/O in viewers(src, null))
- O.show_message("The [name] seizes up and falls limp...", 1) //ded -- Urist
+ overlays.len = 0
+ for(var/mob/O in viewers(src, null))
+ O.show_message("The [name] seizes up and falls limp...", 1) //ded -- Urist
update_canmove()
if(blind) blind.layer = 0
- ticker.mode.check_win()
+ if(ticker && ticker.mode)
+ ticker.mode.check_win()
return ..(gibbed)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/metroid/emote.dm b/code/modules/mob/living/carbon/metroid/emote.dm
index 2f6f000539..2cbc139f5a 100644
--- a/code/modules/mob/living/carbon/metroid/emote.dm
+++ b/code/modules/mob/living/carbon/metroid/emote.dm
@@ -1,4 +1,4 @@
-/mob/living/carbon/slime/emote(var/act,var/m_type=1,var/message = null)
+/mob/living/carbon/slime/emote(var/act, var/m_type=1, var/message = null)
if (findtext(act, "-", 1, null))
@@ -9,7 +9,7 @@
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
- switch(act)
+ switch(act) //Alphabetical please
if ("me")
if(silent)
return
@@ -19,40 +19,51 @@
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
- if (stat)
- return
- if(!(message))
- return
- return custom_emote(m_type, message)
-
- if ("custom")
- return custom_emote(m_type, message)
- if("moan")
- message = "The [src.name] moans."
- m_type = 2
- if("shiver")
- message = "The [src.name] shivers."
- m_type = 2
- if("sway")
- message = "The [src.name] sways around dizzily."
- m_type = 1
- if("twitch")
- message = "The [src.name] twitches."
- m_type = 1
- if("vibrate")
- message = "The [src.name] vibrates!"
- m_type = 1
- if("light")
- message = "The [src.name] lights up for a bit, then stops."
- m_type = 1
- if("jiggle")
- message = "The [src.name] jiggles!"
- m_type = 1
+ if (stat)
+ return
+ if(!(message))
+ return
+ return custom_emote(m_type, message)
if("bounce")
message = "The [src.name] bounces in place."
m_type = 1
+
+ if ("custom")
+ return custom_emote(m_type, message)
+
+ if("jiggle")
+ message = "The [src.name] jiggles!"
+ m_type = 1
+
+ if("light")
+ message = "The [src.name] lights up for a bit, then stops."
+ m_type = 1
+
+ if("moan")
+ message = "The [src.name] moans."
+ m_type = 2
+
+ if("shiver")
+ message = "The [src.name] shivers."
+ m_type = 2
+
+ if("sway")
+ message = "The [src.name] sways around dizzily."
+ m_type = 1
+
+ if("twitch")
+ message = "The [src.name] twitches."
+ m_type = 1
+
+ if("vibrate")
+ message = "The [src.name] vibrates!"
+ m_type = 1
+
+ if ("help") //This is an exception
+ src << "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate"
+
else
- src << text("Invalid Emote: []", act)
+ src << "\blue Unusable emote '[act]'. Say *help for a list."
if ((message && src.stat == 0))
if (m_type & 1)
for(var/mob/O in viewers(src, null))
diff --git a/code/modules/mob/living/carbon/metroid/hud.dm b/code/modules/mob/living/carbon/metroid/hud.dm
index c770083906..cfaa7f4f16 100644
--- a/code/modules/mob/living/carbon/metroid/hud.dm
+++ b/code/modules/mob/living/carbon/metroid/hud.dm
@@ -1,4 +1,2 @@
-
/mob/living/carbon/slime/proc/regular_hud_updates()
- return
-
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm
index 47e9f6c675..c82d517d59 100644
--- a/code/modules/mob/living/carbon/metroid/life.dm
+++ b/code/modules/mob/living/carbon/metroid/life.dm
@@ -1,3 +1,10 @@
+/mob/living/carbon/slime
+ var/AIproc = 0 // determines if the AI loop is activated
+ var/Atkcool = 0 // attack cooldown
+ var/Tempstun = 0 // temporary temperature stuns
+ var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while
+ var/SStun = 0 // stun variable
+
/mob/living/carbon/slime/Life()
set invisibility = 0
set background = 1
@@ -15,114 +22,80 @@
handle_targets()
+ if (!ckey)
+ handle_speech_and_mood()
- var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
+ var/datum/gas_mixture/environment
if(src.loc)
environment = loc.return_air()
-
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
//to find it.
src.blinded = null
- // Basically just deletes any screen objects :<
- regular_hud_updates()
+ regular_hud_updates() // Basically just deletes any screen objects :<
- //Handle temperature/pressure differences between body and environment
if(environment)
- handle_environment(environment)
+ handle_environment(environment) // Handle temperature/pressure differences between body and environment
- //Status updates, death etc.
- handle_regular_status_updates()
-
-
-
-
-
-/mob/living/carbon/slime
- var/AIproc = 0 // determines if the AI loop is activated
- var/Atkcool = 0 // attack cooldown
- var/Tempstun = 0 // temporary temperature stuns
- var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while
- var/SStun = 0 // stun variable
+ handle_regular_status_updates() // Status updates, death etc.
/mob/living/carbon/slime/proc/AIprocess() // the master AI process
- //world << "AI proc started."
if(AIproc || stat == DEAD || client) return
var/hungry = 0
- var/starving = 0
- if(istype(src, /mob/living/carbon/slime/adult))
- switch(nutrition)
- if(400 to 1100) hungry = 1
- if(0 to 399)
- starving = 1
- else
- switch(nutrition)
- if(150 to 900) hungry = 1
- if(0 to 149) starving = 1
+ if (nutrition < get_starve_nutrition())
+ hungry = 2
+ else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition())
+ hungry = 1
+
AIproc = 1
- //world << "AIproc [AIproc] && stat != 2 [stat] && (attacked > 0 [attacked] || starving [starving] || hungry [hungry] || rabid [rabid] || Victim [Victim] || Target [Target]"
- while(AIproc && stat != 2 && (attacked > 0 || starving || hungry || rabid || Victim))
+
+ while(AIproc && stat != 2 && (attacked || hungry || rabid || Victim))
if(Victim) // can't eat AND have this little process at the same time
- //world << "break 1"
break
if(!Target || client)
- //world << "break 2"
break
-
if(Target.health <= -70 || Target.stat == 2)
Target = null
AIproc = 0
- //world << "break 3"
break
if(Target)
- //world << "[Target] Target Found"
for(var/mob/living/carbon/slime/M in view(1,Target))
if(M.Victim == Target)
Target = null
AIproc = 0
- //world << "break 4"
break
if(!AIproc)
- //world << "break 5"
break
if(Target in view(1,src))
-
if(istype(Target, /mob/living/silicon))
if(!Atkcool)
- spawn()
- Atkcool = 1
- sleep(15)
+ Atkcool = 1
+ spawn(45)
Atkcool = 0
if(Target.Adjacent(src))
Target.attack_slime(src)
- //world << "retrun 1"
return
if(!Target.lying && prob(80))
if(Target.client && Target.health >= 20)
if(!Atkcool)
- spawn()
- Atkcool = 1
- sleep(25)
+ Atkcool = 1
+ spawn(45)
Atkcool = 0
if(Target.Adjacent(src))
Target.attack_slime(src)
-
- if(prob(30))
- step_to(src, Target)
-
else
if(!Atkcool && Target.Adjacent(src))
Feedon(Target)
@@ -133,13 +106,13 @@
else
if(Target in view(7, src))
- if(Target.Adjacent(src))
+ if(!Target.Adjacent(src)) // Bug of the month candidate: slimes were attempting to move to target only if it was directly next to them, which caused them to target things, but not approach them
step_to(src, Target)
+ sleep(5)
else
Target = null
AIproc = 0
- //world << "break 6"
break
var/sleeptime = movement_delay()
@@ -148,7 +121,6 @@
sleep(sleeptime + 2) // this is about as fast as a player slime can go
AIproc = 0
- //world << "AI proc ended."
/mob/living/carbon/slime/proc/handle_environment(datum/gas_mixture/environment)
if(!environment)
@@ -166,28 +138,11 @@
else
loc_temp = environment.temperature
- /*
- if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10)))
- var/transfer_coefficient
-
- transfer_coefficient = 1
- if(wear_mask && (wear_mask.body_parts_covered & HEAD) && (environment.temperature < wear_mask.protective_temperature))
- transfer_coefficient *= wear_mask.heat_transfer_coefficient
-
- // handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient)
- */
-
-
if(loc_temp < 310.15) // a cold place
bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
else // a hot place
bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
- /*
- if(stat==2)
- bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000)
-
- */
//Account for massive pressure differences
if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc
@@ -207,7 +162,6 @@
return //TODO: DEFERRED
-
/mob/living/carbon/slime/proc/adjust_body_temperature(current, loc_temp, boost)
var/temperature = current
var/difference = abs(current-loc_temp) //get difference
@@ -229,33 +183,28 @@
if(reagents) reagents.metabolize(src)
-
src.updatehealth()
return //TODO: DEFERRED
-
/mob/living/carbon/slime/proc/handle_regular_status_updates()
- if(istype(src, /mob/living/carbon/slime/adult))
+ if(is_adult)
health = 200 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
else
health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
-
-
-
if(health < config.health_threshold_dead && stat != 2)
death()
return
else if(src.health < config.health_threshold_crit)
- // if(src.health <= 20 && prob(1)) spawn(0) emote("gasp")
- //if(!src.rejuv) src.oxyloss++
- if(!src.reagents.has_reagent("inaprovaline")) src.adjustOxyLoss(10)
+ if(!src.reagents.has_reagent("inaprovaline"))
+ src.adjustOxyLoss(10)
- if(src.stat != DEAD) src.stat = UNCONSCIOUS
+ if(src.stat != DEAD)
+ src.stat = UNCONSCIOUS
if(prob(30))
adjustOxyLoss(-1)
@@ -264,12 +213,9 @@
adjustCloneLoss(-1)
adjustBruteLoss(-1)
-
if (src.stat == DEAD)
-
src.lying = 1
src.blinded = 1
-
else
if (src.paralysis || src.stunned || src.weakened || (status_flags && FAKEDEATH)) //Stunned etc.
if (src.stunned > 0)
@@ -314,89 +260,25 @@
return 1
-
/mob/living/carbon/slime/proc/handle_nutrition()
- if(prob(20))
- if(istype(src, /mob/living/carbon/slime/adult)) nutrition-=rand(4,6)
- else nutrition-=rand(2,3)
+ if (prob(15))
+ nutrition -= 1 + is_adult
if(nutrition <= 0)
nutrition = 0
if(prob(75))
-
adjustToxLoss(rand(0,5))
- else
- if(istype(src, /mob/living/carbon/slime/adult))
- if(nutrition >= 1000)
- if(prob(40)) amount_grown++
+ else if (nutrition >= get_grow_nutrition() && amount_grown < 10)
+ nutrition -= 20
+ amount_grown++
+ if(amount_grown >= 10 && !Victim && !Target && !ckey)
+ if(is_adult)
+ Reproduce()
else
- if(nutrition >= 800)
- if(prob(40)) amount_grown++
-
- if(amount_grown >= 10 && !Victim && !Target)
- if(istype(src, /mob/living/carbon/slime/adult))
- if(!client)
- for(var/i=1,i<=4,i++)
- if(prob(70))
- var/mob/living/carbon/slime/M = new primarytype(loc)
- M.powerlevel = round(powerlevel/4)
- M.Friends = Friends
- M.tame = tame
- M.rabid = rabid
- M.Discipline = Discipline
- if(i != 1) step_away(M,src)
- else
- var/mutations = pick("one","two","three","four")
- switch(mutations)
- if("one")
- var/mob/living/carbon/slime/M = new mutationone(loc)
- M.powerlevel = round(powerlevel/4)
- M.Friends = Friends
- M.tame = tame
- M.rabid = rabid
- M.Discipline = Discipline
- if(i != 1) step_away(M,src)
- if("two")
- var/mob/living/carbon/slime/M = new mutationtwo(loc)
- M.powerlevel = round(powerlevel/4)
- M.Friends = Friends
- M.tame = tame
- M.rabid = rabid
- M.Discipline = Discipline
- if(i != 1) step_away(M,src)
- if("three")
- var/mob/living/carbon/slime/M = new mutationthree(loc)
- M.powerlevel = round(powerlevel/4)
- M.Friends = Friends
- M.tame = tame
- M.rabid = rabid
- M.Discipline = Discipline
- if(i != 1) step_away(M,src)
- if("four")
- var/mob/living/carbon/slime/M = new mutationfour(loc)
- M.powerlevel = round(powerlevel/4)
- M.Friends = Friends
- M.tame = tame
- M.rabid = rabid
- M.Discipline = Discipline
- if(i != 1) step_away(M,src)
-
- del(src)
-
- else
- if(!client)
- var/mob/living/carbon/slime/adult/A = new adulttype(src.loc)
- A.nutrition = nutrition
-// A.nutrition += 100
- A.powerlevel = max(0, powerlevel-1)
- A.Friends = Friends
- A.tame = tame
- A.rabid = rabid
- del(src)
-
+ Evolve()
/mob/living/carbon/slime/proc/handle_targets()
if(Tempstun)
@@ -408,8 +290,7 @@
if(attacked > 50) attacked = 50
if(attacked > 0)
- if(prob(85))
- attacked--
+ attacked--
if(Discipline > 0)
@@ -419,136 +300,278 @@
if(prob(10))
Discipline--
-
if(!client)
-
if(!canmove) return
- // DO AI STUFF HERE
-
- if(Target)
- if(attacked <= 0)
- Target = null
-
if(Victim) return // if it's eating someone already, continue eating!
-
- if(prob(1))
- emote(pick("bounce","sway","light","vibrate","jiggle"))
+ if(Target)
+ --target_patience
+ if (target_patience <= 0 || SStun || Discipline || attacked) // Tired of chasing or something draws out attention
+ target_patience = 0
+ Target = null
if(AIproc && SStun) return
-
var/hungry = 0 // determines if the slime is hungry
- var/starving = 0 // determines if the slime is starving-hungry
- if(istype(src, /mob/living/carbon/slime/adult)) // 1200 max nutrition
- switch(nutrition)
- if(601 to 900)
- if(prob(25)) hungry = 1//Ensures they continue eating, but aren't as aggressive at the same time
- if(301 to 600) hungry = 1
- if(0 to 300)
- starving = 1
- else
- switch(nutrition) // 1000 max nutrition
- if(501 to 700)
- if(prob(25)) hungry = 1
- if(201 to 500) hungry = 1
- if(0 to 200) starving = 1
+ if (nutrition < get_starve_nutrition())
+ hungry = 2
+ else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition())
+ hungry = 1
-
- if(starving && !client) // if a slime is starving, it starts losing its friends
+ if(hungry == 2 && !client) // if a slime is starving, it starts losing its friends
if(Friends.len > 0 && prob(1))
var/mob/nofriend = pick(Friends)
- Friends -= nofriend
+ --Friends[nofriend]
if(!Target)
- var/list/targets = list()
+ if(will_hunt() && hungry || attacked || rabid) // Only add to the list if we need to
+ var/list/targets = list()
- if(hungry || starving) //Only add to the list if we need to
for(var/mob/living/L in view(7,src))
- //Ignore other slimes, dead mobs and simple_animals
- if(isslime(L) || L.stat != CONSCIOUS || isanimal(L))
+ if(isslime(L) || L.stat == DEAD) // Ignore other slimes and dead mobs
continue
- if(issilicon(L))
- if(!istype(src, /mob/living/carbon/slime/adult)) //Non-starving diciplined adult slimes wont eat things
- if(!starving && Discipline > 0)
+ if(L in Friends) // No eating friends!
+ continue
+
+ if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence
+ targets += L // Possible target found!
+
+ if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men
+ var/mob/living/carbon/human/H = L
+ if(H.dna)
+ if(H.dna.mutantrace == "slime")
continue
- if(tame) //Tame slimes ignore electronic life
+ if(!L.canmove) // Only one slime can latch on at a time.
+ var/notarget = 0
+ for(var/mob/living/carbon/slime/M in view(1,L))
+ if(M.Victim == L)
+ notarget = 1
+ if(notarget)
continue
- targets += L //Possible target found!
+ targets += L // Possible target found!
- else if(iscarbon(L))
-
- if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men
- var/mob/living/carbon/human/H = L
- if(H.dna)
- if(H.dna.mutantrace == "slime")
- continue
-
- if(!istype(src, /mob/living/carbon/slime/adult)) //Non-starving diciplined adult slimes wont eat things
- if(!starving && Discipline > 0)
- continue
-
- if(L in Friends) //No eating friends!
- continue
-
- if(tame && ishuman(L)) //Tame slimes dont eat people.
- continue
-
- if(!L.canmove) //Only one slime can latch on at a time.
-
- var/notarget = 0
- for(var/mob/living/carbon/slime/M in view(1,L))
- if(M.Victim == L)
- notarget = 1
- if(notarget)
- continue
-
- targets += L //Possible target found!
-
-
-
- if((hungry || starving) && targets.len > 0)
- if(!istype(src, /mob/living/carbon/slime/adult))
- if(!starving)
+ if(targets.len > 0)
+ if(attacked || rabid || hungry == 2)
+ Target = targets[1] // I am attacked and am fighting back or so hungry I don't even care
+ else
for(var/mob/living/carbon/C in targets)
if(!Discipline && prob(5))
- if(ishuman(C))
- Target = C
- break
- if(isalienadult(C))
+ if(ishuman(C) || isalienadult(C))
Target = C
break
- if(islarva(C))
+ if(islarva(C) || ismonkey(C))
Target = C
break
- if(ismonkey(C))
- Target = C
- break
- else
- Target = targets[1]
- else
- Target = targets[1] // closest target
- if(targets.len > 0)
- if(attacked > 0 || rabid)
- Target = targets[1] //closest mob probably attacked it, so override Target and attack the nearest!
+ if (Target)
+ target_patience = rand(5,7)
+ if (is_adult)
+ target_patience += 3
+ if(!Target) // If we have no target, we are wandering or following orders
+ if (Leader)
+ if (holding_still)
+ holding_still = max(holding_still - 1, 0)
+ else if(canmove && isturf(loc))
+ step_to(src, Leader)
- if(!Target)
- if(hungry || starving)
- if(canmove && isturf(loc) && prob(50))
+ else if(hungry)
+ if (holding_still)
+ holding_still = max(holding_still - hungry, 0)
+ else if(canmove && isturf(loc) && prob(50))
step(src, pick(cardinal))
else
- if(canmove && isturf(loc) && prob(33))
+ if (holding_still)
+ holding_still = max(holding_still - 1, 0)
+ else if(canmove && isturf(loc) && prob(33))
step(src, pick(cardinal))
- else
- if(!AIproc)
- spawn() AIprocess()
+ else if(!AIproc)
+ spawn()
+ AIprocess()
+
+/mob/living/carbon/slime/proc/handle_speech_and_mood()
+ //Mood starts here
+ var/newmood = ""
+ if (rabid || attacked) newmood = "angry"
+ else if (Target) newmood = "mischevous"
+
+ if (!newmood)
+ if (Discipline && prob(25))
+ newmood = "pout"
+ else if (prob(1))
+ newmood = pick("sad", ":3", "pout")
+
+ if ((mood == "sad" || mood == ":3" || mood == "pout") && !newmood)
+ if (prob(75)) newmood = mood
+
+ if (newmood != mood) // This is so we don't redraw them every time
+ mood = newmood
+ regenerate_icons()
+
+ //Speech understanding starts here
+ var/to_say
+ if (speech_buffer.len > 0)
+ var/who = speech_buffer[1] // Who said it?
+ var/phrase = speech_buffer[2] // What did they say?
+ if ((findtext(phrase, num2text(number)) || findtext(phrase, "slimes"))) // Talking to us
+ if (findtext(phrase, "hello") || findtext(phrase, "hi"))
+ to_say = pick("Hello...", "Hi...")
+ else if (findtext(phrase, "follow"))
+ if (Leader)
+ if (Leader == who) // Already following him
+ to_say = pick("Yes...", "Lead...", "Following...")
+ else if (Friends[who] > Friends[Leader]) // VIVA
+ Leader = who
+ to_say = "Yes... I follow [who]..."
+ else
+ to_say = "No... I follow [Leader]..."
+ else
+ if (Friends[who] > 2)
+ Leader = who
+ to_say = "I follow..."
+ else // Not friendly enough
+ to_say = pick("No...", "I won't follow...")
+ else if (findtext(phrase, "stop"))
+ if (Victim) // We are asked to stop feeding
+ if (Friends[who] > 4)
+ Victim = null
+ Target = null
+ if (Friends[who] < 7)
+ --Friends[who]
+ to_say = "Grrr..." // I'm angry but I do it
+ else
+ to_say = "Fine..."
+ else if (Target) // We are asked to stop chasing
+ if (Friends[who] > 3)
+ Target = null
+ if (Friends[who] < 6)
+ --Friends[who]
+ to_say = "Grrr..." // I'm angry but I do it
+ else
+ to_say = "Fine..."
+ else if (Leader) // We are asked to stop following
+ if (Leader == who)
+ to_say = "Yes... I'll stay..."
+ Leader = null
+ else
+ if (Friends[who] > Friends[Leader])
+ Leader = null
+ to_say = "Yes... I'll stop..."
+ else
+ to_say = "No... I'll keep following..."
+ else if (findtext(phrase, "stay"))
+ if (Leader)
+ if (Leader == who)
+ holding_still = Friends[who] * 10
+ to_say = "Yes... Staying..."
+ else if (Friends[who] > Friends[Leader])
+ holding_still = (Friends[who] - Friends[Leader]) * 10
+ to_say = "Yes... Staying..."
+ else
+ to_say = "No... I'll keep following..."
+ else
+ if (Friends[who] > 2)
+ holding_still = Friends[who] * 10
+ to_say = "Yes... Staying..."
+ else
+ to_say = "No... I won't stay..."
+ speech_buffer = list()
+
+ //Speech starts here
+ if (to_say)
+ say (to_say)
+ else if(prob(1))
+ emote(pick("bounce","sway","light","vibrate","jiggle"))
+ else
+ var/t = 10
+ var/slimes_near = -1 // Don't count myself
+ var/dead_slimes = 0
+ var/friends_near = list()
+ for (var/mob/living/carbon/M in view(7,src))
+ if (isslime(M))
+ ++slimes_near
+ if (M.stat == DEAD)
+ ++dead_slimes
+ if (M in Friends)
+ t += 20
+ friends_near += M
+ if (nutrition < get_hunger_nutrition()) t += 10
+ if (nutrition < get_starve_nutrition()) t += 10
+ if (prob(2) && prob(t))
+ var/phrases = list()
+ if (Target) phrases += "[Target]... looks tasty..."
+ if (nutrition < get_starve_nutrition())
+ phrases += "So... hungry..."
+ phrases += "Very... hungry..."
+ phrases += "Need... food..."
+ phrases += "Must... eat..."
+ else if (nutrition < get_hunger_nutrition())
+ phrases += "Hungry..."
+ phrases += "Where is the food?"
+ phrases += "I want to eat..."
+ phrases += "Rawr..."
+ phrases += "Blop..."
+ phrases += "Blorble..."
+ if (rabid || attacked)
+ phrases += "Hrr..."
+ phrases += "Nhuu..."
+ phrases += "Unn..."
+ if (mood == ":3")
+ phrases += "Purr..."
+ if (attacked)
+ phrases += "Grrr..."
+ if (getToxLoss() > 30)
+ phrases += "Cold..."
+ if (getToxLoss() > 60)
+ phrases += "So... cold..."
+ phrases += "Very... cold..."
+ if (getToxLoss() > 90)
+ phrases += "..."
+ phrases += "C... c..."
+ if (Victim)
+ phrases += "Nom..."
+ phrases += "Tasty..."
+ if (powerlevel > 3) phrases += "Bzzz..."
+ if (powerlevel > 5) phrases += "Zap..."
+ if (powerlevel > 8) phrases += "Zap... Bzz..."
+ if (mood == "sad") phrases += "Bored..."
+ if (slimes_near) phrases += "Brother..."
+ if (slimes_near > 1) phrases += "Brothers..."
+ if (dead_slimes) phrases += "What happened?"
+ if (!slimes_near)
+ phrases += "Lonely..."
+ for (var/M in friends_near)
+ phrases += "[M]... friend..."
+ if (nutrition < get_hunger_nutrition())
+ phrases += "[M]... feed me..."
+ say (pick(phrases))
+
+/mob/living/carbon/slime/proc/get_max_nutrition() // Can't go above it
+ if (is_adult) return 1200
+ else return 1000
+
+/mob/living/carbon/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat
+ if (is_adult) return 1000
+ else return 800
+
+/mob/living/carbon/slime/proc/get_hunger_nutrition() // Below it we will always eat
+ if (is_adult) return 600
+ else return 500
+
+/mob/living/carbon/slime/proc/get_starve_nutrition() // Below it we will eat before everything else
+ if (is_adult) return 300
+ else return 200
+
+/mob/living/carbon/slime/proc/will_hunt(var/hunger = -1) // Check for being stopped from feeding and chasing
+ if (hunger == 2 || rabid || attacked) return 1
+ if (Leader) return 0
+ if (holding_still) return 0
+ return 1
diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm
index 0f4d205156..67f0b904ed 100644
--- a/code/modules/mob/living/carbon/metroid/metroid.dm
+++ b/code/modules/mob/living/carbon/metroid/metroid.dm
@@ -3,7 +3,8 @@
icon = 'icons/mob/slimes.dmi'
icon_state = "grey baby slime"
pass_flags = PASSTABLE
- speak_emote = list("hums")
+ var/is_adult = 0
+ speak_emote = list("telepathically chirps")
layer = 5
@@ -12,7 +13,7 @@
gender = NEUTER
update_icon = 0
- nutrition = 700 // 1000 = max
+ nutrition = 700
see_in_dark = 8
update_slimes = 0
@@ -22,67 +23,58 @@
status_flags = CANPARALYSE|CANPUSH
var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside
+ var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35
- var/powerlevel = 0 // 1-10 controls how much electricity they are generating
- var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows into an adult
- // if adult: if 10: reproduces
+ var/powerlevel = 0 // 1-10 controls how much electricity they are generating
+ var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces
+ var/number = 0 // Used to understand when someone is talking to it
var/mob/living/Victim = null // the person the slime is currently feeding on
var/mob/living/Target = null // AI variable - tells the slime to hunt this down
+ var/mob/living/Leader = null // AI variable - tells the slime to follow this person
- var/attacked = 0 // determines if it's been attacked recently. Can be any number, is a cooloff-ish variable
- var/tame = 0 // if set to 1, the slime will not eat humans ever, or attack them
- var/rabid = 0 // if set to 1, the slime will attack and eat anything it comes in contact with
+ var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable
+ var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with
+ var/holding_still = 0 // AI variable, cooloff-ish for how long it's going to stay in one place
+ var/target_patience = 0 // AI variable, cooloff-ish for how long it's going to follow its target
- var/list/Friends = list() // A list of potential friends
- var/list/FriendsWeight = list() // A list containing values respective to Friends. This determines how many times a slime "likes" something. If the slime likes it more than 2 times, it becomes a friend
+ var/list/Friends = list() // A list of friends; they are not considered targets for feeding; passed down after splitting
- // slimes pass on genetic data, so all their offspring have the same "Friends",
+ var/list/speech_buffer = list() // Last phrase said near it and person who said it
+
+ var/mood = "" // To show its face
///////////TIME FOR SUBSPECIES
var/colour = "grey"
- var/primarytype = /mob/living/carbon/slime
- var/mutationone = /mob/living/carbon/slime/orange
- var/mutationtwo = /mob/living/carbon/slime/metal
- var/mutationthree = /mob/living/carbon/slime/blue
- var/mutationfour = /mob/living/carbon/slime/purple
- var/adulttype = /mob/living/carbon/slime/adult
var/coretype = /obj/item/slime_extract/grey
-
-/mob/living/carbon/slime/adult
- name = "adult slime"
- icon = 'icons/mob/slimes.dmi'
- icon_state = "grey adult slime"
- speak_emote = list("telepathically chirps")
-
- health = 200
- gender = NEUTER
-
- update_icon = 0
- nutrition = 800 // 1200 = max
-
+ var/list/slime_mutation[4]
/mob/living/carbon/slime/New()
- var/datum/reagents/R = new/datum/reagents(100)
- reagents = R
- R.my_atom = src
- if(name == "baby slime")
- name = text("[colour] baby slime ([rand(1, 1000)])")
- else
- name = text("[colour] adult slime ([rand(1,1000)])")
- real_name = name
- spawn (1)
- regenerate_icons()
- src << "\blue Your icons have been generated!"
+ create_reagents(100)
+ spawn (0)
+ number = rand(1, 1000)
+ name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
+ icon_state = "[colour] [is_adult ? "adult" : "baby"] slime"
+ real_name = name
+ slime_mutation = mutation_table(colour)
+ mutation_chance = rand(25, 35)
+ var/sanitizedcolour = replacetext(colour, " ", "")
+ coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
..()
-/mob/living/carbon/slime/adult/New()
- //verbs.Remove(/mob/living/carbon/slime/verb/ventcrawl)
+/mob/living/carbon/slime/regenerate_icons()
+ icon_state = "[colour] [is_adult ? "adult" : "baby"] slime"
+ overlays.len = 0
+ if (mood)
+ overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]")
..()
/mob/living/carbon/slime/movement_delay()
+ if (bodytemperature >= 330.23) // 135 F
+ return -1 // slimes become supercharged at high temperatures
+
var/tally = 0
var/health_deficiency = (100 - health)
@@ -92,115 +84,93 @@
tally += (283.222 - bodytemperature) / 10 * 1.75
if(reagents)
- if(reagents.has_reagent("hyperzine")) // hyperzine slows slimes down
- tally *= 2 // moves twice as slow
+ if(reagents.has_reagent("hyperzine")) // Hyperzine slows slimes down
+ tally *= 2
- if(reagents.has_reagent("frostoil")) // frostoil also makes them move VEEERRYYYYY slow
+ if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow
tally *= 5
if(health <= 0) // if damaged, the slime moves twice as slow
tally *= 2
- if (bodytemperature >= 330.23) // 135 F
- return -1 // slimes become supercharged at high temperatures
-
- return tally+config.slime_delay
-
+ return tally + config.slime_delay
/mob/living/carbon/slime/Bump(atom/movable/AM as mob|obj, yes)
- spawn( 0 )
- if ((!( yes ) || now_pushing))
- return
- now_pushing = 1
+ if ((!(yes) || now_pushing))
+ return
+ now_pushing = 1
- if(isobj(AM))
- if(!client && powerlevel > 0)
- var/probab = 10
- switch(powerlevel)
- if(1 to 2) probab = 20
- if(3 to 4) probab = 30
- if(5 to 6) probab = 40
- if(7 to 8) probab = 60
- if(9) probab = 70
- if(10) probab = 95
- if(prob(probab))
+ if(isobj(AM))
+ if(!client && powerlevel > 0)
+ var/probab = 10
+ switch(powerlevel)
+ if(1 to 2) probab = 20
+ if(3 to 4) probab = 30
+ if(5 to 6) probab = 40
+ if(7 to 8) probab = 60
+ if(9) probab = 70
+ if(10) probab = 95
+ if(prob(probab))
+ if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille))
+ if(nutrition <= get_hunger_nutrition() && !Atkcool)
+ if (is_adult || prob(5))
+ AM.attack_slime(src)
+ spawn()
+ Atkcool = 1
+ sleep(45)
+ Atkcool = 0
+ if(ismob(AM))
+ var/mob/tmob = AM
- if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille))
- if(istype(src, /mob/living/carbon/slime/adult))
- if(nutrition <= 600 && !Atkcool)
- AM.attack_slime(src)
- spawn()
- Atkcool = 1
- sleep(15)
- Atkcool = 0
- else
- if(nutrition <= 500 && !Atkcool)
- if(prob(5))
- AM.attack_slime(src)
- spawn()
- Atkcool = 1
- sleep(15)
- Atkcool = 0
-
- if(ismob(AM))
- var/mob/tmob = AM
-
- if(istype(src, /mob/living/carbon/slime/adult))
- if(istype(tmob, /mob/living/carbon/human))
- if(prob(90))
- now_pushing = 0
- return
- else
- if(istype(tmob, /mob/living/carbon/human))
+ if(is_adult)
+ if(istype(tmob, /mob/living/carbon/human))
+ if(prob(90))
now_pushing = 0
return
+ else
+ if(istype(tmob, /mob/living/carbon/human))
+ now_pushing = 0
+ return
- now_pushing = 0
- ..()
- if (!( istype(AM, /atom/movable) ))
- return
- if (!( now_pushing ))
- now_pushing = 1
- if (!( AM.anchored ))
- var/t = get_dir(src, AM)
- if (istype(AM, /obj/structure/window))
- if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
- for(var/obj/structure/window/win in get_step(AM,t))
- now_pushing = 0
- return
- step(AM, t)
- now_pushing = null
+ now_pushing = 0
+ ..()
+ if (!istype(AM, /atom/movable))
return
- return
+ if (!( now_pushing ))
+ now_pushing = 1
+ if (!( AM.anchored ))
+ var/t = get_dir(src, AM)
+ if (istype(AM, /obj/structure/window))
+ if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
+ for(var/obj/structure/window/win in get_step(AM,t))
+ now_pushing = 0
+ return
+ step(AM, t)
+ now_pushing = null
/mob/living/carbon/slime/Process_Spacemove()
return 2
-
/mob/living/carbon/slime/Stat()
..()
statpanel("Status")
- if(istype(src, /mob/living/carbon/slime/adult))
+ if(is_adult)
stat(null, "Health: [round((health / 200) * 100)]%")
else
stat(null, "Health: [round((health / 150) * 100)]%")
-
if (client.statpanel == "Status")
- if(istype(src,/mob/living/carbon/slime/adult))
- stat(null, "Nutrition: [nutrition]/1200")
- if(amount_grown >= 10)
+ stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]")
+ if(amount_grown >= 10)
+ if(is_adult)
stat(null, "You can reproduce!")
- else
- stat(null, "Nutrition: [nutrition]/1000")
- if(amount_grown >= 10)
+ else
stat(null, "You can evolve!")
stat(null,"Power Level: [powerlevel]")
-
/mob/living/carbon/slime/adjustFireLoss(amount)
..(-abs(amount)) // Heals them
return
@@ -210,25 +180,18 @@
..(Proj)
return 0
-
/mob/living/carbon/slime/emp_act(severity)
powerlevel = 0 // oh no, the power!
..()
/mob/living/carbon/slime/ex_act(severity)
-
- if (stat == 2 && client)
- return
-
- else if (stat == 2 && !client)
- del(src)
- return
+ ..()
var/b_loss = null
var/f_loss = null
switch (severity)
if (1.0)
- b_loss += 500
+ del(src)
return
if (2.0)
@@ -260,7 +223,7 @@
//paralysis += 1
- show_message("\red The blob attacks you!")
+ show_message(" The blob attacks you!")
adjustFireLoss(damage)
@@ -271,7 +234,6 @@
/mob/living/carbon/slime/u_equip(obj/item/W as obj)
return
-
/mob/living/carbon/slime/attack_ui(slot)
return
@@ -286,52 +248,48 @@
updatehealth()
return
-
/mob/living/carbon/slime/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
- if(Victim) return // can't attack while eating!
+ if (Victim) return // can't attack while eating!
if (health > -100)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red The [M.name] has glomped []!", src), 1)
-
+ visible_message(" The [M.name] has glomped [src]!", \
+ " The [M.name] has glomped [src]!")
var/damage = rand(1, 3)
attacked += 5
- if(istype(src, /mob/living/carbon/slime/adult))
+ if(M.is_adult)
damage = rand(1, 6)
else
damage = rand(1, 3)
adjustBruteLoss(damage)
-
updatehealth()
-
return
-
/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
- for(var/mob/O in viewers(src, null))
- O.show_message("\red [M] [M.attacktext] [src]!", 1)
+ visible_message("[M] [M.attacktext] [src]!", \
+ "[M] [M.attacktext] [src]!")
M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])")
src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
+ attacked += 10
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/slime/attack_paw(mob/living/carbon/monkey/M as mob)
- if(!(istype(M, /mob/living/carbon/monkey))) return//Fix for aliens receiving double messages when attacking other aliens.
+ if(!(istype(M, /mob/living/carbon/monkey)))
+ return // Fix for aliens receiving double messages when attacking other aliens.
if (!ticker)
M << "You cannot attack people before the game has started."
@@ -340,6 +298,7 @@
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
+
..()
switch(M.a_intent)
@@ -352,9 +311,8 @@
if (health > 0)
attacked += 10
//playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [M.name] has attacked [src]!"), 1)
+ visible_message("[M.name] has attacked [src]!", \
+ "[M.name] has attacked [src]!")
adjustBruteLoss(rand(1, 3))
updatehealth()
return
@@ -374,15 +332,11 @@
if(Victim)
if(Victim == M)
if(prob(60))
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message("\red [M] attempts to wrestle \the [name] off!", 1)
+ visible_message("[M] attempts to wrestle \the [name] off!")
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
else
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message("\red [M] manages to wrestle \the [name] off!", 1)
+ visible_message(" [M] manages to wrestle \the [name] off!")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(prob(90) && !client)
@@ -402,21 +356,17 @@
else
if(prob(30))
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message("\red [M] attempts to wrestle \the [name] off of [Victim]!", 1)
+ visible_message("[M] attempts to wrestle \the [name] off of [Victim]!")
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
else
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message("\red [M] manages to wrestle \the [name] off of [Victim]!", 1)
+ visible_message(" [M] manages to wrestle \the [name] off of [Victim]!")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(prob(80) && !client)
Discipline++
- if(!istype(src, /mob/living/carbon/slime/adult))
+ if(!is_adult)
if(Discipline == 1)
attacked = 0
@@ -432,18 +382,13 @@
return
-
-
-
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message("\red [src] has been touched with the stun gloves by [M]!", 1, "\red You hear someone fall.", 2)
+ visible_message("[src] has been touched with the stun gloves by [M]!")
return
else
M << "\red Not enough charge! "
@@ -455,21 +400,18 @@
help_shake_act(M)
if ("grab")
- if (M == src)
+ if (M == src || anchored)
return
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, src )
+ var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
M.put_in_active_hand(G)
- grabbed_by += G
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
+ visible_message("[M] has grabbed [src] passively!")
else
@@ -479,8 +421,9 @@
if (prob(90))
if (HULK in M.mutations)
damage += 5
- if(Victim)
+ if(Victim || Target)
Victim = null
+ Target = null
anchored = 0
if(prob(80) && !client)
Discipline++
@@ -492,17 +435,14 @@
playsound(loc, "punch", 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has punched []!", M, src), 1)
+ visible_message("[M] has punched [src]!", \
+ "[M] has punched [src]!")
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has attempted to punch []!", M, src), 1)
+ visible_message("[M] has attempted to punch [src]!")
return
@@ -518,48 +458,41 @@
switch(M.a_intent)
if ("help")
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
+ visible_message("[M] caresses [src] with its scythe like arm.")
if ("hurt")
- if ((prob(95) && health > 0))
+ if (prob(95))
attacked += 10
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
var/damage = rand(15, 30)
if (damage >= 25)
damage = rand(20, 40)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has attacked [name]!", M), 1)
+ visible_message("[M] has attacked [name]!", \
+ "[M] has attacked [name]!")
else
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has wounded [name]!", M), 1)
+ visible_message("[M] has wounded [name]!", \
+ ")[M] has wounded [name]!")
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has attempted to lunge at [name]!", M), 1)
+ visible_message("[M] has attempted to lunge at [name]!", \
+ "[M] has attempted to lunge at [name]!")
if ("grab")
- if (M == src)
+ if (M == src || anchored)
return
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
+ var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src )
M.put_in_active_hand(G)
- grabbed_by += G
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- O.show_message(text("\red [] has grabbed [name] passively!", M), 1)
+ visible_message(" [M] has grabbed [name] passively!")
if ("disarm")
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
@@ -567,12 +500,12 @@
attacked += 10
if(prob(95))
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has tackled [name]!", M), 1)
+ visible_message("[M] has tackled [name]!", \
+ "[M] has tackled [name]!")
- if(Victim)
+ if(Victim || Target)
Victim = null
+ Target = null
anchored = 0
if(prob(80) && !client)
Discipline++
@@ -593,68 +526,123 @@
else
drop_item()
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has disarmed [name]!", M), 1)
+ visible_message("[M] has disarmed [name]!",
+ "[M] has disarmed [name]!")
adjustBruteLoss(damage)
updatehealth()
return
+/mob/living/carbon/slime/attackby(obj/item/W, mob/user)
+ if(W.force > 0)
+ attacked += 10
+ if(prob(25))
+ user << "[W] passes right through [src]!"
+ return
+ if(Discipline && prob(50)) // wow, buddy, why am I getting attacked??
+ Discipline = 0
+ if(W.force >= 3)
+ if(is_adult)
+ if(prob(5 + round(W.force/2)))
+ if(Victim || Target)
+ if(prob(80) && !client)
+ Discipline++
+
+ Victim = null
+ Target = null
+ anchored = 0
+
+ spawn()
+ SStun = 1
+ sleep(rand(5,20))
+ SStun = 0
+
+ spawn(0)
+ if(user)
+ canmove = 0
+ step_away(src, user)
+ if(prob(25 + W.force))
+ sleep(2)
+ if(user)
+ step_away(src, user)
+ canmove = 1
+
+ else
+ if(prob(10 + W.force*2))
+ if(Victim || Target)
+ if(prob(80) && !client)
+ Discipline++
+ if(Discipline == 1)
+ attacked = 0
+ spawn()
+ SStun = 1
+ sleep(rand(5,20))
+ SStun = 0
+
+ Victim = null
+ Target = null
+ anchored = 0
+
+ spawn(0)
+ if(user)
+ canmove = 0
+ step_away(src, user)
+ if(prob(25 + W.force*4))
+ sleep(2)
+ if(user)
+ step_away(src, user)
+ canmove = 1
+ ..()
/mob/living/carbon/slime/restrained()
return 0
-
mob/living/carbon/slime/var/co2overloadtime = null
mob/living/carbon/slime/var/temperature_resistance = T0C+75
-
-/mob/living/carbon/slime/show_inv(mob/user as mob)
-
- user.set_machine(src)
- var/dat = {"
-
[name]
-