mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 15:17:01 +01:00
## About The Pull Request This pr improves the gameplay of blackout drunk character via: -Add hiccup sound cues and emote -Add warning for duration running out -Makes it more reasonable for blackout character to survives -Makes it harder for blackout character to sleep Balance changes: -Blackout char will have random 10 seconds bouts of inability to interact with advance tools, computer, tools, scanner etc.. -Blackout char will gain some stamina regen, sort of a "too drunk to feel tired" buff To-do - [x] Add some sort of buff for blackout character ## Why It's Good For The Game Makes it so blackout character gameplay is more enjoyable than just getting sleep for 90 seconds, plus more feedback for the surrounding player to know that they are blackout. The penalty is added so that its harder for player to majorly grief i.e assembling the ttv, or turning off power/sm cooling, wont stop them outright tho. Fixes #79138, #79163 ## Changelog 🆑 qol: improves blackout drunk character gameplay fix: fixed improper prob() placement that caused blackout character to be forced sleep sound: added hiccup sound /🆑
317 lines
12 KiB
Plaintext
317 lines
12 KiB
Plaintext
#define OWNER 0
|
|
#define STRANGER 1
|
|
|
|
/datum/brain_trauma/severe/split_personality
|
|
name = "Split Personality"
|
|
desc = "Patient's brain is split into two personalities, which randomly switch control of the body."
|
|
scan_desc = "complete lobe separation"
|
|
gain_text = span_warning("You feel like your mind was split in two.")
|
|
lose_text = span_notice("You feel alone again.")
|
|
var/current_controller = OWNER
|
|
var/initialized = FALSE //to prevent personalities deleting themselves while we wait for ghosts
|
|
var/mob/living/split_personality/stranger_backseat //there's two so they can swap without overwriting
|
|
var/mob/living/split_personality/owner_backseat
|
|
///The role to display when polling ghost
|
|
var/poll_role = "split personality"
|
|
|
|
/datum/brain_trauma/severe/split_personality/on_gain()
|
|
var/mob/living/M = owner
|
|
if(M.stat == DEAD || !M.client) //No use assigning people to a corpse or braindead
|
|
qdel(src)
|
|
return
|
|
..()
|
|
make_backseats()
|
|
get_ghost()
|
|
|
|
/datum/brain_trauma/severe/split_personality/proc/make_backseats()
|
|
stranger_backseat = new(owner, src)
|
|
var/datum/action/cooldown/spell/personality_commune/stranger_spell = new(src)
|
|
stranger_spell.Grant(stranger_backseat)
|
|
|
|
owner_backseat = new(owner, src)
|
|
var/datum/action/cooldown/spell/personality_commune/owner_spell = new(src)
|
|
owner_spell.Grant(owner_backseat)
|
|
|
|
/// Attempts to get a ghost to play the personality
|
|
/datum/brain_trauma/severe/split_personality/proc/get_ghost()
|
|
var/datum/callback/to_call = CALLBACK(src, PROC_REF(schism))
|
|
owner.AddComponent(/datum/component/orbit_poll, \
|
|
ignore_key = POLL_IGNORE_SPLITPERSONALITY, \
|
|
job_bans = ROLE_PAI, \
|
|
title = "[owner.real_name]'s [poll_role]", \
|
|
to_call = to_call, \
|
|
)
|
|
|
|
/// Ghost poll has concluded
|
|
/datum/brain_trauma/severe/split_personality/proc/schism(mob/dead/observer/ghost)
|
|
if(isnull(ghost))
|
|
qdel(src)
|
|
return
|
|
|
|
stranger_backseat.key = ghost.key
|
|
stranger_backseat.log_message("became [key_name(owner)]'s split personality.", LOG_GAME)
|
|
message_admins("[ADMIN_LOOKUPFLW(stranger_backseat)] became [ADMIN_LOOKUPFLW(owner)]'s split personality.")
|
|
|
|
|
|
/datum/brain_trauma/severe/split_personality/on_life(seconds_per_tick, times_fired)
|
|
if(owner.stat == DEAD)
|
|
if(current_controller != OWNER)
|
|
switch_personalities(TRUE)
|
|
qdel(src)
|
|
else if(SPT_PROB(1.5, seconds_per_tick))
|
|
switch_personalities()
|
|
..()
|
|
|
|
/datum/brain_trauma/severe/split_personality/on_lose()
|
|
if(current_controller != OWNER) //it would be funny to cure a guy only to be left with the other personality, but it seems too cruel
|
|
switch_personalities(TRUE)
|
|
QDEL_NULL(stranger_backseat)
|
|
QDEL_NULL(owner_backseat)
|
|
..()
|
|
|
|
|
|
/datum/brain_trauma/severe/split_personality/proc/switch_personalities(reset_to_owner = FALSE)
|
|
if(QDELETED(owner) || QDELETED(stranger_backseat) || QDELETED(owner_backseat))
|
|
return
|
|
|
|
var/mob/living/split_personality/current_backseat
|
|
var/mob/living/split_personality/new_backseat
|
|
if(current_controller == STRANGER || reset_to_owner)
|
|
current_backseat = owner_backseat
|
|
new_backseat = stranger_backseat
|
|
else
|
|
current_backseat = stranger_backseat
|
|
new_backseat = owner_backseat
|
|
|
|
if(!current_backseat.client) //Make sure we never switch to a logged off mob.
|
|
return
|
|
|
|
current_backseat.log_message("assumed control of [key_name(owner)] due to [src]. (Original owner: [current_controller == OWNER ? owner.key : current_backseat.key])", LOG_GAME)
|
|
to_chat(owner, span_userdanger("You feel your control being taken away... your other personality is in charge now!"))
|
|
to_chat(current_backseat, span_userdanger("You manage to take control of your body!"))
|
|
|
|
//Body to backseat
|
|
|
|
var/h2b_id = owner.computer_id
|
|
var/h2b_ip= owner.lastKnownIP
|
|
owner.computer_id = null
|
|
owner.lastKnownIP = null
|
|
|
|
new_backseat.ckey = owner.ckey
|
|
|
|
new_backseat.name = owner.name
|
|
|
|
if(owner.mind)
|
|
new_backseat.mind = owner.mind
|
|
|
|
if(!new_backseat.computer_id)
|
|
new_backseat.computer_id = h2b_id
|
|
|
|
if(!new_backseat.lastKnownIP)
|
|
new_backseat.lastKnownIP = h2b_ip
|
|
|
|
if(reset_to_owner && new_backseat.mind)
|
|
new_backseat.ghostize(FALSE)
|
|
|
|
//Backseat to body
|
|
|
|
var/s2h_id = current_backseat.computer_id
|
|
var/s2h_ip= current_backseat.lastKnownIP
|
|
current_backseat.computer_id = null
|
|
current_backseat.lastKnownIP = null
|
|
|
|
owner.ckey = current_backseat.ckey
|
|
owner.mind = current_backseat.mind
|
|
|
|
if(!owner.computer_id)
|
|
owner.computer_id = s2h_id
|
|
|
|
if(!owner.lastKnownIP)
|
|
owner.lastKnownIP = s2h_ip
|
|
|
|
current_controller = !current_controller
|
|
|
|
|
|
/mob/living/split_personality
|
|
name = "split personality"
|
|
real_name = "unknown conscience"
|
|
var/mob/living/carbon/body
|
|
var/datum/brain_trauma/severe/split_personality/trauma
|
|
|
|
/mob/living/split_personality/Initialize(mapload, _trauma)
|
|
if(iscarbon(loc))
|
|
body = loc
|
|
name = body.real_name
|
|
real_name = body.real_name
|
|
trauma = _trauma
|
|
return ..()
|
|
|
|
/mob/living/split_personality/Life(seconds_per_tick = SSMOBS_DT, times_fired)
|
|
if(QDELETED(body))
|
|
qdel(src) //in case trauma deletion doesn't already do it
|
|
|
|
if((body.stat == DEAD && trauma.owner_backseat == src))
|
|
trauma.switch_personalities()
|
|
qdel(trauma)
|
|
|
|
//if one of the two ghosts, the other one stays permanently
|
|
if(!body.client && trauma.initialized)
|
|
trauma.switch_personalities()
|
|
qdel(trauma)
|
|
|
|
..()
|
|
|
|
/mob/living/split_personality/Login()
|
|
. = ..()
|
|
if(!. || !client)
|
|
return FALSE
|
|
to_chat(src, span_notice("As a split personality, you cannot do anything but observe. However, you will eventually gain control of your body, switching places with the current personality."))
|
|
to_chat(src, span_warning("<b>Do not commit suicide or put the body in a deadly position. Behave like you care about it as much as the owner.</b>"))
|
|
|
|
/mob/living/split_personality/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null)
|
|
to_chat(src, span_warning("You cannot speak, your other self is controlling your body!"))
|
|
return FALSE
|
|
|
|
/mob/living/split_personality/emote(act, m_type = null, message = null, intentional = FALSE, force_silence = FALSE)
|
|
return FALSE
|
|
|
|
///////////////BRAINWASHING////////////////////
|
|
|
|
/datum/brain_trauma/severe/split_personality/brainwashing
|
|
name = "Split Personality"
|
|
desc = "Patient's brain is split into two personalities, which randomly switch control of the body."
|
|
scan_desc = "complete lobe separation"
|
|
gain_text = ""
|
|
lose_text = span_notice("You are free of your brainwashing.")
|
|
can_gain = FALSE
|
|
var/codeword
|
|
var/objective
|
|
|
|
/datum/brain_trauma/severe/split_personality/brainwashing/New(obj/item/organ/internal/brain/B, _permanent, _codeword, _objective)
|
|
..()
|
|
if(_codeword)
|
|
codeword = _codeword
|
|
else
|
|
codeword = pick(strings("ion_laws.json", "ionabstract")\
|
|
| strings("ion_laws.json", "ionobjects")\
|
|
| strings("ion_laws.json", "ionadjectives")\
|
|
| strings("ion_laws.json", "ionthreats")\
|
|
| strings("ion_laws.json", "ionfood")\
|
|
| strings("ion_laws.json", "iondrinks"))
|
|
|
|
/datum/brain_trauma/severe/split_personality/brainwashing/on_gain()
|
|
..()
|
|
var/mob/living/split_personality/traitor/traitor_backseat = stranger_backseat
|
|
traitor_backseat.codeword = codeword
|
|
traitor_backseat.objective = objective
|
|
|
|
/datum/brain_trauma/severe/split_personality/brainwashing/make_backseats()
|
|
stranger_backseat = new /mob/living/split_personality/traitor(owner, src, codeword, objective)
|
|
owner_backseat = new(owner, src)
|
|
|
|
/datum/brain_trauma/severe/split_personality/brainwashing/get_ghost()
|
|
set waitfor = FALSE
|
|
var/list/mob/dead/observer/candidates = poll_candidates_for_mob("Do you want to play as [owner.real_name]'s brainwashed mind?", null, null, 7.5 SECONDS, stranger_backseat)
|
|
if(LAZYLEN(candidates))
|
|
var/mob/dead/observer/C = pick(candidates)
|
|
stranger_backseat.key = C.key
|
|
else
|
|
qdel(src)
|
|
|
|
/datum/brain_trauma/severe/split_personality/brainwashing/on_life(seconds_per_tick, times_fired)
|
|
return //no random switching
|
|
|
|
/datum/brain_trauma/severe/split_personality/brainwashing/handle_hearing(datum/source, list/hearing_args)
|
|
if(!owner.can_hear() || owner == hearing_args[HEARING_SPEAKER] || !owner.has_language(hearing_args[HEARING_LANGUAGE]))
|
|
return
|
|
|
|
var/message = hearing_args[HEARING_RAW_MESSAGE]
|
|
if(findtext(message, codeword))
|
|
hearing_args[HEARING_RAW_MESSAGE] = replacetext(message, codeword, span_warning("[codeword]"))
|
|
addtimer(CALLBACK(src, TYPE_PROC_REF(/datum/brain_trauma/severe/split_personality, switch_personalities)), 10)
|
|
|
|
/datum/brain_trauma/severe/split_personality/brainwashing/handle_speech(datum/source, list/speech_args)
|
|
if(findtext(speech_args[SPEECH_MESSAGE], codeword))
|
|
speech_args[SPEECH_MESSAGE] = "" //oh hey did you want to tell people about the secret word to bring you back?
|
|
|
|
/mob/living/split_personality/traitor
|
|
name = "split personality"
|
|
real_name = "unknown conscience"
|
|
var/objective
|
|
var/codeword
|
|
|
|
/mob/living/split_personality/traitor/Login()
|
|
. = ..()
|
|
if(!. || !client)
|
|
return FALSE
|
|
to_chat(src, span_notice("As a brainwashed personality, you cannot do anything yet but observe. However, you may gain control of your body if you hear the special codeword, switching places with the current personality."))
|
|
to_chat(src, span_notice("Your activation codeword is: <b>[codeword]</b>"))
|
|
if(objective)
|
|
to_chat(src, span_notice("Your master left you an objective: <b>[objective]</b>. Follow it at all costs when in control."))
|
|
|
|
/datum/brain_trauma/severe/split_personality/blackout
|
|
name = "Alcohol-Induced CNS Impairment"
|
|
desc = "Patient's CNS has been temporarily impaired by imbibed alcohol, blocking memory formation, and causing reduced cognition and stupefaction."
|
|
scan_desc = "alcohol-induced CNS impairment"
|
|
gain_text = span_warning("Crap, that was one drink too many. You black out...")
|
|
lose_text = "You wake up very, very confused and hungover. All you can remember is drinking a lot of alcohol... what happened?"
|
|
poll_role = "blacked out drunkard"
|
|
/// Duration of effect, tracked in seconds, not deciseconds. qdels when reaching 0.
|
|
var/duration_in_seconds = 180
|
|
|
|
/datum/brain_trauma/severe/split_personality/blackout/on_gain()
|
|
. = ..()
|
|
RegisterSignal(owner, COMSIG_ATOM_SPLASHED, PROC_REF(on_splashed))
|
|
notify_ghosts("[owner] is blacking out!", source = owner, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "Bro I'm not even drunk right now")
|
|
|
|
/datum/brain_trauma/severe/split_personality/blackout/on_lose()
|
|
. = ..()
|
|
owner.add_mood_event("hang_over", /datum/mood_event/hang_over)
|
|
UnregisterSignal(owner, COMSIG_ATOM_SPLASHED)
|
|
|
|
/datum/brain_trauma/severe/split_personality/blackout/proc/on_splashed()
|
|
SIGNAL_HANDLER
|
|
if(prob(20))//we don't want every single splash to wake them up now do we
|
|
qdel(src)
|
|
|
|
/datum/brain_trauma/severe/split_personality/blackout/on_life(seconds_per_tick, times_fired)
|
|
if(current_controller == OWNER && stranger_backseat)//we should only start transitioning after the other personality has entered
|
|
owner.overlay_fullscreen("fade_to_black", /atom/movable/screen/fullscreen/blind)
|
|
owner.clear_fullscreen("fade_to_black", animated = 4 SECONDS)
|
|
switch_personalities()
|
|
if(owner.stat == DEAD)
|
|
if(current_controller != OWNER)
|
|
switch_personalities(TRUE)
|
|
qdel(src)
|
|
return
|
|
if(duration_in_seconds <= 0)
|
|
qdel(src)
|
|
return
|
|
else if(duration_in_seconds <= 50)
|
|
to_chat(owner, span_warning("You have 50 seconds left before sobering up!"))
|
|
if(prob(10) && !HAS_TRAIT(owner, TRAIT_DISCOORDINATED_TOOL_USER))
|
|
ADD_TRAIT(owner, TRAIT_DISCOORDINATED_TOOL_USER, TRAUMA_TRAIT)
|
|
owner.balloon_alert(owner, "dexterity reduced temporarily!")
|
|
//We then send a callback to automatically re-add the trait
|
|
addtimer(TRAIT_CALLBACK_REMOVE(owner, TRAIT_DISCOORDINATED_TOOL_USER, TRAUMA_TRAIT), 10 SECONDS)
|
|
addtimer(CALLBACK(owner, TYPE_PROC_REF(/atom, balloon_alert), owner, "dexterity regained!"), 10 SECONDS)
|
|
if(prob(15))
|
|
playsound(owner,'sound/effects/sf_hiccup_male_01.ogg', 50)
|
|
owner.emote("hiccup")
|
|
owner.adjustStaminaLoss(-5) //too drunk to feel anything
|
|
duration_in_seconds -= seconds_per_tick
|
|
|
|
/mob/living/split_personality/blackout
|
|
name = "blacked-out drunkard"
|
|
real_name = "drunken consciousness"
|
|
|
|
/mob/living/split_personality/blackout/Login()
|
|
. = ..()
|
|
if(!. || !client)
|
|
return FALSE
|
|
to_chat(src, span_notice("You're the incredibly inebriated leftovers of your host's consciousness! Make sure to act the part and leave a trail of confusion and chaos in your wake."))
|
|
to_chat(src, span_boldwarning("Do not commit suicide or put the body in danger, you have a minor liscense to grief just like a clown, do not kill anyone or create a situation leading to the body being in danger or in harm ways. While you're drunk, you're not suicidal."))
|
|
|
|
#undef OWNER
|
|
#undef STRANGER
|