From 9784e29eb9f4410bba4dfc7c20a198448bfcc1a2 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 13 Nov 2014 22:05:30 -0600 Subject: [PATCH] Map voting --- code/__HELPERS/files.dm | 26 ++ code/controllers/configuration.dm | 4 + code/controllers/voting.dm | 581 +++++++++++++++--------------- code/game/gamemodes/gameticker.dm | 330 ++++++++--------- code/world.dm | 24 +- maps/voting/Readme.txt | 11 + sound/misc/rockthevote.ogg | Bin 0 -> 50904 bytes 7 files changed, 529 insertions(+), 447 deletions(-) create mode 100644 maps/voting/Readme.txt create mode 100644 sound/misc/rockthevote.ogg diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm index d804dcb06a9..e0c51d699f1 100644 --- a/code/__HELPERS/files.dm +++ b/code/__HELPERS/files.dm @@ -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) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index e658a70f2c3..bade956545d 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -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]'" diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index c3aec025521..894afa28ce5 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -10,304 +10,321 @@ 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) - if (istype(vote)) - qdel(vote) + if (vote != src) + if (istype(vote)) + qdel(vote) - vote = src + vote = src - 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 - if(mode == "gamemode" && ticker.current_state >= 2) - world << "Voting aborted due to game start." - src.reset() - return +/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 + if(mode == "gamemode" && ticker.current_state >= 2) + world << "Voting aborted due to game start." + src.reset() + return - // 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) - - if(time_remaining < 0) - result() - for(var/client/C in voting) - if(C) - C << browse(null,"window=vote;can_close=0") - reset() - else - for(var/client/C in voting) - if(C) - C << browse(vote.interface(C),"window=vote;can_close=0") - - voting.Cut() - - proc/reset() - initiator = null - time_remaining = 0 - mode = null - question = null - choices.Cut() - voted.Cut() - voting.Cut() - current_votes.Cut() - - proc/get_result() - //get the highest number of votes - var/greatest_votes = 0 - var/total_votes = 0 - for(var/option in choices) - var/votes = choices[option] - total_votes += votes - if(votes > greatest_votes) - greatest_votes = votes - //default-vote for everyone who didn't vote - if(!config.vote_no_default && choices.len) - var/non_voters = (clients.len - total_votes) - if(non_voters > 0) - if(mode == "restart") - choices["Continue Playing"] += non_voters - if(choices["Continue Playing"] >= greatest_votes) - greatest_votes = choices["Continue Playing"] - else if(mode == "gamemode") - if(master_mode in choices) - choices[master_mode] += non_voters - if(choices[master_mode] >= greatest_votes) - greatest_votes = choices[master_mode] - else if(mode == "crew_transfer") - var/factor = 0.5 - switch(world.time / (10 * 60)) // minutes - if(0 to 60) - factor = 0.5 - if(61 to 120) - factor = 0.8 - if(121 to 240) - factor = 1 - if(241 to 300) - factor = 1.2 - else - factor = 1.4 - choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor) - world << "Crew Transfer Factor: [factor]" - greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"]) - - - //get all options with that many votes and return them in a list - . = list() - if(greatest_votes) - for(var/option in choices) - if(choices[option] == greatest_votes) - . += option - return . - - proc/announce_result() - var/list/winners = get_result() - var/text - if(winners.len > 0) - if(winners.len > 1) - text = "Vote Tied Between:\n" - for(var/option in winners) - text += "\t[option]\n" - . = pick(winners) - text += "Vote Result: [.]" - else - text += "Vote Result: Inconclusive - No Votes!" - log_vote(text) - world << "[text]" - return . - - proc/result() - . = announce_result() - var/restart = 0 - if(.) - switch(mode) - if("restart") - if(. == "Restart Round") - restart = 1 - if("gamemode") - if(master_mode != .) - world.save_mode(.) - if(ticker && ticker.mode) - restart = 1 - else - master_mode = . - if(!going) - going = 1 - world << "The round will start soon." - if("crew_transfer") - if(. == "Initiate Crew Transfer") - init_shift_change(null, 1) - - - if(restart) - world << "World restarting due to vote..." - feedback_set_details("end_error","restart vote") - if(blackbox) blackbox.save_all_data_to_sql() - CallHook("Reboot",list()) - sleep(50) - log_game("Rebooting due to restart vote") - world.Reboot() - - return . - - proc/submit_vote(var/ckey, var/vote) - if(mode) - if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) - return 0 - if(current_votes[ckey]) - choices[choices[current_votes[ckey]]]-- - if(vote && 1<=vote && vote<=choices.len) - voted += usr.ckey - choices[choices[vote]]++ //check this - current_votes[ckey] = vote - return vote - return 0 - - 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) - if(next_allowed_time > world.time) - return 0 + // Calculate how much time is remaining by comparing current time, to time of vote start, + // plus vote duration + 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() + for(var/client/C in voting) + if(C) + C << browse(null,"window=vote;can_close=0") reset() - switch(vote_type) - if("restart") - choices.Add("Restart Round","Continue Playing") - if("gamemode") - if(ticker.current_state >= 2) - return 0 - choices.Add(config.votable_modes) - if("crew_transfer") - if(ticker.current_state <= 2) - return 0 - question = "End the shift?" - choices.Add("Initiate Crew Transfer", "Continue The Round") - if("custom") - question = html_encode(input(usr,"What is the vote for?") as text|null) - if(!question) return 0 - for(var/i=1,i<=10,i++) - 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) - 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]" - - log_vote(text) - world << "[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote." - switch(vote_type) - if("crew_transfer") - world << sound('sound/voice/Serithi/Shuttlehere.ogg') - if("gamemode") - world << sound('sound/voice/Serithi/pretenddemoc.ogg') - if("custom") - world << sound('sound/voice/Serithi/weneedvote.ogg') - if(mode == "gamemode" && going) - going = 0 - world << "Round start has been delayed." - - time_remaining = round(config.vote_period/10) - return 1 - return 0 - - proc/interface(var/client/C) - if(!C) return - var/admin = 0 - var/trialmin = 0 - if(C.holder) - admin = 1 - if(C.holder.rights & R_ADMIN) - trialmin = 1 - voting |= C - - . = "Voting Panel" - if(mode) - if(question) . += "

