Map voting

This commit is contained in:
Chris
2014-11-13 22:05:30 -06:00
parent ca9f2a3887
commit 9784e29eb9
7 changed files with 529 additions and 447 deletions

View File

@@ -12,6 +12,32 @@
return text
/proc/get_maps(root="maps/voting/")
var/list/maps = list()
var/recursion_limit = 20 //lots of maps waiting to be played, feels like TF2
//Get our potential maps
//testing("starting in [root]")
for(var/potential in flist(root))
if(copytext(potential,-1,0 != "/")) continue // Not a directory, ignore it.
//testing("Inside [root + potential]")
if(!recursion_limit) break
//our current working directory
var/path = root + potential
//The DMB that has the map we want.
var/binary
//Looking for a binary
for(var/binaries in flist(path))
//testing("Checking file [binaries]")
if(copytext(binaries,-4,0) == ".dmb")
binary = binaries
break
if(!binary)
warning("Map folder [path] does not contain a valid byond binary, skipping.")
else
maps[potential] = path + binary
recursion_limit--
return maps
//Sends resource files to client cache
/client/proc/getFiles()
for(var/file in args)

View File

@@ -153,6 +153,8 @@
var/emag_recharge_rate = 0
var/emag_recharge_ticks = 0
var/map_voting = 0
/datum/configuration/New()
. = ..()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
@@ -504,6 +506,8 @@
media_secret_key = value
if("vgws_base_url")
vgws_base_url = value
if("map_voting")
map_voting = 1
else
diary << "Unknown setting in configuration: '[name]'"

View File

@@ -10,8 +10,10 @@ var/global/datum/controller/vote/vote = new()
var/list/voted = list()
var/list/voting = list()
var/list/current_votes = list()
var/list/ismapvote
var/chosen_map
New()
/datum/controller/vote/New()
. = ..()
if (vote != src)
@@ -20,7 +22,7 @@ var/global/datum/controller/vote/vote = new()
vote = src
proc/process() //called by master_controller
/datum/controller/vote/proc/process() //called by master_controller
if(mode)
// No more change mode votes after the game has started.
// 3 is GAME_STATE_PLAYING, but that #define is undefined for some reason
@@ -31,7 +33,7 @@ var/global/datum/controller/vote/vote = new()
// Calculate how much time is remaining by comparing current time, to time of vote start,
// plus vote duration
time_remaining = round((started_time + config.vote_period - world.time)/10)
time_remaining = (ismapvote && ismapvote.len) ? (round((started_time + 600 - world.time)/10)) : (round((started_time + config.vote_period - world.time)/10))
if(time_remaining < 0)
result()
@@ -44,9 +46,9 @@ var/global/datum/controller/vote/vote = new()
if(C)
C << browse(vote.interface(C),"window=vote;can_close=0")
voting.Cut()
//voting.Cut()
proc/reset()
/datum/controller/vote/proc/reset()
initiator = null
time_remaining = 0
mode = null
@@ -56,7 +58,7 @@ var/global/datum/controller/vote/vote = new()
voting.Cut()
current_votes.Cut()
proc/get_result()
/datum/controller/vote/proc/get_result()
//get the highest number of votes
var/greatest_votes = 0
var/total_votes = 0
@@ -104,14 +106,14 @@ var/global/datum/controller/vote/vote = new()
. += option
return .
proc/announce_result()
/datum/controller/vote/proc/announce_result()
var/list/winners = get_result()
var/text
if(winners.len > 0)
if(winners.len > 1)
text = "<b>Vote Tied Between:</b>\n"
text = "<b>Vote Tied Between:</b><br>"
for(var/option in winners)
text += "\t[option]\n"
text += "\t[option]<br>"
. = pick(winners)
text += "<b>Vote Result: [.]</b>"
else
@@ -120,7 +122,7 @@ var/global/datum/controller/vote/vote = new()
world << "<font color='purple'>[text]</font>"
return .
proc/result()
/datum/controller/vote/proc/result()
. = announce_result()
var/restart = 0
if(.)
@@ -141,6 +143,10 @@ var/global/datum/controller/vote/vote = new()
if("crew_transfer")
if(. == "Initiate Crew Transfer")
init_shift_change(null, 1)
if("map")
if(.)
chosen_map = ismapvote[.]
//testing("Vote picked [chosen_map]")
if(restart)
@@ -154,7 +160,7 @@ var/global/datum/controller/vote/vote = new()
return .
proc/submit_vote(var/ckey, var/vote)
/datum/controller/vote/proc/submit_vote(var/ckey, var/vote)
if(mode)
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
return 0
@@ -167,7 +173,7 @@ var/global/datum/controller/vote/vote = new()
return vote
return 0
proc/initiate_vote(var/vote_type, var/initiator_key)
/datum/controller/vote/proc/initiate_vote(var/vote_type, var/initiator_key)
if(!mode)
if(started_time != null && !check_rights(R_ADMIN))
var/next_allowed_time = (started_time + config.vote_delay)
@@ -194,16 +200,25 @@ var/global/datum/controller/vote/vote = new()
var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null))
if(!option || mode || !usr.client) break
choices.Add(option)
if("map")
question = "Rock The Vote Next Map!"
var/list/maps = get_maps()
for(var/key in maps)
choices.Add(key)
if(!choices.len)
world << "<span class='danger'>Failed to initiate map vote, no maps found.</span>"
return 0
ismapvote = maps
else return 0
mode = vote_type
initiator = initiator_key
started_time = world.time
var/text = "[capitalize(mode)] vote started by [initiator]."
if(mode == "custom")
text += "\n[question]"
text += "<br>[question]"
log_vote(text)
world << "<font color='purple'><b>[text]</b>\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>"
world << "<font color='purple'><b>[text]</b><br>Type vote to place your votes.<br>You have [ismapvote && ismapvote.len ? "60" : config.vote_period/10] seconds to vote.</font>"
switch(vote_type)
if("crew_transfer")
world << sound('sound/voice/Serithi/Shuttlehere.ogg')
@@ -211,15 +226,17 @@ var/global/datum/controller/vote/vote = new()
world << sound('sound/voice/Serithi/pretenddemoc.ogg')
if("custom")
world << sound('sound/voice/Serithi/weneedvote.ogg')
if("map")
world << sound('sound/misc/rockthevote.ogg')
if(mode == "gamemode" && going)
going = 0
world << "<font color='red'><b>Round start has been delayed.</b></font>"
time_remaining = round(config.vote_period/10)
time_remaining = (ismapvote && ismapvote.len ? 60 : round(config.vote_period/10))
return 1
return 0
proc/interface(var/client/C)
/datum/controller/vote/proc/interface(var/client/C)
if(!C) return
var/admin = 0
var/trialmin = 0
@@ -277,7 +294,7 @@ var/global/datum/controller/vote/vote = new()
return .
Topic(href,href_list[],hsrc)
/datum/controller/vote/Topic(href,href_list[],hsrc)
if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid
switch(href_list["vote"])
if("close")

