Adds a new race: Ethereal (also adds wrappers for nutrition adjustment) (#40995)
cl Qustinnus / Floyd / Ethereal sprites by Space, is that it? / Alerts and food sprites by MrDroppodBringer
add: Adds Ethereal; a race which lives off of electricity and shines bright. If they are healthy they shine a bright green light, and the more damaged they are, the less they shine and the greyer they become. Their punches do burn damage and they are weak to blunt attacks!
They dont need to eat normal food and dont have nutrition, Instead they gain charge by going into borg rechargers, eating ethereal food or doign specific interactions.
refactor: all nutrition changes now go through a proc so we can override behavior
/cl
Adds Ethereal. A race which is essentialy inspired by Zoltan but then with different mechanics to make it fit with SS13 more. I'm trying to stay away from making them actually provide power but the change from nutrition to electricity seemed kind of fun.
They have the following specifications:
They are walking lights; and shine bright and green if healthy, and get greyer and darker the more damaged they are. When dead they are just a grey unlit corpse.
They do burn punch damage instead of blunt.
They are weaker to blunt; especially when low on charge
They have charge instead of nutrition. Charge is gained by some interactions or by going into a borg charger. or eating new ethereal food.
They are slightly stronger to shock damage, and gain charge from it a bit; however, it is still deadly to them and thus they aren't free insulated gloves.
@@ -90,6 +90,8 @@
|
||||
#define NO_DNA_COPY 14
|
||||
#define DRINKSBLOOD 15
|
||||
#define NOEYES 16
|
||||
#define DYNCOLORS 17 //Use this if you want to change the race's color without the player being able to pick their own color. AKA special color shifting
|
||||
#define AGENDER 18
|
||||
|
||||
#define ORGAN_SLOT_BRAIN "brain"
|
||||
#define ORGAN_SLOT_APPENDIX "appendix"
|
||||
|
||||
@@ -68,6 +68,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
|
||||
#define ismoth(A) (is_species(A, /datum/species/moth))
|
||||
#define ishumanbasic(A) (is_species(A, /datum/species/human))
|
||||
#define iscatperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/felinid) )
|
||||
#define isethereal(A) (is_species(A, /datum/species/ethereal))
|
||||
|
||||
//more carbon mobs
|
||||
#define ismonkey(A) (istype(A, /mob/living/carbon/monkey))
|
||||
|
||||
@@ -162,6 +162,13 @@
|
||||
//Used as an upper limit for species that continuously gain nutriment
|
||||
#define NUTRITION_LEVEL_ALMOST_FULL 535
|
||||
|
||||
//Charge levels for Ethereals
|
||||
#define ETHEREAL_CHARGE_NONE 0
|
||||
#define ETHEREAL_CHARGE_LOWPOWER 20
|
||||
#define ETHEREAL_CHARGE_NORMAL 50
|
||||
#define ETHEREAL_CHARGE_ALMOSTFULL 75
|
||||
#define ETHEREAL_CHARGE_FULL 100
|
||||
|
||||
//Slime evolution threshold. Controls how fast slimes can split/grow
|
||||
#define SLIME_EVOLUTION_THRESHOLD 10
|
||||
|
||||
@@ -252,6 +259,7 @@
|
||||
#define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you
|
||||
|
||||
#define HUNGER_FACTOR 0.1 //factor at which mob nutrition decreases
|
||||
#define ETHEREAL_CHARGE_FACTOR 0.12 //factor at which ethereal's charge decreases
|
||||
#define REAGENTS_METABOLISM 0.4 //How many units of reagent are consumed per tick, by default.
|
||||
#define REAGENTS_EFFECT_MULTIPLIER (REAGENTS_METABOLISM / 0.4) // By defining the effect multiplier this way, it'll exactly adjust all effects according to how they originally were with the 0.4 metabolism
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings, GLOB.moth_wings_list)
|
||||
|
||||
//For now we will always return none for tail_human and ears.
|
||||
return(list("mcolor" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), "tail_lizard" = pick(GLOB.tails_list_lizard), "tail_human" = "None", "wings" = "None", "snout" = pick(GLOB.snouts_list), "horns" = pick(GLOB.horns_list), "ears" = "None", "frills" = pick(GLOB.frills_list), "spines" = pick(GLOB.spines_list), "body_markings" = pick(GLOB.body_markings_list), "legs" = "Normal Legs", "caps" = pick(GLOB.caps_list), "moth_wings" = pick(GLOB.moth_wings_list)))
|
||||
return(list("mcolor" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),"ethcolor" = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)], "tail_lizard" = pick(GLOB.tails_list_lizard), "tail_human" = "None", "wings" = "None", "snout" = pick(GLOB.snouts_list), "horns" = pick(GLOB.horns_list), "ears" = "None", "frills" = pick(GLOB.frills_list), "spines" = pick(GLOB.spines_list), "body_markings" = pick(GLOB.body_markings_list), "legs" = "Normal Legs", "caps" = pick(GLOB.caps_list), "moth_wings" = pick(GLOB.moth_wings_list)))
|
||||
|
||||
/proc/random_hair_style(gender)
|
||||
switch(gender)
|
||||
@@ -116,6 +116,13 @@
|
||||
if(!findname(.))
|
||||
break
|
||||
|
||||
/proc/random_unique_ethereal_name(attempts_to_find_unique_name=10)
|
||||
for(var/i in 1 to attempts_to_find_unique_name)
|
||||
. = capitalize(ethereal_name())
|
||||
|
||||
if(!findname(.))
|
||||
break
|
||||
|
||||
/proc/random_unique_moth_name(attempts_to_find_unique_name=10)
|
||||
for(var/i in 1 to attempts_to_find_unique_name)
|
||||
. = capitalize(pick(GLOB.moth_first)) + " " + capitalize(pick(GLOB.moth_last))
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
else
|
||||
return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]"
|
||||
|
||||
/proc/ethereal_name()
|
||||
var/tempname = "[pick(GLOB.ethereal_names)] [random_capital_letter()]"
|
||||
if(prob(65))
|
||||
tempname += random_capital_letter()
|
||||
return tempname
|
||||
|
||||
/proc/plasmaman_name()
|
||||
return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]"
|
||||
|
||||
|
||||
@@ -765,3 +765,7 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
|
||||
return "twelfth"
|
||||
else
|
||||
return "[number]\th"
|
||||
|
||||
|
||||
/proc/random_capital_letter()
|
||||
return uppertext(pick(GLOB.alphabet))
|
||||
@@ -36,6 +36,8 @@ GLOBAL_LIST_EMPTY(wings_open_list)
|
||||
GLOBAL_LIST_EMPTY(r_wings_list)
|
||||
GLOBAL_LIST_EMPTY(moth_wings_list)
|
||||
GLOBAL_LIST_EMPTY(caps_list)
|
||||
|
||||
GLOBAL_LIST_INIT(color_list_ethereal, list("F Class(Green)" = "97ee63", "F2 Class (Light Green)" = "00fa9a", "F3 Class (Dark Green)" = "37835b", "M Class (Red)" = "9c3030", "M1 Class (Purple)" = "ee82ee", "G Class (Yellow)" = "fbdf56", "O Class (Blue)" = "3399ff", "A Class (Cyan)" = "00ffff"))
|
||||
|
||||
GLOBAL_LIST_INIT(ghost_forms_with_directions_list, list("ghost")) //stores the ghost forms that support directional sprites
|
||||
GLOBAL_LIST_INIT(ghost_forms_with_accessories_list, list("ghost")) //stores the ghost forms that support hair and other such things
|
||||
|
||||
@@ -16,6 +16,7 @@ GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt"))
|
||||
GLOBAL_LIST_INIT(moth_first, world.file2list("strings/names/moth_first.txt"))
|
||||
GLOBAL_LIST_INIT(moth_last, world.file2list("strings/names/moth_last.txt"))
|
||||
GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt"))
|
||||
GLOBAL_LIST_INIT(ethereal_names, world.file2list("strings/names/ethereal.txt"))
|
||||
GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt"))
|
||||
GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt"))
|
||||
GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt"))
|
||||
|
||||
@@ -479,6 +479,13 @@ Recharging stations are available in robotics, the dormitory bathrooms, and the
|
||||
desc = "Unit's power cell is running low. Recharging stations are available in robotics, the dormitory bathrooms, and the AI satellite."
|
||||
icon_state = "lowcell"
|
||||
|
||||
//Ethereal
|
||||
|
||||
/obj/screen/alert/etherealcharge
|
||||
name = "Low Blood Charge"
|
||||
desc = "Your blood's electric charge is running low, find a source of charge for your blood. Use a recharging station found in robotics or the dormitory bathrooms, or eat some Ethereal-friendly food."
|
||||
icon_state = "etherealcharge"
|
||||
|
||||
//Need to cover all use cases - emag, illegal upgrade module, malf AI hack, traitor cyborg
|
||||
/obj/screen/alert/hacked
|
||||
name = "Hacked"
|
||||
|
||||
@@ -266,6 +266,12 @@
|
||||
print_mood(user)
|
||||
|
||||
/datum/component/mood/proc/HandleNutrition(mob/living/L)
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(isethereal(H))
|
||||
HandleCharge(H)
|
||||
if(H.has_trait(TRAIT_NOHUNGER))
|
||||
return FALSE //no mood events for nutrition
|
||||
switch(L.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
if (!L.has_trait(TRAIT_VORACIOUS))
|
||||
@@ -283,5 +289,17 @@
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
add_event(null, "nutrition", /datum/mood_event/starving)
|
||||
|
||||
/datum/component/mood/proc/HandleCharge(mob/living/carbon/human/H)
|
||||
var/datum/species/ethereal/E = H.dna?.species
|
||||
switch(E.ethereal_charge)
|
||||
if(ETHEREAL_CHARGE_NONE to ETHEREAL_CHARGE_LOWPOWER)
|
||||
add_event(null, "charge", /datum/mood_event/decharged)
|
||||
if(ETHEREAL_CHARGE_LOWPOWER to ETHEREAL_CHARGE_NORMAL)
|
||||
add_event(null, "charge", /datum/mood_event/lowpower)
|
||||
if(ETHEREAL_CHARGE_NORMAL to ETHEREAL_CHARGE_ALMOSTFULL)
|
||||
clear_event(null, "charge")
|
||||
if(ETHEREAL_CHARGE_ALMOSTFULL to ETHEREAL_CHARGE_FULL)
|
||||
add_event(null, "charge", /datum/mood_event/charged)
|
||||
|
||||
#undef MINOR_INSANITY_PEN
|
||||
#undef MAJOR_INSANITY_PEN
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
for(var/datum/reagent/R in M.reagents.reagent_list) //Not just toxins!
|
||||
M.reagents.remove_reagent(R.id, actual_power)
|
||||
if(food_conversion)
|
||||
M.nutrition += 0.3
|
||||
M.adjust_nutrition(0.3)
|
||||
if(prob(2))
|
||||
to_chat(M, "<span class='notice'>You feel a mild warmth as your blood purifies itself.</span>")
|
||||
return 1
|
||||
@@ -157,7 +157,7 @@
|
||||
C.reagents.metabolize(C, can_overdose=TRUE)
|
||||
C.overeatduration = max(C.overeatduration - 2, 0)
|
||||
var/lost_nutrition = 9 - (reduced_hunger * 5)
|
||||
C.nutrition = max(C.nutrition - (lost_nutrition * HUNGER_FACTOR), 0) //Hunger depletes at 10x the normal speed
|
||||
C.adjust_nutrition(-lost_nutrition * HUNGER_FACTOR) //Hunger depletes at 10x the normal speed
|
||||
if(prob(2))
|
||||
to_chat(C, "<span class='notice'>You feel an odd gurgle in your stomach, as if it was working much faster than normal.</span>")
|
||||
return 1
|
||||
|
||||
@@ -48,4 +48,4 @@ Bonus
|
||||
else
|
||||
to_chat(M, "<span class='warning'><i>[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]</i></span>")
|
||||
M.overeatduration = max(M.overeatduration - 100, 0)
|
||||
M.nutrition = max(M.nutrition - 100, 0)
|
||||
M.adjust_nutrition(-100)
|
||||
@@ -52,7 +52,7 @@
|
||||
if(prob(3))
|
||||
to_chat(affected_mob, "<span class='warning'><i>[pick("Your stomach silently rumbles...", "Your stomach seizes up and falls limp, muscles dead and lifeless.", "You could eat a crayon")]</i></span>")
|
||||
affected_mob.overeatduration = max(affected_mob.overeatduration - 100, 0)
|
||||
affected_mob.nutrition = max(affected_mob.nutrition - 100, 0)
|
||||
affected_mob.adjust_nutrition(-100)
|
||||
if(prob(15))
|
||||
to_chat(affected_mob, "<span class='danger'>[pick("You feel uncomfortably hot...", "You feel like unzipping your jumpsuit", "You feel like taking off some clothes...")]</span>")
|
||||
affected_mob.adjust_bodytemperature(40)
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
D.visible_message("<span class='danger'>[A] has [atk_verb]ed [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
D.apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
D.apply_damage(damage, A.dna.species.attack_type, affecting, armor_block)
|
||||
|
||||
log_combat(A, D, "punched")
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
var/atom/throw_target = get_edge_target_turf(D, A.dir)
|
||||
D.throw_at(throw_target, 1, 14, A)
|
||||
D.apply_damage(10, BRUTE)
|
||||
D.apply_damage(10, A.dna.species.attack_type)
|
||||
log_combat(A, D, "kicked (CQC)")
|
||||
if(D.IsParalyzed() && !D.stat)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D]'s head, knocking [D.p_them()] out!</span>", \
|
||||
@@ -111,7 +111,7 @@
|
||||
if(I && D.temporarilyRemoveItemFromInventory(I))
|
||||
A.put_in_hands(I)
|
||||
D.adjustStaminaLoss(50)
|
||||
D.apply_damage(25, BRUTE)
|
||||
D.apply_damage(25, A.dna.species.attack_type)
|
||||
return TRUE
|
||||
|
||||
/datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -177,7 +177,7 @@
|
||||
if(I && D.temporarilyRemoveItemFromInventory(I))
|
||||
A.put_in_hands(I)
|
||||
D.Jitter(2)
|
||||
D.apply_damage(5, BRUTE)
|
||||
D.apply_damage(5, A.dna.species.attack_type)
|
||||
else
|
||||
D.visible_message("<span class='danger'>[A] attempted to disarm [D]!</span>", \
|
||||
"<span class='userdanger'>[A] attempted to disarm [D]!</span>")
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
D.visible_message("<span class='warning'>[A] karate chops [D]'s neck!</span>", \
|
||||
"<span class='userdanger'>[A] karate chops your neck, rendering you unable to speak!</span>")
|
||||
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
|
||||
D.apply_damage(5, BRUTE)
|
||||
D.apply_damage(5, A.dna.species.attack_type)
|
||||
if(D.silent <= 10)
|
||||
D.silent = CLAMP(D.silent + 10, 0, 10)
|
||||
log_combat(A, D, "neck chopped")
|
||||
@@ -131,7 +131,7 @@
|
||||
if(!(D.mobility_flags & MOBILITY_STAND))
|
||||
bonus_damage += 5
|
||||
picked_hit_type = "stomps on"
|
||||
D.apply_damage(bonus_damage, BRUTE)
|
||||
D.apply_damage(bonus_damage, A.dna.species.attack_type)
|
||||
if(picked_hit_type == "kicks" || picked_hit_type == "stomps on")
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
playsound(get_turf(D), 'sound/effects/hit_kick.ogg', 50, 1, -1)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
atk_verb = pick("punches", "smashes", "ruptures", "cracks")
|
||||
D.visible_message("<span class='danger'>[A] [atk_verb] [D] with inhuman strength, sending [D.p_them()] flying backwards!</span>", \
|
||||
"<span class='userdanger'>[A] [atk_verb] you with inhuman strength, sending you flying backwards!</span>")
|
||||
D.apply_damage(rand(15,30), BRUTE)
|
||||
D.apply_damage(rand(15,30), A.dna.species.attack_type)
|
||||
playsound(D, 'sound/effects/meteorimpact.ogg', 25, 1, -1)
|
||||
var/throwtarget = get_edge_target_turf(A, get_dir(A, get_step_away(D, A)))
|
||||
D.throw_at(throwtarget, 4, 2, A)//So stuff gets tossed around at the same time.
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
D.visible_message("<span class='danger'>[A] [atk_verb] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [atk_verb] you!</span>")
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 40, 1, -1)
|
||||
D.apply_damage(rand(5,10), BRUTE, BODY_ZONE_HEAD)
|
||||
A.apply_damage(rand(5,10), BRUTE, BODY_ZONE_HEAD)
|
||||
D.apply_damage(rand(5,10), A.dna.species.attack_type, BODY_ZONE_HEAD)
|
||||
A.apply_damage(rand(5,10), A.dna.species.attack_type, BODY_ZONE_HEAD)
|
||||
if(!istype(D.head,/obj/item/clothing/head/helmet/) && !istype(D.head,/obj/item/clothing/head/hardhat))
|
||||
D.adjustBrainLoss(5)
|
||||
A.Stun(rand(10,45))
|
||||
@@ -53,7 +53,7 @@
|
||||
atk_verb = pick("punches", "kicks", "hits", "slams into")
|
||||
D.visible_message("<span class='danger'>[A] [atk_verb] [D] with inhuman strength, sending [D.p_them()] flying backwards!</span>", \
|
||||
"<span class='userdanger'>[A] [atk_verb] you with inhuman strength, sending you flying backwards!</span>")
|
||||
D.apply_damage(rand(15,30), BRUTE)
|
||||
D.apply_damage(rand(15,30), A.dna.species.attack_type)
|
||||
playsound(get_turf(D), 'sound/effects/meteorimpact.ogg', 25, 1, -1)
|
||||
var/throwtarget = get_edge_target_turf(A, get_dir(A, get_step_away(D, A)))
|
||||
D.throw_at(throwtarget, 4, 2, A)//So stuff gets tossed around at the same time.
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the head!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you in the jaw!</span>")
|
||||
D.apply_damage(20, BRUTE, BODY_ZONE_HEAD)
|
||||
D.apply_damage(20, A.dna.species.attack_type, BODY_ZONE_HEAD)
|
||||
D.drop_all_held_items()
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
D.Stun(80)
|
||||
@@ -93,7 +93,7 @@
|
||||
"<span class='userdanger'>[A] piledrives you with their elbow!</span>")
|
||||
if(D.stat)
|
||||
D.death() //FINISH HIM!
|
||||
D.apply_damage(50, BRUTE, BODY_ZONE_CHEST)
|
||||
D.apply_damage(50, A.dna.species.attack_type, BODY_ZONE_CHEST)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1)
|
||||
return 1
|
||||
log_combat(A, D, "elbow dropped (Sleeping Carp)")
|
||||
|
||||
@@ -19,6 +19,19 @@
|
||||
description = "<span class='boldwarning'>I'm starving!</span>\n"
|
||||
mood_change = -15
|
||||
|
||||
//charge
|
||||
/datum/mood_event/charged
|
||||
description = "<span class='nicegreen'>I feel the power in my veins!</span>\n"
|
||||
mood_change = 6
|
||||
|
||||
/datum/mood_event/lowpower
|
||||
description = "<span class='warning'>My power is running low, I should go charge up somewhere.</span>\n"
|
||||
mood_change = -7
|
||||
|
||||
/datum/mood_event/decharged
|
||||
description = "<span class='boldwarning'>I'm in desperate need of some electricity!</span>\n"
|
||||
mood_change = -12
|
||||
|
||||
//Disgust
|
||||
/datum/mood_event/gross
|
||||
description = "<span class='warning'>I saw something gross.</span>\n"
|
||||
|
||||
@@ -439,7 +439,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
|
||||
if(food <= 0)
|
||||
dat += "<br>You ran out of food and starved."
|
||||
if(obj_flags & EMAGGED)
|
||||
user.nutrition = 0 //yeah you pretty hongry
|
||||
user.set_nutrition(0) //yeah you pretty hongry
|
||||
to_chat(user, "<span class='userdanger'>Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.</span>")
|
||||
if(fuel <= 0)
|
||||
dat += "<br>You ran out of fuel, and drift, slowly, into a star."
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
req_access = list(ACCESS_ROBOTICS)
|
||||
state_open = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/cyborgrecharger
|
||||
occupant_typecache = list(/mob/living/silicon/robot)
|
||||
occupant_typecache = list(/mob/living/silicon/robot, /mob/living/carbon/human)
|
||||
var/recharge_speed
|
||||
var/repairs
|
||||
|
||||
@@ -80,13 +80,13 @@
|
||||
|
||||
/obj/machinery/recharge_station/open_machine()
|
||||
. = ..()
|
||||
if(iscyborg(occupant))
|
||||
if(iscyborg(occupant) || isethereal(occupant))
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
/obj/machinery/recharge_station/close_machine()
|
||||
. = ..()
|
||||
if(occupant)
|
||||
if(iscyborg(occupant))
|
||||
if(iscyborg(occupant) || isethereal(occupant))
|
||||
use_power = ACTIVE_POWER_USE
|
||||
add_fingerprint(occupant)
|
||||
|
||||
@@ -104,13 +104,20 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/recharge_station/proc/process_occupant()
|
||||
if(occupant && iscyborg(occupant))
|
||||
if(!occupant)
|
||||
return
|
||||
if(iscyborg(occupant))
|
||||
var/mob/living/silicon/robot/R = occupant
|
||||
restock_modules()
|
||||
if(repairs)
|
||||
R.heal_bodypart_damage(repairs, repairs - 1)
|
||||
if(R.cell)
|
||||
R.cell.charge = min(R.cell.charge + recharge_speed, R.cell.maxcharge)
|
||||
if(isethereal(occupant))
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
var/datum/species/ethereal/E = H.dna?.species
|
||||
if(E)
|
||||
E.adjust_charge(recharge_speed / 70) //Around 3 per process if unupgraded
|
||||
|
||||
/obj/machinery/recharge_station/proc/restock_modules()
|
||||
if(occupant)
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
if (istype(R, /datum/reagent/consumable))
|
||||
var/datum/reagent/consumable/nutri_check = R
|
||||
if(nutri_check.nutriment_factor >0)
|
||||
H.nutrition += nutri_check.nutriment_factor * nutri_check.volume
|
||||
H.adjust_nutrition(nutri_check.nutriment_factor * nutri_check.volume)
|
||||
reagents.remove_reagent(nutri_check.id,nutri_check.volume)
|
||||
reagents.trans_to(H, reagents.total_volume, transfered_by = user)
|
||||
qdel(src)
|
||||
|
||||
@@ -197,9 +197,9 @@
|
||||
..()
|
||||
to_chat(user,"<span class='caution'>Your stomach rumbles...</span>")
|
||||
if(user.nutrition)
|
||||
user.nutrition = 200
|
||||
user.set_nutrition(200)
|
||||
if(user.nutrition <= 0)
|
||||
user.nutrition = 0
|
||||
user.set_nutrition(0)
|
||||
|
||||
/obj/item/book/granter/spell/blind
|
||||
spell = /obj/effect/proc_holder/spell/targeted/trigger/blind
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
name = "syndi-cakes"
|
||||
icon_state = "syndi_cakes"
|
||||
|
||||
/obj/item/trash/energybar
|
||||
name = "energybar wrapper"
|
||||
icon_state = "energybar"
|
||||
|
||||
/obj/item/trash/waffles
|
||||
name = "waffles tray"
|
||||
icon_state = "waffles"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
// Mutant randomizing, doesn't affect the mob appearance unless it's the specific mutant.
|
||||
H.dna.features["mcolor"] = random_short_color()
|
||||
H.dna.features["ethcolor"] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)]
|
||||
H.dna.features["tail_lizard"] = pick(GLOB.tails_list_lizard)
|
||||
H.dna.features["snout"] = pick(GLOB.snouts_list)
|
||||
H.dna.features["horns"] = pick(GLOB.horns_list)
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
changeling.trueabsorbs++
|
||||
|
||||
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
|
||||
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
|
||||
user.set_nutrition(min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED))
|
||||
|
||||
if(target.mind)//if the victim has got a mind
|
||||
// Absorb a lizard, speak Draconic.
|
||||
|
||||
@@ -180,7 +180,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
||||
if(soulsOwned.Find(soul))
|
||||
return
|
||||
soulsOwned += soul
|
||||
owner.current.nutrition = NUTRITION_LEVEL_FULL
|
||||
owner.current.set_nutrition(NUTRITION_LEVEL_FULL)
|
||||
to_chat(owner.current, "<span class='warning'>You feel satiated as you received a new soul.</span>")
|
||||
update_hud()
|
||||
switch(SOULVALUE)
|
||||
|
||||
@@ -69,7 +69,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/skin_tone = "caucasian1" //Skin color
|
||||
var/eye_color = "000" //Eye color
|
||||
var/datum/species/pref_species = new /datum/species/human() //Mutant race
|
||||
var/list/features = list("mcolor" = "FFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "ears" = "None", "wings" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs", "moth_wings" = "Plain")
|
||||
var/list/features = list("mcolor" = "FFF", "ethcolor" = "9c3030", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "ears" = "None", "wings" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs", "moth_wings" = "Plain")
|
||||
|
||||
var/list/custom_names = list()
|
||||
var/preferred_ai_core_display = "Blue"
|
||||
@@ -211,7 +211,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Name:</b> "
|
||||
dat += "<a href='?_src_=prefs;preference=name;task=input'>[real_name]</a><BR>"
|
||||
|
||||
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : "Female"]</a><BR>"
|
||||
if(!(AGENDER in pref_species.species_traits))
|
||||
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : "Female"]</a><BR>"
|
||||
dat += "<b>Age:</b> <a href='?_src_=prefs;preference=age;task=input'>[age]</a><BR>"
|
||||
|
||||
dat += "<b>Special Names:</b><BR>"
|
||||
@@ -271,6 +272,16 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
mutant_colors = TRUE
|
||||
|
||||
if(istype(pref_species, /datum/species/ethereal)) //not the best thing to do tbf but I dont know whats better.
|
||||
|
||||
if(!use_skintones)
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
|
||||
dat += "<h3>Ethereal Color</h3>"
|
||||
|
||||
dat += "<span style='border: 1px solid #161616; background-color: #[features["ethcolor"]];'> </span> <a href='?_src_=prefs;preference=color_ethereal;task=input'>Change</a><BR>"
|
||||
|
||||
|
||||
if((EYECOLOR in pref_species.species_traits) && !(NOEYES in pref_species.species_traits))
|
||||
|
||||
if(!use_skintones && !mutant_colors)
|
||||
@@ -1374,6 +1385,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
||||
|
||||
if("color_ethereal")
|
||||
var/new_etherealcolor = input(user, "Choose your ethereal color", "Character Preference") as null|anything in GLOB.color_list_ethereal
|
||||
if(new_etherealcolor)
|
||||
features["ethcolor"] = GLOB.color_list_ethereal[new_etherealcolor]
|
||||
|
||||
|
||||
if("tail_lizard")
|
||||
var/new_tail
|
||||
@@ -1703,8 +1720,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
pref_species = new /datum/species/human
|
||||
save_character()
|
||||
|
||||
character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE)
|
||||
character.dna.features = features.Copy()
|
||||
character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE)
|
||||
character.dna.real_name = character.real_name
|
||||
|
||||
if("tail_lizard" in pref_species.default_features)
|
||||
|
||||
@@ -237,6 +237,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
|
||||
WRITE_FILE(S["features["mcolor"]"] , "#FFF")
|
||||
|
||||
if(!S["feature_ethcolor"] || S["feature_ethcolor"] == "#000")
|
||||
WRITE_FILE(S["feature_ethcolor"] , "#9c3030")
|
||||
|
||||
//Character
|
||||
S["real_name"] >> real_name
|
||||
@@ -256,6 +259,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["backbag"] >> backbag
|
||||
S["uplink_loc"] >> uplink_spawn_loc
|
||||
S["feature_mcolor"] >> features["mcolor"]
|
||||
S["feature_ethcolor"] >> features["ethcolor"]
|
||||
S["feature_lizard_tail"] >> features["tail_lizard"]
|
||||
S["feature_lizard_snout"] >> features["snout"]
|
||||
S["feature_lizard_horns"] >> features["horns"]
|
||||
@@ -316,6 +320,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
if(!features["mcolor"] || features["mcolor"] == "#000")
|
||||
features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
|
||||
|
||||
if(!features["ethcolor"] || features["ethcolor"] == "#000")
|
||||
features["ethcolor"] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)]
|
||||
|
||||
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
|
||||
be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body))
|
||||
@@ -339,6 +346,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag))
|
||||
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc))
|
||||
features["mcolor"] = sanitize_hexcolor(features["mcolor"], 3, 0)
|
||||
features["ethcolor"] = copytext(features["ethcolor"],1,7)
|
||||
features["tail_lizard"] = sanitize_inlist(features["tail_lizard"], GLOB.tails_list_lizard)
|
||||
features["tail_human"] = sanitize_inlist(features["tail_human"], GLOB.tails_list_human, "None")
|
||||
features["snout"] = sanitize_inlist(features["snout"], GLOB.snouts_list)
|
||||
@@ -397,6 +405,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc)
|
||||
WRITE_FILE(S["species"] , pref_species.id)
|
||||
WRITE_FILE(S["feature_mcolor"] , features["mcolor"])
|
||||
WRITE_FILE(S["feature_ethcolor"] , features["ethcolor"])
|
||||
WRITE_FILE(S["feature_lizard_tail"] , features["tail_lizard"])
|
||||
WRITE_FILE(S["feature_human_tail"] , features["tail_human"])
|
||||
WRITE_FILE(S["feature_lizard_snout"] , features["snout"])
|
||||
|
||||
@@ -36,4 +36,4 @@
|
||||
if(foodtype & H.dna.species.toxic_food)
|
||||
to_chat(H, "<span class='warning'>You don't feel so good...</span>")
|
||||
H.adjust_disgust(25 + 30 * fraction)
|
||||
last_check_time = world.time
|
||||
last_check_time = world.time
|
||||
@@ -88,10 +88,10 @@ All foods are distributed among various categories. Use common sense.
|
||||
if(!reagents.total_volume) //Shouldn't be needed but it checks to see if it has anything left in it.
|
||||
to_chat(user, "<span class='notice'>None of [src] left, oh no!</span>")
|
||||
qdel(src)
|
||||
return 0
|
||||
return FALSE
|
||||
if(iscarbon(M))
|
||||
if(!canconsume(M, user))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/fullness = M.nutrition + 10
|
||||
for(var/datum/reagent/consumable/C in M.reagents.reagent_list) //we add the nutrition value of what we're currently digesting
|
||||
@@ -100,7 +100,7 @@ All foods are distributed among various categories. Use common sense.
|
||||
if(M == user) //If you're eating it yourself.
|
||||
if(junkiness && M.satiety < -150 && M.nutrition > NUTRITION_LEVEL_STARVING + 50 && !user.has_trait(TRAIT_VORACIOUS))
|
||||
to_chat(M, "<span class='notice'>You don't feel like eating any more junk food at the moment.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
else if(fullness <= 50)
|
||||
user.visible_message("<span class='notice'>[user] hungrily [eatverb]s \the [src], gobbling it down!</span>", "<span class='notice'>You hungrily [eatverb] \the [src], gobbling it down!</span>")
|
||||
else if(fullness > 50 && fullness < 150)
|
||||
@@ -111,7 +111,7 @@ All foods are distributed among various categories. Use common sense.
|
||||
user.visible_message("<span class='notice'>[user] unwillingly [eatverb]s a bit of \the [src].</span>", "<span class='notice'>You unwillingly [eatverb] a bit of \the [src].</span>")
|
||||
else if(fullness > (600 * (1 + M.overeatduration / 2000))) // The more you eat - the more you can eat
|
||||
user.visible_message("<span class='warning'>[user] cannot force any more of \the [src] to go down [user.p_their()] throat!</span>", "<span class='warning'>You cannot force any more of \the [src] to go down your throat!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(M.has_trait(TRAIT_VORACIOUS))
|
||||
M.changeNext_move(CLICK_CD_MELEE * 0.5) //nom nom nom
|
||||
else
|
||||
@@ -122,7 +122,7 @@ All foods are distributed among various categories. Use common sense.
|
||||
else
|
||||
M.visible_message("<span class='warning'>[user] cannot force any more of [src] down [M]'s throat!</span>", \
|
||||
"<span class='warning'>[user] cannot force any more of [src] down [M]'s throat!</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(!do_mob(user, M))
|
||||
return
|
||||
@@ -146,7 +146,7 @@ All foods are distributed among various categories. Use common sense.
|
||||
bitecount++
|
||||
On_Consume(M)
|
||||
checkLiked(fraction, M)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
@@ -132,6 +132,13 @@
|
||||
tastes = list("brains" = 1, "meat" = 1)
|
||||
foodtype = RAW | MEAT | TOXIC
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ethereal
|
||||
icon_state = "etherealmeat"
|
||||
desc = "So shiny you feel like ingesting it might make you shine too"
|
||||
filling_color = "#97ee63"
|
||||
list_reagents = list("liquidelectricity" = 3)
|
||||
tastes = list("pure electrictiy" = 2, "meat" = 1)
|
||||
foodtype = RAW | MEAT | TOXIC
|
||||
|
||||
////////////////////////////////////// OTHER MEATS ////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -281,3 +281,11 @@
|
||||
bonus_reagents = list("nutriment" = 8, "vitamin" = 1)
|
||||
tastes = list("bun" = 4, "bacon" = 2)
|
||||
foodtype = GRAIN | MEAT
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/burger/empoweredburger
|
||||
name = "empowered burger"
|
||||
desc = "It's shockingly good, if you live off of electricity that is."
|
||||
icon_state = "empoweredburger"
|
||||
list_reagents = list("nutriment" = 8, "liquidelectricity" = 5)
|
||||
tastes = list("bun" = 2, "pure electricity" = 4)
|
||||
foodtype = GRAIN | TOXIC
|
||||
@@ -92,3 +92,13 @@
|
||||
filling_color = "#F5F5DC"
|
||||
tastes = list("sweetness" = 3, "cake" = 1)
|
||||
foodtype = GRAIN | FRUIT | VEGETABLES
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/energybar
|
||||
name = "High-power energy bars"
|
||||
icon_state = "energybar"
|
||||
desc = "An energy bar with a lot of punch, you probably shouldn't eat this if you're not an Ethereal."
|
||||
trash = /obj/item/trash/energybar
|
||||
list_reagents = list("nutriment" = 3, "liquidelectricity" = 3)
|
||||
filling_color = "#97ee63"
|
||||
tastes = list("pure electricity" = 3, "fitness" = 2)
|
||||
foodtype = TOXIC
|
||||
|
||||
@@ -293,3 +293,13 @@
|
||||
|
||||
result = /obj/item/reagent_containers/food/snacks/burger/baconburger
|
||||
subcategory = CAT_BURGER
|
||||
|
||||
/datum/crafting_recipe/food/empoweredburger
|
||||
name = "Empowered Burger"
|
||||
reqs = list(
|
||||
/obj/item/stack/sheet/mineral/plasma = 2,
|
||||
/obj/item/reagent_containers/food/snacks/bun = 1
|
||||
)
|
||||
|
||||
result = /obj/item/reagent_containers/food/snacks/burger/empoweredburger
|
||||
subcategory = CAT_BURGER
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
nutrition_ratio = 1
|
||||
if(satiety > 80)
|
||||
nutrition_ratio *= 1.25
|
||||
nutrition = max(0, nutrition - nutrition_ratio * HUNGER_FACTOR)
|
||||
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
|
||||
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
|
||||
|
||||
//Effects of bloodloss
|
||||
|
||||
@@ -480,7 +480,7 @@
|
||||
playsound(get_turf(src), 'sound/effects/splat.ogg', 50, 1)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!blood)
|
||||
nutrition -= lost_nutrition
|
||||
adjust_nutrition(-lost_nutrition)
|
||||
adjustToxLoss(-3)
|
||||
for(var/i=0 to distance)
|
||||
if(blood)
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
. = ..()
|
||||
if(. && (movement_type & FLOATING)) //floating is easy
|
||||
if(has_trait(TRAIT_NOHUNGER))
|
||||
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
|
||||
set_nutrition(NUTRITION_LEVEL_FED - 1) //just less than feeling vigorous
|
||||
else if(nutrition && stat != DEAD)
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
adjust_nutrition(-(HUNGER_FACTOR/10))
|
||||
if(m_intent == MOVE_INTENT_RUN)
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
adjust_nutrition(-(HUNGER_FACTOR/10))
|
||||
|
||||
@@ -773,6 +773,7 @@
|
||||
hud_used.healthdoll.icon_state = "healthdoll_DEAD"
|
||||
|
||||
/mob/living/carbon/human/fully_heal(admin_revive = 0)
|
||||
dna?.species.spec_fully_heal(src)
|
||||
if(admin_revive)
|
||||
regenerate_limbs()
|
||||
regenerate_organs()
|
||||
@@ -869,6 +870,20 @@
|
||||
. = ..()
|
||||
. *= physiology.do_after_speed
|
||||
|
||||
/mob/living/carbon/human/updatehealth()
|
||||
. = ..()
|
||||
dna?.species.spec_updatehealth(src)
|
||||
|
||||
/mob/living/carbon/human/adjust_nutrition(var/change) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks
|
||||
if(has_trait(TRAIT_NOHUNGER))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/set_nutrition(var/change) //Seriously fuck you oldcoders.
|
||||
if(has_trait(TRAIT_NOHUNGER))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/species
|
||||
var/race = null
|
||||
|
||||
@@ -978,6 +993,9 @@
|
||||
/mob/living/carbon/human/species/lizard
|
||||
race = /datum/species/lizard
|
||||
|
||||
/mob/living/carbon/human/species/ethereal
|
||||
race = /datum/species/ethereal
|
||||
|
||||
/mob/living/carbon/human/species/lizard/ashwalker
|
||||
race = /datum/species/lizard/ashwalker
|
||||
|
||||
|
||||
@@ -477,12 +477,18 @@
|
||||
if(stat == CONSCIOUS)
|
||||
to_chat(src, "<span class='notice'>You feel your heart beating again!</span>")
|
||||
siemens_coeff *= physiology.siemens_coeff
|
||||
|
||||
dna.species.spec_electrocute_act(src, shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
|
||||
if(.)
|
||||
electrocution_animation(40)
|
||||
|
||||
/mob/living/carbon/human/emag_act(mob/user)
|
||||
.=..()
|
||||
dna?.species.spec_emag_act(src)
|
||||
|
||||
/mob/living/carbon/human/emp_act(severity)
|
||||
dna?.species.spec_emp_act(src, severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_CONTENTS)
|
||||
return
|
||||
@@ -734,20 +740,21 @@
|
||||
to_chat(src, "<span class='danger'>Your thinking is clouded and distant.</span>")
|
||||
else if(oxyloss > 30)
|
||||
to_chat(src, "<span class='danger'>You're choking!</span>")
|
||||
|
||||
switch(nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
to_chat(src, "<span class='info'>You're completely stuffed!</span>")
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
to_chat(src, "<span class='info'>You're well fed!</span>")
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(src, "<span class='info'>You're not hungry.</span>")
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
to_chat(src, "<span class='info'>You could use a bite to eat.</span>")
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
to_chat(src, "<span class='info'>You feel quite hungry.</span>")
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
to_chat(src, "<span class='danger'>You're starving!</span>")
|
||||
|
||||
if(!has_trait(TRAIT_NOHUNGER))
|
||||
switch(nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
to_chat(src, "<span class='info'>You're completely stuffed!</span>")
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
to_chat(src, "<span class='info'>You're well fed!</span>")
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(src, "<span class='info'>You're not hungry.</span>")
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
to_chat(src, "<span class='info'>You could use a bite to eat.</span>")
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
to_chat(src, "<span class='info'>You feel quite hungry.</span>")
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
to_chat(src, "<span class='danger'>You're starving!</span>")
|
||||
|
||||
if(roundstart_quirks.len)
|
||||
to_chat(src, "<span class='notice'>You have these quirks: [get_trait_string()].</span>")
|
||||
|
||||
@@ -39,6 +39,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/heatmod = 1 // multiplier for heat damage
|
||||
var/acidmod = 1 // multiplier for acid damage // yogs - Old Plant People
|
||||
var/stunmod = 1 // multiplier for stun duration
|
||||
var/attack_type = BRUTE //Type of damage attack does
|
||||
var/punchdamagelow = 0 //lowest possible punch damage
|
||||
var/punchdamagehigh = 9 //highest possible punch damage
|
||||
var/punchstunthreshold = 9//damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical
|
||||
@@ -245,6 +246,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
|
||||
/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
|
||||
// Drop the items the new species can't wear
|
||||
if((AGENDER in species_traits))
|
||||
C.gender = PLURAL
|
||||
for(var/slot_id in no_equip)
|
||||
var/obj/item/thing = C.get_item_by_slot(slot_id)
|
||||
if(thing && (!thing.species_exception || !is_type_in_list(src,thing.species_exception)))
|
||||
@@ -951,6 +954,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
////////
|
||||
|
||||
/datum/species/proc/handle_digestion(mob/living/carbon/human/H)
|
||||
if(has_trait(TRAIT_NOHUNGER))
|
||||
return //hunger is for BABIES
|
||||
|
||||
//The fucking TRAIT_FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
|
||||
if(H.has_trait(TRAIT_FAT))//I share your pain, past coder.
|
||||
@@ -982,7 +987,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
H.Jitter(5)
|
||||
hunger_rate = 3 * HUNGER_FACTOR
|
||||
hunger_rate *= H.physiology.hunger_mod
|
||||
H.nutrition = max(0, H.nutrition - hunger_rate)
|
||||
H.adjust_nutrition(-hunger_rate)
|
||||
|
||||
|
||||
if (H.nutrition > NUTRITION_LEVEL_FULL)
|
||||
@@ -1087,9 +1092,14 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
else
|
||||
. += (health_deficiency / 25)
|
||||
if(CONFIG_GET(flag/disable_human_mood))
|
||||
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
|
||||
if((hungry >= 70) && !flight) //Being hungry will still allow you to use a flightsuit/wings.
|
||||
. += hungry / 50
|
||||
if(!H.has_trait(TRAIT_NOHUNGER))
|
||||
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
|
||||
if((hungry >= 70) && !flight) //Being hungry will still allow you to use a flightsuit/wings.
|
||||
. += hungry / 50
|
||||
else if(isethereal(H))
|
||||
var/datum/species/ethereal/E = H.dna.species
|
||||
if(E.ethereal_charge <= ETHEREAL_CHARGE_NORMAL)
|
||||
. += 1.5 * (1 - E.ethereal_charge / 100)
|
||||
|
||||
//Moving in high gravity is very slow (Flying too)
|
||||
if(gravity > STANDARD_GRAVITY)
|
||||
@@ -1110,6 +1120,21 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
// ATTACK PROCS //
|
||||
//////////////////
|
||||
|
||||
/datum/species/proc/spec_updatehealth(mob/living/carbon/human/H)
|
||||
return
|
||||
|
||||
/datum/species/proc/spec_fully_heal(mob/living/carbon/human/H)
|
||||
return
|
||||
|
||||
/datum/species/proc/spec_emp_act(mob/living/carbon/human/H, severity)
|
||||
return
|
||||
|
||||
/datum/species/proc/spec_emag_act(mob/living/carbon/human/H, mob/user)
|
||||
return
|
||||
|
||||
/datum/species/proc/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
return
|
||||
|
||||
/datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(!((target.health < 0 || target.has_trait(TRAIT_FAKEDEATH)) && !(target.mobility_flags & MOBILITY_STAND)))
|
||||
target.help_shake_act(user)
|
||||
@@ -1189,7 +1214,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
|
||||
if(user.limb_destroyer)
|
||||
target.dismembering_strike(user, affecting.body_zone)
|
||||
target.apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
target.apply_damage(damage, attack_type, affecting, armor_block)
|
||||
log_combat(user, target, "punched")
|
||||
if((target.stat != DEAD) && damage >= user.dna.species.punchstunthreshold)
|
||||
target.visible_message("<span class='danger'>[user] has knocked [target] down!</span>", \
|
||||
|
||||
141
code/modules/mob/living/carbon/human/species_types/ethereal.dm
Normal file
@@ -0,0 +1,141 @@
|
||||
#define ETHEREAL_COLORS list("#00ffff", "#ffc0cb", "#9400D3", "#4B0082", "#0000FF", "#00FF00", "#FFFF00", "#FF7F00", "#FF0000")
|
||||
|
||||
/datum/species/ethereal
|
||||
name = "Ethereal"
|
||||
id = "ethereal"
|
||||
attack_verb = "burn"
|
||||
attack_sound = 'sound/weapons/etherealhit.ogg'
|
||||
miss_sound = 'sound/weapons/etherealmiss.ogg'
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ethereal
|
||||
exotic_bloodtype = "LE" //Liquid Electricity. fuck you think of something better gamer
|
||||
siemens_coeff = 0.5 //They thrive on energy
|
||||
brutemod = 1.25 //They're weak to punches
|
||||
attack_type = BURN //burn bish
|
||||
damage_overlay_type = "" //We are too cool for regular damage overlays
|
||||
species_traits = list(DYNCOLORS, NOSTOMACH, AGENDER, NO_UNDERWEAR)
|
||||
inherent_traits = list(TRAIT_NOHUNGER)
|
||||
sexes = FALSE //no fetish content allowed
|
||||
toxic_food = NONE
|
||||
var/current_color
|
||||
var/ethereal_charge = ETHEREAL_CHARGE_FULL
|
||||
var/EMPeffect = FALSE
|
||||
var/emageffect = FALSE
|
||||
var/r1
|
||||
var/g1
|
||||
var/b1
|
||||
var/static/r2 = 237
|
||||
var/static/g2 = 164
|
||||
var/static/b2 = 149
|
||||
//this is shit but how do i fix it? no clue.
|
||||
|
||||
|
||||
/datum/species/ethereal/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
|
||||
.=..()
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
default_color = "#" + H.dna.features["ethcolor"]
|
||||
r1 = GetRedPart(default_color)
|
||||
g1 = GetGreenPart(default_color)
|
||||
b1 = GetBluePart(default_color)
|
||||
spec_updatehealth(H)
|
||||
|
||||
/datum/species/ethereal/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
|
||||
.=..()
|
||||
C.set_light(0)
|
||||
|
||||
/datum/species/ethereal/random_name(gender,unique,lastname)
|
||||
if(unique)
|
||||
return random_unique_ethereal_name()
|
||||
|
||||
var/randname = ethereal_name()
|
||||
|
||||
return randname
|
||||
|
||||
/datum/species/ethereal/spec_updatehealth(mob/living/carbon/human/H)
|
||||
.=..()
|
||||
if(H.stat != DEAD && !EMPeffect)
|
||||
var/healthpercent = max(H.health, 0) / 100
|
||||
if(!emageffect)
|
||||
current_color = rgb(r2 + ((r1-r2)*healthpercent), g2 + ((g1-g2)*healthpercent), b2 + ((b1-b2)*healthpercent))
|
||||
H.set_light(1 + (2 * healthpercent), 1 + (1 * healthpercent), current_color)
|
||||
fixed_mut_color = copytext(current_color, 2)
|
||||
else
|
||||
H.set_light(0)
|
||||
fixed_mut_color = rgb(128,128,128)
|
||||
H.update_body()
|
||||
|
||||
/datum/species/ethereal/spec_emp_act(mob/living/carbon/human/H, severity)
|
||||
.=..()
|
||||
EMPeffect = TRUE
|
||||
spec_updatehealth(H)
|
||||
to_chat(H, "<span class='notice'>You feel the light of your body leave you.</span>")
|
||||
switch(severity)
|
||||
if(EMP_LIGHT)
|
||||
addtimer(CALLBACK(src, .proc/stop_emp, H), 100, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 seconds
|
||||
if(EMP_HEAVY)
|
||||
addtimer(CALLBACK(src, .proc/stop_emp, H), 200, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds
|
||||
|
||||
/datum/species/ethereal/spec_emag_act(mob/living/carbon/human/H, mob/user)
|
||||
if(emageffect)
|
||||
return
|
||||
emageffect = TRUE
|
||||
to_chat(user, "<span class='notice'>You tap [H] on the back with your card.</span>")
|
||||
H.visible_message("<span class='danger'>[H] starts flickering in an array of colors!</span>")
|
||||
handle_emag(H)
|
||||
addtimer(CALLBACK(src, .proc/stop_emag, H), 300, TIMER_UNIQUE|TIMER_OVERRIDE) //Disco mode for 30 seconds! This doesn't affect the ethereal at all besides either annoying some players, or making someone look badass.
|
||||
|
||||
|
||||
/datum/species/ethereal/spec_life(mob/living/carbon/human/H)
|
||||
.=..()
|
||||
handle_charge(H)
|
||||
|
||||
/datum/species/ethereal/spec_fully_heal(mob/living/carbon/human/H)
|
||||
.=..()
|
||||
set_charge(ETHEREAL_CHARGE_FULL)
|
||||
|
||||
/datum/species/ethereal/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
.=..()
|
||||
adjust_charge(shock_damage * siemens_coeff * 2)
|
||||
to_chat(H, "<span class='notice'>You absorb some of the shock into your body!</span>")
|
||||
|
||||
|
||||
/datum/species/ethereal/proc/stop_emp(mob/living/carbon/human/H)
|
||||
EMPeffect = FALSE
|
||||
spec_updatehealth(H)
|
||||
to_chat(H, "<span class='notice'>You feel more energized as your shine comes back.</span>")
|
||||
|
||||
|
||||
/datum/species/ethereal/proc/handle_emag(mob/living/carbon/human/H)
|
||||
if(!emageffect)
|
||||
return
|
||||
current_color = pick(ETHEREAL_COLORS)
|
||||
spec_updatehealth(H)
|
||||
addtimer(CALLBACK(src, .proc/handle_emag, H), 5) //Call ourselves every 0.5 seconds to change color
|
||||
|
||||
/datum/species/ethereal/proc/stop_emag(mob/living/carbon/human/H)
|
||||
emageffect = FALSE
|
||||
spec_updatehealth(H)
|
||||
H.visible_message("<span class='danger'>[H] stops flickering and goes back to their normal state!</span>")
|
||||
|
||||
/datum/species/ethereal/proc/handle_charge(mob/living/carbon/human/H)
|
||||
var/charge_rate = ETHEREAL_CHARGE_FACTOR
|
||||
brutemod = 1.25
|
||||
adjust_charge(-charge_rate)
|
||||
switch(ethereal_charge)
|
||||
if(ETHEREAL_CHARGE_NONE)
|
||||
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 3)
|
||||
if(ETHEREAL_CHARGE_NONE to ETHEREAL_CHARGE_LOWPOWER)
|
||||
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 2)
|
||||
apply_damage(0.5, BRUTE)
|
||||
brutemod = 1.75
|
||||
if(ETHEREAL_CHARGE_LOWPOWER to ETHEREAL_CHARGE_NORMAL)
|
||||
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 1)
|
||||
brutemod = 1.5
|
||||
else
|
||||
H.clear_alert("ethereal_charge")
|
||||
|
||||
/datum/species/ethereal/proc/adjust_charge(var/change)
|
||||
ethereal_charge = CLAMP(ethereal_charge + change, ETHEREAL_CHARGE_NONE, ETHEREAL_CHARGE_FULL)
|
||||
|
||||
/datum/species/ethereal/proc/set_charge(var/change)
|
||||
ethereal_charge = CLAMP(change, ETHEREAL_CHARGE_NONE, ETHEREAL_CHARGE_FULL)
|
||||
@@ -292,9 +292,9 @@
|
||||
if(isturf(H.loc)) //else, there's considered to be no light
|
||||
var/turf/T = H.loc
|
||||
light_amount = min(1,T.get_lumcount()) - 0.5
|
||||
H.nutrition += light_amount * 10
|
||||
H.adjust_nutrition(light_amount * 10)
|
||||
if(H.nutrition > NUTRITION_LEVEL_ALMOST_FULL)
|
||||
H.nutrition = NUTRITION_LEVEL_ALMOST_FULL
|
||||
H.set_nutrition(NUTRITION_LEVEL_ALMOST_FULL)
|
||||
if(light_amount > 0.2) //if there's enough light, heal
|
||||
H.heal_overall_damage(1,1)
|
||||
H.adjustToxLoss(-1)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
if(H.blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
if(H.nutrition >= NUTRITION_LEVEL_STARVING)
|
||||
H.blood_volume += 3
|
||||
H.nutrition -= 2.5
|
||||
H.adjust_nutrition(-2.5)
|
||||
if(H.blood_volume < BLOOD_VOLUME_OKAY)
|
||||
if(prob(5))
|
||||
to_chat(H, "<span class='danger'>You feel drained!</span>")
|
||||
@@ -170,7 +170,7 @@
|
||||
to_chat(H, "<span class='notice'>You feel very bloated!</span>")
|
||||
else if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
H.blood_volume += 3
|
||||
H.nutrition -= 2.5
|
||||
H.adjust_nutrition(-2.5)
|
||||
|
||||
..()
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
. = ..()
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.dna.features["moth_wings"] = "[(H.client && H.client.prefs && LAZYLEN(H.client.prefs.features) && H.client.prefs.features["moth_wings"]) ? H.client.prefs.features["moth_wings"] : "Plain"]"
|
||||
handle_mutant_bodyparts(H)
|
||||
|
||||
/datum/species/moth/random_name(gender,unique,lastname)
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
if(isturf(H.loc)) //else, there's considered to be no light
|
||||
var/turf/T = H.loc
|
||||
light_amount = min(1,T.get_lumcount()) - 0.5
|
||||
H.nutrition += light_amount * 10
|
||||
H.adjust_nutrition(light_amount * 10)
|
||||
if(H.nutrition > NUTRITION_LEVEL_ALMOST_FULL)
|
||||
H.nutrition = NUTRITION_LEVEL_ALMOST_FULL
|
||||
H.set_nutrition(NUTRITION_LEVEL_ALMOST_FULL)
|
||||
if(light_amount > 0.2) //if there's enough light, heal
|
||||
H.heal_overall_damage(1,1)
|
||||
H.adjustToxLoss(-1)
|
||||
@@ -64,4 +64,4 @@
|
||||
H.adjustFireLoss(rand(5,15))
|
||||
H.show_message("<span class='userdanger'>The radiation beam singes you!</span>")
|
||||
if(/obj/item/projectile/energy/florayield)
|
||||
H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL)
|
||||
H.set_nutrition(min(H.nutrition+30, NUTRITION_LEVEL_FULL))
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
respawn_progress = 0
|
||||
return
|
||||
var/turf/T = get_turf(owner)
|
||||
|
||||
if(istype(T))
|
||||
var/light_amount = T.get_lumcount()
|
||||
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
|
||||
@@ -187,6 +188,9 @@
|
||||
return
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(isethereal(AM))
|
||||
AM.emp_act(EMP_LIGHT)
|
||||
|
||||
if(iscyborg(AM))
|
||||
var/mob/living/silicon/robot/borg = AM
|
||||
if(!borg.lamp_cooldown)
|
||||
|
||||
@@ -417,7 +417,7 @@
|
||||
if(SSmobs.times_fired%3==1)
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(5)
|
||||
nutrition += 10
|
||||
adjust_nutrition(10)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -471,7 +471,7 @@
|
||||
SetParalyzed(0, FALSE)
|
||||
SetSleeping(0, FALSE)
|
||||
radiation = 0
|
||||
nutrition = NUTRITION_LEVEL_FED + 50
|
||||
set_nutrition(NUTRITION_LEVEL_FED + 50)
|
||||
bodytemperature = BODYTEMP_NORMAL
|
||||
set_blindness(0)
|
||||
set_blurriness(0)
|
||||
@@ -1209,4 +1209,4 @@
|
||||
if("resize")
|
||||
update_transform()
|
||||
if("lighting_alpha")
|
||||
sync_lighting_plane_alpha()
|
||||
sync_lighting_plane_alpha()
|
||||
@@ -239,19 +239,19 @@
|
||||
/mob/living/simple_animal/slime/proc/handle_nutrition()
|
||||
|
||||
if(docile) //God as my witness, I will never go hungry again
|
||||
nutrition = 700
|
||||
set_nutrition(700) //fuck you for using the base nutrition var
|
||||
return
|
||||
|
||||
if(prob(15))
|
||||
nutrition -= 1 + is_adult
|
||||
adjust_nutrition(-(1 + is_adult))
|
||||
|
||||
if(nutrition <= 0)
|
||||
nutrition = 0
|
||||
set_nutrition(0)
|
||||
if(prob(75))
|
||||
adjustBruteLoss(rand(0,5))
|
||||
|
||||
else if (nutrition >= get_grow_nutrition() && amount_grown < SLIME_EVOLUTION_THRESHOLD)
|
||||
nutrition -= 20
|
||||
adjust_nutrition(-20)
|
||||
amount_grown++
|
||||
update_action_buttons_icon()
|
||||
|
||||
@@ -262,7 +262,7 @@
|
||||
Evolve()
|
||||
|
||||
/mob/living/simple_animal/slime/proc/add_nutrition(nutrition_to_add = 0)
|
||||
nutrition = min((nutrition + nutrition_to_add), get_max_nutrition())
|
||||
set_nutrition(min((nutrition + nutrition_to_add), get_max_nutrition()))
|
||||
if(nutrition >= get_grow_nutrition())
|
||||
if(powerlevel<10)
|
||||
if(prob(30-powerlevel*2))
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
var/mob/living/simple_animal/slime/M
|
||||
M = new(loc, child_colour)
|
||||
if(ckey)
|
||||
M.nutrition = new_nutrition //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature!
|
||||
M.set_nutrition(new_nutrition) //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature!
|
||||
M.powerlevel = new_powerlevel
|
||||
if(i != 1)
|
||||
step_away(M,src)
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
create_reagents(100)
|
||||
set_colour(new_colour)
|
||||
. = ..()
|
||||
nutrition = 700
|
||||
set_nutrition(700)
|
||||
|
||||
/mob/living/simple_animal/slime/Destroy()
|
||||
for (var/A in actions)
|
||||
@@ -261,7 +261,7 @@
|
||||
return
|
||||
attacked += 5
|
||||
if(nutrition >= 100) //steal some nutrition. negval handled in life()
|
||||
nutrition -= (50 + (40 * M.is_adult))
|
||||
adjust_nutrition(-(50 + (40 * M.is_adult)))
|
||||
M.add_nutrition(50 + (40 * M.is_adult))
|
||||
if(health > 0)
|
||||
M.adjustBruteLoss(-10 + (-10 * M.is_adult))
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
continue
|
||||
var/datum/atom_hud/alternate_appearance/AA = v
|
||||
AA.onNewMob(src)
|
||||
nutrition = rand(NUTRITION_LEVEL_START_MIN, NUTRITION_LEVEL_START_MAX)
|
||||
set_nutrition(rand(NUTRITION_LEVEL_START_MIN, NUTRITION_LEVEL_START_MAX))
|
||||
. = ..()
|
||||
update_config_movespeed()
|
||||
update_movespeed(TRUE)
|
||||
@@ -937,6 +937,12 @@
|
||||
var/datum/language_holder/H = get_language_holder()
|
||||
H.open_language_menu(usr)
|
||||
|
||||
/mob/proc/adjust_nutrition(var/change) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks
|
||||
nutrition = max(0, nutrition + change)
|
||||
|
||||
/mob/proc/set_nutrition(var/change) //Seriously fuck you oldcoders.
|
||||
nutrition = max(0, change)
|
||||
|
||||
/mob/setMovetype(newval)
|
||||
. = ..()
|
||||
update_movespeed(FALSE)
|
||||
|
||||
@@ -449,7 +449,7 @@
|
||||
var/list/babies = list()
|
||||
for(var/i=1,i<=number,i++)
|
||||
var/mob/living/simple_animal/slime/M = new/mob/living/simple_animal/slime(loc)
|
||||
M.nutrition = round(nutrition/number)
|
||||
M.set_nutrition(round(nutrition/number))
|
||||
step_away(M,src)
|
||||
babies += M
|
||||
new_slime = pick(babies)
|
||||
|
||||
@@ -602,7 +602,13 @@
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
if(istype(H))
|
||||
|
||||
if(isethereal(H))
|
||||
to_chat(H, "<span class='notice'>You start channeling some power through the [fitting] into your body.</span>")
|
||||
if(do_after(user, 50, target = src))
|
||||
to_chat(H, "<span class='notice'>You receive some charge from the [fitting].</span>")
|
||||
H.dna?.species.adjust_charge(5)
|
||||
return
|
||||
|
||||
if(H.gloves)
|
||||
var/obj/item/clothing/gloves/G = H.gloves
|
||||
if(G.max_heat_protection_temperature)
|
||||
|
||||
@@ -1764,7 +1764,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
/datum/reagent/consumable/ethanol/fernet/on_mob_life(mob/living/carbon/M)
|
||||
if(M.nutrition <= NUTRITION_LEVEL_STARVING)
|
||||
M.adjustToxLoss(1*REM, 0)
|
||||
M.nutrition = max(M.nutrition - 5, 0)
|
||||
M.adjust_nutrition(-5)
|
||||
M.overeatduration = 0
|
||||
return ..()
|
||||
|
||||
@@ -1783,7 +1783,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
/datum/reagent/consumable/ethanol/fernet_cola/on_mob_life(mob/living/carbon/M)
|
||||
if(M.nutrition <= NUTRITION_LEVEL_STARVING)
|
||||
M.adjustToxLoss(0.5*REM, 0)
|
||||
M.nutrition = max(M.nutrition - 3, 0)
|
||||
M.adjust_nutrition(- 3)
|
||||
M.overeatduration = 0
|
||||
return ..()
|
||||
|
||||
@@ -1801,7 +1801,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
glass_desc = "A glass of Fanciulli. It's just Manhattan with Fernet."
|
||||
|
||||
/datum/reagent/consumable/ethanol/fanciulli/on_mob_life(mob/living/carbon/M)
|
||||
M.nutrition = max(M.nutrition - 5, 0)
|
||||
M.adjust_nutrition(-5)
|
||||
M.overeatduration = 0
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -638,7 +638,7 @@
|
||||
M.adjustOxyLoss(-0.5, 0)
|
||||
if(M.nutrition && (M.nutrition - 2 > 0))
|
||||
if(!(M.mind && M.mind.assigned_role == "Medical Doctor")) //Drains the nutrition of the holder. Not medical doctors though, since it's the Doctor's Delight!
|
||||
M.nutrition -= 2
|
||||
M.adjust_nutrition(-2)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
|
||||
/datum/reagent/consumable/on_mob_life(mob/living/carbon/M)
|
||||
current_cycle++
|
||||
M.nutrition += nutriment_factor
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.has_trait(TRAIT_NOHUNGER))
|
||||
H.adjust_nutrition(nutriment_factor)
|
||||
holder.remove_reagent(src.id, metabolization_rate)
|
||||
|
||||
/datum/reagent/consumable/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
@@ -626,7 +629,7 @@
|
||||
|
||||
/datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/M)
|
||||
if(M.nutrition > NUTRITION_LEVEL_FULL - 25)
|
||||
M.nutrition -= 3*nutriment_factor
|
||||
M.adjust_nutrition(-3*nutriment_factor)
|
||||
..()
|
||||
|
||||
////Lavaland Flora Reagents////
|
||||
@@ -687,3 +690,22 @@
|
||||
nutriment_factor = 5 * REAGENTS_METABOLISM
|
||||
color = "#eef442" // rgb: 238, 244, 66
|
||||
taste_description = "mournful honking"
|
||||
|
||||
|
||||
/datum/reagent/consumable/liquidelectricity
|
||||
name = "Liquid Electricity"
|
||||
id = "liquidelectricity"
|
||||
description = "The blood of Ethereals, and the stuff that keeps them going. Great for them, horrid for anyone else."
|
||||
nutriment_factor = 5 * REAGENTS_METABOLISM
|
||||
color = "#97ee63"
|
||||
taste_description = "pure electrictiy"
|
||||
|
||||
/datum/reagent/consumable/liquidelectricity/on_mob_life(mob/living/carbon/M)
|
||||
if(isethereal(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/species/ethereal/E = H.dna?.species
|
||||
E.adjust_charge(5*REM)
|
||||
else if(prob(25)) //scp13 optimization
|
||||
M.electrocute_act(rand(10,15), "Liquid Electricity in their body", 1) //lmao at the newbs who eat energy bars
|
||||
playsound(M, "sparks", 50, 1)
|
||||
return ..()
|
||||
@@ -357,7 +357,7 @@
|
||||
/datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
|
||||
if(iscarbon(M) && M.stat != DEAD)
|
||||
if(method in list(INGEST, VAPOR, INJECT))
|
||||
M.nutrition -= 5
|
||||
M.adjust_nutrition(-5)
|
||||
if(show_message)
|
||||
to_chat(M, "<span class='warning'>Your stomach feels empty and cramps!</span>")
|
||||
else
|
||||
|
||||
@@ -660,7 +660,7 @@
|
||||
/datum/reagent/toxin/lipolicide/on_mob_life(mob/living/carbon/M)
|
||||
if(M.nutrition <= NUTRITION_LEVEL_STARVING)
|
||||
M.adjustToxLoss(1*REM, 0)
|
||||
M.nutrition = max(M.nutrition - 3, 0) // making the chef more valuable, one meme trap at a time
|
||||
M.adjust_nutrition(-3) // making the chef more valuable, one meme trap at a time
|
||||
M.overeatduration = 0
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@
|
||||
/obj/item/reagent_containers/blood/lizard
|
||||
blood_type = "L"
|
||||
|
||||
/obj/item/reagent_containers/blood/ethereal
|
||||
blood_type = "LE"
|
||||
|
||||
/obj/item/reagent_containers/blood/universal
|
||||
blood_type = "U"
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/nanite_program/metabolic_synthesis/active_effect()
|
||||
host_mob.nutrition -= 0.5
|
||||
host_mob.adjust_nutrition(-0.5)
|
||||
|
||||
/datum/nanite_program/triggered/access
|
||||
name = "Subdermal ID"
|
||||
|
||||
@@ -866,7 +866,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
healing_types += CLONE
|
||||
|
||||
owner.apply_damage_type(-heal_amount, damagetype=pick(healing_types))
|
||||
owner.nutrition += 3
|
||||
owner.adjust_nutrition(3)
|
||||
M.adjustCloneLoss(heal_amount * 1.2) //This way, two people can't just convert each other's damage away.
|
||||
else
|
||||
messagedelivered = FALSE
|
||||
|
||||
@@ -36,7 +36,7 @@ Burning extracts:
|
||||
S.visible_message("<span class='danger'>A baby slime emerges from [src], and it nuzzles [user] before burbling hungrily!</span>")
|
||||
S.Friends[user] = 20 //Gas, gas, gas
|
||||
S.bodytemperature = T0C + 400 //We gonna step on the gas.
|
||||
S.nutrition = S.get_hunger_nutrition() //Tonight, we fight!
|
||||
S.set_nutrition(S.get_hunger_nutrition()) //Tonight, we fight!
|
||||
..()
|
||||
|
||||
/obj/item/slimecross/burning/orange
|
||||
|
||||
@@ -128,7 +128,7 @@ Regenerative extracts:
|
||||
colour = "silver"
|
||||
|
||||
/obj/item/slimecross/regenerative/silver/core_effect(mob/living/target, mob/user)
|
||||
target.nutrition = NUTRITION_LEVEL_FULL - 1
|
||||
target.set_nutrition(NUTRITION_LEVEL_FULL - 1)
|
||||
to_chat(target, "<span class='notice'>You feel satiated.</span>")
|
||||
|
||||
/obj/item/slimecross/regenerative/bluespace
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
/obj/item/slime_extract/purple/activate(mob/living/carbon/human/user, datum/species/jelly/luminescent/species, activation_type)
|
||||
switch(activation_type)
|
||||
if(SLIME_ACTIVATE_MINOR)
|
||||
user.nutrition += 50
|
||||
user.adjust_nutrition(50)
|
||||
user.blood_volume += 50
|
||||
to_chat(user, "<span class='notice'>You activate [src], and your body is refilled with fresh slime jelly!</span>")
|
||||
return 150
|
||||
@@ -635,7 +635,7 @@
|
||||
return
|
||||
|
||||
M.docile = 1
|
||||
M.nutrition = 700
|
||||
M.set_nutrition(700)
|
||||
to_chat(M, "<span class='warning'>You absorb the potion and feel your intense desire to feed melt away.</span>")
|
||||
to_chat(user, "<span class='notice'>You feed the slime the potion, removing its hunger and calming it.</span>")
|
||||
var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN)
|
||||
|
||||
@@ -320,7 +320,7 @@
|
||||
body_gender = H.gender
|
||||
should_draw_gender = S.sexes
|
||||
|
||||
if(MUTCOLORS in S.species_traits)
|
||||
if((MUTCOLORS in S.species_traits) || (DYNCOLORS in S.species_traits))
|
||||
if(S.fixed_mut_color)
|
||||
species_color = S.fixed_mut_color
|
||||
else
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
user.visible_message("[user] extracts [target]'s fat!", "<span class='notice'>You extract [target]'s fat.</span>")
|
||||
target.overeatduration = 0 //patient is unfatted
|
||||
var/removednutriment = target.nutrition
|
||||
target.nutrition = NUTRITION_LEVEL_WELL_FED
|
||||
target.set_nutrition(NUTRITION_LEVEL_WELL_FED)
|
||||
removednutriment -= 450 //whatever was removed goes into the meat
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/typeofmeat = /obj/item/reagent_containers/food/snacks/meat/slab/human
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
if(owner.nutrition <= hunger_threshold)
|
||||
synthesizing = TRUE
|
||||
to_chat(owner, "<span class='notice'>You feel less hungry...</span>")
|
||||
owner.nutrition += 50
|
||||
owner.adjust_nutrition(50)
|
||||
addtimer(CALLBACK(src, .proc/synth_cool), 50)
|
||||
|
||||
/obj/item/organ/cyberimp/chest/nutriment/proc/synth_cool()
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
/obj/item/reagent_containers/food/snacks/chips = 6,
|
||||
/obj/item/reagent_containers/food/snacks/sosjerky = 6,
|
||||
/obj/item/reagent_containers/food/snacks/no_raisin = 6,
|
||||
/obj/item/reagent_containers/food/drinks/dry_ramen = 3)
|
||||
/obj/item/reagent_containers/food/drinks/dry_ramen = 3,
|
||||
/obj/item/reagent_containers/food/snacks/energybar = 6)
|
||||
contraband = list(/obj/item/reagent_containers/food/snacks/syndicake = 6)
|
||||
refill_canister = /obj/item/vending_refill/snack
|
||||
var/chef_compartment_access = "28" //ACCESS_KITCHEN
|
||||
|
||||
@@ -71,4 +71,4 @@
|
||||
user.adjustCloneLoss(-hp_gained, 0)
|
||||
user.updatehealth()
|
||||
user.adjustBrainLoss(-hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!"
|
||||
user.nutrition = min(user.nutrition + hp_gained, NUTRITION_LEVEL_FULL)
|
||||
user.set_nutrition(min(user.nutrition + hp_gained, NUTRITION_LEVEL_FULL))
|
||||
|
||||
@@ -438,6 +438,7 @@ ROUNDSTART_RACES plasmaman
|
||||
#ROUNDSTART_RACES shadow
|
||||
|
||||
## Races that are better than humans in some ways, but worse in others
|
||||
ROUNDSTART_RACES ethereal
|
||||
#ROUNDSTART_RACES jelly
|
||||
#ROUNDSTART_RACES golem
|
||||
#ROUNDSTART_RACES adamantine
|
||||
|
||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 24 KiB |
BIN
sound/weapons/etherealhit.ogg
Normal file
BIN
sound/weapons/etherealmiss.ogg
Normal file
38
strings/names/ethereal.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
Aten
|
||||
Apollo
|
||||
Arche
|
||||
Atlas
|
||||
Eos
|
||||
Halo
|
||||
Kale
|
||||
Nysa
|
||||
Orion
|
||||
Pallas
|
||||
Rigel
|
||||
Themis
|
||||
Aurora
|
||||
Andromeda
|
||||
Lyra
|
||||
Saggitarius
|
||||
Crux
|
||||
Canis
|
||||
Cygnus
|
||||
Corvus
|
||||
Cepheus
|
||||
Auriga
|
||||
Corona
|
||||
Aquilla
|
||||
Serpens
|
||||
Cetus
|
||||
Puppis
|
||||
Ophiuchus
|
||||
Carina
|
||||
Cassiopeia
|
||||
Canes
|
||||
Fornax
|
||||
Berenices
|
||||
Coma
|
||||
Vela
|
||||
Triangulum
|
||||
Tau
|
||||
Ceti
|
||||
@@ -1935,6 +1935,7 @@
|
||||
#include "code\modules\mob\living\carbon\human\species_types\angel.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species_types\corporate.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species_types\dullahan.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species_types\ethereal.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species_types\felinid.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species_types\flypeople.dm"
|
||||
#include "code\modules\mob\living\carbon\human\species_types\golems.dm"
|
||||
|
||||