211 lines
7.4 KiB
CoffeeScript
211 lines
7.4 KiB
CoffeeScript
|
@PokeBattle.mixins.BattleProtocolParser =
|
||
|
update: (actions) ->
|
||
|
return if actions.length == 0
|
||
|
@notify()
|
||
|
hadStuff = (@updateQueue.length > 0)
|
||
|
@updateQueue.push(actions...)
|
||
|
@_update() unless hadStuff
|
||
|
|
||
|
_update: (wasAtBottom) ->
|
||
|
view = @view
|
||
|
queue = @updateQueue
|
||
|
return if !queue # closed battle in the middle of getting updates
|
||
|
if queue.length == 0
|
||
|
view.renderUserInfo()
|
||
|
view.resetPopovers()
|
||
|
if wasAtBottom || view.skip? then view.chatView.scrollToBottom()
|
||
|
if view.skip?
|
||
|
delete view.skip
|
||
|
view.$('.battle_pane').show()
|
||
|
return
|
||
|
wasAtBottom ||= view.chatView.isAtBottom()
|
||
|
action = queue.shift()
|
||
|
[ type, rest... ] = action
|
||
|
protocol = (key for key, value of Protocol when value == type)[0]
|
||
|
try
|
||
|
if window.localStorage.debug == 'true'
|
||
|
console.log "Received protocol: #{protocol} with args: #{rest}"
|
||
|
catch
|
||
|
|
||
|
done = () =>
|
||
|
return if done.called
|
||
|
done.called = true
|
||
|
if view.skip?
|
||
|
@_update.call(this, wasAtBottom)
|
||
|
else
|
||
|
# setTimeout 0 lets the browser breathe.
|
||
|
setTimeout(@_update.bind(this, wasAtBottom), 0)
|
||
|
|
||
|
doneTimeout = ->
|
||
|
setTimeout(done, 0)
|
||
|
|
||
|
doneSpeedTimeout = () =>
|
||
|
if view.skip? || view.speed <= 1
|
||
|
done()
|
||
|
else
|
||
|
setTimeout(done, (view.speed - 1) * 1000)
|
||
|
|
||
|
try
|
||
|
switch type
|
||
|
when Protocol.CHANGE_HP
|
||
|
[player, slot, newPercent] = rest
|
||
|
pokemon = @getPokemon(player, slot)
|
||
|
pokemon.set('percent', newPercent)
|
||
|
if view.skip? then done() else setTimeout(done, 500)
|
||
|
when Protocol.CHANGE_EXACT_HP
|
||
|
[player, slot, newHP] = rest
|
||
|
pokemon = @getPokemon(player, slot)
|
||
|
pokemon.set('hp', newHP)
|
||
|
done()
|
||
|
when Protocol.SWITCH_OUT
|
||
|
[player, slot] = rest
|
||
|
view.switchOut(player, slot, done)
|
||
|
when Protocol.SWITCH_IN
|
||
|
# TODO: Get Pokemon data, infer which Pokemon it is.
|
||
|
# Currently, it cheats with `fromSlot`.
|
||
|
[player, toSlot, fromSlot] = rest
|
||
|
team = @getTeam(player).get('pokemon').models
|
||
|
[team[toSlot], team[fromSlot]] = [team[fromSlot], team[toSlot]]
|
||
|
# TODO: Again, automatic.
|
||
|
view.switchIn(player, toSlot, fromSlot, doneSpeedTimeout)
|
||
|
when Protocol.CHANGE_PP
|
||
|
[player, slot, moveIndex, newPP] = rest
|
||
|
pokemon = @getPokemon(player, slot)
|
||
|
pokemon.setPP(moveIndex, newPP)
|
||
|
done()
|
||
|
when Protocol.REQUEST_ACTIONS
|
||
|
[validActions] = rest
|
||
|
view.enableButtons(validActions)
|
||
|
PokeBattle.notifyUser(PokeBattle.NotificationTypes.ACTION_REQUESTED, @id + "_" + @get('turn'))
|
||
|
done()
|
||
|
when Protocol.START_TURN
|
||
|
[turn] = rest
|
||
|
view.beginTurn(turn, doneTimeout)
|
||
|
when Protocol.CONTINUE_TURN
|
||
|
view.continueTurn(doneTimeout)
|
||
|
when Protocol.RAW_MESSAGE
|
||
|
[message] = rest
|
||
|
view.addLog("#{message}<br>")
|
||
|
done()
|
||
|
when Protocol.FAINT
|
||
|
[player, slot] = rest
|
||
|
view.faint(player, slot, done)
|
||
|
when Protocol.MAKE_MOVE
|
||
|
# TODO: Send move id instead
|
||
|
[player, slot, moveName] = rest
|
||
|
view.logMove(player, slot, moveName, done)
|
||
|
when Protocol.END_BATTLE
|
||
|
[winner] = rest
|
||
|
view.announceWinner(winner, done)
|
||
|
when Protocol.FORFEIT_BATTLE
|
||
|
[forfeiter] = rest
|
||
|
view.announceForfeit(forfeiter, done)
|
||
|
when Protocol.TIMER_WIN
|
||
|
[winner] = rest
|
||
|
view.announceTimer(winner, done)
|
||
|
when Protocol.BATTLE_EXPIRED
|
||
|
view.announceExpiration(done)
|
||
|
when Protocol.MOVE_SUCCESS
|
||
|
[player, slot, targetSlots, moveName] = rest
|
||
|
view.moveSuccess(player, slot, targetSlots, moveName, done)
|
||
|
when Protocol.CANNED_TEXT
|
||
|
cannedInteger = rest.splice(0, 1)
|
||
|
view.parseCannedText(cannedInteger, rest, done)
|
||
|
when Protocol.EFFECT_END
|
||
|
[player, slot, effect] = rest
|
||
|
view.endEffect(player, slot, effect, done)
|
||
|
when Protocol.POKEMON_ATTACH
|
||
|
[player, slot, attachment] = rest
|
||
|
view.attachPokemon(player, slot, attachment, done)
|
||
|
when Protocol.TEAM_ATTACH
|
||
|
[player, attachment] = rest
|
||
|
view.attachTeam(player, attachment, done)
|
||
|
when Protocol.BATTLE_ATTACH
|
||
|
[attachment] = rest
|
||
|
view.attachBattle(attachment, done)
|
||
|
when Protocol.POKEMON_UNATTACH
|
||
|
[player, slot, attachment] = rest
|
||
|
view.unattachPokemon(player, slot, attachment, done)
|
||
|
when Protocol.TEAM_UNATTACH
|
||
|
[player, attachment] = rest
|
||
|
view.unattachTeam(player, attachment, done)
|
||
|
when Protocol.BATTLE_UNATTACH
|
||
|
[attachment] = rest
|
||
|
view.unattachBattle(attachment, done)
|
||
|
when Protocol.INITIALIZE
|
||
|
# TODO: Handle non-team-preview
|
||
|
[teams] = rest
|
||
|
@receiveTeams(teams)
|
||
|
view.preloadImages()
|
||
|
if !@get('spectating')
|
||
|
PokeBattle.notifyUser(PokeBattle.NotificationTypes.BATTLE_STARTED, @id)
|
||
|
done()
|
||
|
when Protocol.START_BATTLE
|
||
|
view.removeTeamPreview()
|
||
|
view.renderBattle()
|
||
|
done()
|
||
|
when Protocol.REARRANGE_TEAMS
|
||
|
arrangements = rest
|
||
|
@get('teams').forEach (team, i) ->
|
||
|
team.rearrange(arrangements[i])
|
||
|
done()
|
||
|
when Protocol.RECEIVE_TEAM
|
||
|
[team] = rest
|
||
|
@receiveTeam(team)
|
||
|
done()
|
||
|
when Protocol.SPRITE_CHANGE
|
||
|
[player, slot, newSpecies, newForme] = rest
|
||
|
pokemon = @getPokemon(player, slot)
|
||
|
pokemon.set('species', newSpecies)
|
||
|
pokemon.set('forme', newForme)
|
||
|
view.changeSprite(player, slot, newSpecies, newForme, done)
|
||
|
when Protocol.NAME_CHANGE
|
||
|
[player, slot, newName] = rest
|
||
|
pokemon = @getPokemon(player, slot)
|
||
|
view.changeName(player, slot, newName, done)
|
||
|
when Protocol.BOOSTS
|
||
|
[player, slot, deltaBoosts] = rest
|
||
|
view.boost(player, slot, deltaBoosts, floatText: true)
|
||
|
done()
|
||
|
when Protocol.SET_BOOSTS
|
||
|
[player, slot, boosts] = rest
|
||
|
view.setBoosts(player, slot, boosts)
|
||
|
done()
|
||
|
when Protocol.RESET_BOOSTS
|
||
|
[player, slot] = rest
|
||
|
view.resetBoosts(player, slot)
|
||
|
done()
|
||
|
when Protocol.MOVESET_UPDATE
|
||
|
[player, slot, movesetJSON] = rest
|
||
|
pokemon = @getPokemon(player, slot)
|
||
|
pokemon.set(movesetJSON)
|
||
|
done()
|
||
|
when Protocol.WEATHER_CHANGE
|
||
|
[newWeather] = rest
|
||
|
view.changeWeather(newWeather, done)
|
||
|
when Protocol.TEAM_PREVIEW
|
||
|
view.renderTeamPreview()
|
||
|
done()
|
||
|
when Protocol.ACTIVATE_ABILITY
|
||
|
[player, slot, ability] = rest
|
||
|
pokemon = @getPokemon(player, slot)
|
||
|
pokemon.set('ability', ability)
|
||
|
view.activateAbility(player, slot, ability, done)
|
||
|
when Protocol.END_MOVE
|
||
|
doneSpeedTimeout()
|
||
|
when Protocol.ILLUSION_CHANGE
|
||
|
[player, slot, change] = rest
|
||
|
pokemon = @getPokemon(player, slot)
|
||
|
pokemon.setIllu(change)
|
||
|
done()
|
||
|
when Protocol.VISIBLE_TEAM
|
||
|
view.setVisibleTeam()
|
||
|
else
|
||
|
done()
|
||
|
catch e
|
||
|
console.error(e)
|
||
|
console.error(e.stack)
|
||
|
done()
|
||
|
if wasAtBottom && !view.chatView.isAtBottom()
|
||
|
view.chatView.scrollToBottom()
|