Vote: '[question]'

" - else . += "

Vote: [capitalize(mode)]

" - . += "Time Left: [time_remaining] s

" - if(admin) - . += "(Cancel Vote) " else - . += "

Start a vote:



" - . += "Close" - return . + //voting.Cut() + +/datum/controller/vote/proc/reset() + initiator = null + time_remaining = 0 + mode = null + question = null + choices.Cut() + voted.Cut() + voting.Cut() + current_votes.Cut() + +/datum/controller/vote/proc/get_result() + //get the highest number of votes + var/greatest_votes = 0 + var/total_votes = 0 + for(var/option in choices) + var/votes = choices[option] + total_votes += votes + if(votes > greatest_votes) + greatest_votes = votes + //default-vote for everyone who didn't vote + if(!config.vote_no_default && choices.len) + var/non_voters = (clients.len - total_votes) + if(non_voters > 0) + if(mode == "restart") + choices["Continue Playing"] += non_voters + if(choices["Continue Playing"] >= greatest_votes) + greatest_votes = choices["Continue Playing"] + else if(mode == "gamemode") + if(master_mode in choices) + choices[master_mode] += non_voters + if(choices[master_mode] >= greatest_votes) + greatest_votes = choices[master_mode] + else if(mode == "crew_transfer") + var/factor = 0.5 + switch(world.time / (10 * 60)) // minutes + if(0 to 60) + factor = 0.5 + if(61 to 120) + factor = 0.8 + if(121 to 240) + factor = 1 + if(241 to 300) + factor = 1.2 + else + factor = 1.4 + choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor) + world << "Crew Transfer Factor: [factor]" + greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"]) - 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") - voting -= usr.client - usr << browse(null, "window=vote") - return - if("cancel") - if(usr.client.holder) - reset() - if("toggle_restart") - if(usr.client.holder) - config.allow_vote_restart = !config.allow_vote_restart - if("toggle_gamemode") - if(usr.client.holder) - config.allow_vote_mode = !config.allow_vote_mode + //get all options with that many votes and return them in a list + . = list() + if(greatest_votes) + for(var/option in choices) + if(choices[option] == greatest_votes) + . += option + return . + +/datum/controller/vote/proc/announce_result() + var/list/winners = get_result() + var/text + if(winners.len > 0) + if(winners.len > 1) + text = "Vote Tied Between:
" + for(var/option in winners) + text += "\t[option]
" + . = pick(winners) + text += "Vote Result: [.]" + else + text += "Vote Result: Inconclusive - No Votes!" + log_vote(text) + world << "[text]" + return . + +/datum/controller/vote/proc/result() + . = announce_result() + var/restart = 0 + if(.) + switch(mode) if("restart") - if(config.allow_vote_restart || usr.client.holder) - initiate_vote("restart",usr.key) + if(. == "Restart Round") + restart = 1 if("gamemode") - if(config.allow_vote_mode || usr.client.holder) - initiate_vote("gamemode",usr.key) + if(master_mode != .) + world.save_mode(.) + if(ticker && ticker.mode) + restart = 1 + else + master_mode = . + if(!going) + going = 1 + world << "The round will start soon." if("crew_transfer") - if(config.allow_vote_restart || usr.client.holder) - initiate_vote("crew_transfer",usr.key) + if(. == "Initiate Crew Transfer") + init_shift_change(null, 1) + if("map") + if(.) + chosen_map = ismapvote[.] + //testing("Vote picked [chosen_map]") + + + if(restart) + world << "World restarting due to vote..." + feedback_set_details("end_error","restart vote") + if(blackbox) blackbox.save_all_data_to_sql() + CallHook("Reboot",list()) + sleep(50) + log_game("Rebooting due to restart vote") + world.Reboot() + + return . + +/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 + if(current_votes[ckey]) + choices[choices[current_votes[ckey]]]-- + if(vote && 1<=vote && vote<=choices.len) + voted += usr.ckey + choices[choices[vote]]++ //check this + current_votes[ckey] = vote + return vote + return 0 + +/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) + if(next_allowed_time > world.time) + return 0 + + reset() + switch(vote_type) + if("restart") + choices.Add("Restart Round","Continue Playing") + if("gamemode") + if(ticker.current_state >= 2) + return 0 + choices.Add(config.votable_modes) + if("crew_transfer") + if(ticker.current_state <= 2) + return 0 + question = "End the shift?" + choices.Add("Initiate Crew Transfer", "Continue The Round") if("custom") - if(usr.client.holder) - initiate_vote("custom",usr.key) + question = html_encode(input(usr,"What is the vote for?") as text|null) + if(!question) return 0 + for(var/i=1,i<=10,i++) + 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 << "Failed to initiate map vote, no maps found." + 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 += "
[question]" + + log_vote(text) + world << "[text]
Type vote to place your votes.
You have [ismapvote && ismapvote.len ? "60" : config.vote_period/10] seconds to vote.
" + switch(vote_type) + if("crew_transfer") + world << sound('sound/voice/Serithi/Shuttlehere.ogg') + if("gamemode") + 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 << "Round start has been delayed." + + time_remaining = (ismapvote && ismapvote.len ? 60 : round(config.vote_period/10)) + return 1 + return 0 + +/datum/controller/vote/proc/interface(var/client/C) + if(!C) return + var/admin = 0 + var/trialmin = 0 + if(C.holder) + admin = 1 + if(C.holder.rights & R_ADMIN) + trialmin = 1 + voting |= C + + . = "Voting Panel" + if(mode) + if(question) . += "