View File

@@ -63,7 +63,7 @@ var/global/datum/controller/gameticker/ticker
vote.process()
watchdog.check_for_update()
if(watchdog.waiting)
world << "\blue Server update detected, restarting momentarily."
world << "<span class='notice'>Server update detected, restarting momentarily.</span>"
watchdog.signal_ready()
return
if(going)
@@ -209,7 +209,7 @@ var/global/datum/controller/gameticker/ticker
var/obj/screen/cinematic = null
//Plus it provides an easy way to make cinematics for other events. Just use this as a template :)
proc/station_explosion_cinematic(var/station_missed=0, var/override = null)
/datum/controller/gameticker/proc/station_explosion_cinematic(var/station_missed=0, var/override = null)
if( cinematic ) return //already a cinematic in progress!
//initialise our cinematic screen object
@@ -307,7 +307,7 @@ var/global/datum/controller/gameticker/ticker
return
proc/create_characters()
/datum/controller/gameticker/proc/create_characters()
for(var/mob/new_player/player in player_list)
if(player.ready && player.mind)
if(player.mind.assigned_role=="AI")
@@ -320,13 +320,13 @@ var/global/datum/controller/gameticker/ticker
del(player)
proc/collect_minds()
/datum/controller/gameticker/proc/collect_minds()
for(var/mob/living/player in player_list)
if(player.mind)
ticker.minds += player.mind
proc/equip_characters()
/datum/controller/gameticker/proc/equip_characters()
var/captainless=1
for(var/mob/living/carbon/human/player in player_list)
if(player && player.mind && player.mind.assigned_role)
@@ -341,7 +341,7 @@ var/global/datum/controller/gameticker/ticker
M << "Captainship not forced on anyone."
proc/process()
/datum/controller/gameticker/proc/process()
if(current_state != GAME_STATE_PLAYING)
return 0
@@ -362,22 +362,24 @@ var/global/datum/controller/gameticker/ticker
spawn
declare_completion()
if(config.map_voting)
vote.initiate_vote("map","The Server")
spawn(50)
if (mode.station_was_nuked)
feedback_set_details("end_proper","nuke")
if(!delay_end && !watchdog.waiting)
world << "\blue <B>Rebooting due to destruction of station in [restart_timeout/10] seconds</B>"
world << "<span class='notice'><B>Rebooting due to destruction of station in [restart_timeout/10] seconds</B></span>"
else
feedback_set_details("end_proper","proper completion")
if(!delay_end && !watchdog.waiting)
world << "\blue <B>Restarting in [restart_timeout/10] seconds</B>"
world << "<span class='notice'><B>Restarting in [restart_timeout/10] seconds</B></span>"
if(blackbox)
blackbox.save_all_data_to_sql()
if (watchdog.waiting)
world << "\blue <B>Server will shut down for an automatic update in a few seconds.</B>"
world << "<span class='notice'><B>Server will shut down for an automatic update in a few seconds.</B></span>"
watchdog.signal_ready()
else if(!delay_end)
sleep(restart_timeout)
@@ -385,13 +387,13 @@ var/global/datum/controller/gameticker/ticker
CallHook("Reboot",list())
world.Reboot()
else
world << "\blue <B>An admin has delayed the round end</B>"
world << "<span class='notice'><B>An admin has delayed the round end</B></span>"
else
world << "\blue <B>An admin has delayed the round end</B>"
world << "<span class='notice'><B>An admin has delayed the round end</B></span>"
return 1
proc/getfactionbyname(var/name)
/datum/controller/gameticker/proc/getfactionbyname(var/name)
for(var/datum/faction/F in factions)
if(F.name == name)
return F

