From 9ca2a8746c17b9f3f8abbca9dbf378ad8f09a97c Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Tue, 12 Apr 2016 19:45:15 +0200 Subject: [PATCH] Added /timer command for enabling the timer after battle has started --- client/app/js/concerns/commands.coffee | 2 + client/app/js/concerns/errors.coffee | 4 +- client/app/js/concerns/main_buttons.coffee | 32 +++++++- client/app/js/helpers/challenge_pane.coffee | 18 +++-- client/templates/index.jade | 4 + public/js/app.js | 51 ++++++++++--- public/js/replays.js | 19 +++-- server/bw/battle.coffee | 12 ++- server/commands.coffee | 22 ++++++ server/conditions.coffee | 61 ++++++++------- server/index.coffee | 38 +++++++-- server/randomTeams.coffee | 85 ++++++++++++--------- server/server.coffee | 64 ++++++++++++---- 13 files changed, 298 insertions(+), 114 deletions(-) diff --git a/client/app/js/concerns/commands.coffee b/client/app/js/concerns/commands.coffee index 148c1f6..aa61aba 100644 --- a/client/app/js/concerns/commands.coffee +++ b/client/app/js/concerns/commands.coffee @@ -98,6 +98,8 @@ makeCommand "pbv", (room, pokemon...) -> else room.announce('success', "PBV: #{messages.join('; ')}") + + findPokemonAtPBV = (pbv) -> messages = [] counter = 0 diff --git a/client/app/js/concerns/errors.coffee b/client/app/js/concerns/errors.coffee index e76d20e..2c39267 100644 --- a/client/app/js/concerns/errors.coffee +++ b/client/app/js/concerns/errors.coffee @@ -9,7 +9,7 @@ PokeBattle.events.on "errorMessage", (type, args...) -> options = title: "Your login timed out!" body: """To access the simulator, you need to - login again.""" + login again.""" $modal = PokeBattle.modal('modals/errors', options) $modal.find('.modal-footer button').first().focus() PokeBattle.primus.end() @@ -33,6 +33,8 @@ PokeBattle.events.on "errorMessage", (type, args...) -> when e.FIND_BATTLE PokeBattle.events.trigger("findBattleCanceled") + PokeBattle.events.trigger("findBattleCanceledUnranked") + PokeBattle.events.trigger("findBattleCanceledRandom") # Show errors [errors] = args diff --git a/client/app/js/concerns/main_buttons.coffee b/client/app/js/concerns/main_buttons.coffee index d68ea64..11d5589 100644 --- a/client/app/js/concerns/main_buttons.coffee +++ b/client/app/js/concerns/main_buttons.coffee @@ -28,6 +28,17 @@ $ -> Conditions.PRANKSTER_SWAGGER_CLAUSE Conditions.TIMED_BATTLE ] + createChallengeButton + eventName: "findBattleRandom" + button: $mainButtons.find('.find_battle_random') + clauses: [ + Conditions.SLEEP_CLAUSE + Conditions.EVASION_CLAUSE + Conditions.SPECIES_CLAUSE + Conditions.OHKO_CLAUSE + Conditions.PRANKSTER_SWAGGER_CLAUSE + Conditions.TIMED_BATTLE + ] createChallengePaneNew populate: $mainButtons.find('.find_battle_select_team') @@ -45,6 +56,12 @@ $ -> .addClass('icon-spinner spinner-anim') .removeClass("icon-earth") + $mainButtons.find('.find_battle_random').on 'challenge', -> + $this = $(this) + $this.find('.find-icon') + .addClass('icon-spinner spinner-anim') + .removeClass("icon-earth") + $mainButtons.find('.display_credits').click -> $modal = PokeBattle.modal('modals/credits') $modal.find('.modal-footer button').first().focus() @@ -68,15 +85,28 @@ depressFindBattleUnranked = -> .addClass("icon-earth") $mainButtons.find('.find_battle_select_team .select').removeClass('disabled') +depressFindBattleRandom = -> + $mainButtons = $('.main_buttons') + $button = $mainButtons.find('.find_battle_random') + $button.removeClass("disabled") + $button.find('.find-icon') + .removeClass("icon-spinner spinner-anim") + .addClass("icon-earth") + $mainButtons.find('.find_battle_select_team .select').removeClass('disabled') + $(window).load -> $mainButtons = $('.main_buttons') PokeBattle.battles.on 'add', (battle) -> if !battle.get('spectating') depressFindBattle() depressFindBattleUnranked() + depressFindBattleRandom() PokeBattle.primus.on 'findBattleCanceled', depressFindBattle PokeBattle.events.on 'findBattleCanceled', depressFindBattle PokeBattle.primus.on 'findBattleCanceledUnranked', depressFindBattleUnranked - PokeBattle.events.on 'findBattleCanceledUnranked', depressFindBattleUnranked \ No newline at end of file + PokeBattle.events.on 'findBattleCanceledUnranked', depressFindBattleUnranked + + PokeBattle.primus.on 'findBattleCanceledRandom', depressFindBattleRandom + PokeBattle.events.on 'findBattleCanceledRandom', depressFindBattleRandom \ No newline at end of file diff --git a/client/app/js/helpers/challenge_pane.coffee b/client/app/js/helpers/challenge_pane.coffee index 4e1f459..32b0b2e 100644 --- a/client/app/js/helpers/challenge_pane.coffee +++ b/client/app/js/helpers/challenge_pane.coffee @@ -58,13 +58,17 @@ class @challengePaneObject format = defaultformat() # Toggle state when you press the button. if !$button.hasClass('disabled') - team = getSelectedTeam() - unless team - alert("You need to create a team using the Teambuilder before you can battle.") - PokeBattle.navigation.showTeambuilder() - return - disableButtons() - teamJSON = team.toNonNullJSON().pokemon + if $eventName is "findBattleRandom" + teamJSON = [] + disableButtons() + else + team = getSelectedTeam() + unless team + alert("You need to create a team using the Teambuilder before you can battle.") + PokeBattle.navigation.showTeambuilder() + return + disableButtons() + teamJSON = team.toNonNullJSON().pokemon # Send the event PokeBattle.primus.send($eventName, format, teamJSON, options.selectedAlt) $button.addClass('disabled').trigger('challenge') diff --git a/client/templates/index.jade b/client/templates/index.jade index efd38b7..783dcc0 100644 --- a/client/templates/index.jade +++ b/client/templates/index.jade @@ -13,6 +13,10 @@ block content .button.big.find_battle span.find-icon.icon-earth | Ranked battle + p + .button.big.find_battle_random + span.find-icon.icon-earth + | Random battle .find_battle_select_team .section .button.teambuilder_button diff --git a/public/js/app.js b/public/js/app.js index 0433469..1ab1428 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -7697,14 +7697,19 @@ format = defaultformat(); } if (!$button.hasClass('disabled')) { - team = getSelectedTeam(); - if (!team) { - alert("You need to create a team using the Teambuilder before you can battle."); - PokeBattle.navigation.showTeambuilder(); - return; + if ($eventName === "findBattleRandom") { + teamJSON = []; + disableButtons(); + } else { + team = getSelectedTeam(); + if (!team) { + alert("You need to create a team using the Teambuilder before you can battle."); + PokeBattle.navigation.showTeambuilder(); + return; + } + disableButtons(); + teamJSON = team.toNonNullJSON().pokemon; } - disableButtons(); - teamJSON = team.toNonNullJSON().pokemon; PokeBattle.primus.send($eventName, format, teamJSON, options.selectedAlt); return $button.addClass('disabled').trigger('challenge'); } else { @@ -11325,7 +11330,7 @@ } options = { title: "Your login timed out!", - body: "To access the simulator, you need to\nlogin again." + body: "To access the simulator, you need to\nlogin again." }; $modal = PokeBattle.modal('modals/errors', options); $modal.find('.modal-footer button').first().focus(); @@ -11353,6 +11358,8 @@ return PokeBattle.primus.end(); case e.FIND_BATTLE: PokeBattle.events.trigger("findBattleCanceled"); + PokeBattle.events.trigger("findBattleCanceledUnranked"); + PokeBattle.events.trigger("findBattleCanceledRandom"); errors = args[0]; return alert(errors); case e.BATTLE_DNE: @@ -11409,7 +11416,7 @@ }).call(this); (function() { - var depressFindBattle, depressFindBattleUnranked; + var depressFindBattle, depressFindBattleRandom, depressFindBattleUnranked; $(function() { var $mainButtons; @@ -11427,6 +11434,11 @@ button: $mainButtons.find('.find_battle_non_ranked'), clauses: [Conditions.SLEEP_CLAUSE, Conditions.EVASION_CLAUSE, Conditions.SPECIES_CLAUSE, Conditions.OHKO_CLAUSE, Conditions.PRANKSTER_SWAGGER_CLAUSE, Conditions.TIMED_BATTLE] }); + createChallengeButton({ + eventName: "findBattleRandom", + button: $mainButtons.find('.find_battle_random'), + clauses: [Conditions.SLEEP_CLAUSE, Conditions.EVASION_CLAUSE, Conditions.SPECIES_CLAUSE, Conditions.OHKO_CLAUSE, Conditions.PRANKSTER_SWAGGER_CLAUSE, Conditions.TIMED_BATTLE] + }); createChallengePaneNew({ populate: $mainButtons.find('.find_battle_select_team') }); @@ -11440,6 +11452,11 @@ $this = $(this); return $this.find('.find-icon').addClass('icon-spinner spinner-anim').removeClass("icon-earth"); }); + $mainButtons.find('.find_battle_random').on('challenge', function() { + var $this; + $this = $(this); + return $this.find('.find-icon').addClass('icon-spinner spinner-anim').removeClass("icon-earth"); + }); return $mainButtons.find('.display_credits').click(function() { var $modal; $modal = PokeBattle.modal('modals/credits'); @@ -11465,19 +11482,31 @@ return $mainButtons.find('.find_battle_select_team .select').removeClass('disabled'); }; + depressFindBattleRandom = function() { + var $button, $mainButtons; + $mainButtons = $('.main_buttons'); + $button = $mainButtons.find('.find_battle_random'); + $button.removeClass("disabled"); + $button.find('.find-icon').removeClass("icon-spinner spinner-anim").addClass("icon-earth"); + return $mainButtons.find('.find_battle_select_team .select').removeClass('disabled'); + }; + $(window).load(function() { var $mainButtons; $mainButtons = $('.main_buttons'); PokeBattle.battles.on('add', function(battle) { if (!battle.get('spectating')) { depressFindBattle(); - return depressFindBattleUnranked(); + depressFindBattleUnranked(); + return depressFindBattleRandom(); } }); PokeBattle.primus.on('findBattleCanceled', depressFindBattle); PokeBattle.events.on('findBattleCanceled', depressFindBattle); PokeBattle.primus.on('findBattleCanceledUnranked', depressFindBattleUnranked); - return PokeBattle.events.on('findBattleCanceledUnranked', depressFindBattleUnranked); + PokeBattle.events.on('findBattleCanceledUnranked', depressFindBattleUnranked); + PokeBattle.primus.on('findBattleCanceledRandom', depressFindBattleRandom); + return PokeBattle.events.on('findBattleCanceledRandom', depressFindBattleRandom); }); }).call(this); diff --git a/public/js/replays.js b/public/js/replays.js index 5263c12..1f20af3 100644 --- a/public/js/replays.js +++ b/public/js/replays.js @@ -5315,14 +5315,19 @@ format = defaultformat(); } if (!$button.hasClass('disabled')) { - team = getSelectedTeam(); - if (!team) { - alert("You need to create a team using the Teambuilder before you can battle."); - PokeBattle.navigation.showTeambuilder(); - return; + if ($eventName === "findBattleRandom") { + teamJSON = []; + disableButtons(); + } else { + team = getSelectedTeam(); + if (!team) { + alert("You need to create a team using the Teambuilder before you can battle."); + PokeBattle.navigation.showTeambuilder(); + return; + } + disableButtons(); + teamJSON = team.toNonNullJSON().pokemon; } - disableButtons(); - teamJSON = team.toNonNullJSON().pokemon; PokeBattle.primus.send($eventName, format, teamJSON, options.selectedAlt); return $button.addClass('disabled').trigger('challenge'); } else { diff --git a/server/bw/battle.coffee b/server/bw/battle.coffee index f56947b..a7cf814 100644 --- a/server/bw/battle.coffee +++ b/server/bw/battle.coffee @@ -11,6 +11,8 @@ Query = require './queries' {Room} = require '../rooms' logger = require '../logger' +randomTeam = require('../randomTeams') + # Represents a single ongoing battle class @Battle extends Room @@ -41,7 +43,7 @@ class @Battle extends Room action: (action) -> @performMove(action.pokemon, action.move) - constructor: (@id, @players, attributes = {}) -> + constructor: (@id, @players, attributes = {}, randomTeams = false) -> super(@id) # Number of pokemon on each side of the field @numActive = attributes.numActive || 1 @@ -109,7 +111,13 @@ class @Battle extends Room @playerIds.push(player.id) @playerNames.push(player.name) # TODO: Get the actual player object and use player.name - @teams[player.id] = new Team(this, player.id, player.name, player.team, @numActive) + if randomTeams + rteam2 = [] + randomTeam.createTeam @format, @conditions, (rTeam, rteamName) -> + rteam2 = rTeam + @teams[player.id] = new Team(this, player.id, player.name, rteam2, @numActive) + else + @teams[player.id] = new Team(this, player.id, player.name, player.team, @numActive) # Holds battle state information @replacing = false diff --git a/server/commands.coffee b/server/commands.coffee index eff546f..3cc4cab 100644 --- a/server/commands.coffee +++ b/server/commands.coffee @@ -4,10 +4,13 @@ alts = require('./alts') auth = require('./auth') ratings = require('./ratings') errors = require('../shared/errors') +conditions = require './conditions' exports.Commands = Commands = {} exports.HelpDescriptions = HelpDescriptions = {} +server_ = {} + desc = (description) -> desc.lastDescription = description @@ -95,6 +98,7 @@ makeOwnerCommand = (commandNames..., func) -> @executeCommand = (server, user, room, commandName, args...) -> {args, callback} = parseArguments(args) + server_ = server callback ||= -> func = Commands[commandName] if !func @@ -348,3 +352,21 @@ makeOwnerCommand "eval", (user, room, next, pieces...) -> catch e user.error(errors.COMMAND_ERROR, room.name, "EVAL ERROR: #{e.message}") next() + +desc "Makes the battle timed" +makeCommand "timer", (user, room, next) -> + controller = server_.findBattle(room.id) + isBattler = false + console.log(user.id) + player = room.getPlayer(user.id) + if 4 not in controller.battle.conditions and player != null + controller.battle.conditions.push(4) + conditions.attach(controller) + room.initTimer() + room.startingTimer() + room.onBeginTurn() + room.send + else if 4 in controller.battle.conditions + user.announce(room.name, "error", "The timer is already enabled!") + else if getPlayer == null + user.announce(room.name, "error", "You are not a battler!") \ No newline at end of file diff --git a/server/conditions.coffee b/server/conditions.coffee index 5f110b9..fce5f1b 100644 --- a/server/conditions.coffee +++ b/server/conditions.coffee @@ -211,29 +211,10 @@ createCondition Conditions.RATED_BATTLE, createCondition Conditions.TIMED_BATTLE, attach: initialize: -> - @playerTimes = {} - @lastActionTimes = {} - now = Date.now() - - # Set up initial values - for id in @playerIds - @playerTimes[id] = now + @TEAM_PREVIEW_TIMER - - # Set up timers and event listeners - check = () => - @startBattle() - @sendUpdates() - @teamPreviewTimerId = setTimeout(check, @TEAM_PREVIEW_TIMER) - @once('end', => clearTimeout(@teamPreviewTimerId)) - @once('start', => clearTimeout(@teamPreviewTimerId)) + @initTimer() start: -> - nowTime = Date.now() - for id in @playerIds - @playerTimes[id] = nowTime + @DEFAULT_TIMER - # Remove first turn since we'll be increasing it again. - @playerTimes[id] -= @TIMER_PER_TURN_INCREASE - @startTimer() + @startingTimer() requestActions: (playerId) -> # If a player has selected a move, then there's an amount of time spent @@ -258,11 +239,7 @@ createCondition Conditions.TIMED_BATTLE, # Show players updated times beginTurn: -> - remainingTimes = [] - for id in @playerIds - @addTime(id, @TIMER_PER_TURN_INCREASE) - remainingTimes.push(@timeRemainingFor(id)) - @send('updateTimers', @id, remainingTimes) + @onBeginTurn() continueTurn: -> for id in @playerIds @@ -285,6 +262,38 @@ createCondition Conditions.TIMED_BATTLE, TIMER_CAP: 3 * 60 * 1000 # three minutes TEAM_PREVIEW_TIMER: 1.5 * 60 * 1000 # 1 minute and 30 seconds + initTimer: -> + @playerTimes = {} + @lastActionTimes = {} + now = Date.now() + + # Set up initial values + for id in @playerIds + @playerTimes[id] = now + @TEAM_PREVIEW_TIMER + + # Set up timers and event listeners + check = () => + @startBattle() + @sendUpdates() + @teamPreviewTimerId = setTimeout(check, @TEAM_PREVIEW_TIMER) + @once('end', => clearTimeout(@teamPreviewTimerId)) + @once('start', => clearTimeout(@teamPreviewTimerId)) + + startingTimer: -> + nowTime = Date.now() + for id in @playerIds + @playerTimes[id] = nowTime + @DEFAULT_TIMER + # Remove first turn since we'll be increasing it again. + @playerTimes[id] -= @TIMER_PER_TURN_INCREASE + @startTimer() + + onBeginTurn: -> + remainingTimes = [] + for id in @playerIds + @addTime(id, @TIMER_PER_TURN_INCREASE) + remainingTimes.push(@timeRemainingFor(id)) + @send('updateTimers', @id, remainingTimes) + startTimer: (msecs) -> msecs ?= @DEFAULT_TIMER @timerId = setTimeout(@declareWinner.bind(this), msecs) diff --git a/server/index.coffee b/server/index.coffee index 99a2bda..a087b05 100644 --- a/server/index.coffee +++ b/server/index.coffee @@ -283,7 +283,7 @@ CLIENT_VERSION = assets.getVersion() if user.authority == auth.levels.OWNER teamArr = [] for [1..number] - randomTeam.createTeam format, (team) -> + randomTeam.createTeamBookshelf format, [], (team) -> teamArr.push(team) teams = new database.Teams(teamArr) spark.send('receiveTeams', teams.toJSON()) @@ -383,9 +383,6 @@ CLIENT_VERSION = assets.getVersion() callback(battleMetadata) spark.on 'findBattle', (format, team, altName=null) -> - console.log('find battle') - console.log(format) - console.log(team) return unless _.isString(format) return unless _.isObject(team) return unless !altName || _.isString(altName) @@ -394,7 +391,7 @@ CLIENT_VERSION = assets.getVersion() if not valid user.error(errors.INVALID_ALT_NAME, "You do not own this alt") else - validationErrors = server.queuePlayer(user.name, team, format, altName) + validationErrors = server.queuePlayer(user.name, team, format, altName, "ranked") if validationErrors.length > 0 user.error(errors.FIND_BATTLE, validationErrors) @@ -411,7 +408,7 @@ CLIENT_VERSION = assets.getVersion() if not valid user.error(errors.INVALID_ALT_NAME, "You do not own this alt") else - validationErrors = server.queuePlayerunranked(user.name, team, format, altName) + validationErrors = server.queuePlayer(user.name, team, format, altName, "unranked") if validationErrors.length > 0 user.error(errors.FIND_BATTLE, validationErrors) @@ -419,6 +416,23 @@ CLIENT_VERSION = assets.getVersion() server.removePlayerunranked(user.name) user.send("findBattleCanceledUnranked") + spark.on 'findBattleRandom', (format, team, altName=null) -> + return unless _.isString(format) + return unless _.isObject(team) + return unless !altName || _.isString(altName) + # Note: If altName == null, then isAltOwnedBy will return true + alts.isAltOwnedBy user.name, altName, (err, valid) -> + if not valid + user.error(errors.INVALID_ALT_NAME, "You do not own this alt") + else + validationErrors = server.queuePlayer(user.name, team, format, altName, "random") + if validationErrors.length > 0 + user.error(errors.FIND_BATTLE, validationErrors) + + spark.on 'cancelFindBattleRandom', -> + server.removePlayerrandom(user.name) + user.send("findBattleCanceledRandom") + spark.on 'sendMove', (battleId, moveName, slot, forTurn, options, callback) -> return unless _.isString(moveName) return unless _.isFinite(slot) @@ -497,10 +511,20 @@ CLIENT_VERSION = assets.getVersion() ratings.getRanks ratingKeys, (err, fullRanks) -> ranks = _.compact(fullRanks) setTimeout(battleSearchUnranked, 5 * 1000) - + battleSearchRandom = -> + server.beginBattlesrandom (err, battleIds) -> + if err then return + for id in battleIds + battle = server.findBattle(id) + playerIds = battle.getPlayerIds() + ratingKeys = playerIds.map((id) -> battle.getPlayer(id).ratingKey) + ratings.getRanks ratingKeys, (err, fullRanks) -> + ranks = _.compact(fullRanks) + setTimeout(battleSearchRandom, 5 * 1000) battleSearch() battleSearchUnranked() + battleSearchRandom() httpServer.listen(port) diff --git a/server/randomTeams.coffee b/server/randomTeams.coffee index 784f6bc..95a426e 100644 --- a/server/randomTeams.coffee +++ b/server/randomTeams.coffee @@ -7,46 +7,59 @@ Formats = FormatsClass.Formats() pokemonArr = [] hasmega = false -createTeam = (format, next) -> +createTeamBookshelf = (format, requs, next) -> + createTeam format, requs, (mons, teamname) -> + team = {} + team.name = teamname + team.id = Math.floor(Math.random() * (10000000) + 10000000) + team.generation = Formats[format].generation + team.pokemon = mons + + attributes = _.pick(team, 'id', 'name', 'generation') + attributes['trainer_id'] = 1 + attributes['contents'] = JSON.stringify(mons) + + Team = new database.Team(attributes) + next(Team) + +createTeam = (format, requs, next) -> pokemonArr = [] hasmega = false - conditions = Formats[format] - if conditions.tierBased == false - console.log("PBV is not supported") - return - #throw error - generation = conditions.generation.toUpperCase() - for condNum in conditions.conditions - for conditionName, conditionNumber of FormatsClass.Conditions - if conditionNumber is condNum - if /TIER_/.test(conditionName) - tier = conditionName.replace /TIER_/, "" - break - getValidFormes generation, tier, (list) -> - if list.length < 6 - console.log("Not enough pokemon in this tier to make a team") - return - team = {} - team.name = "Random" + tier - team.id = Math.floor(Math.random() * (10000000) + 10000000) - team.generation = conditions.generation - getPokemonArr = -> - if pokemonArr.length < 6 - generatePokemon list, generation, (pkmn) -> - pokemonArr.push(pkmn) - getPokemonArr() - getPokemonArr() + genTeam = -> + conditions = Formats[format] + if conditions.tierBased == false + console.log("PBV is not supported") + return + #throw error + generation = conditions.generation.toUpperCase() + for condNum in conditions.conditions + for conditionName, conditionNumber of FormatsClass.Conditions + if conditionNumber is condNum + if /TIER_/.test(conditionName) + tier = conditionName.replace /TIER_/, "" + break + getValidFormes generation, tier, (list) -> + if list.length < 6 + console.log("Not enough pokemon in this tier to make a team") + return + getPokemonArr = -> + if pokemonArr.length < 6 + generatePokemon list, generation, (pkmn) -> + pokemonArr.push(pkmn) + getPokemonArr() + getPokemonArr() - pokemonArr.splice(6) - team.pokemon = pokemonArr + pokemonArr.splice(6) - attributes = _.pick(team, 'id', 'name', 'generation') - attributes['trainer_id'] = 1 - attributes['contents'] = JSON.stringify(team.pokemon) - - Team = new database.Team(attributes) - next(Team) + err = require('./conditions').validateTeam(requs, pokemonArr, gen.GenerationJSON[generation]) + if err.length > 0 + console.log(err) + genTeam() + return + teamname = "Random" + tier + next(pokemonArr, teamname) + genTeam() getValidFormes = (generation, tier, next) -> filteredlist = [] @@ -228,4 +241,4 @@ determineIVs = (type) -> ivObj.specialAttack = 30 return ivObj -module.exports = {createTeam} +module.exports = {createTeamBookshelf, createTeam} diff --git a/server/server.coffee b/server/server.coffee index 669507e..5771c8b 100644 --- a/server/server.coffee +++ b/server/server.coffee @@ -44,11 +44,14 @@ class @BattleServer constructor: -> @queues = {} @unrankedqueues = {} + @randomqueues = {} allformats = ConditionsFunc.Formats() for format of allformats @queues[format] = new BattleQueue() @unrankedqueues[format] = new BattleQueue() @unrankedqueues[format].setUnranked() + @randomqueues[format] = new BattleQueue() + @randomqueues[format].setUnranked() @battles = {} # A hash mapping users to battles. @@ -211,18 +214,26 @@ class @BattleServer # Adds the player to the queue. Note that there is no validation on whether altName # is correct, so make - queuePlayer: (playerId, team, format = DEFAULT_FORMAT, altName) -> + queuePlayer: (playerId, team, format = DEFAULT_FORMAT, altName, queuetype) -> if @isLockedDown() err = ["The server is restarting after all battles complete. No new battles can start at this time."] - else if format != DEFAULT_FORMAT + else if format != DEFAULT_FORMAT and queuetype is "ranked" # TODO: Implement ratings for other formats err = ["The server doesn't support this ladder at this time. Please ask for challenges instead."] else - err = @validateTeam(team, format, FIND_BATTLE_CONDITIONS) + if queuetype isnt "random" + err = @validateTeam(team, format, FIND_BATTLE_CONDITIONS) + else + err = [] if err.length == 0 name = @users.get(playerId).name ratingKey = alts.uniqueId(playerId, altName) - @queues[format].add(playerId, altName || name, team, ratingKey) + if queuetype is "ranked" + @queues[format].add(playerId, altName || name, team, ratingKey) + else if queuetype is "unranked" + @unrankedqueues[format].add(playerId, altName || name, team, ratingKey) + else if queuetype is "random" + @randomqueues[format].add(playerId, altName || name, team, ratingKey) return err queuedPlayers: (format = DEFAULT_FORMAT) -> @@ -253,16 +264,6 @@ class @BattleServer ######################################################################################### # Adds the player to the queue. Note that there is no validation on whether altName # is correct, so make - queuePlayerunranked: (playerId, team, format = DEFAULT_FORMAT, altName) -> - if @isLockedDown() - err = ["The server is restarting after all battles complete. No new battles can start at this time."] - else - err = @validateTeam(team, format, FIND_BATTLE_CONDITIONS) - if err.length == 0 - name = @users.get(playerId).name - ratingKey = alts.uniqueId(playerId, altName) - @unrankedqueues[format].add(playerId, altName || name, team, ratingKey) - return err queuedPlayersunranked: (format = DEFAULT_FORMAT) -> @unrankedqueues[format].queuedPlayers() @@ -289,9 +290,40 @@ class @BattleServer return next(err) if err next(null, _.flatten(battleIds)) return true +######################################################################################### + # Adds the player to the queue. Note that there is no validation on whether altName + # is correct, so make + + queuedPlayersrandom: (format = DEFAULT_FORMAT) -> + @randomqueues[format].queuedPlayers() + + removePlayerrandom: (playerId, format = DEFAULT_FORMAT) -> + return false if format not of @randomqueues + @randomqueues[format].remove(playerId) + return true + + beginBattlesrandom: (next) -> + allformats = ConditionsFunc.Formats() + array = for format in Object.keys(allformats) + do (format) => (callback) => + @randomqueues[format].pairPlayers (err, pairs) => + if err then console.log(err) + if err then return callback(err) + # Create a battle for each pair + battleIds = [] + for pair in pairs + id = @createBattle(format, pair, FIND_BATTLE_CONDITIONS_UNRANKED, true) + battleIds.push(id) + callback(null, battleIds) + async.parallel array, (err, battleIds) -> + return next(err) if err + next(null, _.flatten(battleIds)) + return true + + ######################################################################################### # Creates a battle and returns its battleId - createBattle: (rawFormat = DEFAULT_FORMAT, pair = [], conditions = []) -> + createBattle: (rawFormat = DEFAULT_FORMAT, pair = [], conditions = [], random = false) -> allformats = ConditionsFunc.Formats() format = allformats[rawFormat] generation = format.generation @@ -300,7 +332,7 @@ class @BattleServer {BattleController} = require("../server/#{generation}/battle_controller") playerIds = pair.map((user) -> user.name) battleId = @generateBattleId(playerIds) - battle = new Battle(battleId, pair, format: rawFormat, conditions: _.clone(conditions)) + battle = new Battle(battleId, pair, format: rawFormat, conditions: _.clone(conditions), random) @battles[battleId] = new BattleController(battle) for player in pair # Add user to spectators