mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
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.
306 lines
11 KiB
Plaintext
306 lines
11 KiB
Plaintext
#define MINOR_INSANITY_PEN 5
|
|
#define MAJOR_INSANITY_PEN 10
|
|
|
|
/datum/component/mood
|
|
var/mood //Real happiness
|
|
var/sanity = 100 //Current sanity
|
|
var/shown_mood //Shown happiness, this is what others can see when they try to examine you, prevents antag checking by noticing traitors are always very happy.
|
|
var/mood_level = 5 //To track what stage of moodies they're on
|
|
var/sanity_level = 5 //To track what stage of sanity they're on
|
|
var/mood_modifier = 1 //Modifier to allow certain mobs to be less affected by moodlets
|
|
var/datum/mood_event/list/mood_events = list()
|
|
var/insanity_effect = 0 //is the owner being punished for low mood? If so, how much?
|
|
var/obj/screen/mood/screen_obj
|
|
var/obj/screen/sanity/screen_obj_sanity
|
|
|
|
/datum/component/mood/Initialize()
|
|
if(!isliving(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
START_PROCESSING(SSmood, src)
|
|
|
|
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
|
|
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
|
|
|
|
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
|
|
var/mob/living/owner = parent
|
|
if(owner.hud_used)
|
|
modify_hud()
|
|
var/datum/hud/hud = owner.hud_used
|
|
hud.show_hud(hud.hud_version)
|
|
|
|
/datum/component/mood/Destroy()
|
|
STOP_PROCESSING(SSmood, src)
|
|
unmodify_hud()
|
|
return ..()
|
|
|
|
/datum/component/mood/proc/print_mood(mob/user)
|
|
var/msg = "<span class='info'>*---------*\n<EM>Your current mood</EM>\n"
|
|
msg += "<span class='notice'>My mental status: </span>" //Long term
|
|
switch(sanity)
|
|
if(SANITY_GREAT to INFINITY)
|
|
msg += "<span class='nicegreen'>My mind feels like a temple!<span>\n"
|
|
if(SANITY_NEUTRAL to SANITY_GREAT)
|
|
msg += "<span class='nicegreen'>I have been feeling great lately!<span>\n"
|
|
if(SANITY_DISTURBED to SANITY_NEUTRAL)
|
|
msg += "<span class='nicegreen'>I have felt quite decent lately.<span>\n"
|
|
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
|
msg += "<span class='warning'>I'm feeling a little bit unhinged...</span>\n"
|
|
if(SANITY_CRAZY to SANITY_UNSTABLE)
|
|
msg += "<span class='boldwarning'>I'm freaking out!!</span>\n"
|
|
if(SANITY_INSANE to SANITY_CRAZY)
|
|
msg += "<span class='boldwarning'>AHAHAHAHAHAHAHAHAHAH!!</span>\n"
|
|
|
|
msg += "<span class='notice'>My current mood: </span>" //Short term
|
|
switch(mood_level)
|
|
if(1)
|
|
msg += "<span class='boldwarning'>I wish I was dead!<span>\n"
|
|
if(2)
|
|
msg += "<span class='boldwarning'>I feel terrible...<span>\n"
|
|
if(3)
|
|
msg += "<span class='boldwarning'>I feel very upset.<span>\n"
|
|
if(4)
|
|
msg += "<span class='boldwarning'>I'm a bit sad.<span>\n"
|
|
if(5)
|
|
msg += "<span class='nicegreen'>I'm alright.<span>\n"
|
|
if(6)
|
|
msg += "<span class='nicegreen'>I feel pretty okay.<span>\n"
|
|
if(7)
|
|
msg += "<span class='nicegreen'>I feel pretty good.<span>\n"
|
|
if(8)
|
|
msg += "<span class='nicegreen'>I feel amazing!<span>\n"
|
|
if(9)
|
|
msg += "<span class='nicegreen'>I love life!<span>\n"
|
|
|
|
msg += "<span class='notice'>Moodlets:\n</span>"//All moodlets
|
|
if(mood_events.len)
|
|
for(var/i in mood_events)
|
|
var/datum/mood_event/event = mood_events[i]
|
|
msg += event.description
|
|
else
|
|
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.<span>\n"
|
|
to_chat(user || parent, msg)
|
|
|
|
/datum/component/mood/proc/update_mood() //Called whenever a mood event is added or removed
|
|
mood = 0
|
|
shown_mood = 0
|
|
for(var/i in mood_events)
|
|
var/datum/mood_event/event = mood_events[i]
|
|
mood += event.mood_change
|
|
if(!event.hidden)
|
|
shown_mood += event.mood_change
|
|
mood *= mood_modifier
|
|
shown_mood *= mood_modifier
|
|
|
|
switch(mood)
|
|
if(-INFINITY to MOOD_LEVEL_SAD4)
|
|
mood_level = 1
|
|
if(MOOD_LEVEL_SAD4 to MOOD_LEVEL_SAD3)
|
|
mood_level = 2
|
|
if(MOOD_LEVEL_SAD3 to MOOD_LEVEL_SAD2)
|
|
mood_level = 3
|
|
if(MOOD_LEVEL_SAD2 to MOOD_LEVEL_SAD1)
|
|
mood_level = 4
|
|
if(MOOD_LEVEL_SAD1 to MOOD_LEVEL_HAPPY1)
|
|
mood_level = 5
|
|
if(MOOD_LEVEL_HAPPY1 to MOOD_LEVEL_HAPPY2)
|
|
mood_level = 6
|
|
if(MOOD_LEVEL_HAPPY2 to MOOD_LEVEL_HAPPY3)
|
|
mood_level = 7
|
|
if(MOOD_LEVEL_HAPPY3 to MOOD_LEVEL_HAPPY4)
|
|
mood_level = 8
|
|
if(MOOD_LEVEL_HAPPY4 to INFINITY)
|
|
mood_level = 9
|
|
update_mood_icon()
|
|
|
|
|
|
/datum/component/mood/proc/update_mood_icon()
|
|
var/mob/living/owner = parent
|
|
if(owner.client && owner.hud_used)
|
|
if(sanity < 25)
|
|
screen_obj.icon_state = "mood_insane"
|
|
else
|
|
screen_obj.icon_state = "mood[mood_level]"
|
|
screen_obj_sanity.icon_state = "sanity[sanity_level]"
|
|
|
|
/datum/component/mood/process() //Called on SSmood process
|
|
var/mob/living/owner = parent
|
|
|
|
switch(mood_level)
|
|
if(1)
|
|
setSanity(sanity-0.2)
|
|
if(2)
|
|
setSanity(sanity-0.125, minimum=SANITY_CRAZY)
|
|
if(3)
|
|
setSanity(sanity-0.075, minimum=SANITY_UNSTABLE)
|
|
if(4)
|
|
setSanity(sanity-0.025, minimum=SANITY_DISTURBED)
|
|
if(5)
|
|
setSanity(sanity+0.1)
|
|
if(6)
|
|
setSanity(sanity+0.15)
|
|
if(7)
|
|
setSanity(sanity+0.2)
|
|
if(8)
|
|
setSanity(sanity+0.25, maximum=SANITY_GREAT)
|
|
if(9)
|
|
setSanity(sanity+0.4, maximum=INFINITY)
|
|
|
|
if(owner.has_trait(TRAIT_DEPRESSION))
|
|
if(prob(0.05))
|
|
add_event(null, "depression", /datum/mood_event/depression)
|
|
clear_event(null, "jolly")
|
|
if(owner.has_trait(TRAIT_JOLLY))
|
|
if(prob(0.05))
|
|
add_event(null, "jolly", /datum/mood_event/jolly)
|
|
clear_event(null, "depression")
|
|
|
|
HandleNutrition(owner)
|
|
|
|
/datum/component/mood/proc/setSanity(amount, minimum=SANITY_INSANE, maximum=SANITY_NEUTRAL)
|
|
if(amount == sanity)
|
|
return
|
|
// If we're out of the acceptable minimum-maximum range move back towards it in steps of 0.5
|
|
// If the new amount would move towards the acceptable range faster then use it instead
|
|
if(sanity < minimum && amount < sanity + 0.5)
|
|
amount = sanity + 0.5
|
|
else if(sanity > maximum && amount > sanity - 0.5)
|
|
amount = sanity - 0.5
|
|
sanity = amount
|
|
|
|
var/mob/living/master = parent
|
|
switch(sanity)
|
|
if(SANITY_INSANE to SANITY_CRAZY)
|
|
setInsanityEffect(MAJOR_INSANITY_PEN)
|
|
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1.5, movetypes=(~FLYING))
|
|
sanity_level = 6
|
|
if(SANITY_CRAZY to SANITY_UNSTABLE)
|
|
setInsanityEffect(MINOR_INSANITY_PEN)
|
|
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1, movetypes=(~FLYING))
|
|
sanity_level = 5
|
|
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
|
setInsanityEffect(0)
|
|
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=0.5, movetypes=(~FLYING))
|
|
sanity_level = 4
|
|
if(SANITY_DISTURBED to SANITY_NEUTRAL)
|
|
setInsanityEffect(0)
|
|
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
|
|
sanity_level = 3
|
|
if(SANITY_NEUTRAL+1 to SANITY_GREAT+1) //shitty hack but +1 to prevent it from responding to super small differences
|
|
setInsanityEffect(0)
|
|
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
|
|
sanity_level = 2
|
|
if(SANITY_GREAT+1 to INFINITY)
|
|
setInsanityEffect(0)
|
|
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
|
|
sanity_level = 1
|
|
update_mood_icon()
|
|
|
|
/datum/component/mood/proc/setInsanityEffect(newval)
|
|
if(newval == insanity_effect)
|
|
return
|
|
var/mob/living/master = parent
|
|
master.crit_threshold = (master.crit_threshold - insanity_effect) + newval
|
|
insanity_effect = newval
|
|
|
|
/datum/component/mood/proc/add_event(datum/source, category, type, param) //Category will override any events in the same category, should be unique unless the event is based on the same thing like hunger.
|
|
var/datum/mood_event/the_event
|
|
if(mood_events[category])
|
|
the_event = mood_events[category]
|
|
if(the_event.type != type)
|
|
clear_event(null, category)
|
|
else
|
|
if(the_event.timeout)
|
|
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
|
return 0 //Don't have to update the event.
|
|
the_event = new type(src, param)
|
|
|
|
mood_events[category] = the_event
|
|
the_event.category = category
|
|
update_mood()
|
|
|
|
if(the_event.timeout)
|
|
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
|
|
|
/datum/component/mood/proc/clear_event(datum/source, category)
|
|
var/datum/mood_event/event = mood_events[category]
|
|
if(!event)
|
|
return 0
|
|
|
|
mood_events -= category
|
|
qdel(event)
|
|
update_mood()
|
|
|
|
/datum/component/mood/proc/remove_temp_moods(var/admin) //Removes all temp moods
|
|
for(var/i in mood_events)
|
|
var/datum/mood_event/moodlet = mood_events[i]
|
|
if(!moodlet || !moodlet.timeout)
|
|
continue
|
|
mood_events -= moodlet.category
|
|
qdel(moodlet)
|
|
update_mood()
|
|
|
|
|
|
/datum/component/mood/proc/modify_hud(datum/source)
|
|
var/mob/living/owner = parent
|
|
var/datum/hud/hud = owner.hud_used
|
|
screen_obj = new
|
|
screen_obj_sanity = new
|
|
hud.infodisplay += screen_obj
|
|
hud.infodisplay += screen_obj_sanity
|
|
RegisterSignal(hud, COMSIG_PARENT_QDELETED, .proc/unmodify_hud)
|
|
RegisterSignal(screen_obj, COMSIG_CLICK, .proc/hud_click)
|
|
|
|
/datum/component/mood/proc/unmodify_hud(datum/source)
|
|
if(!screen_obj)
|
|
return
|
|
var/mob/living/owner = parent
|
|
var/datum/hud/hud = owner.hud_used
|
|
if(hud && hud.infodisplay)
|
|
hud.infodisplay -= screen_obj
|
|
hud.infodisplay -= screen_obj_sanity
|
|
QDEL_NULL(screen_obj)
|
|
QDEL_NULL(screen_obj_sanity)
|
|
|
|
/datum/component/mood/proc/hud_click(datum/source, location, control, params, mob/user)
|
|
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))
|
|
add_event(null, "nutrition", /datum/mood_event/fat)
|
|
else
|
|
add_event(null, "nutrition", /datum/mood_event/wellfed) // round and full
|
|
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
|
add_event(null, "nutrition", /datum/mood_event/wellfed)
|
|
if( NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
|
add_event(null, "nutrition", /datum/mood_event/fed)
|
|
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
|
clear_event(null, "nutrition")
|
|
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
|
add_event(null, "nutrition", /datum/mood_event/hungry)
|
|
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
|