View File

@@ -5,6 +5,8 @@
cache_lifespan = 0 //stops player uploaded stuff from being kept in the rsc past the current session
#define RECOMMENDED_VERSION 501
/world/New()
// Honk honk, fuck you science
populate_seed_list()
@@ -178,6 +180,26 @@
/world/Reboot(reason)
if(config.map_voting)
//testing("we have done a map vote")
if(fexists(vote.chosen_map))
//testing("[vote.chosen_map] exists")
var/start = 1
var/pos = findtext(vote.chosen_map, "/", start)
var/lastpos = pos
//testing("First slash [lastpos]")
while(pos > 0)
lastpos = pos
pos = findtext(vote.chosen_map, "/", start)
start = pos + 1
//testing("Next slash [pos]")
var/filename = copytext(vote.chosen_map, lastpos + 1, 0)
//testing("Found [filename]")
if(!fcopy(vote.chosen_map, filename))
//testing("Fcopy failed, deleting and copying")
fdel(filename)
fcopy(vote.chosen_map, filename)
spawn(0)
world << sound(pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg','sound/misc/slugmissioncomplete.ogg')) // random end sounds!! - LastyBatsy
@@ -200,7 +222,7 @@
if(C.is_afk(INACTIVITY_KICK))
if(!istype(C.mob, /mob/dead))
log_access("AFK: [key_name(C)]")
C << "\red You have been inactive for more than 10 minutes and have been disconnected."
C << "<span class='warning'>You have been inactive for more than 10 minutes and have been disconnected.</span>"
del(C)
#undef INACTIVITY_KICK

11
maps/voting/Readme.txt Normal file
View File

@@ -0,0 +1,11 @@
To utilize the map voter:
1. Uncomment or put MAP_VOTING in config.txt
2. Compile the DMB's for each map you want to be voted on(requires a recompile on every update)
3. Put each map's DMB in a folder designated to the map's name in maps/voting/ eg MetaStation for Meta Station and Box for Box Station
4. At the natural end of a round the map will be voted upon.
TODO:
Maybe add a verb for admins to force another map using file browse.
Setup a script to easily mass compile the maps (hint hint nexy)

BIN
sound/misc/rockthevote.ogg Normal file

Binary file not shown.