[MIRROR] Mafia notes are no longer automatically written for you & new UI [MDB IGNORE] (#20765)

* Mafia notes are no longer automatically written for you & new UI (#74819)

## About The Pull Request

Notes in Mafia are no longer written for you, you instead write it
yourself and save.
Also adds a button to automatically say out your notes for other
players.

Hides the judgment buttons when it's not time to judge
Makes the UI autoupdate and makes use of ui_data / ui_static_data

Video of it in action: https://www.youtube.com/watch?v=NDUSuIUqQv8

## Why It's Good For The Game

A downside to notes currently is that it's very easy to confirm yourself
as a role against players who don't code-dive to know exactly how notes
should be formatted for any role, this makes it easier, as everyone will
type out their own notes, and can send it directly to chat when needed.

## Changelog

🆑
balance: [Mafia] Notes are no longer written out for you.
qol: [Mafia] You can now send your notes to chat whenever.
qol: [Mafia] Roundend has changed. Solos will win over others in a 1v1,
but a HoP can keep a round going in case they can solo lynch.
/🆑

* Mafia notes are no longer automatically written for you & new UI

---------

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-04-25 18:43:11 +01:00
committed by GitHub
parent 40d402ffca
commit fc1c3d4bea
14 changed files with 228 additions and 214 deletions
+9 -6
View File
@@ -18,6 +18,9 @@
///The length of the roundend report, where people can look over the round and the details.
#define VICTORY_LAP_PERIOD_LENGTH (20 SECONDS)
///The cooldown between being able to send your notes in chat.
#define MAFIA_NOTE_SENDING_COOLDOWN (15 SECONDS)
///How fast the game will speed up when half the players are gone.
#define MAFIA_SPEEDUP_INCREASE 2
@@ -68,12 +71,12 @@
///Flag that decides whether the Mafia ability can be used on dead players. This overwrites the first two, and only allows for dead.
#define CAN_USE_ON_DEAD (1<<2)
#define MAFIA_PHASE_SETUP 1
#define MAFIA_PHASE_DAY 2
#define MAFIA_PHASE_VOTING 3
#define MAFIA_PHASE_JUDGEMENT 4
#define MAFIA_PHASE_NIGHT 5
#define MAFIA_PHASE_VICTORY_LAP 6
#define MAFIA_PHASE_SETUP "No Game"
#define MAFIA_PHASE_DAY "Morning Period"
#define MAFIA_PHASE_VOTING "Voting Period"
#define MAFIA_PHASE_JUDGEMENT "Judgment"
#define MAFIA_PHASE_NIGHT "Night Period"
#define MAFIA_PHASE_VICTORY_LAP "Victory Lap"
#define MAFIA_ALIVE 1
#define MAFIA_DEAD 2
+1 -2
View File
@@ -40,8 +40,7 @@
using_ability = initial(using_ability)
/**
* Called when attempting to use the ability.
* All abilities are called at the end of each phase, and this is called when performing the action.
* Used to check if this ability can be used on a potential target.
* Args:
* game - The Mafia controller that holds reference to the game.
* potential_target - The player we are attempting to validate the action on.
@@ -12,17 +12,13 @@
if(!.)
return FALSE
var/team_text = "Town"
var/fluff = "a member of the station, or great at deception."
if(!(target_role.role_flags & ROLE_UNDETECTABLE))
switch(target_role.team)
if(MAFIA_TEAM_MAFIA)
team_text = "Mafia"
fluff = "an unfeeling, hideous changeling!"
if(MAFIA_TEAM_SOLO)
team_text = "Solo"
fluff = "rogue, with their own objectives..."
to_chat(host_role.body, span_warning("Your investigations reveal that [target_role.body.real_name] is [fluff]"))
host_role.add_note("N[game.turn] - [target_role.body.real_name] - [team_text]")
return TRUE
@@ -15,5 +15,4 @@
return FALSE
to_chat(host_role.body, span_warning("You invoke spirit of [target_role.body.real_name] and learn their role was <b>[target_role.name]<b>."))
host_role.add_note("N[game.turn] - [target_role.body.real_name] - [target_role.name]")
return TRUE
@@ -13,7 +13,6 @@
if(!.)
return FALSE
host_role.add_note("N[game.turn] - [target_role.body.real_name] - Revealed true identity")
to_chat(host_role.body, span_warning("You have revealed the true nature of the [target_role]!"))
target_role.reveal_role(game, verbose = TRUE)
return TRUE
@@ -14,8 +14,6 @@
if((target_role.role_flags & ROLE_UNDETECTABLE))
to_chat(host_role.body,span_warning("[target_role.body.real_name]'s memories reveal that they are the [pick(game.all_roles - target_role)]."))
host_role.add_note("N[game.turn] - [target_role.body.real_name] - Assistant")
else
to_chat(host_role.body,span_warning("[target_role.body.real_name]'s memories reveal that they are the [target_role.name]."))
host_role.add_note("N[game.turn] - [target_role.body.real_name] - [target_role.name]")
return TRUE
@@ -28,7 +28,6 @@
if(target_role == host_role)
use_flags &= ~CAN_USE_ON_SELF
host_role.add_note("N[game.turn] - Protected [target_role.body.real_name]")
RegisterSignal(target_role, COMSIG_MAFIA_ON_KILL, PROC_REF(prevent_kill))
return TRUE
@@ -28,7 +28,6 @@
if(!.)
return FALSE
host_role.add_note("N[game.turn] - Vested")
charges--
return TRUE
+91 -80
View File
@@ -179,7 +179,10 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
*/
/datum/mafia_controller/proc/start_game()
create_bodies()
start_day()
start_day(can_vote = FALSE)
send_message(span_notice("<b>The selected map is [current_map.name]!</b></br>[current_map.description]"))
send_message("<b>Day [turn] started! There is no voting on the first day. Say hello to everybody!</b>")
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(check_trial), FALSE), (FIRST_DAY_PERIOD_LENGTH / time_speedup), TIMER_STOPPABLE) //no voting period = no votes = instant night
/**
* How every day starts.
@@ -188,28 +191,24 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
* * If day one, just a small starting period to see who is in the game and check role, leading to the night phase.
* * Otherwise, it's a longer period used to discuss events that happened during the night, leading to the voting phase.
*/
/datum/mafia_controller/proc/start_day()
/datum/mafia_controller/proc/start_day(can_vote = TRUE)
turn += 1
phase = MAFIA_PHASE_DAY
if(!check_victory())
if(!time_speedup)//lets check if the game should be sped up, if not already.
var/living_players = 0
for(var/i in all_roles)
var/datum/mafia_role/player = i
if(player.game_status == MAFIA_ALIVE)
living_players += 1
if(living_players < all_roles.len / 2)
time_speedup = MAFIA_SPEEDUP_INCREASE
send_message("<span class='bold notice'>With only [living_players] living players left, the game timers have been sped up.</span>")
if(turn == 1)
send_message(span_notice("<b>The selected map is [current_map.name]!</b></br>[current_map.description]"))
send_message("<b>Day [turn] started! There is no voting on the first day. Say hello to everybody!</b>")
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(check_trial), FALSE), (FIRST_DAY_PERIOD_LENGTH / time_speedup), TIMER_STOPPABLE) //no voting period = no votes = instant night
else
send_message("<b>Day [turn] started! Voting will start in 1 minute.</b>")
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(start_voting_phase)), (DAY_PERIOD_LENGTH / time_speedup), TIMER_STOPPABLE)
if(check_victory())
return
SStgui.update_uis(src)
if(!time_speedup)//lets check if the game should be sped up, if not already.
var/living_players = 0
for(var/datum/mafia_role/player as anything in all_roles)
if(player.game_status == MAFIA_ALIVE)
living_players += 1
if(living_players < all_roles.len / 2)
time_speedup = MAFIA_SPEEDUP_INCREASE
send_message("<span class='bold notice'>With only [living_players] living players left, the game timers have been sped up.</span>")
if(can_vote)
send_message("<b>Day [turn] started! Voting will start in 1 minute.</b>")
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(start_voting_phase)), (DAY_PERIOD_LENGTH / time_speedup), TIMER_STOPPABLE)
/**
* Players have finished the discussion period, and now must put up someone to the chopping block.
@@ -222,7 +221,6 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
phase = MAFIA_PHASE_VOTING
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(check_trial), TRUE), (VOTING_PERIOD_LENGTH / time_speedup),TIMER_STOPPABLE) //be verbose!
send_message("<b>Voting started! Vote for who you want to see on trial today.</b>")
SStgui.update_uis(src)
/**
* Players have voted someone up, and now the person must defend themselves while the town votes innocent or guilty.
@@ -245,20 +243,19 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
judgement_abstain_votes = list()
judgement_innocent_votes = list()
judgement_guilty_votes = list()
for(var/datum/mafia_role/abstainee as anything in all_roles)
if(abstainee.game_status == MAFIA_ALIVE && (abstainee != loser))
judgement_abstain_votes += abstainee
for(var/datum/mafia_role/voters as anything in all_roles)
if(voters.game_status == MAFIA_ALIVE && (voters != loser))
judgement_abstain_votes += voters
on_trial = loser
on_trial.body.forceMove(get_turf(town_center_landmark))
phase = MAFIA_PHASE_JUDGEMENT
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(lynch)), (JUDGEMENT_PERIOD_LENGTH / time_speedup),TIMER_STOPPABLE)
reset_votes("Day")
else
if(verbose)
send_message("<b>Not enough people have voted to put someone on trial, nobody will be lynched today.</b>")
if(!check_victory())
lockdown()
SStgui.update_uis(src)
if(verbose)
send_message("<b>Not enough people have voted to put someone on trial, nobody will be lynched today.</b>")
/**
* Players have voted innocent or guilty on the person on trial, and that person is now killed or returned home.
@@ -407,8 +404,8 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
SEND_SIGNAL(src, COMSIG_MAFIA_GAME_END)
if(message)
send_message(message)
for(var/datum/mafia_role/R in all_roles)
R.reveal_role(src)
for(var/datum/mafia_role/roles as anything in all_roles)
roles.reveal_role(src)
phase = MAFIA_PHASE_VICTORY_LAP
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(end_game)), (VICTORY_LAP_PERIOD_LENGTH / time_speedup), TIMER_STOPPABLE)
@@ -465,7 +462,6 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
send_message("<b>Night [turn] started! Lockdown will end in 40 seconds.</b>")
SEND_SIGNAL(src, COMSIG_MAFIA_SUNDOWN)
next_phase_timer = addtimer(CALLBACK(src, PROC_REF(resolve_night)), (NIGHT_PERIOD_LENGTH / time_speedup), TIMER_STOPPABLE)
SStgui.update_uis(src)
/**
* The end of the night, and a series of signals for the order of events on a night.
@@ -485,7 +481,6 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
SEND_SIGNAL(src, COMSIG_MAFIA_NIGHT_END)
toggle_night_curtains(close=FALSE)
start_day()
SStgui.update_uis(src)
/**
* Proc that goes off when players vote for something with their mafia panel.
@@ -602,7 +597,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
H.add_traits(list(TRAIT_NOFIRE, TRAIT_NOBREATH, TRAIT_CANNOT_CRYSTALIZE), MAFIA_TRAIT)
H.equipOutfit(outfit_to_distribute)
H.status_flags |= GODMODE
RegisterSignal(H,COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(display_votes))
RegisterSignal(H, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(display_votes))
var/datum/action/innate/mafia_panel/mafia_panel = new(null,src)
mafia_panel.Grant(H)
var/client/player_client = GLOB.directory[role.player_key]
@@ -613,39 +608,33 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
H.key = role.player_key
role.greet()
/datum/mafia_controller/ui_data(mob/user)
. = ..()
switch(phase)
if(MAFIA_PHASE_DAY, MAFIA_PHASE_VOTING, MAFIA_PHASE_JUDGEMENT)
.["phase"] = "Day [turn]"
if(MAFIA_PHASE_NIGHT)
.["phase"] = "Night [turn]"
else
.["phase"] = "No Game"
/datum/mafia_controller/ui_static_data(mob/user)
var/list/data = list()
if(user.client?.holder)
.["admin_controls"] = TRUE //show admin buttons to start/setup/stop
if(phase == MAFIA_PHASE_JUDGEMENT)
.["judgement_phase"] = TRUE //show judgement section
else
.["judgement_phase"] = FALSE
data["admin_controls"] = TRUE //show admin buttons to start/setup/stop
data["all_roles"] = current_setup_text
var/datum/mafia_role/user_role = player_role_lookup[user]
if(user_role)
.["roleinfo"] = list(
data["roleinfo"] = list(
"role" = user_role.name,
"desc" = user_role.desc,
"action_log" = user_role.role_notes,
"hud_icon" = user_role.hud_icon,
"revealed_icon" = user_role.revealed_icon,
)
var/ability_options = list()
for(var/datum/mafia_ability/action as anything in user_role.role_unique_actions)
if(action.validate_action_target(src, silent = TRUE))
ability_options += list(list("name" = action, "ref" = REF(action)))
.["possible_actions"] = ability_options
.["role_theme"] = user_role.special_ui_theme
else
var/list/lobby_data = list()
return data
/datum/mafia_controller/ui_data(mob/user)
var/list/data = list()
data["phase"] = phase
if(turn)
data["turn"] = " - Day [turn]"
if(phase == MAFIA_PHASE_SETUP)
data["lobbydata"] = list()
for(var/key in GLOB.mafia_signup + GLOB.mafia_bad_signup)
var/list/lobby_member = list()
lobby_member["name"] = key
@@ -653,26 +642,30 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
lobby_member["spectating"] = "Ghost"
if(key in mafia_spectators)
lobby_member["spectating"] = "Spectator"
lobby_data += list(lobby_member)
.["lobbydata"] = lobby_data
var/list/player_data = list()
for(var/datum/mafia_role/R in all_roles)
data["lobbydata"] += list(lobby_member)
return data
data["timeleft"] = next_phase_timer ? timeleft(next_phase_timer) : 0 //the tgui menu counts this down.
var/datum/mafia_role/user_role = player_role_lookup[user]
data["user_notes"] = user_role.written_notes
data["players"] = list()
for(var/datum/mafia_role/role as anything in all_roles)
var/list/player_info = list()
var/list/ability_options = list()
player_info["name"] = role.body.real_name
player_info["ref"] = REF(role)
player_info["alive"] = role.game_status == MAFIA_ALIVE
player_info["possible_actions"] = list()
if(user_role) //not observer
for(var/datum/mafia_ability/action as anything in user_role.role_unique_actions)
if(action.validate_action_target(src, potential_target = R, silent = TRUE))
ability_options += list(list("name" = action, "ref" = REF(action)))
player_info["name"] = R.body.real_name
player_info["ref"] = REF(R)
player_info["possible_actions"] = ability_options
player_info["alive"] = R.game_status == MAFIA_ALIVE
player_data += list(player_info)
.["players"] = player_data
.["timeleft"] = next_phase_timer ? timeleft(next_phase_timer) : 0
if(action.validate_action_target(src, potential_target = role, silent = TRUE))
player_info["possible_actions"] += list(list("name" = action, "ref" = REF(action)))
//Not sure on this, should this info be visible
.["all_roles"] = current_setup_text
data["players"] += list(player_info)
return data
/datum/mafia_controller/ui_assets(mob/user)
return list(
@@ -748,9 +741,9 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
helper.show_help(usr)
if(!user_role)//just the dead
var/client/C = ui.user.client
switch(action)
if("mf_signup")
var/client/C = ui.user.client
if(!SSticker.HasRoundStarted())
to_chat(usr, span_warning("Wait for the round to start."))
return
@@ -767,6 +760,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
try_autostart()
return TRUE
if("mf_spectate")
var/client/C = ui.user.client
if(C.ckey in mafia_spectators)
to_chat(usr, span_notice("You will no longer get messages from the game."))
mafia_spectators -= C.ckey
@@ -775,6 +769,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
mafia_spectators += C.ckey
return TRUE
if("vote_to_start")
var/client/C = ui.user.client
if(phase != MAFIA_PHASE_SETUP)
to_chat(usr, span_notice("You cannot vote to start while a game is underway!"))
return
@@ -796,6 +791,22 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
//User actions (just living)
switch(action)
if("change_notes")
if(user_role.game_status == MAFIA_DEAD)
return TRUE
user_role.written_notes = params["new_notes"]
user_role.body.balloon_alert(user_role.body, "notes saved")
return TRUE
if("send_notes_to_chat")
if(user_role.game_status == MAFIA_DEAD || !user_role.written_notes)
return TRUE
if(phase == MAFIA_PHASE_NIGHT)
return TRUE
if(!COOLDOWN_FINISHED(user_role, note_chat_sending_cooldown))
return FALSE
COOLDOWN_START(user_role, note_chat_sending_cooldown, MAFIA_NOTE_SENDING_COOLDOWN)
user_role.body.say("[user_role.written_notes]", forced = "mafia notes sending")
return TRUE
if("perform_action")
var/datum/mafia_role/target = locate(params["target"]) in all_roles
if(!istype(target))
@@ -842,7 +853,6 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
ui = SStgui.try_update_ui(user, src, null)
if(!ui)
ui = new(user, src, "MafiaPanel")
ui.set_autoupdate(FALSE)
ui.open()
/proc/assoc_value_sum(list/L)
@@ -1021,14 +1031,15 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
desc = "Use this to play."
button_icon = 'icons/obj/mafia.dmi'
button_icon_state = "board"
var/datum/mafia_controller/parent
///The mafia controller that the button will use the UI of.
var/datum/mafia_controller/controller_panel
/datum/action/innate/mafia_panel/New(Target,mf)
/datum/action/innate/mafia_panel/New(Target, datum/mafia_controller/controller)
. = ..()
parent = mf
controller_panel = controller
/datum/action/innate/mafia_panel/Activate()
parent.ui_interact(owner)
controller_panel.ui_interact(owner)
/**
* Creates the global datum for playing mafia games, destroys the last if that's required and returns the new.
@@ -1036,6 +1047,6 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment())
/proc/create_mafia_game()
if(GLOB.mafia_game)
QDEL_NULL(GLOB.mafia_game)
var/datum/mafia_controller/MF = new()
return MF
var/datum/mafia_controller/new_controller = new()
return new_controller
@@ -30,7 +30,6 @@
obsession = pick(all_roles_shuffle) //okay no town just pick anyone here
//if you still don't have an obsession you're playing a single player game like i can't help your dumb ass
to_chat(body, span_userdanger("Your obsession is [obsession.body.real_name]! Get them lynched to win!"))
add_note("I vowed to watch my obsession, [obsession.body.real_name], hang!")
RegisterSignal(obsession, COMSIG_MAFIA_ON_KILL, PROC_REF(check_victory))
UnregisterSignal(game, COMSIG_MAFIA_SUNDOWN)
+4 -4
View File
@@ -10,6 +10,8 @@
///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
var/player_key
var/mob/living/carbon/human/body
@@ -32,7 +34,8 @@
///set this to something cool for antagonists and their window will look different
var/special_ui_theme
var/list/role_notes = list()
///The cooldown between being able to send your will in chat.
COOLDOWN_DECLARE(note_chat_sending_cooldown)
/datum/mafia_role/New(datum/mafia_controller/game)
. = ..()
@@ -92,9 +95,6 @@
/datum/mafia_role/proc/special_reveal_equip(datum/mafia_controller/game)
return
/datum/mafia_role/proc/add_note(note)
role_notes += note
/datum/mafia_role/proc/check_total_victory(alive_town, alive_mafia) //solo antags can win... solo.
return FALSE
+1 -1
View File
@@ -981,7 +981,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
var/datum/mafia_controller/game = GLOB.mafia_game //this needs to change if you want multiple mafia games up at once.
if(!game)
game = create_mafia_game("mafia")
game = create_mafia_game()
game.ui_interact(usr)
/mob/dead/observer/CtrlShiftClick(mob/user)