fairly sure mmo mafia is not a thing and i'm lazy
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
/* DO NOT MERGE, REQUIRES TGUI3 MINIMUM, though the code only supports tgui4 */
|
||||
|
||||
|
||||
/**
|
||||
@@ -16,7 +15,8 @@
|
||||
var/phase = MAFIA_PHASE_SETUP
|
||||
///how long the game has gone on for, changes with every sunrise. day one, night one, day two, etc.
|
||||
var/turn = 0
|
||||
|
||||
///for debugging and testing a full game, or adminbuse. If this is not null, it will use this as a setup. clears when game is over
|
||||
var/list/custom_setup = list()
|
||||
///first day has no voting, and thus is shorter
|
||||
var/first_day_phase_period = 20 SECONDS
|
||||
///talk with others about the last night
|
||||
@@ -193,7 +193,7 @@
|
||||
*/
|
||||
/datum/mafia_controller/proc/check_trial(verbose = TRUE)
|
||||
var/datum/mafia_role/loser = get_vote_winner("Day")//, majority_of_town = TRUE)
|
||||
var/loser_votes = get_vote_count(loser,"Day")
|
||||
// var/loser_votes = get_vote_count(loser,"Day")
|
||||
if(loser)
|
||||
// if(loser_votes > 12)
|
||||
// loser.body.client?.give_award(/datum/award/achievement/mafia/universally_hated, loser.body)
|
||||
@@ -267,6 +267,10 @@
|
||||
* * returns TRUE if someone won the game, halting other procs from continuing in the case of a victory
|
||||
*/
|
||||
/datum/mafia_controller/proc/check_victory()
|
||||
//needed for achievements
|
||||
var/list/total_town = list()
|
||||
var/list/total_mafia = list()
|
||||
|
||||
var/alive_town = 0
|
||||
var/alive_mafia = 0
|
||||
var/list/solos_to_ask = list() //need to ask after because first round is counting team sizes
|
||||
@@ -276,15 +280,19 @@
|
||||
///PHASE ONE: TALLY UP ALL NUMBERS OF PEOPLE STILL ALIVE
|
||||
|
||||
for(var/datum/mafia_role/R in all_roles)
|
||||
if(R.game_status == MAFIA_ALIVE)
|
||||
switch(R.team)
|
||||
if(MAFIA_TEAM_MAFIA)
|
||||
alive_mafia++
|
||||
if(MAFIA_TEAM_TOWN)
|
||||
alive_town++
|
||||
if(MAFIA_TEAM_SOLO)
|
||||
switch(R.team)
|
||||
if(MAFIA_TEAM_MAFIA)
|
||||
total_mafia += R
|
||||
if(R.game_status == MAFIA_ALIVE)
|
||||
alive_mafia += R.vote_power
|
||||
if(MAFIA_TEAM_TOWN)
|
||||
total_town += R
|
||||
if(R.game_status == MAFIA_ALIVE)
|
||||
alive_town += R.vote_power
|
||||
if(MAFIA_TEAM_SOLO)
|
||||
if(R.game_status == MAFIA_ALIVE)
|
||||
if(R.solo_counts_as_town)
|
||||
alive_town++
|
||||
alive_town += R.vote_power
|
||||
solos_to_ask += R
|
||||
|
||||
///PHASE TWO: SEND STATS TO SOLO ANTAGS, SEE IF THEY WON OR TEAMS CANNOT WIN
|
||||
@@ -299,6 +307,8 @@
|
||||
var/solo_end = FALSE
|
||||
for(var/datum/mafia_role/winner in total_victors)
|
||||
send_message("<span class='big comradio'>!! [uppertext(winner.name)] VICTORY !!</span>")
|
||||
// var/client/winner_client = GLOB.directory[winner.player_key]
|
||||
// winner_client?.give_award(winner.winner_award, winner.body)
|
||||
solo_end = TRUE
|
||||
if(solo_end)
|
||||
start_the_end()
|
||||
@@ -306,10 +316,16 @@
|
||||
if(blocked_victory)
|
||||
return FALSE
|
||||
if(alive_mafia == 0)
|
||||
// for(var/datum/mafia_role/townie in total_town)
|
||||
// var/client/townie_client = GLOB.directory[townie.player_key]
|
||||
// townie_client?.give_award(townie.winner_award, townie.body)
|
||||
start_the_end("<span class='big green'>!! TOWN VICTORY !!</span>")
|
||||
return TRUE
|
||||
else if(alive_mafia >= alive_town) //guess could change if town nightkill is added
|
||||
start_the_end("<span class='big red'>!! MAFIA VICTORY !!</span>")
|
||||
// for(var/datum/mafia_role/changeling in total_mafia)
|
||||
// var/client/changeling_client = GLOB.directory[changeling.player_key]
|
||||
// changeling_client?.give_award(changeling.winner_award, changeling.body)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
@@ -337,8 +353,13 @@
|
||||
/datum/mafia_controller/proc/end_game()
|
||||
map_deleter.generate() //remove the map, it will be loaded at the start of the next one
|
||||
QDEL_LIST(all_roles)
|
||||
current_setup_text = null
|
||||
custom_setup = list()
|
||||
turn = 0
|
||||
votes = list()
|
||||
//map gen does not deal with landmarks
|
||||
QDEL_LIST(landmarks)
|
||||
QDEL_NULL(town_center_landmark)
|
||||
phase = MAFIA_PHASE_SETUP
|
||||
|
||||
/**
|
||||
@@ -413,17 +434,17 @@
|
||||
* Arguments:
|
||||
* * voter: the mafia role that is trying to vote for...
|
||||
* * target: the mafia role that is getting voted for
|
||||
* * vt: type of vote submitted (is this the day vote? is this the mafia night vote?)
|
||||
* * vote_type: type of vote submitted (is this the day vote? is this the mafia night vote?)
|
||||
* * teams: see mafia team defines for what to put in, makes the messages only send to a specific team (so mafia night votes only sending messages to mafia at night)
|
||||
*/
|
||||
/datum/mafia_controller/proc/vote_for(datum/mafia_role/voter,datum/mafia_role/target,vt, teams)
|
||||
if(!votes[vt])
|
||||
votes[vt] = list()
|
||||
var/old_vote = votes[vt][voter]
|
||||
/datum/mafia_controller/proc/vote_for(datum/mafia_role/voter,datum/mafia_role/target,vote_type, teams)
|
||||
if(!votes[vote_type])
|
||||
votes[vote_type] = list()
|
||||
var/old_vote = votes[vote_type][voter]
|
||||
if(old_vote && old_vote == target)
|
||||
votes[vt] -= voter
|
||||
votes[vote_type] -= voter
|
||||
else
|
||||
votes[vt][voter] = target
|
||||
votes[vote_type][voter] = target
|
||||
if(old_vote && old_vote == target)
|
||||
send_message("<span class='notice'>[voter.body.real_name] retracts their vote for [target.body.real_name]!</span>", team = teams)
|
||||
else
|
||||
@@ -437,12 +458,12 @@
|
||||
/**
|
||||
* Clears out the votes of a certain type (day votes, mafia kill votes) while leaving others untouched
|
||||
*/
|
||||
/datum/mafia_controller/proc/reset_votes(vt)
|
||||
/datum/mafia_controller/proc/reset_votes(vote_type)
|
||||
var/list/bodies_to_update = list()
|
||||
for(var/vote in votes[vt])
|
||||
var/datum/mafia_role/R = votes[vt][vote]
|
||||
for(var/vote in votes[vote_type])
|
||||
var/datum/mafia_role/R = votes[vote_type][vote]
|
||||
bodies_to_update += R.body
|
||||
votes[vt] = list()
|
||||
votes[vote_type] = list()
|
||||
for(var/mob/M in bodies_to_update)
|
||||
M.update_icon()
|
||||
|
||||
@@ -450,38 +471,39 @@
|
||||
* Returns how many people voted for the role, in whatever vote (day vote, night kill vote)
|
||||
* Arguments:
|
||||
* * role: the mafia role the proc tries to get the amount of votes for
|
||||
* * vt: the vote type (getting how many day votes were for the role, or mafia night votes for the role)
|
||||
* * vote_type: the vote type (getting how many day votes were for the role, or mafia night votes for the role)
|
||||
*/
|
||||
/datum/mafia_controller/proc/get_vote_count(role,vt)
|
||||
/datum/mafia_controller/proc/get_vote_count(role,vote_type)
|
||||
. = 0
|
||||
for(var/votee in votes[vt])
|
||||
if(votes[vt][votee] == role)
|
||||
. += 1
|
||||
for(var/v in votes[vote_type])
|
||||
var/datum/mafia_role/votee = v
|
||||
if(votes[vote_type][votee] == role)
|
||||
. += votee.vote_power
|
||||
|
||||
/**
|
||||
* Returns whichever role got the most votes, in whatever vote (day vote, night kill vote)
|
||||
* returns null if no votes
|
||||
* Arguments:
|
||||
* * vt: the vote type (getting the role that got the most day votes, or the role that got the most mafia votes)
|
||||
* * vote_type: the vote type (getting the role that got the most day votes, or the role that got the most mafia votes)
|
||||
*/
|
||||
/datum/mafia_controller/proc/get_vote_winner(vt)
|
||||
/datum/mafia_controller/proc/get_vote_winner(vote_type)
|
||||
var/list/tally = list()
|
||||
for(var/votee in votes[vt])
|
||||
if(!tally[votes[vt][votee]])
|
||||
tally[votes[vt][votee]] = 1
|
||||
for(var/votee in votes[vote_type])
|
||||
if(!tally[votes[vote_type][votee]])
|
||||
tally[votes[vote_type][votee]] = 1
|
||||
else
|
||||
tally[votes[vt][votee]] += 1
|
||||
tally[votes[vote_type][votee]] += 1
|
||||
sortTim(tally,/proc/cmp_numeric_dsc,associative=TRUE)
|
||||
return length(tally) ? tally[1] : null
|
||||
|
||||
/**
|
||||
* Returns a random person who voted for whatever vote (day vote, night kill vote)
|
||||
* Arguments:
|
||||
* * vt: vote type (getting a random day voter, or mafia night voter)
|
||||
* * vote_type: vote type (getting a random day voter, or mafia night voter)
|
||||
*/
|
||||
/datum/mafia_controller/proc/get_random_voter(vt)
|
||||
if(length(votes[vt]))
|
||||
return pick(votes[vt])
|
||||
/datum/mafia_controller/proc/get_random_voter(vote_type)
|
||||
if(length(votes[vote_type]))
|
||||
return pick(votes[vote_type])
|
||||
|
||||
/**
|
||||
* Adds mutable appearances to people who get publicly voted on (so not night votes) showing how many people are picking them
|
||||
@@ -604,9 +626,6 @@
|
||||
basic_setup()
|
||||
if("nuke")
|
||||
end_game()
|
||||
for(var/i in landmarks)
|
||||
qdel(i)
|
||||
qdel(town_center_landmark)
|
||||
qdel(src)
|
||||
if("next_phase")
|
||||
var/datum/timedevent/timer = SStimer.timer_id_dict[next_phase_timer]
|
||||
@@ -623,11 +642,33 @@
|
||||
continue
|
||||
player.body.forceMove(get_turf(player.assigned_landmark))
|
||||
if(failed.len)
|
||||
to_chat(usr, "List of players who no longer had a body (if you see this, the game is runtiming anyway so just hit \"New Game\" to end it")
|
||||
to_chat(usr, "List of players who no longer had a body (if you see this, the game is runtiming anyway so just hit \"New Game\" to end it)")
|
||||
for(var/i in failed)
|
||||
var/datum/mafia_role/fail = i
|
||||
to_chat(usr, fail.player_key)
|
||||
switch(action)
|
||||
if("debug_setup")
|
||||
var/list/debug_setup = list()
|
||||
var/list/rolelist_dict = list()
|
||||
var/done = FALSE
|
||||
for(var/p in typesof(/datum/mafia_role))
|
||||
var/datum/mafia_role/path = p
|
||||
rolelist_dict[initial(path.name) + " ([uppertext(initial(path.team))])"] = path
|
||||
rolelist_dict = list("CANCEL", "FINISH") + rolelist_dict
|
||||
while(!done)
|
||||
to_chat(usr, "You have a total player count of [assoc_value_sum(debug_setup)] in this setup.")
|
||||
var/chosen_role_name = input(usr,"Select a role!","Custom Setup Creation",rolelist_dict[1]) as null|anything in rolelist_dict
|
||||
if(chosen_role_name == "CANCEL")
|
||||
return
|
||||
if(chosen_role_name == "FINISH")
|
||||
break
|
||||
var/found_path = rolelist_dict[chosen_role_name]
|
||||
var/role_count = input(usr,"How many? Zero to cancel.","Custom Setup Creation",0) as null|num
|
||||
if(role_count > 0)
|
||||
debug_setup[found_path] = role_count
|
||||
custom_setup = debug_setup
|
||||
if("cancel_setup")
|
||||
custom_setup = list()
|
||||
switch(action) //both living and dead
|
||||
if("mf_lookup")
|
||||
var/role_lookup = params["atype"]
|
||||
var/datum/mafia_role/helper
|
||||
@@ -662,8 +703,7 @@
|
||||
spectators += C.ckey
|
||||
if(user_role.game_status == MAFIA_DEAD)
|
||||
return
|
||||
var/self_voting = user_role == on_trial ? TRUE : FALSE //used to block people from voting themselves innocent or guilty
|
||||
//User actions
|
||||
//User actions (just living)
|
||||
switch(action)
|
||||
if("mf_action")
|
||||
if(!user_role.actions.Find(params["atype"]))
|
||||
@@ -678,7 +718,7 @@
|
||||
if("Vote")
|
||||
if(phase != MAFIA_PHASE_VOTING)
|
||||
return
|
||||
vote_for(user_role,target,vt="Day")
|
||||
vote_for(user_role,target,vote_type="Day")
|
||||
if("Kill Vote")
|
||||
if(phase != MAFIA_PHASE_NIGHT || user_role.team != MAFIA_TEAM_MAFIA)
|
||||
return
|
||||
@@ -731,31 +771,87 @@
|
||||
. += L[key]
|
||||
|
||||
/**
|
||||
* Returns all setups that the amount of players signed up could support (so fill each role)
|
||||
* Arguments:
|
||||
* * ready_count: the amount of players signed up (not sane, so some players may have disconnected or rejoined ss13).
|
||||
* Returns a semirandom setup, with...
|
||||
* Town, Two invest roles, one protect role, sometimes a misc role, and the rest assistants for town.
|
||||
* Mafia, 2 normal mafia and one special.
|
||||
* Neutral, two disruption roles, sometimes one is a killing.
|
||||
*
|
||||
* See _defines.dm in the mafia folder for a rundown on what these groups of roles include.
|
||||
*/
|
||||
/datum/mafia_controller/proc/find_best_setup(ready_count)
|
||||
var/list/all_setups = GLOB.mafia_setups
|
||||
var/valid_setups = list()
|
||||
for(var/S in all_setups)
|
||||
var/req_players = assoc_value_sum(S)
|
||||
if(req_players <= ready_count)
|
||||
valid_setups += list(S)
|
||||
return length(valid_setups) > 0 ? pick(valid_setups) : null
|
||||
/datum/mafia_controller/proc/generate_random_setup()
|
||||
var/invests_left = 2
|
||||
var/protects_left = 1
|
||||
var/miscs_left = prob(35)
|
||||
var/mafiareg_left = 2
|
||||
var/mafiaspe_left = 1
|
||||
var/killing_role = prob(50)
|
||||
var/disruptors = killing_role ? 1 : 2 //still required to calculate overflow
|
||||
var/overflow_left = MAFIA_MAX_PLAYER_COUNT - (invests_left + protects_left + miscs_left + mafiareg_left + mafiaspe_left + killing_role + disruptors)
|
||||
|
||||
var/list/random_setup = list()
|
||||
for(var/i in 1 to MAFIA_MAX_PLAYER_COUNT) //should match the number of roles to add
|
||||
if(overflow_left)
|
||||
add_setup_role(random_setup, TOWN_OVERFLOW)
|
||||
overflow_left--
|
||||
else if(invests_left)
|
||||
add_setup_role(random_setup, TOWN_INVEST)
|
||||
invests_left--
|
||||
else if(protects_left)
|
||||
add_setup_role(random_setup, TOWN_PROTECT)
|
||||
protects_left--
|
||||
else if(miscs_left)
|
||||
add_setup_role(random_setup, TOWN_MISC)
|
||||
miscs_left--
|
||||
else if(mafiareg_left)
|
||||
add_setup_role(random_setup, MAFIA_REGULAR)
|
||||
mafiareg_left--
|
||||
else if(mafiaspe_left)
|
||||
add_setup_role(random_setup, MAFIA_SPECIAL)
|
||||
mafiaspe_left--
|
||||
else if(killing_role)
|
||||
add_setup_role(random_setup, NEUTRAL_KILL)
|
||||
killing_role--
|
||||
else
|
||||
add_setup_role(random_setup, NEUTRAL_DISRUPT)
|
||||
return random_setup
|
||||
|
||||
/**
|
||||
* Helper proc that adds a random role of a type to a setup. if it doesn't exist in the setup, it adds the path to the list and otherwise bumps the path in the list up one
|
||||
*/
|
||||
/datum/mafia_controller/proc/add_setup_role(setup_list, wanted_role_type)
|
||||
var/list/role_type_paths = list()
|
||||
for(var/path in typesof(/datum/mafia_role))
|
||||
var/datum/mafia_role/instance = path
|
||||
if(initial(instance.role_type) == wanted_role_type)
|
||||
role_type_paths += instance
|
||||
|
||||
var/mafia_path = pick(role_type_paths)
|
||||
var/datum/mafia_role/mafia_path_type = mafia_path
|
||||
var/found_role
|
||||
for(var/searched_path in setup_list)
|
||||
var/datum/mafia_role/searched_path_type = searched_path
|
||||
if(initial(mafia_path_type.name) == initial(searched_path_type.name))
|
||||
found_role = searched_path
|
||||
break
|
||||
if(found_role)
|
||||
setup_list[found_role] += 1
|
||||
return
|
||||
setup_list[mafia_path] = 1
|
||||
|
||||
/**
|
||||
* Called when enough players have signed up to fill a setup. DOESN'T NECESSARILY MEAN THE GAME WILL START.
|
||||
*
|
||||
* Checks for a custom setup, if so gets the required players from that and if not it sets the player requirement to MAFIA_MAX_PLAYER_COUNT and generates one IF basic setup starts a game.
|
||||
* Checks if everyone signed up is an observer, and is still connected. If people aren't, they're removed from the list.
|
||||
* If there aren't enough players post sanity, it aborts. otherwise, it selects enough people for the game and starts preparing the game for real.
|
||||
*/
|
||||
/datum/mafia_controller/proc/basic_setup()
|
||||
var/ready_count = length(GLOB.mafia_signup)
|
||||
var/list/setup = find_best_setup(ready_count)
|
||||
if(!setup)
|
||||
return
|
||||
var/req_players = assoc_value_sum(setup) //12
|
||||
var/req_players
|
||||
var/list/setup = custom_setup
|
||||
if(!setup.len)
|
||||
req_players = MAFIA_MAX_PLAYER_COUNT
|
||||
else
|
||||
req_players = assoc_value_sum(setup)
|
||||
|
||||
//final list for all the players who will be in this game
|
||||
var/list/filtered_keys = list()
|
||||
@@ -783,8 +879,10 @@
|
||||
for(var/unpicked in possible_keys)
|
||||
var/client/unpicked_client = GLOB.directory[unpicked]
|
||||
to_chat(unpicked_client, "<span class='danger'>Sorry, the starting mafia game has too many players and you were not picked.</span>")
|
||||
to_chat(unpicked_client, "<span class='warning'>You're still signed up, and have another chance to join when the one starting now finishes.</span>")
|
||||
to_chat(unpicked_client, "<span class='warning'>You're still signed up, getting messages from the current round, and have another chance to join when the one starting now finishes.</span>")
|
||||
|
||||
if(!setup.len) //don't actually have one yet, so generate a max player random setup. it's good to do this here instead of above so it doesn't generate one every time a game could possibly start.
|
||||
setup = generate_random_setup()
|
||||
prepare_game(setup,filtered_keys)
|
||||
start_game()
|
||||
|
||||
@@ -794,12 +892,9 @@
|
||||
* Only checks if everyone is actually valid to start (still connected and an observer) if there are enough players (basic_setup)
|
||||
*/
|
||||
/datum/mafia_controller/proc/try_autostart()
|
||||
if(phase != MAFIA_PHASE_SETUP)
|
||||
if(phase != MAFIA_PHASE_SETUP) // || !(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME))
|
||||
return
|
||||
var/min_players = INFINITY // fairly sure mmo mafia is not a thing and i'm lazy
|
||||
for(var/setup in GLOB.mafia_setups)
|
||||
min_players = min(min_players,assoc_value_sum(setup))
|
||||
if(GLOB.mafia_signup.len >= min_players)//enough people to try and make something
|
||||
if(GLOB.mafia_signup.len >= MAFIA_MAX_PLAYER_COUNT || custom_setup.len)//enough people to try and make something (or debug mode)
|
||||
basic_setup()
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user