Merge pull request #3487 from Crazylemon64/slime_fancy_stuff

Fancy Slime People features
This commit is contained in:
Fox McCloud
2016-03-08 20:18:51 -05:00
8 changed files with 265 additions and 45 deletions
@@ -104,6 +104,13 @@
desc = "A complex, organic knot of jelly and crystalline particles."
icon = 'icons/mob/slimes.dmi'
icon_state = "green slime extract"
// parent_organ = "chest" Hello I am from the ministry of rubber forehead aliens how are you
/obj/item/organ/brain/slime/take_damage(var/amount, var/silent = 1)
//Slimes are 150% more vulnerable to brain damage
damage = between(0, src.damage + (1.5*amount), max_damage) //Since they take the damage twice, this is +150%
return ..()
/obj/item/organ/internal/brain/golem
name = "Runic mind"
@@ -1490,6 +1490,8 @@
if(species.default_language)
remove_language(species.default_language)
species.handle_pre_change(src)
species = all_species[new_species]
if(oldspecies)
+10 -7
View File
@@ -70,6 +70,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
handle_pain()
handle_heartbeat()
handle_heartattack()
species.handle_life(src)
if(!client)
species.handle_npc(src)
@@ -457,19 +458,20 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
//Body temperature is too hot.
fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode
var/mult = species.hot_env_multiplier
if(bodytemperature >= species.heat_level_1 && bodytemperature <= species.heat_level_2)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
if(bodytemperature > species.heat_level_2 && bodytemperature <= species.heat_level_3)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
if(bodytemperature > species.heat_level_3 && bodytemperature < INFINITY)
if(on_fire)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire")
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire")
fire_alert = max(fire_alert, 2)
else
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
else if(bodytemperature < species.cold_level_1)
@@ -479,14 +481,15 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(stat == DEAD) return 1 //ZomgPonies -- No need for cold burn damage if dead
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/mult = species.cold_env_multiplier
if(bodytemperature >= species.cold_level_2 && bodytemperature <= species.cold_level_1)
take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature")
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
if(bodytemperature >= species.cold_level_3 && bodytemperature < species.cold_level_2)
take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature")
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
if(bodytemperature > -INFINITY && bodytemperature < species.cold_level_3)
take_overall_damage(burn=COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature")
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
// Account for massive pressure differences. Done by Polymorph
@@ -32,10 +32,12 @@
var/cold_level_1 = 260 // Cold damage level 1 below this point.
var/cold_level_2 = 200 // Cold damage level 2 below this point.
var/cold_level_3 = 120 // Cold damage level 3 below this point.
var/cold_env_multiplier = 1 // Damage multiplier for being in a cold environment
var/heat_level_1 = 360 // Heat damage level 1 above this point.
var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 460 // Heat damage level 3 above this point; used for body temperature
var/hot_env_multiplier = 1 // Damage multiplier for being in a hot environment
var/heat_level_3_breathe = 1000 // Heat damage level 3 above this point; used for breathed air temperature
var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing)
@@ -128,6 +130,7 @@
"r_foot" = list("path" = /obj/item/organ/external/foot/right)
)
var/cyborg_type = "Cyborg"
var/list/proc/species_abilities = list()
/datum/species/New()
//If the species has eyes, they are the default vision organ
@@ -294,33 +297,60 @@
switch(breath.temperature)
if(-INFINITY to cold_level_3)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Cold")
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
if(cold_level_3 to cold_level_2)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Cold")
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
if(cold_level_2 to cold_level_1)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Cold")
H.apply_damage(cold_env_multiplier*COLD_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
if(heat_level_1 to heat_level_2)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Heat")
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
if(heat_level_2 to heat_level_3_breathe)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Heat")
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
if(heat_level_3_breathe to INFINITY)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
return
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/C) //Handles anything not already covered by basic species assignment.
grant_abilities(C)
return
/datum/species/proc/grant_abilities(var/mob/living/carbon/human/H)
for(var/proc/ability in species_abilities)
H.verbs += ability
return
/datum/species/proc/handle_pre_change(var/mob/living/carbon/human/H)
remove_abilities(H)
return
/datum/species/proc/remove_abilities(var/mob/living/carbon/human/H)
for (var/proc/ability in species_abilities)
H.verbs -= ability
return
// Do species-specific reagent handling here
// Return 1 if it should do normal processing too
// Return 0 if it shouldn't deplete and do its normal effect
// Other return values will cause weird badness
/datum/species/proc/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R)
return 1
// For special snowflake species effects
// (Slime People changing color based on the reagents they consume)
/datum/species/proc/handle_life(var/mob/living/carbon/human/H)
return 1
/datum/species/proc/handle_dna(var/mob/living/carbon/C, var/remove) //Handles DNA mutations, as that doesn't work at init. Make sure you call genemutcheck on any blocks changed here
return
@@ -613,10 +643,3 @@ It'll return null if the organ doesn't correspond, so include null checks when u
if(!(organ_slot in has_organ))
return null
return has_organ[organ_slot]
// Do species-specific reagent handling here
// Return 1 if it should do normal processing too
// Return 0 if it shouldn't deplete and do its normal effect
// Other return values will cause weird badness
/datum/species/proc/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R)
return 1
@@ -367,6 +367,12 @@
path = /mob/living/carbon/human/slime
unarmed_type = /datum/unarmed_attack/punch
// More sensitive to the cold
cold_level_1 = 280
cold_level_2 = 240
cold_level_3 = 200
cold_env_multiplier = 3
flags = IS_WHITELISTED | NO_BREATHE | HAS_LIPS | NO_INTORGANS | NO_SCAN
clothing_flags = HAS_SOCKS
bodyflags = HAS_SKIN_COLOR | NO_EYES
@@ -381,8 +387,158 @@
suicide_messages = list(
"is melting into a puddle!",
"is turning a dull, brown color and melting into a puddle!",
"is ripping out their own core!")
"is ripping out their own core!",
"is turning a dull, brown color and melting into a puddle!")
var/list/mob/living/carbon/human/recolor_list = list()
species_abilities = list(
/mob/living/carbon/human/verb/toggle_recolor_verb,
/mob/living/carbon/human/proc/regrow_limbs
)
/datum/species/slime/handle_life(var/mob/living/carbon/human/H)
//This is allegedly for code "style". Like a plaid sweater?
#define SLIMEPERSON_COLOR_SHIFT_TRIGGER 0.1
#define SLIMEPERSON_ICON_UPDATE_PERIOD 200 // 20 seconds
#define SLIMEPERSON_BLOOD_SCALING_FACTOR 5 // Used to adjust how much of an effect the blood has on the rate of color change. Higher is slower.
// Slowly shifting to the color of the reagents
if((H in recolor_list) && H.reagents.total_volume > SLIMEPERSON_COLOR_SHIFT_TRIGGER)
var/blood_amount = H.vessel.total_volume
var/r_color = mix_color_from_reagents(H.reagents.reagent_list)
var/new_body_color = BlendRGB(r_color, rgb(H.r_skin, H.g_skin, H.b_skin), (blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)/((blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)+(H.reagents.total_volume)))
var/list/new_color_list = ReadRGB(new_body_color)
H.r_skin = new_color_list[1]
H.g_skin = new_color_list[2]
H.b_skin = new_color_list[3]
if(world.time % SLIMEPERSON_ICON_UPDATE_PERIOD > SLIMEPERSON_ICON_UPDATE_PERIOD - 20) // The 20 is because this gets called every 2 seconds, from the mob controller
for(var/organname in H.organs_by_name)
var/obj/item/organ/external/E = H.organs_by_name[organname]
if(istype(E) && E.dna.species == "Slime People")
E.sync_colour_to_human(H)
H.update_hair(0)
H.update_body()
return ..()
#undef SLIMEPERSON_COLOR_SHIFT_TRIGGER
#undef SLIMEPERSON_ICON_UPDATE_PERIOD
#undef SLIMEPERSON_BLOOD_SCALING_FACTOR
/mob/living/carbon/human/proc/toggle_recolor(var/silent = 0)
var/datum/species/slime/S = all_species[get_species()]
if(!istype(S))
if(!silent)
src << "You're not a slime person!"
return
if(src in S.recolor_list)
S.recolor_list -= src
if(!silent)
src << "You adjust your internal chemistry to filter out pigments from things you consume."
else
S.recolor_list += src
if(!silent)
src << "You adjust your internal chemistry to permit pigments in chemicals you consume to tint you."
/mob/living/carbon/human/verb/toggle_recolor_verb()
set category = "IC"
set name = "Toggle Reagent Recoloring"
set desc = "While active, you'll slowly adjust your body's color to that of the reagents inside of you, moderated by how much blood you have."
toggle_recolor()
/mob/living/carbon/human/proc/regrow_limbs()
set category = "IC"
set name = "Regrow Limbs"
set desc = "Regrow one of your missing limbs at the cost of a large amount of hunger"
#define SLIMEPERSON_HUNGERCOST 125
#define SLIMEPERSON_MINHUNGER 300
#define SLIMEPERSON_REGROWTHDELAY 450 // 45 seconds
if(stat || paralysis || stunned)
src << "<span class='warning'>You cannot regenerate missing limbs in your current state.</span>"
return
if(nutrition < SLIMEPERSON_MINHUNGER)
src << "<span class='warning'>You're too hungry to regenerate a limb!</span>"
return
var/list/missing_limbs = list()
for(var/l in organs_by_name)
var/obj/item/organ/external/E = organs_by_name[l]
if(!istype(E) || istype(E, /obj/item/organ/external/stump))
var/list/limblist = species.has_limbs[l]
var/obj/item/organ/external/limb = limblist["path"]
var/parent_organ = initial(limb.parent_organ)
var/obj/item/organ/external/parentLimb = organs_by_name[parent_organ]
if(!istype(parentLimb) || parentLimb.is_stump())
continue
missing_limbs[initial(limb.name)] = l
if(!missing_limbs.len)
src << "<span class='warning'>You're not missing any limbs!</span>"
return
var/limb_select = input(src, "Choose a limb to regrow", "Limb Regrowth") as null|anything in missing_limbs
var/chosen_limb = missing_limbs[limb_select]
visible_message("<span class='notice'>[src] begins to hold still and concentrate on their missing [limb_select]...</span>", "<span class='notice'>You begin to focus on regrowing your missing [limb_select]... (This will take [round(SLIMEPERSON_REGROWTHDELAY/10)] seconds, and you must hold still.)</span>")
if(do_after(src, SLIMEPERSON_REGROWTHDELAY, needhand=0, target = src))
if(stat || paralysis || stunned)
src << "<span class='warning'>You cannot regenerate missing limbs in your current state.</span>"
return
if(nutrition < SLIMEPERSON_MINHUNGER)
src << "<span class='warning'>You're too hungry to regenerate a limb!</span>"
return
var/obj/item/organ/external/O = organs_by_name[chosen_limb]
var/stored_brute = 0
var/stored_burn = 0
if(istype(O))
if(!O.is_stump())
src << "<span class='warning'>Your limb has already been replaced in some way!</span>"
return
else
src << "<span class='warning'>You distribute the damaged tissue around your body, out of the way of your new pseudopod!</span>"
var/obj/item/organ/external/doomedStump = O
stored_brute = doomedStump.brute_dam
stored_burn = doomedStump.burn_dam
qdel(O)
var/limb_list = species.has_limbs[chosen_limb]
var/obj/item/organ/external/limb_path = limb_list["path"]
// Parent check
var/obj/item/organ/external/potential_parent = organs_by_name[initial(limb_path.parent_organ)]
if(!istype(potential_parent) || potential_parent.is_stump())
src << "<span class='danger'>You've lost the organ that you've been growing your new part on!</span>"
return // No rayman for you
// Grah this line will leave a "not used" warning, in spite of the fact that the new() proc WILL do the thing.
// Bothersome.
var/obj/item/organ/external/new_limb = new limb_path(src)
new_limb.open = 0 // This is just so that the compiler won't think that new_limb is unused, because the compiler is horribly stupid.
adjustBruteLoss(stored_brute)
adjustFireLoss(stored_burn)
update_body()
updatehealth()
UpdateDamageIcon()
nutrition -= SLIMEPERSON_HUNGERCOST
visible_message("<span class='notice'>[src] finishes regrowing their missing [new_limb]!</span>", "<span class='notice'>You finish regrowing your [limb_select]</span>")
else
src << "<span class='warning'>You need to hold still in order to regrow a limb!</span>"
return
#undef SLIMEPERSON_HUNGERCOST
#undef SLIMEPERSON_MINHUNGER
#undef SLIMEPERSON_REGROWTHDELAY
/datum/species/slime/handle_pre_change(var/mob/living/carbon/human/H)
..()
if(H in recolor_list)
H.toggle_recolor(silent = 1)
/datum/species/grey
name = "Grey"
@@ -486,8 +642,8 @@
suicide_messages = list(
"is losing branches!",
"is pulling themselves apart!",
"pulls out a secret stash of herbicide and takes a hearty swig!")
"pulls out a secret stash of herbicide and takes a hearty swig!",
"is pulling themselves apart!")
/datum/species/diona/can_understand(var/mob/other)
var/mob/living/simple_animal/diona/D = other
@@ -586,15 +742,15 @@
"is powering down!",
"is smashing their own monitor!",
"is twisting their own neck!",
"is blocking their ventilation port!",
"is downloading extra RAM!",
"is frying their own circuits!")
"is frying their own circuits!",
"is blocking their ventilation port!")
species_abilities = list(
/mob/living/carbon/human/proc/change_monitor
)
/datum/species/machine/handle_death(var/mob/living/carbon/human/H)
H.h_style = ""
spawn(100)
if(H) H.update_hair()
/datum/species/machine/handle_post_spawn(var/mob/living/carbon/human/H)
..()
H.verbs += /mob/living/carbon/human/proc/change_monitor
if(H) H.update_hair()