mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 11:36:24 +01:00
21b4095dfd
Upstream 04/17/2026 fixes https://github.com/Bubberstation/Bubberstation/issues/5549 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com> Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com> Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com> Co-authored-by: loganuk <fakeemail123@aol.com> Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> Co-authored-by: Lucy <lucy@absolucy.moe> Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com> Co-authored-by: Isratosh <Isratosh@hotmail.com> Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com> Co-authored-by: Alexander V. <volas@ya.ru> Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com> Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Iamgoofball <iamgoofball@gmail.com> Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com> Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com> Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com> Co-authored-by: Josh <josh.adam.powell@gmail.com> Co-authored-by: Josh Powell <josh.powell@softwire.com> Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com> Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
207 lines
7.7 KiB
Plaintext
207 lines
7.7 KiB
Plaintext
/datum/mafia_role
|
|
var/name = JOB_ASSISTANT
|
|
var/desc = "You are a crewmember without any special abilities."
|
|
var/win_condition = "kill all mafia and solo killing roles."
|
|
var/team = MAFIA_TEAM_TOWN
|
|
///how the random setup chooses which roles get put in
|
|
var/role_type = TOWN_OVERFLOW
|
|
///role flags (special status of roles like detection immune)
|
|
var/role_flags = NONE
|
|
///The mafia controller board this mafia role is tied to, in case there's several Mafia games at once.
|
|
var/datum/mafia_controller/mafia_game_controller
|
|
|
|
///The mafia popup we edit text to give different alerts for (such as when to vote).
|
|
var/atom/movable/screen/mafia_popup/mafia_alert
|
|
///List of all mafia abilities this role is able to perform.
|
|
var/list/datum/mafia_ability/role_unique_actions = list()
|
|
///The player's written notes, that they can send to chat at any time.
|
|
var/written_notes
|
|
|
|
///The ckey of the person playing as this Mafia role, CAN BE NULL IN FAVOR OF player_pda.
|
|
var/player_key
|
|
///The PDA of the person playing as this Mafia role, CAN BE NULL IN FAVOR OF player_key.
|
|
var/obj/item/modular_computer/player_pda
|
|
|
|
///List of all messages this role got throughout the game.
|
|
var/list/role_messages = list()
|
|
|
|
|
|
var/mob/living/carbon/human/body
|
|
var/obj/effect/landmark/mafia/assigned_landmark
|
|
|
|
///The Mafia innate action panel that allows players to view the game's state.
|
|
var/datum/action/innate/mafia_panel/mafia_panel
|
|
|
|
///how many votes submitted when you vote. used in voting and deciding victory.
|
|
var/vote_power = 1
|
|
///what they get equipped with when they are revealed
|
|
var/datum/outfit/revealed_outfit = /datum/outfit/mafia/assistant
|
|
///what the role gets when it wins a game
|
|
var/winner_award = /datum/award/achievement/mafia/assistant
|
|
|
|
///so mafia have to also kill them to have a majority
|
|
var/game_status = MAFIA_ALIVE
|
|
|
|
///icon state in the mafia dmi of the hud of the role, used in the mafia ui
|
|
var/hud_icon = SECHUD_ASSISTANT
|
|
///icon state in the mafia dmi of the hud of the role, used in the mafia ui
|
|
var/revealed_icon = "assistant"
|
|
///set this to something cool for antagonists and their window will look different
|
|
var/special_ui_theme
|
|
|
|
///The cooldown between being able to send your will in chat.
|
|
COOLDOWN_DECLARE(note_chat_sending_cooldown)
|
|
|
|
/datum/mafia_role/New(datum/mafia_controller/new_game)
|
|
. = ..()
|
|
src.mafia_game_controller = new_game
|
|
mafia_panel = new(null, new_game)
|
|
for(var/datum/mafia_ability/abilities as anything in role_unique_actions + /datum/mafia_ability/voting)
|
|
role_unique_actions += new abilities(src)
|
|
role_unique_actions -= abilities
|
|
|
|
/datum/mafia_role/Destroy(force)
|
|
UnregisterSignal(body, list(COMSIG_MOB_SAY, COMSIG_MOB_DEADSAY))
|
|
QDEL_NULL(mafia_alert)
|
|
QDEL_NULL(mafia_panel)
|
|
QDEL_LIST(role_unique_actions)
|
|
//we null these instead of qdel because Mafia controller's mapdeleter deletes it all.
|
|
assigned_landmark = null
|
|
body = null
|
|
role_messages.Cut()
|
|
return ..()
|
|
|
|
/datum/mafia_role/proc/register_body(mob/living/carbon/human/new_body)
|
|
if(body)
|
|
UnregisterSignal(new_body, list(COMSIG_MOB_SAY, COMSIG_MOB_DEADSAY))
|
|
mafia_panel.Remove(body)
|
|
body = new_body
|
|
RegisterSignal(new_body, COMSIG_MOB_SAY, PROC_REF(handle_speech))
|
|
RegisterSignal(new_body, COMSIG_MOB_DEADSAY, PROC_REF(handle_speech_dead))
|
|
mafia_panel.Grant(new_body)
|
|
|
|
/**
|
|
* send_message_to_player
|
|
*
|
|
* Sends a message to a player, checking if they are playing through a PDA or not.
|
|
* Args:
|
|
* * message - The message to send to the person
|
|
* * balloon_alert - Whether it should be as a balloon alert, only if it's to a non-PDA user.
|
|
*/
|
|
/datum/mafia_role/proc/send_message_to_player(message, balloon_alert = FALSE)
|
|
if(player_pda)
|
|
role_messages += message
|
|
return
|
|
if(balloon_alert)
|
|
body.balloon_alert(body, message)
|
|
return
|
|
to_chat(body, message)
|
|
|
|
/**
|
|
* handle_speech
|
|
*
|
|
* Handles Mafia roles talking in chat.
|
|
* First we'll go through their abilities for Ability-specific speech,
|
|
* if none affects it, we will go to day chat (if it is indeed day).
|
|
*/
|
|
/datum/mafia_role/proc/handle_speech(datum/source, list/speech_args)
|
|
SIGNAL_HANDLER
|
|
for(var/datum/mafia_ability/abilities as anything in role_unique_actions)
|
|
if(abilities.handle_speech(source, speech_args))
|
|
return
|
|
if(mafia_game_controller.phase == MAFIA_PHASE_NIGHT)
|
|
return
|
|
var/message = "[source]: [html_decode(speech_args[SPEECH_MESSAGE])]"
|
|
mafia_game_controller.send_message(message, log_only = TRUE)
|
|
|
|
///Same as handle_speech, but for dead players.
|
|
/datum/mafia_role/proc/handle_speech_dead(datum/source, message)
|
|
SIGNAL_HANDLER
|
|
var/message_sent = span_changeling("<b>\[DEAD CHAT\] [source]</b>: [message]")
|
|
mafia_game_controller.send_message(message_sent, team = MAFIA_TEAM_DEAD)
|
|
return MOB_DEADSAY_SIGNAL_INTERCEPT
|
|
|
|
/**
|
|
* Puts the player in their body and keeps track of their previous one to put them back in later.
|
|
* Adds the playing_mafia trait so people examining them will know why they're currently lacking a soul.
|
|
*/
|
|
/datum/mafia_role/proc/put_player_in_body(client/player)
|
|
if(player.mob.mind)
|
|
body.AddComponent( \
|
|
/datum/component/temporary_body, \
|
|
old_mind = player.mob.mind, \
|
|
)
|
|
body.PossessByPlayer(player.key)
|
|
ADD_TRAIT(body, TRAIT_CORPSELOCKED, MAFIA_TRAIT)
|
|
|
|
/**
|
|
* Tests kill immunities, if nothing prevents the kill, kills this role.
|
|
*
|
|
* Does not count as visiting, see visit proc.
|
|
*/
|
|
/datum/mafia_role/proc/kill(datum/mafia_controller/game, datum/mafia_role/attacker, lynch = FALSE)
|
|
if(game_status == MAFIA_DEAD)
|
|
return FALSE
|
|
if(attacker && (attacker.role_flags & ROLE_ROLEBLOCKED))
|
|
return FALSE
|
|
if(SEND_SIGNAL(src, COMSIG_MAFIA_ON_KILL, game, attacker, lynch) & MAFIA_PREVENT_KILL)
|
|
return FALSE
|
|
game_status = MAFIA_DEAD
|
|
//can now hear dead chat speaking.
|
|
team |= MAFIA_TEAM_DEAD
|
|
body.death()
|
|
if(lynch)
|
|
reveal_role(game, verbose = TRUE)
|
|
game.living_roles -= src
|
|
return TRUE
|
|
|
|
/datum/mafia_role/proc/greet()
|
|
mafia_alert = new(body, src)
|
|
SEND_SOUND(body, 'sound/ambience/misc/ambifailure.ogg')
|
|
to_chat(body, span_danger("You are the [name]."))
|
|
to_chat(body, span_danger("[desc]"))
|
|
switch(team)
|
|
if(MAFIA_TEAM_MAFIA)
|
|
to_chat(body,span_danger("You and your co-conspirators win if you outnumber crewmembers."))
|
|
if(MAFIA_TEAM_TOWN)
|
|
to_chat(body,span_danger("You are a crewmember. Find out and lynch the changelings!"))
|
|
if(MAFIA_TEAM_SOLO)
|
|
to_chat(body,span_danger("You are not aligned to town or mafia. Accomplish your own objectives!"))
|
|
to_chat(body, "<span class='warningplain'><b>Be sure to read <a href=\"https://tgstation13.org/wiki/Mafia\">the wiki page</a> to learn more, if you have no idea what's going on.</b></span>")
|
|
|
|
/datum/mafia_role/proc/reveal_role(datum/mafia_controller/game, verbose = FALSE)
|
|
if((role_flags & ROLE_REVEALED))
|
|
return
|
|
if(verbose)
|
|
game.send_message("<span class='big bold notice'>It is revealed that the true role of [body] [game_status == MAFIA_ALIVE ? "is" : "was"] [name]!</span>")
|
|
var/list/oldoutfit = body.get_equipped_items()
|
|
for(var/thing in oldoutfit)
|
|
qdel(thing)
|
|
special_reveal_equip(game)
|
|
body.equipOutfit(revealed_outfit)
|
|
role_flags |= ROLE_REVEALED
|
|
|
|
/datum/mafia_role/proc/special_reveal_equip(datum/mafia_controller/game)
|
|
return
|
|
|
|
/datum/mafia_role/proc/show_help(clueless)
|
|
var/list/result = list()
|
|
var/team_desc = ""
|
|
var/team_span = ""
|
|
var/the = TRUE
|
|
switch(team)
|
|
if(MAFIA_TEAM_TOWN)
|
|
team_desc = "Town"
|
|
team_span = "nicegreen"
|
|
if(MAFIA_TEAM_MAFIA)
|
|
team_desc = "Mafia"
|
|
team_span = "red"
|
|
if(MAFIA_TEAM_SOLO)
|
|
team_desc = "Nobody"
|
|
team_span = "comradio"
|
|
the = FALSE
|
|
result += span_notice("The [span_bold("[name]")] is aligned with [the ? "the " : ""]<span class='[team_span]'>[team_desc]</span>")
|
|
result += "<span class='bold notice'>\"[initial(desc)]\"</span>"
|
|
result += span_notice("[name] wins when they [win_condition]")
|
|
to_chat(clueless, result.Join("</br>"))
|