mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-18 13:43:27 +00:00
* Mafia rebalance and backend refactor (#74640) ## About The Pull Request Turns all Mafia abilities into datums, instead of being a bunch of shitcode on every single job. This means it's easier to add new roles Gives new names to some defines (such as the signal order, to make it easier to tell when something is fired) Adds support for modular Mafia jobs with their abilities being in a certain order (Escort is now properly first). De-snowflakes Changeling killing abilities and day voting, they're now actions that are tallied when necessary. Turns time vars into defines Generalizes a lot of behavior for abilities, now all abilities can properly undo their action at night Fixes problems with the UI (Thoughtfeeder had 2 buttons during night and they overlapped with names, that's been fixed). ### Behavior changes - Doctor/Officer can now protect themselves 1 night, because it gives them a way to protect themselves. - Lawyer/Warden/Ect now choose their abilities at night, rather than the day before. The suspense building up towards the end of the night is part of the game, telling you that it happened at the very start is quite lame (in the case of Lawyer, anyway). - Admin setup now uses TGUI instead of html inputs. - Cut night time by like, 5 seconds, because I found it a little long lol. - HoP doesn't count as votes to win until they reveal, because it makes no sense an unrevealed HoP has their unrevealed votes tallied. I also like those 1v1 Mayor V. Evil scenarios where dead chat goes crazy, and hope to replicate that here. - Mafia now needs 6 people to start instead of 4, because 4 players is just not enough to play a Mafia round that will do anything but annoy people. - The game no longer ends if it's in a standoff with 1 Town, 1 Mafia, and 1 Neutral, as you've got a kingmaker and they should decide who wins. ### Things I want to change in the future Every time night starts/ends, it checks the entire ``GLOB.airlocks`` for doors with the "mafia" ID. This is stupid. Rework ``check_victory()`` to make it make more sense, and be more fun for players. A visible death animation? I want to use something similar to admin popup for messages about people being on stand, and decluttering the UI in general Also more use of balloon alerts instead of to chat messages for everything. Also also, making the UI more responsive to players. Button should be red when a player is selected, so they know that's who they've selected, if they want to unselect. Are votes public when you first cast them? They shouldn't be wtf. Can we also make the description for roles not be a to chat message? It can just say when you hover over the '?' come on. User-written wills instead of auto-generated, and able to send them in chat Add support for roleblock-immune roles ## Why It's Good For The Game Updates a lot of old code to modern standards Makes it considerably easier to work with Mafia and add new roles Makes things less prone to breaking as easily. Code also looks a lot cleaner now. ## Changelog 🆑 refactor: [Mafia] All Mafia abilities have been overhauled in the backend, it's now much easier to understand what each role's ability can do and how it works. admin: [Mafia] Admin setup of Mafia is now in TGUI balance: [Mafia] Doctors/Officers can protect themselves once per game. Be careful around them! fix: [Mafia] Thoughtfeeder's UI buttons at night won't overlap with eachother. fix: [Mafia] HoP's votes now actually matter, instead of being purely visual. qol: [Mafia] Lawyers, Wardens, etc. now perform their night ability at night, instead of the day prior. qol: [Mafia] Night time now lasts 40 seconds instead of 45. /🆑 * Mafia rebalance and backend refactor --------- Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
113 lines
3.5 KiB
Plaintext
113 lines
3.5 KiB
Plaintext
/datum/saymode
|
|
var/key
|
|
var/mode
|
|
|
|
//Return FALSE if you have handled the message. Otherwise, return TRUE and saycode will continue doing saycode things.
|
|
//user = whoever said the message
|
|
//message = the message
|
|
//language = the language.
|
|
/datum/saymode/proc/handle_message(mob/living/user, message, datum/language/language)
|
|
return TRUE
|
|
|
|
/datum/saymode/changeling
|
|
key = MODE_KEY_CHANGELING
|
|
mode = MODE_CHANGELING
|
|
|
|
/datum/saymode/changeling/handle_message(mob/living/user, message, datum/language/language)
|
|
//we can send the message
|
|
if(!user.mind)
|
|
return FALSE
|
|
if(user.mind.has_antag_datum(/datum/antagonist/fallen_changeling))
|
|
to_chat(user, span_changeling("<b>We're cut off from the hivemind! We've lost everything! EVERYTHING!!</b>"))
|
|
return FALSE
|
|
var/datum/antagonist/changeling/ling_sender = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
|
if(!ling_sender)
|
|
return FALSE
|
|
if(HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE))
|
|
to_chat(user, span_warning("The poison in the air hinders our ability to interact with the hivemind."))
|
|
return FALSE
|
|
|
|
user.log_talk(message, LOG_SAY, tag="changeling [ling_sender.changelingID]")
|
|
var/msg = span_changeling("<b>[ling_sender.changelingID]:</b> [message]")
|
|
|
|
//the recipients can recieve the message
|
|
for(var/datum/antagonist/changeling/ling_reciever in GLOB.antagonists)
|
|
if(!ling_reciever.owner)
|
|
continue
|
|
var/mob/living/ling_mob = ling_reciever.owner.current
|
|
//removes types that override the presence of being changeling (for example, borged lings still can't hivemind chat)
|
|
if(!isliving(ling_mob) || issilicon(ling_mob) || isbrain(ling_mob))
|
|
continue
|
|
// can't recieve messages on the hivemind right now
|
|
if(HAS_TRAIT(ling_mob, CHANGELING_HIVEMIND_MUTE))
|
|
continue
|
|
to_chat(ling_mob, msg)
|
|
|
|
for(var/mob/dead/ghost as anything in GLOB.dead_mob_list)
|
|
to_chat(ghost, "[FOLLOW_LINK(ghost, user)] [msg]")
|
|
return FALSE
|
|
|
|
/datum/saymode/xeno
|
|
key = "a"
|
|
mode = MODE_ALIEN
|
|
|
|
/datum/saymode/xeno/handle_message(mob/living/user, message, datum/language/language)
|
|
if(user.hivecheck())
|
|
user.alien_talk(message)
|
|
return FALSE
|
|
|
|
|
|
/datum/saymode/vocalcords
|
|
key = MODE_KEY_VOCALCORDS
|
|
mode = MODE_VOCALCORDS
|
|
|
|
/datum/saymode/vocalcords/handle_message(mob/living/user, message, datum/language/language)
|
|
if(iscarbon(user))
|
|
var/mob/living/carbon/C = user
|
|
var/obj/item/organ/internal/vocal_cords/V = C.get_organ_slot(ORGAN_SLOT_VOICE)
|
|
if(V?.can_speak_with())
|
|
V.handle_speech(message) //message
|
|
V.speak_with(message) //action
|
|
return FALSE
|
|
|
|
|
|
/datum/saymode/binary //everything that uses .b (silicons, drones)
|
|
key = MODE_KEY_BINARY
|
|
mode = MODE_BINARY
|
|
|
|
/datum/saymode/binary/handle_message(mob/living/user, message, datum/language/language)
|
|
if(isdrone(user))
|
|
var/mob/living/simple_animal/drone/D = user
|
|
D.drone_chat(message)
|
|
return FALSE
|
|
if(user.binarycheck())
|
|
user.robot_talk(message)
|
|
return FALSE
|
|
return FALSE
|
|
|
|
|
|
/datum/saymode/holopad
|
|
key = "h"
|
|
mode = MODE_HOLOPAD
|
|
|
|
/datum/saymode/holopad/handle_message(mob/living/user, message, datum/language/language)
|
|
if(isAI(user))
|
|
var/mob/living/silicon/ai/AI = user
|
|
AI.holopad_talk(message, language)
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/datum/saymode/mafia
|
|
key = "j"
|
|
mode = MODE_MAFIA
|
|
|
|
/datum/saymode/mafia/handle_message(mob/living/user, message, datum/language/language)
|
|
var/datum/mafia_controller/MF = GLOB.mafia_game
|
|
if (!MF)
|
|
return TRUE
|
|
var/datum/mafia_role/R = MF.player_role_lookup[user]
|
|
if(!R || R.team != "mafia")
|
|
return TRUE
|
|
MF.send_message(span_changeling("<b>[R.body.real_name]:</b> [message]"), "mafia")
|
|
return FALSE
|