mirror of
https://gitlab.com/Deukhoofd/BattleSim.git
synced 2025-10-27 18:00:03 +00:00
Added /timer command for enabling the timer after battle has started
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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!")
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user