Revert "Merge branch 'master' into Yeehaw"
This reverts commit972c03f79f, reversing changes made to8ebd698763.
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
var/list/modes // allowed modes
|
||||
var/list/gamemode_cache
|
||||
var/list/votable_modes // votable modes
|
||||
var/list/storyteller_cache
|
||||
var/list/mode_names
|
||||
var/list/mode_reports
|
||||
var/list/mode_false_report_weight
|
||||
@@ -38,7 +37,6 @@
|
||||
CRASH("/datum/controller/configuration/Load() called more than once!")
|
||||
InitEntries()
|
||||
LoadModes()
|
||||
storyteller_cache = typecacheof(/datum/dynamic_storyteller, TRUE)
|
||||
if(fexists("[directory]/config.txt") && LoadEntries("config.txt") <= 1)
|
||||
var/list/legacy_configs = list("game_options.txt", "dbconfig.txt", "comms.txt")
|
||||
for(var/I in legacy_configs)
|
||||
@@ -229,7 +227,6 @@
|
||||
for(var/T in gamemode_cache)
|
||||
// I wish I didn't have to instance the game modes in order to look up
|
||||
// their information, but it is the only way (at least that I know of).
|
||||
// for future reference: just use initial() lol
|
||||
var/datum/game_mode/M = new T()
|
||||
|
||||
if(M.config_tag)
|
||||
@@ -320,14 +317,6 @@
|
||||
return new T
|
||||
return new /datum/game_mode/extended()
|
||||
|
||||
/datum/controller/configuration/proc/pick_storyteller(storyteller_name)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/name = initial(S.name)
|
||||
if(name && name == storyteller_name)
|
||||
return T
|
||||
return /datum/dynamic_storyteller/classic
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_modes()
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/probability)
|
||||
|
||||
@@ -386,8 +386,6 @@
|
||||
config_entry_value = 72000
|
||||
min_val = 0
|
||||
|
||||
/datum/config_entry/flag/pai_custom_holoforms
|
||||
|
||||
/datum/config_entry/number/marauder_delay_non_reebe
|
||||
config_entry_value = 1800
|
||||
min_val = 0
|
||||
|
||||
@@ -315,7 +315,7 @@ SUBSYSTEM_DEF(air)
|
||||
var/starting_ats = active_turfs.len
|
||||
sleep(world.tick_lag)
|
||||
var/timer = world.timeofday
|
||||
log_mapping("There are [starting_ats] active turfs at roundstart caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required).")
|
||||
warning("There are [starting_ats] active turfs at roundstart, this is a mapping error caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required)")
|
||||
for(var/turf/T in active_turfs)
|
||||
GLOB.active_turfs_startlist += T
|
||||
|
||||
|
||||
@@ -658,7 +658,7 @@ SUBSYSTEM_DEF(job)
|
||||
message_admins(msg)
|
||||
CRASH(msg)
|
||||
|
||||
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff, bypass_prereqs = FALSE)
|
||||
/datum/controller/subsystem/job/proc/equip_loadout(mob/dead/new_player/N, mob/living/M, equipbackpackstuff)
|
||||
var/mob/the_mob = N
|
||||
if(!the_mob)
|
||||
the_mob = M // cause this doesn't get assigned if player is a latejoiner
|
||||
@@ -671,7 +671,7 @@ SUBSYSTEM_DEF(job)
|
||||
if(!G)
|
||||
continue
|
||||
var/permitted = TRUE
|
||||
if(!bypass_prereqs && G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles))
|
||||
if(G.restricted_roles && G.restricted_roles.len && !(M.mind.assigned_role in G.restricted_roles))
|
||||
permitted = FALSE
|
||||
if(G.donoritem && !G.donator_ckey_check(the_mob.client.ckey))
|
||||
permitted = FALSE
|
||||
|
||||
@@ -13,14 +13,13 @@ SUBSYSTEM_DEF(persistence)
|
||||
var/list/saved_messages = list()
|
||||
var/list/saved_modes = list(1,2,3)
|
||||
var/list/saved_dynamic_rules = list(list(),list(),list())
|
||||
var/list/saved_storytellers = list("foo","bar","baz","foo again","bar again")
|
||||
var/list/saved_threat_levels = list(1,1,1)
|
||||
var/list/saved_maps
|
||||
var/list/saved_trophies = list()
|
||||
var/list/spawned_objects = list()
|
||||
var/list/antag_rep = list()
|
||||
var/list/antag_rep_change = list()
|
||||
var/list/picture_logging_information = list()
|
||||
var/list/saved_votes = list()
|
||||
var/list/obj/structure/sign/picture_frame/photo_frames
|
||||
var/list/obj/item/storage/photo_album/photo_albums
|
||||
|
||||
@@ -30,12 +29,9 @@ SUBSYSTEM_DEF(persistence)
|
||||
LoadChiselMessages()
|
||||
LoadTrophies()
|
||||
LoadRecentModes()
|
||||
LoadRecentStorytellers()
|
||||
LoadRecentRulesets()
|
||||
LoadRecentThreats()
|
||||
LoadRecentMaps()
|
||||
LoadPhotoPersistence()
|
||||
for(var/client/C in GLOB.clients)
|
||||
LoadSavedVote(C.ckey)
|
||||
if(CONFIG_GET(flag/use_antag_rep))
|
||||
LoadAntagReputation()
|
||||
LoadRandomizedRecipes()
|
||||
@@ -173,23 +169,14 @@ SUBSYSTEM_DEF(persistence)
|
||||
return
|
||||
saved_modes = json["data"]
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentRulesets()
|
||||
var/json_file = file("data/RecentRulesets.json")
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentThreats()
|
||||
var/json_file = file("data/RecentThreatLevels.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = json_decode(file2text(json_file))
|
||||
if(!json)
|
||||
return
|
||||
saved_dynamic_rules = json["data"]
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentStorytellers()
|
||||
var/json_file = file("data/RecentStorytellers.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = json_decode(file2text(json_file))
|
||||
if(!json)
|
||||
return
|
||||
saved_storytellers = json["data"]
|
||||
saved_threat_levels = json["data"]
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
|
||||
var/json_file = file("data/RecentMaps.json")
|
||||
@@ -210,15 +197,6 @@ SUBSYSTEM_DEF(persistence)
|
||||
return
|
||||
antag_rep = json_decode(json)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadSavedVote(var/ckey)
|
||||
var/json_file = file("data/player_saves/[copytext(ckey,1,2)]/[ckey]/SavedVotes.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = json_decode(file2text(json_file))
|
||||
if(!json)
|
||||
return
|
||||
saved_votes[ckey] = json["data"]
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SetUpTrophies(list/trophy_items)
|
||||
for(var/A in GLOB.trophy_cases)
|
||||
var/obj/structure/displaycase/trophy/T = A
|
||||
@@ -252,7 +230,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
CollectRoundtype()
|
||||
if(istype(SSticker.mode, /datum/game_mode/dynamic))
|
||||
var/datum/game_mode/dynamic/mode = SSticker.mode
|
||||
CollectStoryteller(mode)
|
||||
CollectThreatLevel(mode)
|
||||
CollectRulesets(mode)
|
||||
RecordMaps()
|
||||
SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
|
||||
@@ -410,16 +388,13 @@ SUBSYSTEM_DEF(persistence)
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectStoryteller(var/datum/game_mode/dynamic/mode)
|
||||
saved_storytellers.len = 5
|
||||
saved_storytellers[5] = saved_storytellers[4]
|
||||
saved_storytellers[4] = saved_storytellers[3]
|
||||
saved_storytellers[3] = saved_storytellers[2]
|
||||
saved_storytellers[2] = saved_storytellers[1]
|
||||
saved_storytellers[1] = mode.storyteller.name
|
||||
var/json_file = file("data/RecentStorytellers.json")
|
||||
/datum/controller/subsystem/persistence/proc/CollectThreatLevel(var/datum/game_mode/dynamic/mode)
|
||||
saved_threat_levels[3] = saved_threat_levels[2]
|
||||
saved_threat_levels[2] = saved_threat_levels [1]
|
||||
saved_threat_levels[1] = mode.threat_level
|
||||
var/json_file = file("data/RecentThreatLevels.json")
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_storytellers
|
||||
file_data["data"] = saved_threat_levels
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
@@ -427,9 +402,8 @@ SUBSYSTEM_DEF(persistence)
|
||||
saved_dynamic_rules[3] = saved_dynamic_rules[2]
|
||||
saved_dynamic_rules[2] = saved_dynamic_rules[1]
|
||||
saved_dynamic_rules[1] = list()
|
||||
for(var/r in mode.executed_rules)
|
||||
var/datum/dynamic_ruleset/rule = r
|
||||
saved_dynamic_rules[1] += rule.config_tag
|
||||
for(var/datum/dynamic_ruleset/ruleset in mode.executed_rules)
|
||||
saved_dynamic_rules[1] += ruleset.config_tag
|
||||
var/json_file = file("data/RecentRulesets.json")
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_dynamic_rules
|
||||
@@ -499,11 +473,3 @@ SUBSYSTEM_DEF(persistence)
|
||||
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveSavedVotes()
|
||||
for(var/ckey in saved_votes)
|
||||
var/json_file = file("data/player_saves/[copytext(ckey,1,2)]/[ckey]/SavedVotes.json")
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_votes[ckey]
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
@@ -17,7 +17,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
/datum/controller/subsystem/processing/quirks/Initialize(timeofday)
|
||||
if(!quirks.len)
|
||||
SetupQuirks()
|
||||
quirk_blacklist = list(list("Blind","Nearsighted"),list("Jolly","Depression","Apathetic"),list("Ageusia","Deviant Tastes"),list("Ananas Affinity","Ananas Aversion"),list("Alcohol Tolerance","Alcohol Intolerance"),list("Alcohol Intolerance","Drunken Resilience"))
|
||||
quirk_blacklist = list(list("Blind","Nearsighted"),list("Jolly","Depression","Apathetic"),list("Ageusia","Deviant Tastes"),list("Ananas Affinity","Ananas Aversion"))
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/SetupQuirks()
|
||||
@@ -46,8 +46,8 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
badquirk = TRUE
|
||||
if(badquirk)
|
||||
cli.prefs.save_character()
|
||||
if (!silent && LAZYLEN(cut))
|
||||
to_chat(to_chat_target || user, "<span class='boldwarning'>Some quirks have been cut from your character because of these quirks conflicting with your job assignment: [english_list(cut)].</span>")
|
||||
if(!silent && LAZYLEN(cut))
|
||||
to_chat(to_chat_target || user, "<span class='boldwarning'>All of your non-neutral character quirks have been cut due to these quirks conflicting with your job assignment: [english_list(cut)].</span>")
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/quirk_path_by_name(name)
|
||||
return quirks[name]
|
||||
@@ -66,7 +66,6 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/our_quirks, datum/job/job)
|
||||
var/list/cut = list()
|
||||
var/list/banned_names = list()
|
||||
var/pointscut = 0
|
||||
for(var/i in job.blacklisted_quirks)
|
||||
var/name = quirk_name_by_path(i)
|
||||
if(name)
|
||||
@@ -76,17 +75,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
for(var/i in blacklisted)
|
||||
our_quirks -= i
|
||||
cut += i
|
||||
pointscut += quirk_points_by_name(i)
|
||||
if (pointscut != 0)
|
||||
for (var/i in shuffle(our_quirks))
|
||||
if (quirk_points_by_name(i) < pointscut || (pointscut < 0) ? quirk_points_by_name(i) <= 0 : quirk_points_by_name(i) >= 0)
|
||||
continue
|
||||
else
|
||||
our_quirks -= i
|
||||
cut += i
|
||||
pointscut += quirk_points_by_name(i)
|
||||
if (pointscut >= 0) //with how it works, it needs to be above zero, not below, as points for positive is positive, and negative is negative, we only want it to break if it's above zero, ie. we cut more positive than negative
|
||||
break
|
||||
|
||||
/* //Code to automatically reduce positive quirks until balance is even.
|
||||
var/points_used = total_points(our_quirks)
|
||||
if(points_used > 0)
|
||||
@@ -102,11 +91,10 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
*/
|
||||
|
||||
//Nah, let's null all non-neutrals out.
|
||||
if (pointscut != 0)// only if the pointscutting didn't work.
|
||||
if(cut.len)
|
||||
for(var/i in our_quirks)
|
||||
if(quirk_points_by_name(i) != 0)
|
||||
//cut += i -- Commented out: Only show the ones that triggered the quirk purge.
|
||||
our_quirks -= i
|
||||
if(cut.len)
|
||||
for(var/i in our_quirks)
|
||||
if(quirk_points_by_name(i) != 0)
|
||||
//cut += i -- Commented out: Only show the ones that triggered the quirk purge.
|
||||
our_quirks -= i
|
||||
|
||||
return cut
|
||||
|
||||
@@ -37,7 +37,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/points = 5000 //number of trade-points we have
|
||||
var/centcom_message = "" //Remarks from CentCom on how well you checked the last order.
|
||||
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies
|
||||
var/passive_supply_points_per_minute = 500
|
||||
var/passive_supply_points_per_minute = 750
|
||||
|
||||
var/list/supply_packs = list()
|
||||
var/list/shoppinglist = list()
|
||||
|
||||
@@ -483,10 +483,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
SSticker.timeLeft = 900
|
||||
SSticker.modevoted = TRUE
|
||||
var/dynamic = CONFIG_GET(flag/dynamic_voting)
|
||||
if(dynamic)
|
||||
SSvote.initiate_vote("dynamic","server",hideresults=TRUE,votesystem=SCORE_VOTING,forced=TRUE,vote_time = 2 MINUTES)
|
||||
else
|
||||
SSvote.initiate_vote("roundtype","server",hideresults=TRUE,votesystem=PLURALITY_VOTING,forced=TRUE, vote_time = 2 MINUTES)
|
||||
SSvote.initiate_vote(dynamic ? "dynamic" : "roundtype","server",TRUE)
|
||||
|
||||
/datum/controller/subsystem/ticker/Recover()
|
||||
current_state = SSticker.current_state
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define VOTE_COOLDOWN 10
|
||||
|
||||
SUBSYSTEM_DEF(vote)
|
||||
name = "Vote"
|
||||
wait = 10
|
||||
@@ -10,17 +8,13 @@ SUBSYSTEM_DEF(vote)
|
||||
|
||||
var/initiator = null
|
||||
var/started_time = null
|
||||
var/end_time = 0
|
||||
var/time_remaining = 0
|
||||
var/mode = null
|
||||
var/vote_system = PLURALITY_VOTING
|
||||
var/question = null
|
||||
var/list/choices = list()
|
||||
var/list/choice_descs = list() // optional descriptions
|
||||
var/list/voted = list()
|
||||
var/list/voting = list()
|
||||
var/list/saved = list()
|
||||
var/list/generated_actions = list()
|
||||
var/next_pop = 0
|
||||
|
||||
var/obfuscated = FALSE//CIT CHANGE - adds obfuscated/admin-only votes
|
||||
|
||||
@@ -28,30 +22,28 @@ SUBSYSTEM_DEF(vote)
|
||||
|
||||
/datum/controller/subsystem/vote/fire() //called by master_controller
|
||||
if(mode)
|
||||
if(end_time < world.time)
|
||||
time_remaining = round((started_time + CONFIG_GET(number/vote_period) - world.time)/10)
|
||||
|
||||
if(time_remaining < 0)
|
||||
result()
|
||||
SSpersistence.SaveSavedVotes()
|
||||
for(var/client/C in voting)
|
||||
C << browse(null, "window=vote;can_close=0")
|
||||
reset()
|
||||
else if(next_pop < world.time)
|
||||
else
|
||||
var/datum/browser/client_popup
|
||||
for(var/client/C in voting)
|
||||
client_popup = new(C, "vote", "Voting Panel", nwidth=600,nheight=700)
|
||||
client_popup = new(C, "vote", "Voting Panel")
|
||||
client_popup.set_window_options("can_close=0")
|
||||
client_popup.set_content(interface(C))
|
||||
client_popup.open(0)
|
||||
next_pop = world.time+VOTE_COOLDOWN
|
||||
|
||||
|
||||
|
||||
/datum/controller/subsystem/vote/proc/reset()
|
||||
initiator = null
|
||||
end_time = 0
|
||||
time_remaining = 0
|
||||
mode = null
|
||||
question = null
|
||||
choices.Cut()
|
||||
choice_descs.Cut()
|
||||
voted.Cut()
|
||||
voting.Cut()
|
||||
obfuscated = FALSE //CIT CHANGE - obfuscated votes
|
||||
@@ -92,114 +84,17 @@ SUBSYSTEM_DEF(vote)
|
||||
. += option
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text)
|
||||
// https://en.wikipedia.org/wiki/Schulze_method#Implementation
|
||||
var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
for(var/a in 1 to choices.len)
|
||||
for(var/b in a+1 to choices.len)
|
||||
var/a_rank = this_vote.Find(a)
|
||||
var/b_rank = this_vote.Find(b)
|
||||
a_rank = a_rank ? a_rank : choices.len+1
|
||||
b_rank = b_rank ? b_rank : choices.len+1
|
||||
if(a_rank<b_rank)
|
||||
d[a][b]++
|
||||
else if(b_rank<a_rank)
|
||||
d[b][a]++
|
||||
//if equal, do nothing
|
||||
var/list/p[][] = new/list(choices.len,choices.len) //matrix of shortest path from a to b
|
||||
for(var/i in 1 to choices.len)
|
||||
for(var/j in 1 to choices.len)
|
||||
if(i != j)
|
||||
var/pref_number = d[i][j]
|
||||
var/opposite_pref = d[j][i]
|
||||
if(pref_number>opposite_pref)
|
||||
p[i][j] = d[i][j]
|
||||
p[j][i] = 0
|
||||
else
|
||||
p[i][j] = 0
|
||||
p[j][i] = d[i][j]
|
||||
for(var/i in 1 to choices.len)
|
||||
for(var/j in 1 to choices.len)
|
||||
if(i != j)
|
||||
for(var/k in 1 to choices.len) // YEAH O(n^3) !!
|
||||
if(i != k && j != k)
|
||||
p[j][k] = max(p[j][k],min(p[j][i], p[i][k]))
|
||||
//one last pass, now that we've done the math
|
||||
for(var/i in 1 to choices.len)
|
||||
for(var/j in 1 to choices.len)
|
||||
if(i != j)
|
||||
SSblackbox.record_feedback("nested tally","voting",p[i][j],list(blackbox_text,"Shortest Paths",choices[i],choices[j]))
|
||||
if(p[i][j] >= p[j][i])
|
||||
choices[choices[i]]++ // higher shortest path = better candidate, so we add to choices here
|
||||
// choices[choices[i]] is the schulze ranking, here, rather than raw vote numbers
|
||||
|
||||
/datum/controller/subsystem/vote/proc/calculate_majority_judgement_vote(var/blackbox_text)
|
||||
// https://en.wikipedia.org/wiki/Majority_judgment
|
||||
var/list/scores_by_choice = list()
|
||||
for(var/choice in choices)
|
||||
scores_by_choice[choice] = list()
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
var/list/pretty_vote = list()
|
||||
for(var/choice in this_vote)
|
||||
sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc)
|
||||
// START BALLOT GATHERING
|
||||
pretty_vote += choice
|
||||
pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]]
|
||||
SSblackbox.record_feedback("associative","voting_ballots",1,pretty_vote)
|
||||
// END BALLOT GATHERING
|
||||
for(var/score_name in scores_by_choice)
|
||||
var/list/score = scores_by_choice[score_name]
|
||||
for(var/indiv_score in score)
|
||||
SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score]))
|
||||
if(score.len == 0)
|
||||
scores_by_choice -= score_name
|
||||
while(scores_by_choice.len > 1)
|
||||
var/highest_median = 0
|
||||
for(var/score_name in scores_by_choice) // first get highest median
|
||||
var/list/score = scores_by_choice[score_name]
|
||||
if(!score.len)
|
||||
scores_by_choice -= score_name
|
||||
continue
|
||||
var/median = score[max(1,round(score.len/2))]
|
||||
if(median >= highest_median)
|
||||
highest_median = median
|
||||
for(var/score_name in scores_by_choice) // then, remove
|
||||
var/list/score = scores_by_choice[score_name]
|
||||
var/median = score[max(1,round(score.len/2))]
|
||||
if(median < highest_median)
|
||||
scores_by_choice -= score_name
|
||||
for(var/score_name in scores_by_choice) // after removals
|
||||
var/list/score = scores_by_choice[score_name]
|
||||
if(score.len == 0)
|
||||
choices[score_name] += 100 // we're in a tie situation--just go with the first one
|
||||
return
|
||||
var/median_pos = max(1,round(score.len/2))
|
||||
score.Cut(median_pos,median_pos+1)
|
||||
choices[score_name]++
|
||||
|
||||
/datum/controller/subsystem/vote/proc/announce_result()
|
||||
var/vote_title_text
|
||||
var/text
|
||||
if(question)
|
||||
text += "<b>[question]</b>"
|
||||
vote_title_text = "[question]"
|
||||
else
|
||||
text += "<b>[capitalize(mode)] Vote</b>"
|
||||
vote_title_text = "[capitalize(mode)] Vote"
|
||||
if(vote_system == RANKED_CHOICE_VOTING)
|
||||
calculate_condorcet_votes(vote_title_text)
|
||||
if(vote_system == SCORE_VOTING)
|
||||
calculate_majority_judgement_vote(vote_title_text)
|
||||
var/list/winners = get_result()
|
||||
var/text
|
||||
var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic"
|
||||
if(winners.len > 0)
|
||||
if(question)
|
||||
text += "<b>[question]</b>"
|
||||
else
|
||||
text += "<b>[capitalize(mode)] Vote</b>"
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes = list()
|
||||
if(!obfuscated && vote_system == RANKED_CHOICE_VOTING)
|
||||
text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
@@ -221,25 +116,17 @@ SUBSYSTEM_DEF(vote)
|
||||
log_vote(text)
|
||||
remove_action_buttons()
|
||||
to_chat(world, "\n<font color='purple'>[text]</font>")
|
||||
switch(vote_system)
|
||||
if(APPROVAL_VOTING,PLURALITY_VOTING)
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
SSblackbox.record_feedback("nested tally","voting",choices[choices[i]],list(vote_title_text,choices[i]))
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
for(var/i=1,i<=voted.len,i++)
|
||||
var/list/myvote = voted[voted[i]]
|
||||
for(var/j=1,j<=myvote.len,j++)
|
||||
SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]]))
|
||||
if(obfuscated) //CIT CHANGE - adds obfuscated votes. this messages admins with the vote's true results
|
||||
var/admintext = "Obfuscated results"
|
||||
if(vote_system == RANKED_CHOICE_VOTING)
|
||||
admintext += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
admintext += "\n<b>[choices[i]]:</b> [votes]"
|
||||
message_admins(admintext)
|
||||
return .
|
||||
|
||||
#define PEACE "calm"
|
||||
#define CHAOS "chaotic"
|
||||
|
||||
/datum/controller/subsystem/vote/proc/result()
|
||||
. = announce_result()
|
||||
var/restart = 0
|
||||
@@ -265,15 +152,33 @@ SUBSYSTEM_DEF(vote)
|
||||
if("dynamic")
|
||||
if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started.
|
||||
return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.")
|
||||
if(. == "Secret")
|
||||
GLOB.master_mode = "secret"
|
||||
SSticker.save_mode(.)
|
||||
message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]")
|
||||
log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].")
|
||||
else
|
||||
GLOB.master_mode = "dynamic"
|
||||
var/datum/dynamic_storyteller/S = config.pick_storyteller(.)
|
||||
GLOB.dynamic_storyteller_type = S
|
||||
GLOB.master_mode = "dynamic"
|
||||
if("extended" in choices)
|
||||
if(. == "extended")
|
||||
GLOB.dynamic_forced_extended = TRUE // we still do the rest of the stuff
|
||||
choices[PEACE] += choices["extended"]
|
||||
var/mean = 0
|
||||
var/voters = 0
|
||||
for(var/client/c in GLOB.clients)
|
||||
var/vote = c.prefs.preferred_chaos
|
||||
if(vote)
|
||||
voters += 1
|
||||
switch(vote)
|
||||
if(CHAOS_NONE)
|
||||
mean -= 0.1
|
||||
if(CHAOS_LOW)
|
||||
mean -= 0.05
|
||||
if(CHAOS_HIGH)
|
||||
mean += 0.05
|
||||
if(CHAOS_MAX)
|
||||
mean += 0.1
|
||||
mean/=voters
|
||||
if(voted.len != 0)
|
||||
mean += (choices[PEACE]*-1+choices[CHAOS])/voted.len
|
||||
GLOB.dynamic_curve_centre = mean*20
|
||||
GLOB.dynamic_curve_width = CLAMP(2-abs(mean*5),0.5,4)
|
||||
to_chat(world,"<span class='boldannounce'>Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width].</span>")
|
||||
log_admin("Dynamic curve centre set to [GLOB.dynamic_curve_centre] and width set to [GLOB.dynamic_curve_width]")
|
||||
if("map")
|
||||
var/datum/map_config/VM = config.maplist[.]
|
||||
message_admins("The map has been voted for and will change to: [VM.map_name]")
|
||||
@@ -291,58 +196,27 @@ SUBSYSTEM_DEF(vote)
|
||||
else
|
||||
to_chat(world, "<span style='boldannounce'>Notice:Restart vote will not restart the server automatically because there are active admins on.</span>")
|
||||
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
|
||||
|
||||
|
||||
return .
|
||||
|
||||
/datum/controller/subsystem/vote/proc/submit_vote(vote, score = 0)
|
||||
/datum/controller/subsystem/vote/proc/submit_vote(vote)
|
||||
if(mode)
|
||||
if(CONFIG_GET(flag/no_dead_vote) && usr.stat == DEAD && !usr.client.holder)
|
||||
return 0
|
||||
if(vote && ISINRANGE(vote, 1, choices.len))
|
||||
switch(vote_system)
|
||||
if(PLURALITY_VOTING)
|
||||
if(usr.ckey in voted)
|
||||
choices[choices[voted[usr.ckey]]]--
|
||||
voted[usr.ckey] = vote
|
||||
choices[choices[vote]]++
|
||||
return vote
|
||||
else
|
||||
voted += usr.ckey
|
||||
voted[usr.ckey] = vote
|
||||
choices[choices[vote]]++ //check this
|
||||
return vote
|
||||
if(APPROVAL_VOTING)
|
||||
if(usr.ckey in voted)
|
||||
if(vote in voted[usr.ckey])
|
||||
voted[usr.ckey] -= vote
|
||||
choices[choices[vote]]--
|
||||
else
|
||||
voted[usr.ckey] += vote
|
||||
choices[choices[vote]]++
|
||||
else
|
||||
voted += usr.ckey
|
||||
voted[usr.ckey] = list(vote)
|
||||
choices[choices[vote]]++
|
||||
return vote
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
if(usr.ckey in voted)
|
||||
if(vote in voted[usr.ckey])
|
||||
voted[usr.ckey] -= vote
|
||||
else
|
||||
voted += usr.ckey
|
||||
voted[usr.ckey] = list()
|
||||
voted[usr.ckey] += vote
|
||||
saved -= usr.ckey
|
||||
if(SCORE_VOTING)
|
||||
if(!(usr.ckey in voted))
|
||||
voted += usr.ckey
|
||||
voted[usr.ckey] = list()
|
||||
voted[usr.ckey][choices[vote]] = score
|
||||
saved -= usr.ckey
|
||||
if(!(usr.ckey in voted))
|
||||
if(vote && 1<=vote && vote<=choices.len)
|
||||
voted += usr.ckey
|
||||
voted[usr.ckey] = vote
|
||||
choices[choices[vote]]++ //check this
|
||||
return vote
|
||||
else if(vote && 1<=vote && vote<=choices.len)
|
||||
choices[choices[voted[usr.ckey]]]--
|
||||
voted[usr.ckey] = vote
|
||||
choices[choices[vote]]++
|
||||
return vote
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, hideresults, votesystem = PLURALITY_VOTING, forced = FALSE,vote_time = -1)//CIT CHANGE - adds hideresults argument to votes to allow for obfuscated votes
|
||||
vote_system = votesystem
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, hideresults)//CIT CHANGE - adds hideresults argument to votes to allow for obfuscated votes
|
||||
if(!mode)
|
||||
if(started_time)
|
||||
var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay))
|
||||
@@ -383,17 +257,11 @@ SUBSYSTEM_DEF(vote)
|
||||
if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote
|
||||
choices.Add("secret", "extended")
|
||||
if("dynamic")
|
||||
for(var/T in config.storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/recent_rounds = 0
|
||||
for(var/i in 1 to SSpersistence.saved_storytellers.len)
|
||||
if(SSpersistence.saved_storytellers[i] == initial(S.name))
|
||||
recent_rounds++
|
||||
if(recent_rounds < initial(S.weight))
|
||||
choices.Add(initial(S.name))
|
||||
choice_descs.Add(initial(S.desc))
|
||||
choices.Add("Secret")
|
||||
choice_descs.Add("Standard secret. Switches mode if it wins.")
|
||||
var/saved_threats = SSpersistence.saved_threat_levels
|
||||
if((saved_threats[1]+saved_threats[2]+saved_threats[3])>150)
|
||||
choices.Add("extended",PEACE,CHAOS)
|
||||
else
|
||||
choices.Add(PEACE,CHAOS)
|
||||
if("custom")
|
||||
question = stripped_input(usr,"What is the vote for?")
|
||||
if(!question)
|
||||
@@ -412,11 +280,9 @@ SUBSYSTEM_DEF(vote)
|
||||
if(mode == "custom")
|
||||
text += "\n[question]"
|
||||
log_vote(text)
|
||||
var/vp = vote_time
|
||||
if(vp == -1)
|
||||
vp = CONFIG_GET(number/vote_period)
|
||||
var/vp = CONFIG_GET(number/vote_period)
|
||||
to_chat(world, "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=[REF(src)]'>here</a> to place your votes.\nYou have [DisplayTimeText(vp)] to vote.</font>")
|
||||
end_time = started_time+vp
|
||||
time_remaining = round(vp/10)
|
||||
for(var/c in GLOB.clients)
|
||||
SEND_SOUND(c, sound('sound/misc/server-ready.ogg'))
|
||||
var/client/C = c
|
||||
@@ -426,11 +292,6 @@ SUBSYSTEM_DEF(vote)
|
||||
C.player_details.player_actions += V
|
||||
V.Grant(C.mob)
|
||||
generated_actions += V
|
||||
if(forced)
|
||||
var/datum/browser/popup = new(C, "vote", "Voting Panel",nwidth=600,nheight=700)
|
||||
popup.set_window_options("can_close=0")
|
||||
popup.set_content(SSvote.interface(C))
|
||||
popup.open(0)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -450,71 +311,14 @@ SUBSYSTEM_DEF(vote)
|
||||
. += "<h2>Vote: '[question]'</h2>"
|
||||
else
|
||||
. += "<h2>Vote: [capitalize(mode)]</h2>"
|
||||
switch(vote_system)
|
||||
if(PLURALITY_VOTING)
|
||||
. += "<h3>Vote one.</h3>"
|
||||
if(APPROVAL_VOTING)
|
||||
. += "<h3>Vote any number of choices.</h3>"
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
. += "<h3>Vote by order of preference. Revoting will demote to the bottom. 1 is your favorite, and higher numbers are worse.</h3>"
|
||||
if(SCORE_VOTING)
|
||||
. += "<h3>Grade the candidates by how much you like them.</h3>"
|
||||
. += "<h3>No-votes have no power--your opinion is only heard if you vote!</h3>"
|
||||
. += "Time Left: [DisplayTimeText(end_time-world.time)]<hr><ul>"
|
||||
switch(vote_system)
|
||||
if(PLURALITY_VOTING, APPROVAL_VOTING)
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
var/ivotedforthis = FALSE
|
||||
switch(vote_system)
|
||||
if(PLURALITY_VOTING)
|
||||
ivotedforthis = ((C.ckey in voted) && (voted[C.ckey] == i))
|
||||
if(APPROVAL_VOTING)
|
||||
ivotedforthis = ((C.ckey in voted) && (i in voted[C.ckey]))
|
||||
if(!votes)
|
||||
votes = 0
|
||||
. += "<li>[ivotedforthis ? "<b>" : ""]<a href='?src=[REF(src)];vote=[i]'>[choices[i]]</a> ([obfuscated ? (admin ? "??? ([votes])" : "???") : votes] votes)[ivotedforthis ? "</b>" : ""]</li>" // CIT CHANGE - adds obfuscated votes
|
||||
if(choice_descs.len >= i)
|
||||
. += "<li>[choice_descs[i]]</li>"
|
||||
. += "</ul><hr>"
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
var/list/myvote = voted[C.ckey]
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/vote = (myvote ? (myvote.Find(i)) : 0)
|
||||
if(vote)
|
||||
. += "<li><b><a href='?src=[REF(src)];vote=[i]'>[choices[i]]</a> ([vote])</b></li>"
|
||||
else
|
||||
. += "<li><a href='?src=[REF(src)];vote=[i]'>[choices[i]]</a></li>"
|
||||
if(choice_descs.len >= i)
|
||||
. += "<li>[choice_descs[i]]</li>"
|
||||
. += "</ul><hr>"
|
||||
if(!(C.ckey in saved))
|
||||
. += "(<a href='?src=[REF(src)];vote=save'>Save vote</a>)"
|
||||
else
|
||||
. += "(Saved!)"
|
||||
. += "(<a href='?src=[REF(src)];vote=load'>Load vote from save</a>)"
|
||||
. += "(<a href='?src=[REF(src)];vote=reset'>Reset votes</a>)"
|
||||
if(SCORE_VOTING)
|
||||
var/list/myvote = voted[C.ckey]
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
. += "<li><b>[choices[i]]</b>"
|
||||
for(var/r in 1 to GLOB.vote_score_options.len)
|
||||
. += " <a href='?src=[REF(src)];vote=[i];score=[r]'>"
|
||||
if((choices[i] in myvote) && myvote[choices[i]] == r)
|
||||
. +="<b>([GLOB.vote_score_options[r]])</b>"
|
||||
else
|
||||
. +="[GLOB.vote_score_options[r]]"
|
||||
. += "</a>"
|
||||
. += "</li>"
|
||||
if(choice_descs.len >= i)
|
||||
. += "<li>[choice_descs[i]]</li>"
|
||||
. += "</ul><hr>"
|
||||
if(!(C.ckey in saved))
|
||||
. += "(<a href='?src=[REF(src)];vote=save'>Save vote</a>)"
|
||||
else
|
||||
. += "(Saved!)"
|
||||
. += "(<a href='?src=[REF(src)];vote=load'>Load vote from save</a>)"
|
||||
. += "(<a href='?src=[REF(src)];vote=reset'>Reset votes</a>)"
|
||||
. += "Time Left: [time_remaining] s<hr><ul>"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
var/ivotedforthis = ((C.ckey in voted) && (voted[C.ckey] == i) ? TRUE : FALSE)
|
||||
if(!votes)
|
||||
votes = 0
|
||||
. += "<li>[ivotedforthis ? "<b>" : ""]<a href='?src=[REF(src)];vote=[i]'>[choices[i]]</a> ([obfuscated ? (admin ? "??? ([votes])" : "???") : votes] votes)[ivotedforthis ? "</b>" : ""]</li>" // CIT CHANGE - adds obfuscated votes
|
||||
. += "</ul><hr>"
|
||||
if(admin)
|
||||
. += "(<a href='?src=[REF(src)];vote=cancel'>Cancel Vote</a>) "
|
||||
else
|
||||
@@ -572,31 +376,8 @@ SUBSYSTEM_DEF(vote)
|
||||
if("custom")
|
||||
if(usr.client.holder)
|
||||
initiate_vote("custom",usr.key)
|
||||
if("reset")
|
||||
if(usr.ckey in voted)
|
||||
voted -= usr.ckey
|
||||
if("save")
|
||||
if(usr.ckey in voted)
|
||||
if(!(usr.ckey in SSpersistence.saved_votes))
|
||||
SSpersistence.saved_votes[usr.ckey] = list()
|
||||
SSpersistence.saved_votes[usr.ckey][mode] = voted[usr.ckey]
|
||||
saved += usr.ckey
|
||||
if("load")
|
||||
if(!(usr.ckey in SSpersistence.saved_votes))
|
||||
SSpersistence.LoadSavedVote(usr.ckey)
|
||||
if(!(usr.ckey in SSpersistence.saved_votes))
|
||||
SSpersistence.saved_votes[usr.ckey] = list()
|
||||
if(usr.ckey in voted)
|
||||
SSpersistence.saved_votes[usr.ckey][mode] = voted[usr.ckey]
|
||||
else
|
||||
SSpersistence.saved_votes[usr.ckey][mode] = list()
|
||||
voted[usr.ckey] = SSpersistence.saved_votes[usr.ckey][mode]
|
||||
saved += usr.ckey
|
||||
else
|
||||
if(vote_system == SCORE_VOTING)
|
||||
submit_vote(round(text2num(href_list["vote"])),round(text2num(href_list["score"])))
|
||||
else
|
||||
submit_vote(round(text2num(href_list["vote"])))
|
||||
submit_vote(round(text2num(href_list["vote"])))
|
||||
usr.vote()
|
||||
|
||||
/datum/controller/subsystem/vote/proc/remove_action_buttons()
|
||||
@@ -611,7 +392,7 @@ SUBSYSTEM_DEF(vote)
|
||||
set category = "OOC"
|
||||
set name = "Vote"
|
||||
|
||||
var/datum/browser/popup = new(src, "vote", "Voting Panel",nwidth=600,nheight=700)
|
||||
var/datum/browser/popup = new(src, "vote", "Voting Panel")
|
||||
popup.set_window_options("can_close=0")
|
||||
popup.set_content(SSvote.interface(client))
|
||||
popup.open(0)
|
||||
@@ -638,3 +419,6 @@ SUBSYSTEM_DEF(vote)
|
||||
var/datum/player_details/P = GLOB.player_details[owner.ckey]
|
||||
if(P)
|
||||
P.player_actions -= src
|
||||
|
||||
#undef PEACE
|
||||
#undef CHAOS
|
||||
|
||||
Reference in New Issue
Block a user