Files
Bubberstation/code/datums/saymode.dm
SkyratBot bad4c9168c [MIRROR] Mafia rebalance and backend refactor [MDB IGNORE] (#20631)
* 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>
2023-04-17 22:00:53 -07:00

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