Merge pull request #5753 from Citadel-Station-13/upstream-merge-35440

[MIRROR] Adds minor roundstart traits! (ala CDDA, etc.)
This commit is contained in:
LetterJay
2018-03-02 23:37:41 -06:00
committed by GitHub
36 changed files with 810 additions and 52 deletions
+6
View File
@@ -32,6 +32,12 @@
font_color = "red"
prayer_type = "CULTIST PRAYER"
deity = "Nar-Sie"
else if(isliving(usr))
var/mob/living/L = usr
if(L.has_trait(TRAIT_SPIRITUAL))
cross.icon_state = "holylight"
font_color = "blue"
prayer_type = "SPIRITUAL PRAYER"
msg = "<span class='adminnotice'>[icon2html(cross, GLOB.admins)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> [msg]</span>"
+131
View File
@@ -149,6 +149,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//Mob preview
var/icon/preview_icon = null
//Trait list
var/list/positive_traits = list()
var/list/negative_traits = list()
var/list/neutral_traits = list()
var/list/all_traits = list()
var/list/character_traits = list()
//Jobs, uses bitflags
var/job_civilian_high = 0
var/job_civilian_med = 0
@@ -252,6 +259,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<center><h2>Occupation Choices</h2>"
dat += "<a href='?_src_=prefs;preference=job;task=menu'>Set Occupation Preferences</a><br></center>"
if(CONFIG_GET(flag/roundstart_traits))
dat += "<center><h2>Trait Setup</h2>"
dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Traits</a><br></center>"
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>"
dat += "<h2>Identity</h2>"
dat += "<table width='100%'><tr><td width='75%' valign='top'>"
if(jobban_isbanned(user, "appearance"))
@@ -868,6 +879,65 @@ GLOBAL_LIST_EMPTY(preferences_datums)
return job_engsec_low
return 0
/datum/preferences/proc/SetTraits(mob/user)
if(!SStraits)
to_chat(user, "<span class='danger'>The trait subsystem is still initializing! Try again in a minute.</span>")
return
var/list/dat = list()
if(!SStraits.traits.len)
dat += "The trait subsystem hasn't finished initializing, please hold..."
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center><br>"
else
dat += "<center><b>Choose trait setup</b></center><br>"
dat += "<div align='center'>Left-click to add or remove traits. You need one negative trait for every positive trait.<br>\
Traits are applied at roundstart and cannot normally be removed.</div>"
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center>"
dat += "<hr>"
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>"
/*dat += "<center><font color='#AAFFAA'>[positive_traits.len] / [MAX_POSITIVE_TRAITS]</font> \
| <font color='#AAAAFF'>[neutral_traits.len] / [MAX_NEUTRAL_TRAITS]</font> \
| <font color='#FFAAAA'>[negative_traits.len] / [MAX_NEGATIVE_TRAITS]</font></center><br>"*/
dat += "<center>[all_traits.len] / [MAX_TRAITS] max traits<br>\
<b>Trait balance remaining:</b> [GetTraitBalance()]</center><br>"
for(var/V in SStraits.traits)
var/datum/trait/T = SStraits.traits[V]
var/trait_name = initial(T.name)
var/has_trait
var/trait_cost = initial(T.value) * -1
for(var/_V in all_traits)
if(_V == trait_name)
has_trait = TRUE
if(has_trait)
trait_cost *= -1 //invert it back, since we'd be regaining this amount
if(trait_cost > 0)
trait_cost = "+[trait_cost]"
var/font_color = "#AAAAFF"
if(initial(T.value) != 0)
font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA"
if(has_trait)
dat += "<b><font color='[font_color]'>[trait_name]</font></b> - [initial(T.desc)] \
<a href='?_src_=prefs;preference=trait;task=update;trait=[trait_name]'>[has_trait ? "Lose" : "Take"] ([trait_cost] pts.)</a><br>"
else
dat += "<font color='[font_color]'>[trait_name]</font> - [initial(T.desc)] \
<a href='?_src_=prefs;preference=trait;task=update;trait=[trait_name]'>[has_trait ? "Lose" : "Take"] ([trait_cost] pts.)</a><br>"
dat += "<br><center><a href='?_src_=prefs;preference=trait;task=reset'>Reset Traits</a></center>"
user << browse(null, "window=preferences")
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Trait Preferences</div>", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way
popup.set_window_options("can_close=0")
popup.set_content(dat.Join())
popup.open(0)
return
/datum/preferences/proc/GetTraitBalance()
var/bal = 0
for(var/V in all_traits)
var/datum/trait/T = SStraits.traits[V]
bal -= initial(T.value)
return bal
/datum/preferences/proc/process_link(mob/user, list/href_list)
if(href_list["jobbancheck"])
var/job = sanitizeSQL(href_list["jobbancheck"])
@@ -915,6 +985,64 @@ GLOBAL_LIST_EMPTY(preferences_datums)
SetChoices(user)
return 1
else if(href_list["preference"] == "trait")
if(SSticker.HasRoundStarted() && !isnewplayer(user))
to_chat(user, "<span class='danger'>The round has already started. Please wait until next round to set up your traits!</span>")
return
switch(href_list["task"])
if("close")
user << browse(null, "window=mob_occupation")
ShowChoices(user)
if("update")
var/trait = href_list["trait"]
var/value = SStraits.trait_points[trait]
if(value == 0)
if(trait in neutral_traits)
neutral_traits -= trait
all_traits -= trait
else
if(all_traits.len >= MAX_TRAITS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
return
neutral_traits += trait
all_traits += trait
else
var/balance = GetTraitBalance()
if(trait in positive_traits)
positive_traits -= trait
all_traits -= trait
else if(trait in negative_traits)
if(balance + value < 0)
to_chat(user, "<span class='warning'>Refunding this would cause you to go below your balance!</span>")
return
negative_traits -= trait
all_traits -= trait
else if(value > 0)
if(all_traits.len >= MAX_TRAITS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
return
if(balance - value < 0)
to_chat(user, "<span class='warning'>You don't have enough balance to gain this trait!</span>")
return
positive_traits += trait
all_traits += trait
else
if(all_traits.len >= MAX_TRAITS)
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
return
negative_traits += trait
all_traits += trait
SetTraits(user)
if("reset")
all_traits = list()
positive_traits = list()
negative_traits = list()
neutral_traits = list()
SetTraits(user)
else
SetTraits(user)
return TRUE
switch(href_list["task"])
if("random")
switch(href_list["preference"])
@@ -1781,3 +1909,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.update_hair()
character.update_body_parts()
character.update_genitals()
if(CONFIG_GET(flag/roundstart_traits))
SStraits.AssignTraits(character, parent)
@@ -369,6 +369,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["job_engsec_med"] >> job_engsec_med
S["job_engsec_low"] >> job_engsec_low
//Traits
S["all_traits"] >> all_traits
S["positive_traits"] >> positive_traits
S["negative_traits"] >> negative_traits
S["neutral_traits"] >> neutral_traits
//Citadel code
S["feature_genitals_use_skintone"] >> features["genitals_use_skintone"]
S["feature_exhibitionist"] >> features["exhibitionist"]
@@ -477,6 +483,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
all_traits = SANITIZE_LIST(all_traits)
positive_traits = SANITIZE_LIST(positive_traits)
negative_traits = SANITIZE_LIST(negative_traits)
neutral_traits = SANITIZE_LIST(neutral_traits)
cit_character_pref_load(S)
return 1
@@ -542,6 +553,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["job_engsec_med"] , job_engsec_med)
WRITE_FILE(S["job_engsec_low"] , job_engsec_low)
//Traits
WRITE_FILE(S["all_traits"] , all_traits)
WRITE_FILE(S["positive_traits"] , positive_traits)
WRITE_FILE(S["negative_traits"] , negative_traits)
WRITE_FILE(S["neutral_traits"] , neutral_traits)
cit_character_pref_save(S)
return 1
+25
View File
@@ -1197,3 +1197,28 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
H.preparePixelProjectile(target, start)
H.fire()
qdel(src)
//Reality Dissociation Syndrome hallucinations only trigger in special cases and have no cost
/datum/hallucination/rds
cost = 0
/datum/hallucination/rds/fourth_wall/New(mob/living/carbon/C, forced = TRUE)
..()
to_chat(C, "<span class='userdanger extremelybig'>[pick("Leave the server" , "Close the game window")] [pick("immediately", "right now")].</span>")
/datum/hallucination/rds/supermatter/New(mob/living/carbon/C, forced = TRUE)
..()
SEND_SOUND(C, 'sound/magic/charge.ogg')
to_chat(C, "<span class='boldannounce'>You feel reality distort for a moment...</span>")
/datum/hallucination/rds/narsie/New(mob/living/carbon/C, forced = TRUE)
C.playsound_local(C, 'sound/creatures/narsie_rises.ogg', 50, FALSE, pressure_affected = FALSE)
to_chat(C, "<span class='narsie'>NAR-SIE HAS RISEN</span>")
/datum/hallucination/rds/ark/New(mob/living/carbon/C, forced = TRUE)
set waitfor = FALSE
..()
C.playsound_local(C, 'sound/machines/clockcult/ark_deathrattle.ogg', 50, FALSE, pressure_affected = FALSE)
C.playsound_local(C, 'sound/effects/clockcult_gateway_disrupted.ogg', 50, FALSE, pressure_affected = FALSE)
sleep(27)
C.playsound_local(C, 'sound/effects/explosion_distant.ogg', 50, FALSE, pressure_affected = FALSE)
@@ -21,7 +21,7 @@
else
gulp_size = max(round(reagents.total_volume / 5), 5)
/obj/item/reagent_containers/food/drinks/attack(mob/M, mob/user, def_zone)
/obj/item/reagent_containers/food/drinks/attack(mob/living/M, mob/user, def_zone)
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
@@ -36,6 +36,8 @@
if(M == user)
to_chat(M, "<span class='notice'>You swallow a gulp of [src].</span>")
if(M.has_trait(TRAIT_VORACIOUS))
M.changeNext_move(CLICK_CD_MELEE * 0.5) //chug! chug! chug!
else
M.visible_message("<span class='danger'>[user] attempts to feed the contents of [src] to [M].</span>", "<span class='userdanger'>[user] attempts to feed the contents of [src] to [M].</span>")
+14 -9
View File
@@ -19,13 +19,18 @@
if(last_check_time + 50 < world.time)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(foodtype & H.dna.species.toxic_food)
to_chat(H,"<span class='warning'>What the hell was that thing?!</span>")
H.adjust_disgust(25 + 30 * fraction)
else if(foodtype & H.dna.species.disliked_food)
to_chat(H,"<span class='notice'>That didn't taste very good...</span>")
H.adjust_disgust(11 + 15 * fraction)
else if(foodtype & H.dna.species.liked_food)
to_chat(H,"<span class='notice'>I love this taste!</span>")
H.adjust_disgust(-5 + -2.5 * fraction)
if(!H.has_trait(TRAIT_AGEUSIA))
if(foodtype & H.dna.species.toxic_food)
to_chat(H,"<span class='warning'>What the hell was that thing?!</span>")
H.adjust_disgust(25 + 30 * fraction)
else if(foodtype & H.dna.species.disliked_food)
to_chat(H,"<span class='notice'>That didn't taste very good...</span>")
H.adjust_disgust(11 + 15 * fraction)
else if(foodtype & H.dna.species.liked_food)
to_chat(H,"<span class='notice'>I love this taste!</span>")
H.adjust_disgust(-5 + -2.5 * fraction)
else
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
+3 -1
View File
@@ -50,7 +50,7 @@
return
/obj/item/reagent_containers/food/snacks/attack(mob/M, mob/user, def_zone)
/obj/item/reagent_containers/food/snacks/attack(mob/living/M, mob/user, def_zone)
if(user.a_intent == INTENT_HARM)
return ..()
if(!eatverb)
@@ -82,6 +82,8 @@
else if(fullness > (600 * (1 + M.overeatduration / 2000))) // The more you eat - the more you can eat
to_chat(M, "<span class='warning'>You cannot force any more of \the [src] to go down your throat!</span>")
return 0
if(M.has_trait(TRAIT_VORACIOUS))
M.changeNext_move(CLICK_CD_MELEE * 0.5) //nom nom nom
else
if(!isbrain(M)) //If you're feeding it to someone else.
if(fullness <= (600 * (1 + M.overeatduration / 1000)))
@@ -379,6 +379,10 @@
if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5)
SSticker.mode.make_antag_chance(humanc)
for(var/V in character.roundstart_traits)
var/datum/trait/T = V
T.on_spawn() //so latejoins still get their correct traits
log_manifest(character.mind.key,character.mind,character,latejoin = TRUE)
/mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee)
@@ -6,8 +6,14 @@
var/t_him = p_them()
var/t_has = p_have()
var/t_is = p_are()
var/obscure_name
var/msg = "<span class='info'>*---------*\nThis is <EM>[name]</EM>!\n"
if(isliving(user))
var/mob/living/L = user
if(L.has_trait(TRAIT_PROSOPAGNOSIA))
obscure_name = TRUE
var/msg = "<span class='info'>*---------*\nThis is <EM>[!obscure_name ? name : "Unknown"]</EM>!\n"
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
@@ -269,6 +275,7 @@
if(digitalcamo)
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
var/traitstring = get_trait_string()
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/cyberimp/eyes/hud/CIH = H.getorgan(/obj/item/organ/cyberimp/eyes/hud)
@@ -296,6 +303,10 @@
R = find_record("name", perpname, GLOB.data_core.medical)
if(R)
msg += "<a href='?src=[REF(src)];hud=m;evaluation=1'>\[Medical evaluation\]</a><br>"
if(traitstring)
msg += "<span class='info'>Detected physiological traits:<br></span>"
msg += "<span class='info'>[traitstring]</span><br>"
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(CIH, /obj/item/organ/cyberimp/eyes/hud/security))
@@ -312,6 +323,10 @@
msg += "<a href='?src=[REF(src)];hud=s;add_crime=1'>\[Add crime\]</a> "
msg += "<a href='?src=[REF(src)];hud=s;view_comment=1'>\[View comment log\]</a> "
msg += "<a href='?src=[REF(src)];hud=s;add_comment=1'>\[Add comment\]</a>\n"
else if(isobserver(user) && traitstring)
msg += "<span class='info'><b>Traits:</b> [traitstring]</span><br>"
if(print_flavor_text() && get_visible_name() != "Unknown")//Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
msg += "[print_flavor_text()]\n"
@@ -655,24 +655,33 @@
if(prob(30))
burndamage += rand(30,40)
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
status = "battered"
if(brutedamage > 40)
status = "mangled"
if(brutedamage > 0 && burndamage > 0)
status += " and "
if(burndamage > 40)
status += "peeling away"
if(has_trait(TRAIT_SELF_AWARE))
status = "[brutedamage] brute damage and [burndamage] burn damage"
if(!brutedamage && !burndamage)
status = "no damage"
else if(burndamage > 10)
status += "blistered"
else if(burndamage > 0)
status += "numb"
if(status == "")
status = "OK"
to_chat(src, "\t <span class='[status == "OK" ? "notice" : "warning"]'>Your [LB.name] is [status].</span>")
else
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
status = "battered"
if(brutedamage > 40)
status = "mangled"
if(brutedamage > 0 && burndamage > 0)
status += " and "
if(burndamage > 40)
status += "peeling away"
else if(burndamage > 10)
status += "blistered"
else if(burndamage > 0)
status += "numb"
if(status == "")
status = "OK"
var/no_damage
if(status == "OK" || status == "no damage")
no_damage = TRUE
to_chat(src, "\t <span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [has_trait(TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>")
for(var/obj/item/I in LB.embedded_objects)
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
@@ -687,6 +696,23 @@
to_chat(src, "<span class='info'>You're completely exhausted.</span>")
else
to_chat(src, "<span class='info'>You feel fatigued.</span>")
if(has_trait(TRAIT_SELF_AWARE))
if(toxloss)
if(toxloss > 10)
to_chat(src, "<span class='danger'>You feel sick.</span>")
else if(toxloss > 20)
to_chat(src, "<span class='danger'>You feel nauseous.</span>")
else if(toxloss > 40)
to_chat(src, "<span class='danger'>You feel very unwell!</span>")
if(oxyloss)
if(oxyloss > 10)
to_chat(src, "<span class='danger'>You feel lightheaded.</span>")
else if(oxyloss > 20)
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>")
if(roundstart_traits.len)
to_chat(src, "<span class='notice'>You have these traits: [get_trait_string()].</span>")
else
if(wear_suit)
wear_suit.add_fingerprint(M)
@@ -9,6 +9,13 @@
/mob/living/carbon/human/Unconscious(amount, updating = 1, ignore_canunconscious = 0)
amount = dna.species.spec_stun(src,amount)
if(has_trait(TRAIT_HEAVY_SLEEPER))
amount *= rand(1.25, 1.3)
return ..()
/mob/living/carbon/human/Sleeping(amount, updating = 1, ignore_sleepimmune = 0)
if(has_trait(TRAIT_HEAVY_SLEEPER))
amount *= rand(1.25, 1.3)
return ..()
/mob/living/carbon/human/cure_husk(list/sources)
@@ -34,6 +34,8 @@
var/list/status_traits = list()
var/list/roundstart_traits = list()
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
var/now_pushing = null //used by living/Collide() and living/PushAM() to prevent potential infinite loop.
+23 -1
View File
@@ -146,10 +146,23 @@
else
status_traits[trait] |= list(source)
/mob/living/proc/remove_trait(trait, list/sources)
/mob/living/proc/add_trait_datum(trait) //separate proc due to the way these ones are handled
if(has_trait(trait))
return
if(!SStraits || !SStraits.traits[trait])
return
var/datum/trait/T = SStraits.traits[trait]
new T (src)
return TRUE
/mob/living/proc/remove_trait(trait, list/sources, force)
if(!status_traits[trait])
return
if(locate(ROUNDSTART_TRAIT) in status_traits[trait] && !force) //mob traits applied through roundstart cannot normally be removed
return
if(!sources) // No defined source cures the trait entirely.
status_traits -= trait
return
@@ -167,6 +180,12 @@
if(!LAZYLEN(status_traits[trait]))
status_traits -= trait
/mob/living/proc/remove_trait_datum(trait)
var/datum/trait/T = roundstart_traits[trait]
if(T)
qdel(T)
return TRUE
/mob/living/proc/has_trait(trait, list/sources)
if(!status_traits[trait])
return FALSE
@@ -181,6 +200,9 @@
if(LAZYLEN(status_traits[trait]))
return TRUE
/mob/living/proc/has_trait_datum(trait)
return roundstart_traits[trait]
/mob/living/proc/remove_all_traits()
status_traits = list()
+1 -1
View File
@@ -9,7 +9,7 @@
/mob/living/carbon/get_taste_sensitivity()
var/obj/item/organ/tongue/tongue = getorganslot(ORGAN_SLOT_TONGUE)
if(istype(tongue))
if(istype(tongue) && !has_trait(TRAIT_AGEUSIA))
. = tongue.taste_sensitivity
else
. = 101 // can't taste anything without a tongue
+2
View File
@@ -246,6 +246,8 @@
var/rand_spr = rand()
if(spread)
randomized_gun_spread = rand(0,spread)
if(user.has_trait(TRAIT_POOR_AIM)) //nice shootin' tex
bonus_spread += 25
var/randomized_bonus_spread = rand(0, bonus_spread)
if(burst_size > 1)
@@ -37,9 +37,12 @@ All effects don't start immediately, but rather get worse over time; the rate is
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER)
H.drunkenness = max((H.drunkenness + (sqrt(volume) * boozepwr * ALCOHOL_RATE)), 0) //Volume, power, and server alcohol rate effect how quickly one gets drunk
var/booze_power = boozepwr
if(H.has_trait(TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker
booze_power *= 0.7
H.drunkenness = max((H.drunkenness + (sqrt(volume) * booze_power * ALCOHOL_RATE)), 0) //Volume, power, and server alcohol rate effect how quickly one gets drunk
var/obj/item/organ/liver/L = H.getorganslot(ORGAN_SLOT_LIVER)
H.applyLiverDamage((max(sqrt(volume) * boozepwr * L.alcohol_tolerance, 0))/4)
H.applyLiverDamage((max(sqrt(volume) * booze_power * L.alcohol_tolerance, 0))/4)
return ..() || .
/datum/reagent/consumable/ethanol/reaction_obj(obj/O, reac_volume)
@@ -117,7 +120,8 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
M.AdjustSleeping(-40, FALSE)
M.Jitter(5)
if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
M.Jitter(5)
..()
. = 1
@@ -150,7 +154,8 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.drowsyness = max(0,M.drowsyness-7)
M.AdjustSleeping(-40)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL)
M.Jitter(5)
if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
M.Jitter(5)
return ..()
/datum/reagent/consumable/ethanol/vodka
@@ -305,7 +310,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
shot_glass_icon_state = "shotglassgreen"
/datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/M)
if(prob(10))
if(prob(10) && !M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
M.hallucination += 4 //Reference to the urban myth
..()
@@ -556,7 +561,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW."
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/M)
M.Stun(40, 0)
if(M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
M.Stun(30, 0) //this realistically does nothing to prevent chainstunning but will cause them to recover faster once it's out of their system
else
M.Stun(40, 0)
return ..()
/datum/reagent/consumable/ethanol/irish_cream
@@ -585,7 +593,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/manly_dorf/on_mob_add(mob/living/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.dna.check_mutation(DWARFISM))
if(H.dna.check_mutation(DWARFISM) || H.has_trait(TRAIT_ALCOHOL_TOLERANCE))
to_chat(H, "<span class='notice'>Now THAT is MANLY!</span>")
boozepwr = 5 //We've had worse in the mines
dorf_mode = TRUE
@@ -1148,8 +1156,9 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/atomicbomb/on_mob_life(mob/living/M)
M.set_drugginess(50)
M.confused = max(M.confused+2,0)
M.Dizzy(10)
if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
M.confused = max(M.confused+2,0)
M.Dizzy(10)
if (!M.slurring)
M.slurring = 1
M.slurring += 3
@@ -184,7 +184,7 @@
/datum/reagent/toxin/mindbreaker
name = "Mindbreaker Toxin"
id = "mindbreaker"
description = "A powerful hallucinogen. Not a thing to be messed with."
description = "A powerful hallucinogen. Not a thing to be messed with. For some mental patients. it counteracts their symptoms and anchors them to reality."
color = "#B31008" // rgb: 139, 166, 233
toxpwr = 0
taste_description = "sourness"
+2
View File
@@ -26,6 +26,8 @@
HMN.regenerate_icons()
else
eye_color = HMN.eye_color
if(HMN.has_trait(TRAIT_NIGHT_VISION) && !lighting_alpha)
lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT
M.update_tint()
owner.update_sight()