var/global/datum/controller/gameticker/ticker /* -- moved to _setup.dm #define GAME_STATE_PREGAME 1 #define GAME_STATE_SETTING_UP 2 #define GAME_STATE_PLAYING 3 #define GAME_STATE_FINISHED 4 */ /datum/controller/gameticker var/current_state = GAME_STATE_PREGAME var/hide_mode = 0 var/datum/game_mode/mode = null var/event_time = null var/event = 0 var/list/datum/mind/minds = list() var/last_readd_lost_minds_to_ticker = 1 // In relation to world time. var/pregame_timeleft = 0 var/round_elapsed_ticks = 0 var/click_delay = 3 var/datum/ai_laws/centralized_ai_laws var/skull_key_assigned = 0 /datum/controller/gameticker/proc/pregame() pregame_timeleft = 180 // raised from 120 to accomodate the v500 ads boutput(world, "Welcome to the pre-game lobby!") boutput(world, "Please, setup your character and select ready. Game will start in [pregame_timeleft] seconds") while(current_state == GAME_STATE_PREGAME) sleep(10) if (!game_start_delayed) pregame_timeleft-- if(pregame_timeleft <= 0) current_state = GAME_STATE_SETTING_UP spawn setup() /datum/controller/gameticker/proc/setup() set background = 1 //Create and announce mode if(master_mode in list("secret","wizard","alien")) src.hide_mode = 1 if((master_mode=="random") || (master_mode=="secret")) src.mode = config.pick_random_mode() else src.mode = config.pick_mode(master_mode) if(hide_mode) var/modes = sortList(config.get_used_mode_names()) boutput(world, "The current game mode is a secret!") boutput(world, "Possibilities: [english_list(modes)]") else src.mode.announce() // uhh is this where this goes?? src.centralized_ai_laws = new /datum/ai_laws/asimov() //Configure mode and assign player to special mode stuff var/can_continue = src.mode.pre_setup() if(!can_continue) qdel(mode) current_state = GAME_STATE_PREGAME boutput(world, "Error setting up [master_mode]. Reverting to pre-game lobby.") spawn pregame() return 0 if (!istype(src.mode, /datum/game_mode/construction) && map_setting != "DESTINY") ooc_allowed = 0 boutput(world, "OOC has been automatically disabled until the round ends.") if (map_setting == "DESTINY") looc_allowed = 1 boutput(world, "LOOC has been automatically enabled.") //Distribute jobs distribute_jobs() //Create player characters and transfer them create_characters() add_minds() // rip collar key, nerds murdered people for you as non-antags and it was annoying //implant_skull_key() //Solarium #ifdef CREW_OBJECTIVES //Create objectives for the non-traitor/nogoodnik crew. generate_crew_objectives() #endif //Equip characters equip_characters() current_state = GAME_STATE_PLAYING round_time_check = world.timeofday spawn(0) ircbot.event("roundstart") mode.post_setup() //Cleanup some stuff for(var/obj/landmark/start/S in world) //Deleting Startpoints but we need the ai point to AI-ize people later if (S.name != "AI") qdel(S) hydro_controls.set_up() manuf_controls.set_up() event_wormhole_buildturflist() total_corruptible_terrain = get_total_corruptible_terrain() mode.post_post_setup() if (istype(random_events,/datum/event_controller/)) spawn(random_events.minor_events_begin) message_admins("Minor Event cycle has been started.") random_events.minor_event_cycle() spawn(random_events.events_begin) message_admins("Random Event cycle has been started.") random_events.event_cycle() random_events.next_event = random_events.events_begin random_events.next_minor_event = random_events.minor_events_begin for(var/obj/landmark/artifact/A in world) if (prob(A.spawnchance)) if (A.spawnpath) new A.spawnpath(A.loc) else Artifact_Spawn(A.loc) var/list/lootspawn = list() for(var/obj/landmark/S in world) if (S.name == "Loot spawn") lootspawn.Add(S.loc) if(lootspawn.len) var/lootamt = rand(5,15) while(lootamt > 0) var/lootloc = lootspawn.len ? pick(lootspawn) : null if (lootloc && prob(75)) new/obj/storage/crate/loot(lootloc) --lootamt shippingmarket.get_market_timeleft() for(var/area/AR in world) if(!AR || teleareas.Find(AR.name)) continue if (istype(AR, /area/wizard_station)) var/entry = text("* []", AR.name) teleareas[entry] = AR continue var/list/topick = get_area_turfs(AR.type); if (topick.len > 0) var/turf/picked = pick(topick) if (picked && picked.z == 1) teleareas += AR.name teleareas[AR.name] = AR teleareas = sortList(teleareas) // Moved wizard's den back to the top of the list for convenience. It's also sorted now (Convair880). logTheThing("ooc", null, null, "Current round begins") boutput(world, "Enjoy the game!") boutput(world, "Tip: [pick(tips)]") //Setup the hub site logging var hublog_filename = "data/stats/data.txt" if (fexists(hublog_filename)) fdel(hublog_filename) hublog = file(hublog_filename) hublog << "" spawn (6000) // 10 minutes in for(var/obj/machinery/power/generatorTemp/E in world) if (E.lastgen <= 0) command_alert("Reports indicate that the engine on-board [station_name()] has not yet been started. Setting up the engine is strongly recommended, or else stationwide power failures may occur.", "Power Grid Warning") break processScheduler.start() /datum/controller/gameticker proc/distribute_jobs() DivideOccupations() proc/create_characters() for(var/mob/new_player/player in mobs) if(player.ready) if(player.mind && player.mind.assigned_role=="AI") player.close_spawn_windows() player.AIize() else if(player.mind && player.mind.special_role == "wraith") player.close_spawn_windows() var/mob/wraith/W = player.make_wraith() if (W) W.set_loc(pick(observer_start)) else if(player.mind && player.mind.special_role == "blob") player.close_spawn_windows() var/mob/living/intangible/blob_overmind/B = player.make_blob() if (B) B.set_loc(pick(observer_start)) else if(player.mind) if (player.client.using_antag_token) player.client.use_antag_token() //Removes a token from the player player.create_character() qdel(player) proc/add_minds(var/periodic_check = 0) for (var/mob/player in mobs) // Who cares about NPCs? Adding them here breaks all antagonist objectives // that attempt to scale with total player count (Convair880). if (player.mind && !istype(player, /mob/new_player) && player.client) if (!(player.mind in ticker.minds)) if (periodic_check == 1) logTheThing("debug", player, null, "Gameticker fallback: re-added player to ticker.minds.") else logTheThing("debug", player, null, "Gameticker setup: added player to ticker.minds.") ticker.minds.Add(player.mind) proc/implant_skull_key() //Hello, I will sneak in a solarium thing here. if(!skull_key_assigned && ticker.minds.len > 5) //Okay enough gaming the system you pricks var/list/HL = list() for (var/mob/living/carbon/human/human in mobs) if (human.client) HL += human if(HL.len > 5) var/mob/living/carbon/human/H = pick(HL) if(istype(H)) skull_key_assigned = 1 spawn(50) if(H.organHolder && H.organHolder.skull) H.organHolder.skull.key = new /obj/item/device/key/skull (H.organHolder.skull) logTheThing("debug", H, null, "has the dubious pleasure of having a key embedded in their skull.") else skull_key_assigned = 0 else if(!skull_key_assigned) logTheThing("debug", null, null, "SpyGuy/collar key: Did not implant a key because there was not enough players.") proc/equip_characters() for(var/mob/living/carbon/human/player in mobs) if(player.mind && player.mind.assigned_role) if(player.mind.assigned_role != "MODE") spawn(0) player.Equip_Rank(player.mind.assigned_role) proc/process() if(current_state != GAME_STATE_PLAYING) return 0 updateRoundTime() mode.process() emergency_shuttle.process() // Minds are sometimes kicked out of the global list, hence the fallback (Convair880). if (src.last_readd_lost_minds_to_ticker && world.time > src.last_readd_lost_minds_to_ticker + 1800) src.add_minds(1) src.last_readd_lost_minds_to_ticker = world.time if(mode.check_finished()) current_state = GAME_STATE_FINISHED spawn declare_completion() ooc_allowed = 1 boutput(world, "OOC is now enabled.") spawn(50) boutput(world, "Restarting soon") sleep(250) if (game_end_delayed == 1) message_admins("Server would have restarted now, but the restart has been delayed[game_end_delayer ? " by [game_end_delayer]" : null]. Remove the delay for an immediate restart.") game_end_delayed = 2 var/ircmsg[] = new() ircmsg["msg"] = "Server would have restarted now, but the restart has been delayed[game_end_delayer ? " by [game_end_delayer]" : null]." ircbot.export("admin", ircmsg) else ircbot.event("roundend") Reboot_server() return 1 proc/updateRoundTime() if (round_time_check) var/elapsed = world.timeofday - round_time_check round_time_check = world.timeofday if (round_time_check == 0) // on the slim chance that this happens exactly on a timeofday rollover round_time_check = 1 // make it nonzero so it doesn't quit updating if (elapsed > 0) ticker.round_elapsed_ticks += elapsed /datum/controller/gameticker/proc/declare_completion() set background = 1 //End of round statistic collection for goonhub statlog_traitors() statlog_ailaws(0) round_end_data(1) //Export round end packet (normal completion) // Score Calculation and Display // Who is alive/dead, who escaped for (var/mob/living/silicon/ai/I in mobs) if (I.stat == 2) score_deadaipenalty = 1 score_deadcrew += 1 for (var/mob/living/carbon/human/I in mobs) if (I.stat == 2 && I.z == 1) score_deadcrew += 1 for(var/mob/living/player in mobs) if (player.client) if (player.stat != 2) var/turf/location = get_turf(player.loc) var/area/escape_zone = locate(/area/shuttle/escape/centcom) if (location in escape_zone) score_escapees += 1 player.unlock_medal("100M dash", 1) player.unlock_medal("Survivor", 1) if (player.check_contents_for(/obj/item/gnomechompski)) player.unlock_medal("Guardin' gnome", 1) if (ishuman(player)) var/mob/living/carbon/human/H = player if (H && istype(H) && H.implant && H.implant.len > 0) var/bullets = 0 for (var/obj/item/implant/I in H) if (istype(I, /obj/item/implant/projectile)) bullets = 1 break if (bullets > 0) H.unlock_medal("It's just a flesh wound!", 1) if (H.limbs && (!H.limbs.l_arm && !H.limbs.r_arm)) H.unlock_medal("Mostly Armless", 1) #ifdef CREW_OBJECTIVES var/list/successfulCrew = list() for (var/datum/mind/crewMind in minds) if (!crewMind.current || !crewMind.objectives.len) continue var/count = 0 var/allComplete = 1 for (var/datum/objective/crew/CO in crewMind.objectives) count++ if(CO.check_completion()) boutput(crewMind.current, "Objective #[count]: [CO.explanation_text] Success") if (!isnull(CO.medal_name) && !isnull(crewMind.current)) crewMind.current.unlock_medal(CO.medal_name, CO.medal_announce) else boutput(crewMind.current, "Objective #[count]: [CO.explanation_text] Failed") allComplete = 0 if (allComplete && count) successfulCrew += "[crewMind.current.real_name] ([crewMind.key])" #endif var/cashscore = 0 var/dmgscore = 0 for(var/mob/living/carbon/human/E in mobs) cashscore = 0 dmgscore = 0 var/turf/location = get_turf(E.loc) var/area/escape_zone = locate(/area/shuttle/escape/centcom) if(E.stat != 2 && location in escape_zone) // Escapee Scores for (var/obj/item/card/id/C1 in E.contents) cashscore += C1.money for (var/obj/item/device/pda2/PDA in E.contents) if (PDA.ID_card) cashscore += PDA.ID_card.money for (var/obj/item/spacecash/C2 in E.contents) cashscore += C2.amount for (var/obj/item/storage/S in E.contents) for (var/obj/item/card/id/C3 in S.contents) cashscore += C3.money for (var/obj/item/device/pda2/PDA in S.contents) if (PDA.ID_card) cashscore += PDA.ID_card.money for (var/obj/item/spacecash/C4 in S.contents) cashscore += C4.amount for(var/datum/data/record/Ba in data_core.bank) if(Ba.fields["name"] == E.real_name) cashscore += Ba.fields["current_money"] if (cashscore > score_richestcash) score_richestcash = cashscore score_richestname = E.real_name score_richestjob = E.job score_richestkey = E.key dmgscore = E.get_brute_damage() + E.get_burn_damage() + E.get_toxin_damage() + E.get_oxygen_deprivation() if (dmgscore > score_dmgestdamage) score_dmgestdamage = dmgscore score_dmgestname = E.real_name score_dmgestjob = E.job score_dmgestkey = E.key var/list/stock_t5 = list() for (var/i = 0, i < 5, i++) if (!stockExchange.balances.len) break var/m = stockExchange.balances[1] var/mv = stockExchange.balances[m] for (var/N in stockExchange.balances) if (stockExchange.balances[N] > mv) m = N mv = stockExchange.balances[N] stock_t5[m] = mv stockExchange.balances -= m if (stock_t5.len) score_allstock_html = "