129 lines
4.3 KiB
CoffeeScript
129 lines
4.3 KiB
CoffeeScript
conditions = require '../conditions'
|
|
{_} = require 'underscore'
|
|
|
|
# Abstracts out sending messages from player to battle.
|
|
# Makes the Battle smoothly go into the next turn
|
|
# Necessary to separate out making commands and executing commands.
|
|
class @BattleController
|
|
constructor: (@battle) ->
|
|
conditions.attach(this)
|
|
@battle.emit('initialize')
|
|
|
|
BATTLE_DELEGATES = 'getPlayer isOver sendRequestTo
|
|
add remove'.trim().split(/\s+/)
|
|
|
|
for method in BATTLE_DELEGATES
|
|
do (method) =>
|
|
this::[method] = ->
|
|
@battle[method].apply(@battle, arguments)
|
|
|
|
# Returns all the player ids participating in this battle.
|
|
getPlayerIds: ->
|
|
@battle.playerIds
|
|
|
|
# Returns all the names of players participating in this battle.
|
|
# These names may be masked by alts
|
|
getPlayerNames: ->
|
|
@battle.playerNames
|
|
|
|
# Tells the player to execute a certain move by name. The move is added
|
|
# to the list of player actions, which are executed once the turn continues.
|
|
makeMove: (playerId, moveName, forSlot = 0, forTurn = @battle.turn, options = {}) ->
|
|
return false if @battle.isOver()
|
|
return false if forTurn != @battle.turn
|
|
return false if playerId not in @battle.playerIds
|
|
pokemon = @battle.getTeam(playerId).at(forSlot)
|
|
return false if !pokemon
|
|
request = @battle.requestFor(pokemon)
|
|
return false if !request
|
|
return false if moveName not in (request.moves || [])
|
|
move = @battle.getMove(moveName)
|
|
@battle.recordMove(playerId, move, forSlot, options)
|
|
@transitionToNextState()
|
|
return true
|
|
|
|
# Tells the player to switch with a certain pokemon specified by position.
|
|
# The switch is added to the list of player actions, which are executed
|
|
# once the turn continues.
|
|
makeSwitch: (playerId, toPosition, forSlot = 0, forTurn = @battle.turn) ->
|
|
return false if @battle.isOver()
|
|
return false if forTurn != @battle.turn
|
|
return false if playerId not in @battle.playerIds
|
|
pokemon = @battle.getTeam(playerId).at(forSlot)
|
|
return false if !pokemon
|
|
request = @battle.requestFor(pokemon)
|
|
return false if !request
|
|
return false if toPosition not in (request.switches || [])
|
|
@battle.recordSwitch(playerId, toPosition, forSlot)
|
|
@transitionToNextState()
|
|
return true
|
|
|
|
# Tells the player to cancel their latest completed request.
|
|
undoCompletedRequest: (playerId, forTurn = @battle.turn) ->
|
|
return false if forTurn != @battle.turn
|
|
@battle.undoCompletedRequest(playerId)
|
|
@sendUpdates()
|
|
return true
|
|
|
|
# Makes a player forfeit.
|
|
forfeit: (playerId) ->
|
|
return if @battle.isOver()
|
|
@battle.forfeit(playerId)
|
|
@sendUpdates()
|
|
|
|
messageSpectators: (user, message) ->
|
|
# In case the user is an alt.
|
|
userName = @battle.getPlayerName(user.name)
|
|
for spectator in @battle.spectators
|
|
spectator.send('updateBattleChat', @battle.id, userName, message)
|
|
|
|
rawMessage: (message) ->
|
|
for spectator in @battle.spectators
|
|
spectator.send('rawBattleMessage', @battle.id, message)
|
|
|
|
# Continue or begin a new turn if each player has made an action.
|
|
transitionToNextState: ->
|
|
return if not @battle.areAllRequestsCompleted()
|
|
if @battle.replacing
|
|
@battle.performReplacements()
|
|
@sendUpdates()
|
|
else
|
|
@continueTurn()
|
|
|
|
# Officially starts the battle.
|
|
beginBattle: ->
|
|
@battle.begin()
|
|
@sendUpdates()
|
|
|
|
beginTurn: ->
|
|
@battle.beginTurn()
|
|
@sendUpdates()
|
|
|
|
# Continues the turn. This is called once all requests
|
|
# have been submitted and the battle is ready to continue.
|
|
#
|
|
# If there are no more requests, the engine progresses to endTurn. Otherwise,
|
|
# it waits for continueTurn to be called again.
|
|
continueTurn: ->
|
|
@battle.continueTurn()
|
|
|
|
# If all requests have been completed, then end the turn.
|
|
# Otherwise, wait for further requests to be completed before ending.
|
|
if @battle.areAllRequestsCompleted() then @endTurn()
|
|
@sendUpdates()
|
|
|
|
# Calls Battle#endTurn. If all pokemon are fainted, then it
|
|
# ends the battle. Otherwise, it will request for new pokemon and wait if
|
|
# any replacements are needed, or begins the next turn.
|
|
endTurn: ->
|
|
@battle.endTurn()
|
|
@sendUpdates()
|
|
|
|
endBattle: ->
|
|
@battle.endBattle()
|
|
@sendUpdates()
|
|
|
|
# Sends battle updates to spectators.
|
|
sendUpdates: ->
|
|
@battle.sendUpdates()
|