Vote: '[question]'

" + else . += "

Vote: [capitalize(mode)]

" + . += "Time Left: [time_remaining] s

" + if(admin) + . += "(Cancel Vote) " + else + . += "

Start a vote:



" + . += "Close" + return . + + +/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") + voting -= usr.client + usr << browse(null, "window=vote") + return + if("cancel") + if(usr.client.holder) + reset() + if("toggle_restart") + if(usr.client.holder) + config.allow_vote_restart = !config.allow_vote_restart + if("toggle_gamemode") + if(usr.client.holder) + config.allow_vote_mode = !config.allow_vote_mode + if("restart") + if(config.allow_vote_restart || usr.client.holder) + initiate_vote("restart",usr.key) + if("gamemode") + if(config.allow_vote_mode || usr.client.holder) + initiate_vote("gamemode",usr.key) + if("crew_transfer") + if(config.allow_vote_restart || usr.client.holder) + initiate_vote("crew_transfer",usr.key) + if("custom") + if(usr.client.holder) + initiate_vote("custom",usr.key) + else + submit_vote(usr.ckey, round(text2num(href_list["vote"]))) + usr.vote() /mob/verb/vote() diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index f6f7bf8dfe8..b12aa49b33c 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -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 << "Server update detected, restarting momentarily." watchdog.signal_ready() return if(going) @@ -209,192 +209,194 @@ 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) - if( cinematic ) return //already a cinematic in progress! +/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 - cinematic = new(src) - cinematic.icon = 'icons/effects/station_explosion.dmi' - cinematic.icon_state = "station_intact" - cinematic.layer = 20 - cinematic.mouse_opacity = 0 - cinematic.screen_loc = "1,0" + //initialise our cinematic screen object + cinematic = new(src) + cinematic.icon = 'icons/effects/station_explosion.dmi' + cinematic.icon_state = "station_intact" + cinematic.layer = 20 + cinematic.mouse_opacity = 0 + cinematic.screen_loc = "1,0" - var/obj/structure/stool/bed/temp_buckle = new(src) - //Incredibly hackish. It creates a bed within the gameticker (lol) to stop mobs running around - if(station_missed) - for(var/mob/living/M in living_mob_list) - M.buckled = temp_buckle //buckles the mob so it can't do anything - if(M.client) - M.client.screen += cinematic //show every client the cinematic - else //nuke kills everyone on z-level 1 to prevent "hurr-durr I survived" - for(var/mob/living/M in living_mob_list) - M.buckled = temp_buckle - if(M.client) - M.client.screen += cinematic + var/obj/structure/stool/bed/temp_buckle = new(src) + //Incredibly hackish. It creates a bed within the gameticker (lol) to stop mobs running around + if(station_missed) + for(var/mob/living/M in living_mob_list) + M.buckled = temp_buckle //buckles the mob so it can't do anything + if(M.client) + M.client.screen += cinematic //show every client the cinematic + else //nuke kills everyone on z-level 1 to prevent "hurr-durr I survived" + for(var/mob/living/M in living_mob_list) + M.buckled = temp_buckle + if(M.client) + M.client.screen += cinematic - switch(M.z) - if(0) //inside a crate or something - var/turf/T = get_turf(M) - if(T && T.z==1) //we don't use M.death(0) because it calls a for(/mob) loop and - M.health = 0 - M.stat = DEAD - if(1) //on a z-level 1 turf. + switch(M.z) + if(0) //inside a crate or something + var/turf/T = get_turf(M) + if(T && T.z==1) //we don't use M.death(0) because it calls a for(/mob) loop and M.health = 0 M.stat = DEAD + if(1) //on a z-level 1 turf. + M.health = 0 + M.stat = DEAD - //Now animate the cinematic - switch(station_missed) - if(1) //nuke was nearby but (mostly) missed - if( mode && !override ) - override = mode.name - switch( override ) - if("nuclear emergency") //Nuke wasn't on station when it blew up - flick("intro_nuke",cinematic) - sleep(35) - world << sound('sound/effects/explosionfar.ogg') - flick("station_intact_fade_red",cinematic) - cinematic.icon_state = "summary_nukefail" - else - flick("intro_nuke",cinematic) - sleep(35) - world << sound('sound/effects/explosionfar.ogg') - //flick("end",cinematic) - - - if(2) //nuke was nowhere nearby //TODO: a really distant explosion animation - sleep(50) - world << sound('sound/effects/explosionfar.ogg') - - - else //station was destroyed - if( mode && !override ) - override = mode.name - switch( override ) - if("nuclear emergency") //Nuke Ops successfully bombed the station - flick("intro_nuke",cinematic) - sleep(35) - flick("station_explode_fade_red",cinematic) - world << sound('sound/effects/explosionfar.ogg') - cinematic.icon_state = "summary_nukewin" - if("AI malfunction") //Malf (screen,explosion,summary) - flick("intro_malf",cinematic) - sleep(76) - flick("station_explode_fade_red",cinematic) - world << sound('sound/effects/explosionfar.ogg') - cinematic.icon_state = "summary_malf" - if("blob") //Station nuked (nuke,explosion,summary) - flick("intro_nuke",cinematic) - sleep(35) - flick("station_explode_fade_red",cinematic) - world << sound('sound/effects/explosionfar.ogg') - cinematic.icon_state = "summary_selfdes" - else //Station nuked (nuke,explosion,summary) - flick("intro_nuke",cinematic) - sleep(35) - flick("station_explode_fade_red", cinematic) - world << sound('sound/effects/explosionfar.ogg') - cinematic.icon_state = "summary_selfdes" - for(var/mob/living/M in living_mob_list) - if(M.loc.z == 1) - M.death()//No mercy - //If its actually the end of the round, wait for it to end. - //Otherwise if its a verb it will continue on afterwards. - sleep(300) - - if(cinematic) del(cinematic) //end the cinematic - if(temp_buckle) del(temp_buckle) //release everybody - return - - - proc/create_characters() - for(var/mob/new_player/player in player_list) - if(player.ready && player.mind) - if(player.mind.assigned_role=="AI") - player.close_spawn_windows() - player.AIize() - else if(!player.mind.assigned_role) - continue + //Now animate the cinematic + switch(station_missed) + if(1) //nuke was nearby but (mostly) missed + if( mode && !override ) + override = mode.name + switch( override ) + if("nuclear emergency") //Nuke wasn't on station when it blew up + flick("intro_nuke",cinematic) + sleep(35) + world << sound('sound/effects/explosionfar.ogg') + flick("station_intact_fade_red",cinematic) + cinematic.icon_state = "summary_nukefail" else - player.FuckUpGenes(player.create_character()) - del(player) + flick("intro_nuke",cinematic) + sleep(35) + world << sound('sound/effects/explosionfar.ogg') + //flick("end",cinematic) - proc/collect_minds() - for(var/mob/living/player in player_list) - if(player.mind) - ticker.minds += player.mind + if(2) //nuke was nowhere nearby //TODO: a really distant explosion animation + sleep(50) + world << sound('sound/effects/explosionfar.ogg') - proc/equip_characters() - var/captainless=1 - for(var/mob/living/carbon/human/player in player_list) - if(player && player.mind && player.mind.assigned_role) - if(player.mind.assigned_role == "Captain") - captainless=0 - if(player.mind.assigned_role != "MODE") - job_master.EquipRank(player, player.mind.assigned_role, 0) - EquipCustomItems(player) - if(captainless) - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << "Captainship not forced on anyone." + else //station was destroyed + if( mode && !override ) + override = mode.name + switch( override ) + if("nuclear emergency") //Nuke Ops successfully bombed the station + flick("intro_nuke",cinematic) + sleep(35) + flick("station_explode_fade_red",cinematic) + world << sound('sound/effects/explosionfar.ogg') + cinematic.icon_state = "summary_nukewin" + if("AI malfunction") //Malf (screen,explosion,summary) + flick("intro_malf",cinematic) + sleep(76) + flick("station_explode_fade_red",cinematic) + world << sound('sound/effects/explosionfar.ogg') + cinematic.icon_state = "summary_malf" + if("blob") //Station nuked (nuke,explosion,summary) + flick("intro_nuke",cinematic) + sleep(35) + flick("station_explode_fade_red",cinematic) + world << sound('sound/effects/explosionfar.ogg') + cinematic.icon_state = "summary_selfdes" + else //Station nuked (nuke,explosion,summary) + flick("intro_nuke",cinematic) + sleep(35) + flick("station_explode_fade_red", cinematic) + world << sound('sound/effects/explosionfar.ogg') + cinematic.icon_state = "summary_selfdes" + for(var/mob/living/M in living_mob_list) + if(M.loc.z == 1) + M.death()//No mercy + //If its actually the end of the round, wait for it to end. + //Otherwise if its a verb it will continue on afterwards. + sleep(300) + + if(cinematic) del(cinematic) //end the cinematic + if(temp_buckle) del(temp_buckle) //release everybody + return - proc/process() - if(current_state != GAME_STATE_PLAYING) - return 0 +/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") + player.close_spawn_windows() + player.AIize() + else if(!player.mind.assigned_role) + continue + else + player.FuckUpGenes(player.create_character()) + del(player) - mode.process() - emergency_shuttle.process() - watchdog.check_for_update() +/datum/controller/gameticker/proc/collect_minds() + for(var/mob/living/player in player_list) + if(player.mind) + ticker.minds += player.mind - var/force_round_end=0 - // If server's empty, force round end. - if(watchdog.waiting && player_list.len == 0) - force_round_end=1 +/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) + if(player.mind.assigned_role == "Captain") + captainless=0 + if(player.mind.assigned_role != "MODE") + job_master.EquipRank(player, player.mind.assigned_role, 0) + EquipCustomItems(player) + if(captainless) + for(var/mob/M in player_list) + if(!istype(M,/mob/new_player)) + M << "Captainship not forced on anyone." - var/mode_finished = mode.check_finished() || (emergency_shuttle.location == 2 && emergency_shuttle.alert == 1) || force_round_end - if(!mode.explosion_in_progress && mode_finished) - current_state = GAME_STATE_FINISHED - spawn - declare_completion() +/datum/controller/gameticker/proc/process() + if(current_state != GAME_STATE_PLAYING) + return 0 - spawn(50) - if (mode.station_was_nuked) - feedback_set_details("end_proper","nuke") - if(!delay_end && !watchdog.waiting) - world << "\blue Rebooting due to destruction of station in [restart_timeout/10] seconds" + mode.process() + + emergency_shuttle.process() + watchdog.check_for_update() + + var/force_round_end=0 + + // If server's empty, force round end. + if(watchdog.waiting && player_list.len == 0) + force_round_end=1 + + var/mode_finished = mode.check_finished() || (emergency_shuttle.location == 2 && emergency_shuttle.alert == 1) || force_round_end + if(!mode.explosion_in_progress && mode_finished) + current_state = GAME_STATE_FINISHED + + 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 << "Rebooting due to destruction of station in [restart_timeout/10] seconds" + else + feedback_set_details("end_proper","proper completion") + if(!delay_end && !watchdog.waiting) + world << "Restarting in [restart_timeout/10] seconds" + + if(blackbox) + blackbox.save_all_data_to_sql() + + if (watchdog.waiting) + world << "Server will shut down for an automatic update in a few seconds." + watchdog.signal_ready() + else if(!delay_end) + sleep(restart_timeout) + if(!delay_end) + CallHook("Reboot",list()) + world.Reboot() else - feedback_set_details("end_proper","proper completion") - if(!delay_end && !watchdog.waiting) - world << "\blue Restarting in [restart_timeout/10] seconds" + world << "An admin has delayed the round end" + else + world << "An admin has delayed the round end" - if(blackbox) - blackbox.save_all_data_to_sql() + return 1 - if (watchdog.waiting) - world << "\blue Server will shut down for an automatic update in a few seconds." - watchdog.signal_ready() - else if(!delay_end) - sleep(restart_timeout) - if(!delay_end) - CallHook("Reboot",list()) - world.Reboot() - else - world << "\blue An admin has delayed the round end" - else - world << "\blue An admin has delayed the round end" - - return 1 - - proc/getfactionbyname(var/name) - for(var/datum/faction/F in factions) - if(F.name == name) - return F +/datum/controller/gameticker/proc/getfactionbyname(var/name) + for(var/datum/faction/F in factions) + if(F.name == name) + return F /datum/controller/gameticker/proc/declare_completion() diff --git a/code/world.dm b/code/world.dm index 6cf2ba3b8e1..cc015a4535b 100644 --- a/code/world.dm +++ b/code/world.dm @@ -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 << "You have been inactive for more than 10 minutes and have been disconnected." del(C) #undef INACTIVITY_KICK diff --git a/maps/voting/Readme.txt b/maps/voting/Readme.txt new file mode 100644 index 00000000000..bfb71247e67 --- /dev/null +++ b/maps/voting/Readme.txt @@ -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) \ No newline at end of file diff --git a/sound/misc/rockthevote.ogg b/sound/misc/rockthevote.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9f967d71bcca75059462eb8537d1b9588ad67646 GIT binary patch literal 50904 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 G1N;wb_OvDd literal 0 HcmV?d00001