mirror of
https://github.com/genxium/DelayNoMore
synced 2025-10-17 04:29:00 +00:00
Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
850eee20a8 | ||
|
5eec7fcfe7 | ||
|
4e42c0770c | ||
|
8647c1a859 | ||
|
a41c68fb13 | ||
|
c5b26d716e | ||
|
1e0959c4cf | ||
|
3e54670a1b | ||
|
b41b86bbd3 | ||
|
db2bc0e3cd | ||
|
eedcf5c4dc | ||
|
c171ebc211 | ||
|
5a463239bb | ||
|
5c06cfdbac | ||
|
7985a242fd | ||
|
bef1df48aa | ||
|
8d989d543a | ||
|
849ce34fe5 | ||
|
195a400dc2 | ||
|
66dfcaa0f5 | ||
|
9917a62526 | ||
|
62e50f8b6c | ||
|
dc66be1599 | ||
|
858eba5243 |
@@ -1,3 +1,7 @@
|
||||
# What to be concerned for internet syncing
|
||||
1. Server received too late (solution: force confirmation)
|
||||
2. Client received too late (solution: prediction and frame chasing, big impact on user experience because the graphics will be inconsistent if mismatches occur too often)
|
||||
|
||||
# Potential avalanche from local lag
|
||||
Under the current "input delay" algorithm, the lag of a single player would cause all the other players to receive outdated commands, e.g. when at a certain moment
|
||||
- player#1: renderFrameId = 100, significantly lagged due to local CPU overheated
|
||||
@@ -7,9 +11,11 @@ Under the current "input delay" algorithm, the lag of a single player would caus
|
||||
|
||||
players #2, #3 #4 would receive "outdated(in their subjective feelings) but all-confirmed commands" from then on, thus forced to rollback and chase many frames - the lag due to "large range of frame-chasing" would then further deteriorate the situation - like an avalanche.
|
||||
|
||||
In a "no-server & p2p" setup, I couldn't think of a proper way to cope with such edge case. Solely on the frontend we could only mitigate the impact to players #2, #3, #4, e.g. a potential lag due to "large range of frame-chasing" is proactively avoided in `<proj-root>/frontend/assets/scripts/Map.js, function update(dt)`.
|
||||
**BE CAUTIOUS, THIS SITUATION HAPPENS QUITE OFTEN FOR REAL DEVICES** where different operating systems and temporary CPU overheat cause different lags for different player in a same battle! If not properly handled, slow tickers would be `inputing in the "history" of other players`, resulting in too frequent prediction mismatch and thus inconsistent graphics for other players!
|
||||
|
||||
However in a "server as authority" setup, the server could force confirming an inputFrame without player#1's upsync, and notify player#1 to apply a "roomDownsyncFrame" as well as drop all its outdated local inputFrames.
|
||||
In a "no-server & p2p" setup, I couldn't think of a proper way to cope with such edge case. Solely on the frontend we could only mitigate the impact to players #2, #3, #4, e.g. a potential lag due to "large range of frame-chasing" is proactively avoided in `<proj-root>/frontend/assets/scripts/Map.js, function update(dt)`.
|
||||
|
||||
To be fair, **a "p2p" setup can reduce round-trip to single-trip**, but w/o a point of authority in such case player#1 needs a way to recognize the slowness (e.g. check the received peer inputs) and ticks faster for a while to catch up; in contrast in a "server as authority" setup, the server could force confirming an inputFrame without player#1's upsync, and notify player#1 to apply a "roomDownsyncFrame" as well as drop all its outdated local inputFrames.
|
||||
|
||||
# Start up frames
|
||||
renderFrameId | generatedInputFrameId | toApplyInputFrameId
|
||||
|
@@ -2,11 +2,11 @@
|
||||
|
||||
This project is a demo for a websocket-based rollback netcode inspired by [GGPO](https://github.com/pond3r/ggpo/blob/master/doc/README.md).
|
||||
|
||||
_(the following gif is sped up to ~1.33x for file size reduction, kindly note that around ~8s countdown, the attack animation is resumed from a partial progress)_
|
||||
_(the following gif is sped up to ~1.5x for file size reduction, kindly note that animations are resumed from a partial progress)_
|
||||
|
||||

|
||||

|
||||
|
||||
Please also checkout [this demo video](https://pan.baidu.com/s/172AmIKxbFgGXZzWVqxNUPA?pwd=e2tp) to see how this demo carries out a full 60fps synchronization with the help of _batched input upsync/downsync_ for satisfying network I/O performance.
|
||||
Please also checkout [this demo video](https://pan.baidu.com/s/1Lmot9cb0pYylfUvC8G4fDg?pwd=ia97) to see how this demo carries out a full 60fps synchronization with the help of _batched input upsync/downsync_ for satisfying network I/O performance.
|
||||
|
||||
The video mainly shows the following features.
|
||||
- The backend receives inputs from frontend peers and broadcasts back for synchronization.
|
||||
|
@@ -17,12 +17,16 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) map[int32]
|
||||
VirtualGridY: last.VirtualGridY,
|
||||
DirX: last.DirX,
|
||||
DirY: last.DirY,
|
||||
ColliderRadius: last.ColliderRadius,
|
||||
VelX: last.VelX,
|
||||
VelY: last.VelY,
|
||||
Speed: last.Speed,
|
||||
BattleState: last.BattleState,
|
||||
CharacterState: last.CharacterState,
|
||||
InAir: last.InAir,
|
||||
JoinIndex: last.JoinIndex,
|
||||
ColliderRadius: last.ColliderRadius,
|
||||
Score: last.Score,
|
||||
Removed: last.Removed,
|
||||
JoinIndex: last.JoinIndex,
|
||||
}
|
||||
if withMetaInfo {
|
||||
toRet[k].Name = last.Name
|
||||
|
@@ -61,10 +61,13 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
ATK_CHARACTER_STATE_IDLE1 = 0
|
||||
ATK_CHARACTER_STATE_WALKING = 1
|
||||
ATK_CHARACTER_STATE_ATK1 = 2
|
||||
ATK_CHARACTER_STATE_ATKED1 = 3
|
||||
ATK_CHARACTER_STATE_IDLE1 = int32(0)
|
||||
ATK_CHARACTER_STATE_WALKING = int32(1)
|
||||
ATK_CHARACTER_STATE_ATK1 = int32(2)
|
||||
ATK_CHARACTER_STATE_ATKED1 = int32(3)
|
||||
ATK_CHARACTER_STATE_INAIR_IDLE1 = int32(4)
|
||||
ATK_CHARACTER_STATE_INAIR_ATK1 = int32(5)
|
||||
ATK_CHARACTER_STATE_INAIR_ATKED1 = int32(6)
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -158,8 +161,9 @@ type Room struct {
|
||||
DismissalWaitGroup sync.WaitGroup
|
||||
Barriers map[int32]*Barrier
|
||||
InputsBuffer *RingBuffer // Indices are STRICTLY consecutive
|
||||
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange]
|
||||
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange]
|
||||
RenderFrameBuffer *RingBuffer // Indices are STRICTLY consecutive
|
||||
LatestPlayerUpsyncedInputFrameId int32
|
||||
LastAllConfirmedInputFrameId int32
|
||||
LastAllConfirmedInputFrameIdWithChange int32
|
||||
LastAllConfirmedInputList []uint64
|
||||
@@ -198,6 +202,7 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
|
||||
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
|
||||
pPlayerFromDbInit.Speed = pR.PlayerDefaultSpeed // Hardcoded
|
||||
pPlayerFromDbInit.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
||||
pPlayerFromDbInit.InAir = true // Hardcoded
|
||||
|
||||
pR.Players[playerId] = pPlayerFromDbInit
|
||||
pR.PlayerDownsyncSessionDict[playerId] = session
|
||||
@@ -229,6 +234,7 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
|
||||
pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
|
||||
pEffectiveInRoomPlayerInstance.Speed = pR.PlayerDefaultSpeed // Hardcoded
|
||||
pEffectiveInRoomPlayerInstance.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
||||
pEffectiveInRoomPlayerInstance.InAir = true // Hardcoded
|
||||
|
||||
pR.PlayerDownsyncSessionDict[playerId] = session
|
||||
pR.PlayerSignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
|
||||
@@ -396,11 +402,11 @@ func (pR *Room) StartBattle() {
|
||||
pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY = float64(spaceW)*0.5, float64(spaceH)*0.5
|
||||
pR.refreshColliders(spaceW, spaceH)
|
||||
|
||||
/**
|
||||
* Will be triggered from a goroutine which executes the critical `Room.AddPlayerIfPossible`, thus the `battleMainLoop` should be detached.
|
||||
* All of the consecutive stages, e.g. settlement, dismissal, should share the same goroutine with `battleMainLoop`.
|
||||
*
|
||||
* As "defer" is only applicable to function scope, the use of "pR.InputsBufferLock" within "battleMainLoop" is embedded into each subroutine call.
|
||||
/*
|
||||
Will be triggered from a goroutine which executes the critical `Room.AddPlayerIfPossible`, thus the `battleMainLoop` should be detached.
|
||||
All of the consecutive stages, e.g. settlement, dismissal, should share the same goroutine with `battleMainLoop`.
|
||||
|
||||
As "defer" is only applicable to function scope, the use of "pR.InputsBufferLock" within "battleMainLoop" is embedded into each subroutine call.
|
||||
*/
|
||||
battleMainLoop := func() {
|
||||
defer func() {
|
||||
@@ -419,7 +425,7 @@ func (pR *Room) StartBattle() {
|
||||
stCalculation := utils.UnixtimeNano()
|
||||
elapsedNanosSinceLastFrameIdTriggered := stCalculation - pR.LastRenderFrameIdTriggeredAt
|
||||
if elapsedNanosSinceLastFrameIdTriggered < pR.RollbackEstimatedDtNanos {
|
||||
Logger.Warn(fmt.Sprintf("renderFrameId=%v@roomId=%v: Is backend running too fast? elapsedNanosSinceLastFrameIdTriggered=%v", pR.RenderFrameId, pR.Id, elapsedNanosSinceLastFrameIdTriggered))
|
||||
Logger.Debug(fmt.Sprintf("renderFrameId=%v@roomId=%v: Is backend running too fast? elapsedNanosSinceLastFrameIdTriggered=%v", pR.RenderFrameId, pR.Id, elapsedNanosSinceLastFrameIdTriggered))
|
||||
}
|
||||
|
||||
if pR.RenderFrameId > pR.BattleDurationFrames {
|
||||
@@ -430,24 +436,6 @@ func (pR *Room) StartBattle() {
|
||||
return
|
||||
}
|
||||
|
||||
if 0 == pR.RenderFrameId {
|
||||
for _, player := range pR.PlayersArr {
|
||||
playerId := player.Id
|
||||
thatPlayerBattleState := atomic.LoadInt32(&(player.BattleState)) // Might be changed in "OnPlayerDisconnected/OnPlayerLost" from other threads
|
||||
// [WARNING] DON'T try to send any message to an inactive player!
|
||||
switch thatPlayerBattleState {
|
||||
case PlayerBattleStateIns.DISCONNECTED:
|
||||
case PlayerBattleStateIns.LOST:
|
||||
case PlayerBattleStateIns.EXPELLED_DURING_GAME:
|
||||
case PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
|
||||
continue
|
||||
}
|
||||
kickoffFrame := pR.RenderFrameBuffer.GetByFrameId(0).(*RoomDownsyncFrame)
|
||||
pR.sendSafely(kickoffFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true)
|
||||
}
|
||||
Logger.Info(fmt.Sprintf("In `battleMainLoop` for roomId=%v sent out kickoffFrame", pR.Id))
|
||||
}
|
||||
|
||||
/*
|
||||
[WARNING]
|
||||
Golang "time.Sleep" is known to be taking longer than specified time to wake up at millisecond granularity, as discussed in https://github.com/golang/go/issues/44343
|
||||
@@ -457,6 +445,21 @@ func (pR *Room) StartBattle() {
|
||||
nextRenderFrameId := int32((totalElapsedNanos + pR.dilutedRollbackEstimatedDtNanos - 1) / pR.dilutedRollbackEstimatedDtNanos) // fast ceiling
|
||||
toSleepNanos := int64(0)
|
||||
if nextRenderFrameId > pR.RenderFrameId {
|
||||
if 0 == pR.RenderFrameId {
|
||||
// It's important to send kickoff frame iff "0 == pR.RenderFrameId && nextRenderFrameId > pR.RenderFrameId", otherwise it might send duplicate kickoff frames
|
||||
for _, player := range pR.PlayersArr {
|
||||
playerId := player.Id
|
||||
thatPlayerBattleState := atomic.LoadInt32(&(player.BattleState)) // Might be changed in "OnPlayerDisconnected/OnPlayerLost" from other threads
|
||||
// [WARNING] DON'T try to send any message to an inactive player!
|
||||
switch thatPlayerBattleState {
|
||||
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
|
||||
continue
|
||||
}
|
||||
kickoffFrame := pR.RenderFrameBuffer.GetByFrameId(0).(*RoomDownsyncFrame)
|
||||
pR.sendSafely(kickoffFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true)
|
||||
}
|
||||
Logger.Info(fmt.Sprintf("In `battleMainLoop` for roomId=%v sent out kickoffFrame", pR.Id))
|
||||
}
|
||||
prevRenderFrameId := pR.RenderFrameId
|
||||
pR.RenderFrameId = nextRenderFrameId
|
||||
|
||||
@@ -495,16 +498,12 @@ func (pR *Room) StartBattle() {
|
||||
case inputsBufferSnapshot := <-playerDownsyncChan:
|
||||
nowBattleState := atomic.LoadInt32(&pR.State)
|
||||
switch nowBattleState {
|
||||
case RoomBattleStateIns.IDLE:
|
||||
case RoomBattleStateIns.STOPPING_BATTLE_FOR_SETTLEMENT:
|
||||
case RoomBattleStateIns.IN_SETTLEMENT:
|
||||
case RoomBattleStateIns.IN_DISMISSAL:
|
||||
case RoomBattleStateIns.IDLE, RoomBattleStateIns.STOPPING_BATTLE_FOR_SETTLEMENT, RoomBattleStateIns.IN_SETTLEMENT, RoomBattleStateIns.IN_DISMISSAL:
|
||||
Logger.Warn(fmt.Sprintf("Battle is not waiting/preparing/active for playerDownsyncChan for (roomId: %d, playerId:%d)", pR.Id, playerId))
|
||||
return
|
||||
}
|
||||
|
||||
pR.downsyncToSinglePlayer(playerId, player, inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, inputsBufferSnapshot.ToSendInputFrameDownsyncs)
|
||||
Logger.Debug(fmt.Sprintf("Sent inputsBufferSnapshot(refRenderFrameId:%d, unconfirmedMask:%v) to for (roomId: %d, playerId:%d)#2", inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, pR.Id, playerId))
|
||||
pR.downsyncToSinglePlayer(playerId, player, inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, inputsBufferSnapshot.ToSendInputFrameDownsyncs, inputsBufferSnapshot.ShouldForceResync)
|
||||
//Logger.Info(fmt.Sprintf("Sent inputsBufferSnapshot(refRenderFrameId:%d, unconfirmedMask:%v) to for (roomId: %d, playerId:%d)#2", inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, pR.Id, playerId))
|
||||
default:
|
||||
}
|
||||
}
|
||||
@@ -563,12 +562,12 @@ func (pR *Room) OnBattleCmdReceived(pReq *WsReq) {
|
||||
atomic.StoreInt32(&(player.AckingFrameId), ackingFrameId)
|
||||
atomic.StoreInt32(&(player.AckingInputFrameId), ackingInputFrameId)
|
||||
|
||||
Logger.Debug(fmt.Sprintf("OnBattleCmdReceived-InputsBufferLock about to lock: roomId=%v, fromPlayerId=%v", pR.Id, playerId))
|
||||
//Logger.Debug(fmt.Sprintf("OnBattleCmdReceived-InputsBufferLock about to lock: roomId=%v, fromPlayerId=%v", pR.Id, playerId))
|
||||
pR.InputsBufferLock.Lock()
|
||||
Logger.Debug(fmt.Sprintf("OnBattleCmdReceived-InputsBufferLock locked: roomId=%v, fromPlayerId=%v", pR.Id, playerId))
|
||||
//Logger.Debug(fmt.Sprintf("OnBattleCmdReceived-InputsBufferLock locked: roomId=%v, fromPlayerId=%v", pR.Id, playerId))
|
||||
defer func() {
|
||||
pR.InputsBufferLock.Unlock()
|
||||
Logger.Debug(fmt.Sprintf("OnBattleCmdReceived-InputsBufferLock unlocked: roomId=%v, fromPlayerId=%v", pR.Id, playerId))
|
||||
//Logger.Debug(fmt.Sprintf("OnBattleCmdReceived-InputsBufferLock unlocked: roomId=%v, fromPlayerId=%v", pR.Id, playerId))
|
||||
}()
|
||||
|
||||
inputsBufferSnapshot := pR.markConfirmationIfApplicable(inputFrameUpsyncBatch, playerId, player)
|
||||
@@ -735,6 +734,7 @@ func (pR *Room) OnDismissed() {
|
||||
pR.RenderFrameBuffer = NewRingBuffer(pR.RenderCacheSize)
|
||||
pR.InputsBuffer = NewRingBuffer((pR.RenderCacheSize >> 1) + 1)
|
||||
|
||||
pR.LatestPlayerUpsyncedInputFrameId = -1
|
||||
pR.LastAllConfirmedInputFrameId = -1
|
||||
pR.LastAllConfirmedInputFrameIdWithChange = -1
|
||||
pR.LastAllConfirmedInputList = make([]uint64, pR.Capacity)
|
||||
@@ -747,9 +747,9 @@ func (pR *Room) OnDismissed() {
|
||||
pR.ServerFps = 60
|
||||
pR.RollbackEstimatedDtMillis = 16.667 // Use fixed-and-low-precision to mitigate the inconsistent floating-point-number issue between Golang and JavaScript
|
||||
pR.RollbackEstimatedDtNanos = 16666666 // A little smaller than the actual per frame time, just for logging FAST FRAME
|
||||
dilutedServerFps := float64(55.0)
|
||||
dilutedServerFps := float64(58.0) // Don't set this value too small, otherwise we might miss force confirmation needs for slow tickers!
|
||||
pR.dilutedRollbackEstimatedDtNanos = int64(float64(pR.RollbackEstimatedDtNanos) * float64(pR.ServerFps) / dilutedServerFps)
|
||||
pR.BattleDurationFrames = 30 * pR.ServerFps
|
||||
pR.BattleDurationFrames = 90 * pR.ServerFps
|
||||
pR.BattleDurationNanos = int64(pR.BattleDurationFrames) * (pR.RollbackEstimatedDtNanos + 1)
|
||||
pR.InputFrameUpsyncDelayTolerance = 2
|
||||
pR.MaxChasingRenderFramesPerUpdate = 8
|
||||
@@ -760,7 +760,7 @@ func (pR *Room) OnDismissed() {
|
||||
pR.MeleeSkillConfig[punchSkillId] = &MeleeBullet{
|
||||
// for offender
|
||||
StartupFrames: int32(10),
|
||||
ActiveFrames: int32(3),
|
||||
ActiveFrames: int32(10),
|
||||
RecoveryFrames: int32(34),
|
||||
RecoveryFramesOnBlock: int32(34),
|
||||
RecoveryFramesOnHit: int32(34),
|
||||
@@ -770,7 +770,7 @@ func (pR *Room) OnDismissed() {
|
||||
},
|
||||
HitboxOffset: float64(12.0), // should be about the radius of the PlayerCollider
|
||||
HitboxSize: &Vec2D{
|
||||
X: float64(23.0),
|
||||
X: float64(24.0),
|
||||
Y: float64(32.0),
|
||||
},
|
||||
|
||||
@@ -782,6 +782,12 @@ func (pR *Room) OnDismissed() {
|
||||
Damage: int32(5),
|
||||
}
|
||||
|
||||
pR.SnapIntoPlatformOverlap = float64(0.1)
|
||||
pR.SnapIntoPlatformThreshold = float64(0.5)
|
||||
pR.JumpingInitVelY = int32(float64(7) * pR.WorldToVirtualGridRatio)
|
||||
pR.GravityX = 0
|
||||
pR.GravityY = -int32(float64(0.5) * pR.WorldToVirtualGridRatio) // makes all "playerCollider.Y" a multiple of 0.5 in all cases
|
||||
|
||||
pR.ChooseStage()
|
||||
pR.EffectivePlayerCount = 0
|
||||
|
||||
@@ -826,10 +832,7 @@ func (pR *Room) OnPlayerDisconnected(playerId int32) {
|
||||
if player, existent := pR.Players[playerId]; existent {
|
||||
thatPlayerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||
switch thatPlayerBattleState {
|
||||
case PlayerBattleStateIns.DISCONNECTED:
|
||||
case PlayerBattleStateIns.LOST:
|
||||
case PlayerBattleStateIns.EXPELLED_DURING_GAME:
|
||||
case PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
|
||||
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
|
||||
Logger.Info("Room OnPlayerDisconnected[early return #1]:", zap.Any("playerId", playerId), zap.Any("playerBattleState", pR.Players[playerId].BattleState), zap.Any("roomId", pR.Id), zap.Any("nowRoomBattleState", pR.State), zap.Any("nowRoomEffectivePlayerCount", pR.EffectivePlayerCount))
|
||||
return
|
||||
}
|
||||
@@ -976,6 +979,7 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool {
|
||||
case PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
|
||||
shouldTryToStartBattle = false
|
||||
atomic.StoreInt32(&(targetPlayer.BattleState), PlayerBattleStateIns.READDED_BATTLE_COLLIDER_ACKED)
|
||||
Logger.Warn(fmt.Sprintf("OnPlayerBattleColliderAcked-reAdded: roomId=%v, roomState=%v, targetPlayerId=%v, targetPlayerBattleState=%v, capacity=%v, EffectivePlayerCount=%v", pR.Id, pR.State, targetPlayer.Id, targetPlayer.BattleState, pR.Capacity, pR.EffectivePlayerCount))
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -1100,6 +1104,10 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*InputFrame
|
||||
}
|
||||
targetInputFrameDownsync.InputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
|
||||
targetInputFrameDownsync.ConfirmedList |= uint64(1 << uint32(player.JoinIndex-1))
|
||||
|
||||
if inputFrameUpsync.InputFrameId > pR.LatestPlayerUpsyncedInputFrameId {
|
||||
pR.LatestPlayerUpsyncedInputFrameId = inputFrameUpsync.InputFrameId
|
||||
}
|
||||
}
|
||||
|
||||
newAllConfirmedCount := int32(0)
|
||||
@@ -1165,31 +1173,40 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) *InputsBu
|
||||
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
|
||||
// Force confirmation of non-all-confirmed inputFrame EXACTLY ONE AT A TIME, returns the non-confirmed mask of players, e.g. in a 4-player-battle returning 1001 means that players with JoinIndex=1 and JoinIndex=4 are non-confirmed for inputFrameId2
|
||||
|
||||
renderFrameId1 := (pR.RenderFrameId - pR.NstDelayFrames) // the renderFrameId which should've been rendered on frontend
|
||||
if 0 > renderFrameId1 {
|
||||
return nil
|
||||
}
|
||||
ok := false
|
||||
renderFrameId2 := int32(-1)
|
||||
if ok, renderFrameId2 = pR.shouldPrefabInputFrameDownsync(prevRenderFrameId-pR.NstDelayFrames, renderFrameId1); !ok {
|
||||
/*
|
||||
The backend "shouldPrefabInputFrameDownsync" shares the same rule as frontend "shouldGenerateInputFrameUpsync".
|
||||
inputFrameId2 := int32(-1)
|
||||
if pR.LatestPlayerUpsyncedInputFrameId > (pR.LastAllConfirmedInputFrameId + (pR.NstDelayFrames >> pR.InputScaleFrames)) {
|
||||
// Type#1 check whether there's a significantly slow ticker among players
|
||||
Logger.Warn(fmt.Sprintf("[type#1 forceConfirmation]For roomId=%d@renderFrameId=%d, curDynamicsRenderFrameId=%d, LatestPlayerUpsyncedInputFrameId:%d, LastAllConfirmedInputFrameId:%d, (pR.NstDelayFrames >> pR.InputScaleFrames):%d; there's a slow ticker suspect, forcing all-confirmation", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LatestPlayerUpsyncedInputFrameId, pR.LastAllConfirmedInputFrameId, (pR.NstDelayFrames >> pR.InputScaleFrames)))
|
||||
inputFrameId2 = pR.LastAllConfirmedInputFrameId + 1
|
||||
} else {
|
||||
// Type#2 check whether there's a significantly slow ticker w.r.t. BackendDynamics, this applies when all players are disconnected temporarily
|
||||
renderFrameId1 := (pR.RenderFrameId - pR.NstDelayFrames) // the "renderFrameId" which should've been rendered on frontend
|
||||
if 0 > renderFrameId1 {
|
||||
// Battle is still in an early stage, no action needed even if there were slow tickers
|
||||
return nil
|
||||
}
|
||||
if ok, renderFrameId2 := pR.shouldPrefabInputFrameDownsync(prevRenderFrameId-pR.NstDelayFrames, renderFrameId1); ok {
|
||||
/*
|
||||
The backend "shouldPrefabInputFrameDownsync" shares the same rule as frontend "shouldGenerateInputFrameUpsync".
|
||||
|
||||
It's also important that "forceConfirmationIfApplicable" is NOT EXECUTED for every renderFrame, such that when a player is forced to resync, it has some time, i.e. (1 << InputScaleFrames) renderFrames, to upsync again.
|
||||
*/
|
||||
return nil
|
||||
It's also important that "forceConfirmationIfApplicable" is NOT EXECUTED for every renderFrame, such that when a player is forced to resync, it has some time, i.e. (1 << InputScaleFrames) renderFrames, to upsync again.
|
||||
*/
|
||||
inputFrameId2 = pR.ConvertToInputFrameId(renderFrameId2, 0) // The inputFrame to force confirmation (if necessary)
|
||||
if inputFrameId2 > pR.LastAllConfirmedInputFrameId {
|
||||
Logger.Debug(fmt.Sprintf("[type#2 forceConfirmation]For roomId=%d@renderFrameId=%d, curDynamicsRenderFrameId=%d, renderFrameId1:%d, renderFrameId2:%d, NstDelayFrames:%d, inputFrameId2:%d, LastAllConfirmedInputFrameId:%d; there's a slow ticker suspect, forcing all-confirmation", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, renderFrameId1, renderFrameId2, pR.NstDelayFrames, inputFrameId2, pR.LastAllConfirmedInputFrameId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inputFrameId2 := pR.ConvertToInputFrameId(renderFrameId2, 0) // The inputFrame to force confirmation (if necessary)
|
||||
if inputFrameId2 < pR.LastAllConfirmedInputFrameId {
|
||||
// No need to force confirmation, the inputFrames already arrived
|
||||
Logger.Debug(fmt.Sprintf("inputFrameId2=%v is already all-confirmed for roomId=%v[type#1], no need to force confirmation of it", inputFrameId2, pR.Id))
|
||||
if pR.LastAllConfirmedInputFrameId >= inputFrameId2 {
|
||||
// No need to force confirmation for either type
|
||||
Logger.Debug(fmt.Sprintf("inputFrameId2=%v is already all-confirmed for roomId=%v, no need to force confirmation", inputFrameId2, pR.Id))
|
||||
return nil
|
||||
}
|
||||
|
||||
tmp := pR.InputsBuffer.GetByFrameId(inputFrameId2)
|
||||
if nil == tmp {
|
||||
panic(fmt.Sprintf("inputFrameId2=%v doesn't exist for roomId=%v, this is abnormal because the server should prefab inputFrameDownsync in a most advanced pace, check the prefab logic! InputsBuffer=%v", inputFrameId2, pR.Id, pR.InputsBufferString(false)))
|
||||
panic(fmt.Sprintf("For roomId=%d, inputFrameId2=%v doesn't exist, this is abnormal because the server should prefab inputFrameDownsync in a most advanced pace, check the prefab logic! InputsBuffer=%v", pR.Id, inputFrameId2, pR.InputsBufferString(false)))
|
||||
}
|
||||
|
||||
totPlayerCnt := uint32(pR.Capacity)
|
||||
@@ -1204,7 +1221,6 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) *InputsBu
|
||||
|
||||
if 0 < unconfirmedMask {
|
||||
// This condition should be rarely met!
|
||||
nextDynamicsRenderFrameId := pR.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames)
|
||||
/*
|
||||
Upon resynced on frontend, "refRenderFrameId" is now set to as advanced as possible, and it's the frontend's responsibility now to pave way for the "gap inputFrames"
|
||||
|
||||
@@ -1212,7 +1228,7 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) *InputsBu
|
||||
|
||||
Upon resync, it's still possible that "refRenderFrameId < frontend.chaserRenderFrameId" -- and this is allowed.
|
||||
*/
|
||||
refRenderFrameIdIfNeeded := nextDynamicsRenderFrameId - 1
|
||||
refRenderFrameIdIfNeeded := pR.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames)
|
||||
if 0 > refRenderFrameIdIfNeeded {
|
||||
// Without a "refRenderFrame", there's no point to force confirmation, i.e. nothing to downsync to the "ACTIVE but slowly ticking frontend(s)"
|
||||
return nil
|
||||
@@ -1268,6 +1284,7 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
|
||||
|
||||
// TODO: Write unit-test for this function to compare with its frontend counter part
|
||||
func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputFrame *InputFrameDownsync, currRenderFrame *RoomDownsyncFrame, collisionSysMap map[int32]*resolv.Object) *RoomDownsyncFrame {
|
||||
topPadding, bottomPadding, leftPadding, rightPadding := pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap
|
||||
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
|
||||
nextRenderFramePlayers := make(map[int32]*PlayerDownsync, pR.Capacity)
|
||||
// Make a copy first
|
||||
@@ -1278,7 +1295,10 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
||||
VirtualGridY: currPlayerDownsync.VirtualGridY,
|
||||
DirX: currPlayerDownsync.DirX,
|
||||
DirY: currPlayerDownsync.DirY,
|
||||
VelX: currPlayerDownsync.VelX,
|
||||
VelY: currPlayerDownsync.VelY,
|
||||
CharacterState: currPlayerDownsync.CharacterState,
|
||||
InAir: true,
|
||||
Speed: currPlayerDownsync.Speed,
|
||||
BattleState: currPlayerDownsync.BattleState,
|
||||
Score: currPlayerDownsync.Score,
|
||||
@@ -1293,30 +1313,111 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
||||
}
|
||||
}
|
||||
|
||||
toRet := &RoomDownsyncFrame{
|
||||
Id: currRenderFrame.Id + 1,
|
||||
Players: nextRenderFramePlayers,
|
||||
CountdownNanos: (pR.BattleDurationNanos - int64(currRenderFrame.Id)*pR.RollbackEstimatedDtNanos),
|
||||
MeleeBullets: make([]*MeleeBullet, 0), // Is there any better way to reduce malloc/free impact, e.g. smart prediction for fixed memory allocation?
|
||||
nextRenderFrameMeleeBullets := make([]*MeleeBullet, 0, len(currRenderFrame.MeleeBullets)) // Is there any better way to reduce malloc/free impact, e.g. smart prediction for fixed memory allocation?
|
||||
effPushbacks := make([]Vec2D, pR.Capacity)
|
||||
hardPushbackNorms := make([][]Vec2D, pR.Capacity)
|
||||
|
||||
// 1. Process player inputs
|
||||
if nil != delayedInputFrame {
|
||||
var delayedInputFrameForPrevRenderFrame *InputFrameDownsync = nil
|
||||
tmp := pR.InputsBuffer.GetByFrameId(pR.ConvertToInputFrameId(currRenderFrame.Id-1, pR.InputDelayFrames))
|
||||
if nil != tmp {
|
||||
delayedInputFrameForPrevRenderFrame = tmp.(*InputFrameDownsync)
|
||||
}
|
||||
inputList := delayedInputFrame.InputList
|
||||
for _, player := range pR.PlayersArr {
|
||||
playerId := player.Id
|
||||
joinIndex := player.JoinIndex
|
||||
currPlayerDownsync, thatPlayerInNextFrame := currRenderFrame.Players[playerId], nextRenderFramePlayers[playerId]
|
||||
if 0 < thatPlayerInNextFrame.FramesToRecover {
|
||||
continue
|
||||
}
|
||||
decodedInput := pR.decodeInput(inputList[joinIndex-1])
|
||||
prevBtnALevel, prevBtnBLevel := int32(0), int32(0)
|
||||
if nil != delayedInputFrameForPrevRenderFrame {
|
||||
prevDecodedInput := pR.decodeInput(delayedInputFrameForPrevRenderFrame.InputList[joinIndex-1])
|
||||
prevBtnALevel = prevDecodedInput.BtnALevel
|
||||
prevBtnBLevel = prevDecodedInput.BtnBLevel
|
||||
}
|
||||
|
||||
if decodedInput.BtnBLevel > prevBtnBLevel {
|
||||
characStateAlreadyInAir := false
|
||||
if ATK_CHARACTER_STATE_INAIR_IDLE1 == thatPlayerInNextFrame.CharacterState || ATK_CHARACTER_STATE_INAIR_ATK1 == thatPlayerInNextFrame.CharacterState || ATK_CHARACTER_STATE_INAIR_ATKED1 == thatPlayerInNextFrame.CharacterState {
|
||||
characStateAlreadyInAir = true
|
||||
}
|
||||
characStateIsInterruptWaivable := false
|
||||
if ATK_CHARACTER_STATE_IDLE1 == thatPlayerInNextFrame.CharacterState || ATK_CHARACTER_STATE_WALKING == thatPlayerInNextFrame.CharacterState || ATK_CHARACTER_STATE_INAIR_IDLE1 == thatPlayerInNextFrame.CharacterState {
|
||||
characStateIsInterruptWaivable = true
|
||||
}
|
||||
if !characStateAlreadyInAir && characStateIsInterruptWaivable {
|
||||
thatPlayerInNextFrame.VelY = pR.JumpingInitVelY
|
||||
// if 1 == currPlayerDownsync.JoinIndex {
|
||||
// Logger.Info(fmt.Sprintf("playerId=%v, joinIndex=%v jumped at {renderFrame.id: %d, virtualX: %d, virtualY: %d, nextVelX: %d, nextVelY: %d, nextCharacterState=%d, inAir=%v}, delayedInputFrame.id=%d", playerId, joinIndex, currRenderFrame.Id, currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, thatPlayerInNextFrame.CharacterState, currPlayerDownsync.InAir, delayedInputFrame.InputFrameId))
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if decodedInput.BtnALevel > prevBtnALevel {
|
||||
punchSkillId := int32(1)
|
||||
punchConfig := pR.MeleeSkillConfig[punchSkillId]
|
||||
var newMeleeBullet MeleeBullet = *punchConfig
|
||||
newMeleeBullet.BattleLocalId = pR.BulletBattleLocalIdCounter
|
||||
pR.BulletBattleLocalIdCounter += 1
|
||||
newMeleeBullet.OffenderJoinIndex = joinIndex
|
||||
newMeleeBullet.OffenderPlayerId = playerId
|
||||
newMeleeBullet.OriginatedRenderFrameId = currRenderFrame.Id
|
||||
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, &newMeleeBullet)
|
||||
thatPlayerInNextFrame.FramesToRecover = newMeleeBullet.RecoveryFrames
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATK1
|
||||
if false == currPlayerDownsync.InAir {
|
||||
thatPlayerInNextFrame.VelX = 0
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("roomId=%v, playerId=%v triggered a rising-edge of btnA at currRenderFrame.id=%v, delayedInputFrame.id=%v", pR.Id, playerId, currRenderFrame.Id, delayedInputFrame.InputFrameId))
|
||||
|
||||
} else if decodedInput.BtnALevel < prevBtnALevel {
|
||||
Logger.Debug(fmt.Sprintf("roomId=%v, playerId=%v triggered a falling-edge of btnA at currRenderFrame.id=%v, delayedInputFrame.id=%v", pR.Id, playerId, currRenderFrame.Id, delayedInputFrame.InputFrameId))
|
||||
} else {
|
||||
// No bullet trigger, process movement inputs
|
||||
// Note that by now "0 == thatPlayerInNextFrame.FramesToRecover", we should change "CharacterState" to "WALKING" or "IDLE" depending on player inputs
|
||||
if 0 != decodedInput.Dx || 0 != decodedInput.Dy {
|
||||
thatPlayerInNextFrame.DirX = decodedInput.Dx
|
||||
thatPlayerInNextFrame.DirY = decodedInput.Dy
|
||||
thatPlayerInNextFrame.VelX = decodedInput.Dx * currPlayerDownsync.Speed
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_WALKING
|
||||
} else {
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
|
||||
thatPlayerInNextFrame.VelX = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bulletPushbacks := make([]Vec2D, pR.Capacity) // Guaranteed determinism regardless of traversal order
|
||||
effPushbacks := make([]Vec2D, pR.Capacity) // Guaranteed determinism regardless of traversal order
|
||||
|
||||
// Reset playerCollider position from the "virtual grid position"
|
||||
// 2. Process player movement
|
||||
for _, player := range pR.PlayersArr {
|
||||
playerId := player.Id
|
||||
joinIndex := player.JoinIndex
|
||||
bulletPushbacks[joinIndex-1].X, bulletPushbacks[joinIndex-1].Y = float64(0), float64(0)
|
||||
effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y = float64(0), float64(0)
|
||||
currPlayerDownsync := currRenderFrame.Players[playerId]
|
||||
newVx, newVy := currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY
|
||||
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
|
||||
playerCollider := collisionSysMap[collisionPlayerIndex]
|
||||
playerCollider.X, playerCollider.Y = VirtualGridToPolygonColliderAnchorPos(newVx, newVy, player.ColliderRadius, player.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.VirtualGridToWorldRatio)
|
||||
currPlayerDownsync, thatPlayerInNextFrame := currRenderFrame.Players[playerId], nextRenderFramePlayers[playerId]
|
||||
// Reset playerCollider position from the "virtual grid position"
|
||||
newVx, newVy := currPlayerDownsync.VirtualGridX+currPlayerDownsync.VelX, currPlayerDownsync.VirtualGridY+currPlayerDownsync.VelY
|
||||
if thatPlayerInNextFrame.VelY == pR.JumpingInitVelY {
|
||||
newVy += thatPlayerInNextFrame.VelY
|
||||
}
|
||||
|
||||
halfColliderWidth, halfColliderHeight := player.ColliderRadius, player.ColliderRadius+player.ColliderRadius // avoid multiplying
|
||||
playerCollider.X, playerCollider.Y = VirtualGridToPolygonColliderBLPos(newVx, newVy, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.VirtualGridToWorldRatio)
|
||||
// Update in the collision system
|
||||
playerCollider.Update()
|
||||
|
||||
if currPlayerDownsync.InAir {
|
||||
thatPlayerInNextFrame.VelX += pR.GravityX
|
||||
thatPlayerInNextFrame.VelY += pR.GravityY
|
||||
}
|
||||
}
|
||||
|
||||
// Check bullet-anything collisions first, because the pushbacks caused by bullets might later be reverted by player-barrier collision
|
||||
// 3. Add bullet colliders into collision system
|
||||
bulletColliders := make(map[int32]*resolv.Object, 0) // Will all be removed at the end of `applyInputFrameDownsyncDynamicsOnSingleRenderFrame` due to the need for being rollback-compatible
|
||||
removedBulletsAtCurrFrame := make(map[int32]int32, 0)
|
||||
for _, meleeBullet := range currRenderFrame.MeleeBullets {
|
||||
@@ -1332,8 +1433,7 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
||||
}
|
||||
offenderWx, offenderWy := VirtualGridToWorldPos(offender.VirtualGridX, offender.VirtualGridY, pR.VirtualGridToWorldRatio)
|
||||
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
||||
|
||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "MeleeBullet")
|
||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "MeleeBullet")
|
||||
newBulletCollider.Data = meleeBullet
|
||||
pR.Space.Add(newBulletCollider)
|
||||
collisionSysMap[collisionBulletIndex] = newBulletCollider
|
||||
@@ -1343,6 +1443,97 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Invoke collision system stepping (no-op for backend collision lib)
|
||||
|
||||
// 5. Calc pushbacks for each player (after its movement) w/o bullets
|
||||
for _, player := range pR.PlayersArr {
|
||||
joinIndex := player.JoinIndex
|
||||
playerId := player.Id
|
||||
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
|
||||
playerCollider := collisionSysMap[collisionPlayerIndex]
|
||||
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
|
||||
hardPushbackNorms[joinIndex-1] = pR.calcHardPushbacksNorms(playerCollider, playerShape, pR.SnapIntoPlatformOverlap, &(effPushbacks[joinIndex-1]))
|
||||
currPlayerDownsync, thatPlayerInNextFrame := currRenderFrame.Players[playerId], nextRenderFramePlayers[playerId]
|
||||
fallStopping := false
|
||||
possiblyFallStoppedOnAnotherPlayer := false
|
||||
if collision := playerCollider.Check(0, 0); nil != collision {
|
||||
for _, obj := range collision.Objects {
|
||||
isBarrier, isAnotherPlayer, isBullet := false, false, false
|
||||
switch obj.Data.(type) {
|
||||
case *Barrier:
|
||||
isBarrier = true
|
||||
case *Player:
|
||||
isAnotherPlayer = true
|
||||
case *MeleeBullet:
|
||||
isBullet = true
|
||||
}
|
||||
if isBullet {
|
||||
// ignore bullets for this step
|
||||
continue
|
||||
}
|
||||
bShape := obj.Shape.(*resolv.ConvexPolygon)
|
||||
overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, bShape)
|
||||
if !overlapped {
|
||||
continue
|
||||
}
|
||||
normAlignmentWithGravity := (overlapResult.OverlapX*float64(0) + overlapResult.OverlapY*float64(-1.0))
|
||||
landedOnGravityPushback := (pR.SnapIntoPlatformThreshold < normAlignmentWithGravity) // prevents false snapping on the lateral sides
|
||||
if landedOnGravityPushback {
|
||||
// kindly note that one player might land on top of another player, and snapping is also required in such case
|
||||
pushbackX, pushbackY = (overlapResult.Overlap-pR.SnapIntoPlatformOverlap)*overlapResult.OverlapX, (overlapResult.Overlap-pR.SnapIntoPlatformOverlap)*overlapResult.OverlapY
|
||||
thatPlayerInNextFrame.InAir = false
|
||||
}
|
||||
if isAnotherPlayer {
|
||||
// [WARNING] See comments of this substep in frontend.
|
||||
pushbackX, pushbackY = (overlapResult.Overlap-pR.SnapIntoPlatformOverlap*2)*overlapResult.OverlapX, (overlapResult.Overlap-pR.SnapIntoPlatformOverlap*2)*overlapResult.OverlapY
|
||||
}
|
||||
for _, hardPushbackNorm := range hardPushbackNorms[joinIndex-1] {
|
||||
projectedMagnitude := pushbackX*hardPushbackNorm.X + pushbackY*hardPushbackNorm.Y
|
||||
if isBarrier || (isAnotherPlayer && 0 > projectedMagnitude) {
|
||||
pushbackX -= projectedMagnitude * hardPushbackNorm.X
|
||||
pushbackY -= projectedMagnitude * hardPushbackNorm.Y
|
||||
}
|
||||
}
|
||||
effPushbacks[joinIndex-1].X += pushbackX
|
||||
effPushbacks[joinIndex-1].Y += pushbackY
|
||||
if currPlayerDownsync.InAir && landedOnGravityPushback {
|
||||
fallStopping = true
|
||||
if isAnotherPlayer {
|
||||
possiblyFallStoppedOnAnotherPlayer = true
|
||||
}
|
||||
}
|
||||
if 1 == joinIndex {
|
||||
halfColliderWidth, halfColliderHeight := player.ColliderRadius, player.ColliderRadius+player.ColliderRadius // avoid multiplying
|
||||
if fallStopping {
|
||||
Logger.Debug(fmt.Sprintf("playerId=%d, joinIndex=%d fallStopping#1\n{renderFrame.id: %d, possiblyFallStoppedOnAnotherPlayer: %v}\nplayerColliderPos=%v, effPushback={%.3f, %.3f}, overlapMag=%.4f", playerId, joinIndex, currRenderFrame.Id, possiblyFallStoppedOnAnotherPlayer, RectCenterStr(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY), effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y, overlapResult.Overlap))
|
||||
} else if currPlayerDownsync.InAir && isBarrier && !landedOnGravityPushback {
|
||||
//Logger.Warn(fmt.Sprintf("playerId=%d, joinIndex=%d inAir & pushed back by barrier & not landed at {renderFrame.id: %d}\nplayerColliderPos=%v, effPushback={%.3f, %.3f}, overlapMag=%.4f, len(hardPushbackNorms)=%d", playerId, joinIndex, currRenderFrame.Id, RectCenterStr(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY), effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y, overlapResult.Overlap, len(hardPushbackNorms)))
|
||||
} else if currPlayerDownsync.InAir && isAnotherPlayer {
|
||||
//Logger.Warn(fmt.Sprintf("playerId=%d, joinIndex=%d inAir & pushed back by another player\n{renderFrame.id: %d}\nplayerColliderPos=%v, anotherPlayerColliderPos=%v, effPushback={%.3f, %.3f}, landedOnGravityPushback=%v, fallStopping=%v, overlapMag=%.4f, len(hardPushbackNorms)=%d", playerId, joinIndex, currRenderFrame.Id, RectCenterStr(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY), RectCenterStr(obj, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY), effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y, landedOnGravityPushback, fallStopping, overlapResult.Overlap, len(hardPushbackNorms)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if fallStopping {
|
||||
thatPlayerInNextFrame.VelX = 0
|
||||
thatPlayerInNextFrame.VelY = 0
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
|
||||
thatPlayerInNextFrame.FramesToRecover = 0
|
||||
}
|
||||
if currPlayerDownsync.InAir {
|
||||
oldNextCharacterState := thatPlayerInNextFrame.CharacterState
|
||||
switch oldNextCharacterState {
|
||||
case ATK_CHARACTER_STATE_IDLE1, ATK_CHARACTER_STATE_WALKING:
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_IDLE1
|
||||
case ATK_CHARACTER_STATE_ATK1:
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_ATK1
|
||||
case ATK_CHARACTER_STATE_ATKED1:
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_ATKED1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Check bullet-anything collisions
|
||||
for _, bulletCollider := range bulletColliders {
|
||||
shouldRemove := false
|
||||
meleeBullet := bulletCollider.Data.(*MeleeBullet)
|
||||
@@ -1356,15 +1547,32 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
||||
case *Player:
|
||||
if meleeBullet.OffenderPlayerId != t.Id {
|
||||
if overlapped, _, _, _ := CalcPushbacks(0, 0, bulletShape, defenderShape); overlapped {
|
||||
joinIndex := t.JoinIndex
|
||||
xfac := float64(1.0) // By now, straight Punch offset doesn't respect "y-axis"
|
||||
if 0 > offender.DirX {
|
||||
xfac = float64(-1.0)
|
||||
}
|
||||
bulletPushbacks[t.JoinIndex-1].X += xfac * meleeBullet.Pushback
|
||||
nextRenderFramePlayers[t.Id].CharacterState = ATK_CHARACTER_STATE_ATKED1
|
||||
pushbackX, pushbackY := -xfac*meleeBullet.Pushback, float64(0)
|
||||
|
||||
for _, hardPushbackNorm := range hardPushbackNorms[joinIndex-1] {
|
||||
projectedMagnitude := pushbackX*hardPushbackNorm.X + pushbackY*hardPushbackNorm.Y
|
||||
if 0 > projectedMagnitude {
|
||||
Logger.Info(fmt.Sprintf("defenderPlayerId=%d, joinIndex=%d reducing bullet pushback={%.3f, %.3f} by {%.3f, %.3f} where hardPushbackNorm={%.3f, %.3f}, projectedMagnitude=%.3f at renderFrame.id=%d", t.Id, joinIndex, pushbackX, pushbackY, projectedMagnitude*hardPushbackNorm.X, projectedMagnitude*hardPushbackNorm.Y, hardPushbackNorm.X, hardPushbackNorm.Y, projectedMagnitude, currRenderFrame.Id))
|
||||
pushbackX -= projectedMagnitude * hardPushbackNorm.X
|
||||
pushbackY -= projectedMagnitude * hardPushbackNorm.Y
|
||||
}
|
||||
}
|
||||
|
||||
effPushbacks[joinIndex-1].X += pushbackX
|
||||
effPushbacks[joinIndex-1].Y += pushbackY
|
||||
atkedPlayerInCurFrame, atkedPlayerInNextFrame := currRenderFrame.Players[t.Id], nextRenderFramePlayers[t.Id]
|
||||
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
|
||||
if atkedPlayerInCurFrame.InAir {
|
||||
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_ATKED1
|
||||
}
|
||||
oldFramesToRecover := nextRenderFramePlayers[t.Id].FramesToRecover
|
||||
if meleeBullet.HitStunFrames > oldFramesToRecover {
|
||||
nextRenderFramePlayers[t.Id].FramesToRecover = meleeBullet.HitStunFrames
|
||||
atkedPlayerInNextFrame.FramesToRecover = meleeBullet.HitStunFrames
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("roomId=%v, a meleeBullet collides w/ player at currRenderFrame.id=%v: b=%v, p=%v", pR.Id, currRenderFrame.Id, ConvexPolygonStr(bulletShape), ConvexPolygonStr(defenderShape)))
|
||||
}
|
||||
@@ -1380,6 +1588,7 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
||||
}
|
||||
}
|
||||
|
||||
// [WARNING] Remove bullets from collisionSys ANYWAY for the convenience of rollback
|
||||
for _, meleeBullet := range currRenderFrame.MeleeBullets {
|
||||
collisionBulletIndex := COLLISION_BULLET_INDEX_PREFIX + meleeBullet.BattleLocalId
|
||||
if bulletCollider, existent := collisionSysMap[collisionBulletIndex]; existent {
|
||||
@@ -1389,124 +1598,48 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
||||
if _, existent := removedBulletsAtCurrFrame[collisionBulletIndex]; existent {
|
||||
continue
|
||||
}
|
||||
toRet.MeleeBullets = append(toRet.MeleeBullets, meleeBullet)
|
||||
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, meleeBullet)
|
||||
}
|
||||
|
||||
if nil != delayedInputFrame {
|
||||
var delayedInputFrameForPrevRenderFrame *InputFrameDownsync = nil
|
||||
tmp := pR.InputsBuffer.GetByFrameId(pR.ConvertToInputFrameId(currRenderFrame.Id-1, pR.InputDelayFrames))
|
||||
if nil != tmp {
|
||||
delayedInputFrameForPrevRenderFrame = tmp.(*InputFrameDownsync)
|
||||
}
|
||||
inputList := delayedInputFrame.InputList
|
||||
// Process player inputs
|
||||
for _, player := range pR.PlayersArr {
|
||||
playerId := player.Id
|
||||
joinIndex := player.JoinIndex
|
||||
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
|
||||
playerCollider := collisionSysMap[collisionPlayerIndex]
|
||||
thatPlayerInNextFrame := nextRenderFramePlayers[playerId]
|
||||
if 0 < thatPlayerInNextFrame.FramesToRecover {
|
||||
// No need to process inputs for this player, but there might be bullet pushbacks on this player
|
||||
// Also note that in this case we keep "CharacterState" of this player from last render frame
|
||||
playerCollider.X += bulletPushbacks[joinIndex-1].X
|
||||
playerCollider.Y += bulletPushbacks[joinIndex-1].Y
|
||||
// Update in the collision system
|
||||
playerCollider.Update()
|
||||
if 0 != bulletPushbacks[joinIndex-1].X || 0 != bulletPushbacks[joinIndex-1].Y {
|
||||
Logger.Debug(fmt.Sprintf("roomId=%v, playerId=%v is pushed back by (%.2f, %.2f) by bullet impacts, now its framesToRecover is %d at currRenderFrame.id=%v", pR.Id, playerId, bulletPushbacks[joinIndex-1].X, bulletPushbacks[joinIndex-1].Y, thatPlayerInNextFrame.FramesToRecover, currRenderFrame.Id))
|
||||
}
|
||||
continue
|
||||
}
|
||||
currPlayerDownsync := currRenderFrame.Players[playerId]
|
||||
decodedInput := pR.decodeInput(inputList[joinIndex-1])
|
||||
prevBtnALevel := int32(0)
|
||||
if nil != delayedInputFrameForPrevRenderFrame {
|
||||
prevDecodedInput := pR.decodeInput(delayedInputFrameForPrevRenderFrame.InputList[joinIndex-1])
|
||||
prevBtnALevel = prevDecodedInput.BtnALevel
|
||||
}
|
||||
// 7. Get players out of stuck barriers if there's any
|
||||
for _, player := range pR.PlayersArr {
|
||||
joinIndex := player.JoinIndex
|
||||
playerId := player.Id
|
||||
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
|
||||
playerCollider := collisionSysMap[collisionPlayerIndex]
|
||||
// Update "virtual grid position"
|
||||
currPlayerDownsync, thatPlayerInNextFrame := currRenderFrame.Players[playerId], nextRenderFramePlayers[playerId]
|
||||
halfColliderWidth, halfColliderHeight := player.ColliderRadius, player.ColliderRadius+player.ColliderRadius // avoid multiplying
|
||||
thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY = PolygonColliderBLToVirtualGridPos(playerCollider.X-effPushbacks[joinIndex-1].X, playerCollider.Y-effPushbacks[joinIndex-1].Y, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.WorldToVirtualGridRatio)
|
||||
|
||||
if decodedInput.BtnALevel > prevBtnALevel {
|
||||
punchSkillId := int32(1)
|
||||
punchConfig := pR.MeleeSkillConfig[punchSkillId]
|
||||
var newMeleeBullet MeleeBullet = *punchConfig
|
||||
newMeleeBullet.BattleLocalId = pR.BulletBattleLocalIdCounter
|
||||
pR.BulletBattleLocalIdCounter += 1
|
||||
newMeleeBullet.OffenderJoinIndex = joinIndex
|
||||
newMeleeBullet.OffenderPlayerId = playerId
|
||||
newMeleeBullet.OriginatedRenderFrameId = currRenderFrame.Id
|
||||
toRet.MeleeBullets = append(toRet.MeleeBullets, &newMeleeBullet)
|
||||
thatPlayerInNextFrame.FramesToRecover = newMeleeBullet.RecoveryFrames
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATK1
|
||||
Logger.Debug(fmt.Sprintf("roomId=%v, playerId=%v triggered a rising-edge of btnA at currRenderFrame.id=%v, delayedInputFrame.id=%v", pR.Id, playerId, currRenderFrame.Id, delayedInputFrame.InputFrameId))
|
||||
|
||||
} else if decodedInput.BtnALevel < prevBtnALevel {
|
||||
Logger.Debug(fmt.Sprintf("roomId=%v, playerId=%v triggered a falling-edge of btnA at currRenderFrame.id=%v, delayedInputFrame.id=%v", pR.Id, playerId, currRenderFrame.Id, delayedInputFrame.InputFrameId))
|
||||
} else {
|
||||
// No bullet trigger, process movement inputs
|
||||
// Note that by now "0 == thatPlayerInNextFrame.FramesToRecover", we should change "CharacterState" to "WALKING" or "IDLE" depending on player inputs
|
||||
if 0 != decodedInput.Dx || 0 != decodedInput.Dy {
|
||||
thatPlayerInNextFrame.DirX = decodedInput.Dx
|
||||
thatPlayerInNextFrame.DirY = decodedInput.Dy
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_WALKING
|
||||
} else {
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
|
||||
}
|
||||
}
|
||||
|
||||
movementX, movementY := VirtualGridToWorldPos(decodedInput.Dx+decodedInput.Dx*currPlayerDownsync.Speed, decodedInput.Dy+decodedInput.Dy*currPlayerDownsync.Speed, pR.VirtualGridToWorldRatio)
|
||||
playerCollider.X += movementX
|
||||
playerCollider.Y += movementY
|
||||
|
||||
// Update in the collision system
|
||||
playerCollider.Update()
|
||||
}
|
||||
|
||||
// handle pushbacks upon collision after all movements treated as simultaneous
|
||||
for _, player := range pR.PlayersArr {
|
||||
joinIndex := player.JoinIndex
|
||||
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
|
||||
playerCollider := collisionSysMap[collisionPlayerIndex]
|
||||
if collision := playerCollider.Check(0, 0); collision != nil {
|
||||
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
|
||||
for _, obj := range collision.Objects {
|
||||
barrierShape := obj.Shape.(*resolv.ConvexPolygon)
|
||||
if overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, barrierShape); overlapped {
|
||||
Logger.Debug(fmt.Sprintf("Overlapped: a=%v, b=%v, pushbackX=%v, pushbackY=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), pushbackX, pushbackY))
|
||||
effPushbacks[joinIndex-1].X += pushbackX
|
||||
effPushbacks[joinIndex-1].Y += pushbackY
|
||||
} else {
|
||||
Logger.Debug(fmt.Sprintf("Collided BUT not overlapped: a=%v, b=%v, overlapResult=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), overlapResult))
|
||||
}
|
||||
}
|
||||
if 1 == thatPlayerInNextFrame.JoinIndex {
|
||||
if currPlayerDownsync.InAir && !thatPlayerInNextFrame.InAir {
|
||||
//Logger.Warn(fmt.Sprintf("playerId=%d, joinIndex=%d fallStopping#2:\n{nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelY: %d}\n\tcalculated from <- playerColliderPos=%v, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, RectCenterStr(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY), effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
||||
} else if !currPlayerDownsync.InAir && thatPlayerInNextFrame.InAir {
|
||||
//Logger.Warn(fmt.Sprintf("playerId=%d, joinIndex=%d took off:\n{nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelY: %d}\n\tcalculated from <- playerColliderPos=%v, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, RectCenterStr(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY), effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
||||
} else if thatPlayerInNextFrame.InAir && (0 != thatPlayerInNextFrame.VelY) {
|
||||
//Logger.Info(fmt.Sprintf("playerId=%d, joinIndex=%d inAir trajectory:\n{nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelY: %d}\n\tcalculated from <- playerColliderPos=%v, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, RectCenterStr(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY), effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
||||
}
|
||||
}
|
||||
|
||||
for _, player := range pR.PlayersArr {
|
||||
playerId := player.Id
|
||||
joinIndex := player.JoinIndex
|
||||
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
|
||||
playerCollider := collisionSysMap[collisionPlayerIndex]
|
||||
|
||||
// Update "virtual grid position"
|
||||
newVx, newVy := PolygonColliderAnchorToVirtualGridPos(playerCollider.X-effPushbacks[joinIndex-1].X, playerCollider.Y-effPushbacks[joinIndex-1].Y, player.ColliderRadius, player.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.WorldToVirtualGridRatio)
|
||||
thatPlayerInNextFrame := nextRenderFramePlayers[playerId]
|
||||
thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY = newVx, newVy
|
||||
}
|
||||
|
||||
Logger.Debug(fmt.Sprintf("After applyInputFrameDownsyncDynamicsOnSingleRenderFrame: currRenderFrame.Id=%v, inputList=%v, currRenderFrame.Players=%v, nextRenderFramePlayers=%v", currRenderFrame.Id, inputList, currRenderFrame.Players, nextRenderFramePlayers))
|
||||
}
|
||||
|
||||
return toRet
|
||||
return &RoomDownsyncFrame{
|
||||
Id: currRenderFrame.Id + 1,
|
||||
Players: nextRenderFramePlayers,
|
||||
MeleeBullets: nextRenderFrameMeleeBullets,
|
||||
CountdownNanos: (pR.BattleDurationNanos - int64(currRenderFrame.Id)*pR.RollbackEstimatedDtNanos),
|
||||
}
|
||||
}
|
||||
|
||||
func (pR *Room) decodeInput(encodedInput uint64) *InputFrameDecoded {
|
||||
encodedDirection := (encodedInput & uint64(15))
|
||||
btnALevel := int32((encodedInput >> 4) & 1)
|
||||
btnBLevel := int32((encodedInput >> 5) & 1)
|
||||
return &InputFrameDecoded{
|
||||
Dx: DIRECTION_DECODER[encodedDirection][0],
|
||||
Dy: DIRECTION_DECODER[encodedDirection][1],
|
||||
BtnALevel: btnALevel,
|
||||
BtnBLevel: btnBLevel,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1517,12 +1650,14 @@ func (pR *Room) inputFrameIdDebuggable(inputFrameId int32) bool {
|
||||
func (pR *Room) refreshColliders(spaceW, spaceH int32) {
|
||||
// Kindly note that by now, we've already got all the shapes in the tmx file into "pR.(Players | Barriers)" from "ParseTmxLayersAndGroups"
|
||||
|
||||
minStep := (int(float64(pR.PlayerDefaultSpeed)*pR.VirtualGridToWorldRatio) << 1) // the approx minimum distance a player can move per frame in world coordinate
|
||||
topPadding, bottomPadding, leftPadding, rightPadding := pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap
|
||||
|
||||
minStep := (int(float64(pR.PlayerDefaultSpeed)*pR.VirtualGridToWorldRatio) << 2) // the approx minimum distance a player can move per frame in world coordinate
|
||||
pR.Space = resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep) // allocate a new collision space everytime after a battle is settled
|
||||
for _, player := range pR.Players {
|
||||
wx, wy := VirtualGridToWorldPos(player.VirtualGridX, player.VirtualGridY, pR.VirtualGridToWorldRatio)
|
||||
colliderWidth, colliderHeight := player.ColliderRadius*2, player.ColliderRadius*3
|
||||
playerCollider := GenerateRectCollider(wx, wy, colliderWidth, colliderHeight, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "Player")
|
||||
colliderWidth, colliderHeight := player.ColliderRadius*2, player.ColliderRadius*4
|
||||
playerCollider := GenerateRectCollider(wx, wy, colliderWidth, colliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "Player") // the coords of all barrier boundaries are multiples of tileWidth(i.e. 16), by adding snapping y-padding when "landedOnGravityPushback" all "playerCollider.Y" would be a multiple of 1.0
|
||||
playerCollider.Data = player
|
||||
pR.Space.Add(playerCollider)
|
||||
// Keep track of the collider in "pR.CollisionSysMap"
|
||||
@@ -1535,6 +1670,7 @@ func (pR *Room) refreshColliders(spaceW, spaceH int32) {
|
||||
for _, barrier := range pR.Barriers {
|
||||
boundaryUnaligned := barrier.Boundary
|
||||
barrierCollider := GenerateConvexPolygonCollider(boundaryUnaligned, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "Barrier")
|
||||
barrierCollider.Data = barrier
|
||||
pR.Space.Add(barrierCollider)
|
||||
}
|
||||
}
|
||||
@@ -1566,7 +1702,7 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
|
||||
if 0 <= pR.LastAllConfirmedInputFrameId {
|
||||
dynamicsStartedAt := utils.UnixtimeNano()
|
||||
// Apply "all-confirmed inputFrames" to move forward "pR.CurDynamicsRenderFrameId"
|
||||
nextDynamicsRenderFrameId := pR.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames)
|
||||
nextDynamicsRenderFrameId := pR.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames) + 1
|
||||
Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, LastAllConfirmedInputFrameId=%v, InputDelayFrames=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames, nextDynamicsRenderFrameId))
|
||||
pR.applyInputFrameDownsyncDynamics(pR.CurDynamicsRenderFrameId, nextDynamicsRenderFrameId, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY)
|
||||
*pDynamicsDuration = utils.UnixtimeNano() - dynamicsStartedAt
|
||||
@@ -1580,53 +1716,91 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
|
||||
|
||||
func (pR *Room) downsyncToAllPlayers(inputsBufferSnapshot *InputsBufferSnapshot) {
|
||||
/*
|
||||
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked for preserving the order of generation of "inputsBufferSnapshot" -- see comments in "OnBattleCmdReceived" and [this issue](https://github.com/genxium/DelayNoMore/issues/12).
|
||||
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is LOCKED to **preserve the order of generation of "inputsBufferSnapshot" for sending** -- see comments in "OnBattleCmdReceived" and [this issue](https://github.com/genxium/DelayNoMore/issues/12).
|
||||
|
||||
Actually if each player session were both intrinsically thread-safe & non-blocking for writing (like Java NIO), I could've just called "playerSession.WriteMessage" while holding "pR.InputsBufferLock" -- but the ws session provided by Gorilla library is neither thread-safe nor non-blocking for writing, which is fine because it creates a chance for the users to solve an interesting problem :)
|
||||
|
||||
Moreover, we're downsyncing a same "inputsBufferSnapshot" for all players in the same battle and this is by design, i.e. not respecting "player.LastSentInputFrameId" because "new all-confirmed inputFrameDownsyncs" are the same for all players and ws is TCP-based (no loss of consecutive packets except for reconnection -- which is already handled by READDED_BATTLE_COLLIDER_ACKED)
|
||||
|
||||
Lastly noting just for fun, if in "OnBattleCmdReceived" we need downsync to a single specific player (keeping **the order of generation of "inputsBufferSnapshot" preserved for sending** of course), in theory it's better to do it by the following order.
|
||||
1. lock "InputsBuffer";
|
||||
2. generate downsync msg;
|
||||
3. lock "pR.PlayerDownsyncChanDict[playerId]";
|
||||
4. put downsync msg to "pR.PlayerDownsyncChanDict[playerId]";
|
||||
5. unlock "InputsBuffer";
|
||||
6. now other threads are allowed to lock "inputsBuffer", and we can do "other things" on "pR.PlayerDownsyncChanDict[playerId]";
|
||||
7. unlock "pR.PlayerDownsyncChanDict[playerId]".
|
||||
|
||||
The difference from our current approach is that the "pR.PlayerDownsyncChanDict[playerId]" in use is a Golang channel, i.e. when executing #4 it automatically executes #3 (before) & #7 (after) as well, thus we couldn't do #5 & #6 in between.
|
||||
*/
|
||||
/*
|
||||
Moreover, we're downsyncing a same "inputsBufferSnapshot" for all players in the same battle and this is by design, i.e. not respecting "player.LastSentInputFrameId" because "new all-confirmed inputFrameDownsyncs" are the same for all players and ws is TCP-based (no loss of consecutive packets except for reconnection -- which is already handled by READDED_BATTLE_COLLIDER_ACKED)
|
||||
*/
|
||||
for playerId, playerDownsyncChan := range pR.PlayerDownsyncChanDict {
|
||||
playerDownsyncChan <- (*inputsBufferSnapshot)
|
||||
Logger.Debug(fmt.Sprintf("Sent inputsBufferSnapshot(refRenderFrameId:%d, unconfirmedMask:%v) to for (roomId: %d, playerId:%d, playerDownsyncChan:%p)#1", inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, pR.Id, playerId, playerDownsyncChan))
|
||||
if true == pR.BackendDynamicsEnabled {
|
||||
for _, player := range pR.PlayersArr {
|
||||
/*
|
||||
[WARNING] Since v0.9.1, the inconsistence between frontend & backend collision handling results became too difficult to track, therefore before we can let frontend use a Golang compiled library for "applyInputFrameDownsyncDynamicsOnSingleRenderFrame", it's a compromise here to force resync for all players in a same room if any player recovered from a reconnection (when it's most likely for anyone to notice an inconsistence).
|
||||
|
||||
That said, we ensured that if "false == BackendDynamicsEnabled" and noone ever disconnects & reconnects, the frontend collision handling results are always consistent.
|
||||
*/
|
||||
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||
thatPlayerJoinMask := uint64(1 << uint32(player.JoinIndex-1))
|
||||
if PlayerBattleStateIns.READDED_BATTLE_COLLIDER_ACKED == playerBattleState {
|
||||
inputsBufferSnapshot.ShouldForceResync = true
|
||||
break
|
||||
} else if PlayerBattleStateIns.ACTIVE == playerBattleState && 0 < (inputsBufferSnapshot.UnconfirmedMask&thatPlayerJoinMask) {
|
||||
/*
|
||||
[WARNING] Whenever there's an ACTIVE SLOW TICKER, all players should also be resynced to avoid inconsistent display. See `<proj-root>/ConcerningEdgeCases.md` for more information.
|
||||
*/
|
||||
inputsBufferSnapshot.ShouldForceResync = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, player := range pR.PlayersArr {
|
||||
/*
|
||||
[WARNING] While the order of generation of "inputsBufferSnapshot" is preserved for sending, the underlying network I/O blocking action is dispatched to "downsyncLoop of each player" such that "markConfirmationIfApplicable & forceConfirmationIfApplicable" can re-hold "pR.InputsBufferLock" asap and proceed with more inputFrameUpsyncs.
|
||||
|
||||
The use of "downsyncLoop of each player" also waives the need of guarding each "pR.PlayerDownsyncSessionDict[playerId]" from multithread-access (e.g. by a "pR.PlayerDownsyncSessionMutexDict[playerId]"), i.e. Gorilla v1.2.0 "conn.WriteMessage" isn't thread-safe https://github.com/gorilla/websocket/blob/v1.2.0/conn.go#L585.
|
||||
*/
|
||||
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||
switch playerBattleState {
|
||||
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
|
||||
continue
|
||||
}
|
||||
|
||||
if playerDownsyncChan, existent := pR.PlayerDownsyncChanDict[player.Id]; existent {
|
||||
playerDownsyncChan <- (*inputsBufferSnapshot)
|
||||
//Logger.Info(fmt.Sprintf("Sent inputsBufferSnapshot(refRenderFrameId:%d, unconfirmedMask:%v) to for (roomId: %d, playerId:%d, playerDownsyncChan:%p)#1", inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, pR.Id, player.Id, playerDownsyncChan))
|
||||
} else {
|
||||
Logger.Warn(fmt.Sprintf("playerDownsyncChan for (roomId: %d, playerId:%d) is gone", pR.Id, player.Id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRenderFrameId int32, unconfirmedMask uint64, toSendInputFrameDownsyncsSnapshot []*InputFrameDownsync) {
|
||||
func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRenderFrameId int32, unconfirmedMask uint64, toSendInputFrameDownsyncsSnapshot []*InputFrameDownsync, shouldForceResync bool) {
|
||||
/*
|
||||
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is unlocked -- otherwise the blocking "sendSafely" might cause significant lag!
|
||||
We hereby assume that Golang runtime allocates & frees small amount of RAM quickly enough compared to either network I/O worst cases or the high frequency "per inputFrameDownsync*player" locking (though "OnBattleCmdReceived" locks at the same frequency but it's inevitable).
|
||||
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is unlocked -- otherwise the network I/O blocking of "sendSafely" might cause significant lag for "markConfirmationIfApplicable & forceConfirmationIfApplicable"!
|
||||
|
||||
We hereby assume that Golang runtime allocates & frees small amount of RAM quickly enough compared to either network I/O blocking in worst cases or the high frequency "per inputFrameDownsync*player" locking (though "OnBattleCmdReceived" locks at the same frequency but it's inevitable).
|
||||
*/
|
||||
|
||||
playerJoinIndex := player.JoinIndex - 1
|
||||
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||
switch playerBattleState {
|
||||
case PlayerBattleStateIns.DISCONNECTED:
|
||||
case PlayerBattleStateIns.LOST:
|
||||
case PlayerBattleStateIns.EXPELLED_DURING_GAME:
|
||||
case PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
|
||||
case PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK:
|
||||
case PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
|
||||
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
|
||||
return
|
||||
}
|
||||
|
||||
shouldResync1 := (PlayerBattleStateIns.READDED_BATTLE_COLLIDER_ACKED == playerBattleState) // i.e. implies that "MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED == player.LastSentInputFrameId"
|
||||
shouldResync2 := (0 < (unconfirmedMask & uint64(1<<uint32(playerJoinIndex)))) // This condition is critical, if we don't send resync upon this condition, the "reconnected or slowly-clocking player" might never get its input synced
|
||||
// shouldResync2 := (0 < unconfirmedMask) // An easier version of the above, might keep sending "refRenderFrame"s to still connected players when any player is disconnected
|
||||
shouldResyncOverall := (shouldResync1 || shouldResync2)
|
||||
|
||||
if shouldResyncOverall {
|
||||
// A rejoined player, should guarantee that when it resyncs to "refRenderFrameId" a matching inputFrame to apply exists
|
||||
Logger.Debug(fmt.Sprintf("Resyncing player: roomId=%v, playerId=%v, playerJoinIndex=%v, renderFrameId=%v, curDynamicsRenderFrameId=%v, playerLastSentInputFrameId=%v, refRenderFrameId=%v", pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, refRenderFrameId))
|
||||
}
|
||||
shouldResync3 := shouldForceResync
|
||||
shouldResyncOverall := (shouldResync1 || shouldResync2 || shouldResync3)
|
||||
|
||||
/*
|
||||
Resync helps
|
||||
1. when player with a slower frontend clock lags significantly behind and thus wouldn't get its inputUpsync recognized due to faster "forceConfirmation"
|
||||
2. reconnection
|
||||
*/
|
||||
|
||||
toSendInputFrameIdSt, toSendInputFrameIdEd := toSendInputFrameDownsyncsSnapshot[0].InputFrameId, toSendInputFrameDownsyncsSnapshot[len(toSendInputFrameDownsyncsSnapshot)-1].InputFrameId+1
|
||||
if pR.BackendDynamicsEnabled && shouldResyncOverall {
|
||||
tmp := pR.RenderFrameBuffer.GetByFrameId(refRenderFrameId)
|
||||
@@ -1638,9 +1812,15 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
|
||||
for _, player := range pR.PlayersArr {
|
||||
refRenderFrame.Players[player.Id].ColliderRadius = player.ColliderRadius // hardcoded for now
|
||||
}
|
||||
if shouldResync3 {
|
||||
refRenderFrame.ShouldForceResync = true
|
||||
}
|
||||
refRenderFrame.BackendUnconfirmedMask = unconfirmedMask
|
||||
pR.sendSafely(refRenderFrame, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false)
|
||||
Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: InputsBuffer=%v", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, pR.InputsBufferString(false)))
|
||||
//Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: InputsBuffer=%v", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, pR.InputsBufferString(false)))
|
||||
if shouldResync1 {
|
||||
Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: shouldResync1=%v, shouldResync2=%v, shouldResync3=%v, playerBattleState=%d", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, shouldResync1, shouldResync2, shouldResync3, playerBattleState))
|
||||
}
|
||||
} else {
|
||||
pR.sendSafely(nil, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_INPUT_BATCH, playerId, false)
|
||||
}
|
||||
@@ -1682,3 +1862,29 @@ func (pR *Room) cloneInputsBuffer(stFrameId, edFrameId int32) []*InputFrameDowns
|
||||
|
||||
return cloned
|
||||
}
|
||||
|
||||
func (pR *Room) calcHardPushbacksNorms(playerCollider *resolv.Object, playerShape *resolv.ConvexPolygon, snapIntoPlatformOverlap float64, pEffPushback *Vec2D) []Vec2D {
|
||||
ret := make([]Vec2D, 0, 10) // no one would simultaneously have more than 5 hardPushbacks
|
||||
collision := playerCollider.Check(0, 0)
|
||||
if nil == collision {
|
||||
return ret
|
||||
}
|
||||
for _, obj := range collision.Objects {
|
||||
switch obj.Data.(type) {
|
||||
case *Barrier:
|
||||
barrierShape := obj.Shape.(*resolv.ConvexPolygon)
|
||||
overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, barrierShape)
|
||||
if !overlapped {
|
||||
continue
|
||||
}
|
||||
// ALWAY snap into hardPushbacks!
|
||||
// [OverlapX, OverlapY] is the unit vector that points into the platform
|
||||
pushbackX, pushbackY = (overlapResult.Overlap-snapIntoPlatformOverlap)*overlapResult.OverlapX, (overlapResult.Overlap-snapIntoPlatformOverlap)*overlapResult.OverlapY
|
||||
ret = append(ret, Vec2D{X: overlapResult.OverlapX, Y: overlapResult.OverlapY})
|
||||
pEffPushback.X += pushbackX
|
||||
pEffPushback.Y += pushbackY
|
||||
default:
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
@@ -30,21 +30,24 @@ type PlayerDownsync struct {
|
||||
VirtualGridX int32 `protobuf:"varint,2,opt,name=virtualGridX,proto3" json:"virtualGridX,omitempty"`
|
||||
VirtualGridY int32 `protobuf:"varint,3,opt,name=virtualGridY,proto3" json:"virtualGridY,omitempty"`
|
||||
DirX int32 `protobuf:"varint,4,opt,name=dirX,proto3" json:"dirX,omitempty"`
|
||||
DirY int32 `protobuf:"varint,5,opt,name=dirY,proto3" json:"dirY,omitempty"`
|
||||
Speed int32 `protobuf:"varint,6,opt,name=speed,proto3" json:"speed,omitempty"` // in terms of virtual grid units
|
||||
BattleState int32 `protobuf:"varint,7,opt,name=battleState,proto3" json:"battleState,omitempty"`
|
||||
JoinIndex int32 `protobuf:"varint,8,opt,name=joinIndex,proto3" json:"joinIndex,omitempty"`
|
||||
ColliderRadius float64 `protobuf:"fixed64,9,opt,name=colliderRadius,proto3" json:"colliderRadius,omitempty"`
|
||||
Removed bool `protobuf:"varint,10,opt,name=removed,proto3" json:"removed,omitempty"`
|
||||
Score int32 `protobuf:"varint,11,opt,name=score,proto3" json:"score,omitempty"`
|
||||
LastMoveGmtMillis int32 `protobuf:"varint,12,opt,name=lastMoveGmtMillis,proto3" json:"lastMoveGmtMillis,omitempty"`
|
||||
FramesToRecover int32 `protobuf:"varint,13,opt,name=framesToRecover,proto3" json:"framesToRecover,omitempty"`
|
||||
Hp int32 `protobuf:"varint,14,opt,name=hp,proto3" json:"hp,omitempty"`
|
||||
MaxHp int32 `protobuf:"varint,15,opt,name=maxHp,proto3" json:"maxHp,omitempty"`
|
||||
CharacterState int32 `protobuf:"varint,16,opt,name=characterState,proto3" json:"characterState,omitempty"`
|
||||
Name string `protobuf:"bytes,17,opt,name=name,proto3" json:"name,omitempty"`
|
||||
DisplayName string `protobuf:"bytes,18,opt,name=displayName,proto3" json:"displayName,omitempty"`
|
||||
Avatar string `protobuf:"bytes,19,opt,name=avatar,proto3" json:"avatar,omitempty"`
|
||||
DirY int32 `protobuf:"varint,5,opt,name=dirY,proto3" json:"dirY,omitempty"` // "dirX" and "dirY" determines character facing
|
||||
VelX int32 `protobuf:"varint,6,opt,name=velX,proto3" json:"velX,omitempty"`
|
||||
VelY int32 `protobuf:"varint,7,opt,name=velY,proto3" json:"velY,omitempty"` // "velX" and "velY" is used to record the accumulated effect by accelerations (including gravity)
|
||||
Speed int32 `protobuf:"varint,8,opt,name=speed,proto3" json:"speed,omitempty"` // this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY"
|
||||
BattleState int32 `protobuf:"varint,9,opt,name=battleState,proto3" json:"battleState,omitempty"`
|
||||
JoinIndex int32 `protobuf:"varint,10,opt,name=joinIndex,proto3" json:"joinIndex,omitempty"`
|
||||
ColliderRadius float64 `protobuf:"fixed64,11,opt,name=colliderRadius,proto3" json:"colliderRadius,omitempty"`
|
||||
Removed bool `protobuf:"varint,12,opt,name=removed,proto3" json:"removed,omitempty"`
|
||||
Score int32 `protobuf:"varint,13,opt,name=score,proto3" json:"score,omitempty"`
|
||||
LastMoveGmtMillis int32 `protobuf:"varint,14,opt,name=lastMoveGmtMillis,proto3" json:"lastMoveGmtMillis,omitempty"`
|
||||
FramesToRecover int32 `protobuf:"varint,15,opt,name=framesToRecover,proto3" json:"framesToRecover,omitempty"`
|
||||
Hp int32 `protobuf:"varint,16,opt,name=hp,proto3" json:"hp,omitempty"`
|
||||
MaxHp int32 `protobuf:"varint,17,opt,name=maxHp,proto3" json:"maxHp,omitempty"`
|
||||
CharacterState int32 `protobuf:"varint,18,opt,name=characterState,proto3" json:"characterState,omitempty"`
|
||||
InAir bool `protobuf:"varint,19,opt,name=inAir,proto3" json:"inAir,omitempty"` // by design a standalone field only inferred by the collision result of "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" instead of "characterState", because we need check the transition for "characterState" from this field, i.e. "inAir (prev -> curr)"
|
||||
Name string `protobuf:"bytes,20,opt,name=name,proto3" json:"name,omitempty"`
|
||||
DisplayName string `protobuf:"bytes,21,opt,name=displayName,proto3" json:"displayName,omitempty"`
|
||||
Avatar string `protobuf:"bytes,22,opt,name=avatar,proto3" json:"avatar,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PlayerDownsync) Reset() {
|
||||
@@ -114,6 +117,20 @@ func (x *PlayerDownsync) GetDirY() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PlayerDownsync) GetVelX() int32 {
|
||||
if x != nil {
|
||||
return x.VelX
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PlayerDownsync) GetVelY() int32 {
|
||||
if x != nil {
|
||||
return x.VelY
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PlayerDownsync) GetSpeed() int32 {
|
||||
if x != nil {
|
||||
return x.Speed
|
||||
@@ -191,6 +208,13 @@ func (x *PlayerDownsync) GetCharacterState() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PlayerDownsync) GetInAir() bool {
|
||||
if x != nil {
|
||||
return x.InAir
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *PlayerDownsync) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
@@ -220,6 +244,7 @@ type InputFrameDecoded struct {
|
||||
Dx int32 `protobuf:"varint,1,opt,name=dx,proto3" json:"dx,omitempty"`
|
||||
Dy int32 `protobuf:"varint,2,opt,name=dy,proto3" json:"dy,omitempty"`
|
||||
BtnALevel int32 `protobuf:"varint,3,opt,name=btnALevel,proto3" json:"btnALevel,omitempty"`
|
||||
BtnBLevel int32 `protobuf:"varint,4,opt,name=btnBLevel,proto3" json:"btnBLevel,omitempty"`
|
||||
}
|
||||
|
||||
func (x *InputFrameDecoded) Reset() {
|
||||
@@ -275,6 +300,13 @@ func (x *InputFrameDecoded) GetBtnALevel() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *InputFrameDecoded) GetBtnBLevel() int32 {
|
||||
if x != nil {
|
||||
return x.BtnBLevel
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type InputFrameUpsync struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -638,6 +670,7 @@ type InputsBufferSnapshot struct {
|
||||
RefRenderFrameId int32 `protobuf:"varint,1,opt,name=refRenderFrameId,proto3" json:"refRenderFrameId,omitempty"`
|
||||
UnconfirmedMask uint64 `protobuf:"varint,2,opt,name=unconfirmedMask,proto3" json:"unconfirmedMask,omitempty"`
|
||||
ToSendInputFrameDownsyncs []*InputFrameDownsync `protobuf:"bytes,3,rep,name=toSendInputFrameDownsyncs,proto3" json:"toSendInputFrameDownsyncs,omitempty"`
|
||||
ShouldForceResync bool `protobuf:"varint,4,opt,name=shouldForceResync,proto3" json:"shouldForceResync,omitempty"`
|
||||
}
|
||||
|
||||
func (x *InputsBufferSnapshot) Reset() {
|
||||
@@ -693,6 +726,13 @@ func (x *InputsBufferSnapshot) GetToSendInputFrameDownsyncs() []*InputFrameDowns
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *InputsBufferSnapshot) GetShouldForceResync() bool {
|
||||
if x != nil {
|
||||
return x.ShouldForceResync
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type MeleeBullet struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -901,6 +941,11 @@ type BattleColliderInfo struct {
|
||||
SpAtkLookupFrames int32 `protobuf:"varint,25,opt,name=spAtkLookupFrames,proto3" json:"spAtkLookupFrames,omitempty"`
|
||||
RenderCacheSize int32 `protobuf:"varint,26,opt,name=renderCacheSize,proto3" json:"renderCacheSize,omitempty"`
|
||||
MeleeSkillConfig map[int32]*MeleeBullet `protobuf:"bytes,27,rep,name=meleeSkillConfig,proto3" json:"meleeSkillConfig,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // skillId -> skill
|
||||
SnapIntoPlatformOverlap float64 `protobuf:"fixed64,28,opt,name=snapIntoPlatformOverlap,proto3" json:"snapIntoPlatformOverlap,omitempty"`
|
||||
SnapIntoPlatformThreshold float64 `protobuf:"fixed64,29,opt,name=snapIntoPlatformThreshold,proto3" json:"snapIntoPlatformThreshold,omitempty"`
|
||||
JumpingInitVelY int32 `protobuf:"varint,30,opt,name=jumpingInitVelY,proto3" json:"jumpingInitVelY,omitempty"`
|
||||
GravityX int32 `protobuf:"varint,31,opt,name=gravityX,proto3" json:"gravityX,omitempty"`
|
||||
GravityY int32 `protobuf:"varint,32,opt,name=gravityY,proto3" json:"gravityY,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BattleColliderInfo) Reset() {
|
||||
@@ -1117,6 +1162,41 @@ func (x *BattleColliderInfo) GetMeleeSkillConfig() map[int32]*MeleeBullet {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *BattleColliderInfo) GetSnapIntoPlatformOverlap() float64 {
|
||||
if x != nil {
|
||||
return x.SnapIntoPlatformOverlap
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BattleColliderInfo) GetSnapIntoPlatformThreshold() float64 {
|
||||
if x != nil {
|
||||
return x.SnapIntoPlatformThreshold
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BattleColliderInfo) GetJumpingInitVelY() int32 {
|
||||
if x != nil {
|
||||
return x.JumpingInitVelY
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BattleColliderInfo) GetGravityX() int32 {
|
||||
if x != nil {
|
||||
return x.GravityX
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BattleColliderInfo) GetGravityY() int32 {
|
||||
if x != nil {
|
||||
return x.GravityY
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type RoomDownsyncFrame struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -1127,6 +1207,7 @@ type RoomDownsyncFrame struct {
|
||||
CountdownNanos int64 `protobuf:"varint,3,opt,name=countdownNanos,proto3" json:"countdownNanos,omitempty"`
|
||||
MeleeBullets []*MeleeBullet `protobuf:"bytes,4,rep,name=meleeBullets,proto3" json:"meleeBullets,omitempty"` // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise
|
||||
BackendUnconfirmedMask uint64 `protobuf:"varint,5,opt,name=backendUnconfirmedMask,proto3" json:"backendUnconfirmedMask,omitempty"` // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
|
||||
ShouldForceResync bool `protobuf:"varint,6,opt,name=shouldForceResync,proto3" json:"shouldForceResync,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RoomDownsyncFrame) Reset() {
|
||||
@@ -1196,13 +1277,20 @@ func (x *RoomDownsyncFrame) GetBackendUnconfirmedMask() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RoomDownsyncFrame) GetShouldForceResync() bool {
|
||||
if x != nil {
|
||||
return x.ShouldForceResync
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_room_downsync_frame_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_room_downsync_frame_proto_rawDesc = []byte{
|
||||
0x0a, 0x19, 0x72, 0x6f, 0x6f, 0x6d, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x5f,
|
||||
0x66, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x73, 0x1a, 0x0e, 0x67, 0x65, 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x22, 0xb2, 0x04, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f,
|
||||
0x6f, 0x74, 0x6f, 0x22, 0xf0, 0x04, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f,
|
||||
0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61,
|
||||
0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x76, 0x69,
|
||||
@@ -1211,279 +1299,304 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
|
||||
0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x64, 0x69, 0x72, 0x58, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x69,
|
||||
0x72, 0x58, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x69, 0x72, 0x59, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x04, 0x64, 0x69, 0x72, 0x59, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b,
|
||||
0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x0b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0e,
|
||||
0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x18, 0x09,
|
||||
0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x52, 0x61,
|
||||
0x64, 0x69, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18,
|
||||
0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73,
|
||||
0x63, 0x6f, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65,
|
||||
0x47, 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x11, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c,
|
||||
0x69, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65,
|
||||
0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x66, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02,
|
||||
0x68, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x68, 0x70, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x6d, 0x61, 0x78, 0x48, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x61, 0x78,
|
||||
0x48, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x53,
|
||||
0x74, 0x61, 0x74, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x72,
|
||||
0x61, 0x63, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20,
|
||||
0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x12, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x51, 0x0a, 0x11, 0x49, 0x6e, 0x70, 0x75,
|
||||
0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x78, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x79, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x50, 0x0a, 0x10, 0x49,
|
||||
0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12,
|
||||
0x52, 0x04, 0x64, 0x69, 0x72, 0x59, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x65, 0x6c, 0x58, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x76, 0x65, 0x6c, 0x58, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x65,
|
||||
0x6c, 0x59, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x76, 0x65, 0x6c, 0x59, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73,
|
||||
0x70, 0x65, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74,
|
||||
0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x61, 0x74, 0x74, 0x6c,
|
||||
0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72,
|
||||
0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0e, 0x63, 0x6f,
|
||||
0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72,
|
||||
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18,
|
||||
0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x11,
|
||||
0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69,
|
||||
0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x76,
|
||||
0x65, 0x47, 0x6d, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x0f, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x0f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x63,
|
||||
0x6f, 0x76, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x68, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x02, 0x68, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x78, 0x48, 0x70, 0x18, 0x11, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x61, 0x78, 0x48, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x68,
|
||||
0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x12, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x0e, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61,
|
||||
0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x41, 0x69, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x05, 0x69, 0x6e, 0x41, 0x69, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b,
|
||||
0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x6f, 0x0a, 0x11, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x64,
|
||||
0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x78, 0x12, 0x0e, 0x0a, 0x02, 0x64,
|
||||
0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x62,
|
||||
0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09,
|
||||
0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x74, 0x6e,
|
||||
0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x74,
|
||||
0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x50, 0x0a, 0x10, 0x49, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69,
|
||||
0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
|
||||
0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x22, 0x7c, 0x0a, 0x12, 0x49, 0x6e, 0x70,
|
||||
0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x12,
|
||||
0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x22, 0x7c, 0x0a,
|
||||
0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73,
|
||||
0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75,
|
||||
0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d,
|
||||
0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0f, 0x48,
|
||||
0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x28,
|
||||
0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54,
|
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xb8, 0x02, 0x0a, 0x05, 0x57, 0x73, 0x52,
|
||||
0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x63, 0x6b,
|
||||
0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x63,
|
||||
0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x4e, 0x0a, 0x15, 0x69, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61,
|
||||
0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73,
|
||||
0x79, 0x6e, 0x63, 0x52, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55,
|
||||
0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x27, 0x0a, 0x02, 0x68, 0x62,
|
||||
0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
|
||||
0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52,
|
||||
0x02, 0x68, 0x62, 0x22, 0x89, 0x02, 0x0a, 0x06, 0x57, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x65, 0x74,
|
||||
0x12, 0x20, 0x0a, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67,
|
||||
0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x03, 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44,
|
||||
0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72, 0x64,
|
||||
0x66, 0x12, 0x54, 0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44,
|
||||
0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75,
|
||||
0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x17,
|
||||
0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79,
|
||||
0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x73, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65,
|
||||
0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x22,
|
||||
0xc6, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72,
|
||||
0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, 0x66, 0x52,
|
||||
0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x10, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72,
|
||||
0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x75,
|
||||
0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x58,
|
||||
0x0a, 0x19, 0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x19, 0x74,
|
||||
0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44,
|
||||
0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x22, 0xe5, 0x05, 0x0a, 0x0b, 0x4d, 0x65, 0x6c,
|
||||
0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x61, 0x74, 0x74,
|
||||
0x6c, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x0d, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x24,
|
||||
0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69,
|
||||
0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x6f,
|
||||
0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
|
||||
0x12, 0x34, 0x0a, 0x15, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x4f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x15, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f,
|
||||
0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65,
|
||||
0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x48, 0x69, 0x74, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x13, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x48, 0x69, 0x74, 0x12, 0x35, 0x0a, 0x0b, 0x6d, 0x6f, 0x76, 0x65,
|
||||
0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
|
||||
0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x63,
|
||||
0x32, 0x44, 0x52, 0x0b, 0x6d, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12,
|
||||
0x22, 0x0a, 0x0c, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66,
|
||||
0x73, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x0a, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a,
|
||||
0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x52, 0x0a, 0x68, 0x69,
|
||||
0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x38, 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67,
|
||||
0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69,
|
||||
0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74,
|
||||
0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0d,
|
||||
0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x2e,
|
||||
0x0a, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
|
||||
0x54, 0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x65,
|
||||
0x61, 0x73, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06,
|
||||
0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64,
|
||||
0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x10, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72,
|
||||
0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10,
|
||||
0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64,
|
||||
0x22, 0x98, 0x0d, 0x0a, 0x12, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69,
|
||||
0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x67,
|
||||
0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5f, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x54, 0x6f, 0x56, 0x65,
|
||||
0x63, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65,
|
||||
0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x72,
|
||||
0x54, 0x6f, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x11, 0x73, 0x74, 0x72, 0x54, 0x6f, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x12, 0x6b, 0x0a, 0x15, 0x73, 0x74, 0x72, 0x54, 0x6f, 0x50,
|
||||
0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x18,
|
||||
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x42,
|
||||
0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72,
|
||||
0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x72, 0x74,
|
||||
0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6c,
|
||||
0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x22, 0xb8, 0x02, 0x0a, 0x05, 0x57, 0x73, 0x52, 0x65, 0x71, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d,
|
||||
0x73, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61,
|
||||
0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49,
|
||||
0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67,
|
||||
0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x4e, 0x0a, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18,
|
||||
0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49,
|
||||
0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52,
|
||||
0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e,
|
||||
0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x27, 0x0a, 0x02, 0x68, 0x62, 0x18, 0x08, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x72,
|
||||
0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x02, 0x68, 0x62, 0x22,
|
||||
0x89, 0x02, 0x0a, 0x06, 0x57, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0b,
|
||||
0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74,
|
||||
0x12, 0x2b, 0x0a, 0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73,
|
||||
0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72, 0x64, 0x66, 0x12, 0x54, 0x0a,
|
||||
0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73,
|
||||
0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x17, 0x69, 0x6e, 0x70, 0x75,
|
||||
0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61,
|
||||
0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x42,
|
||||
0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x2e, 0x53, 0x74, 0x72, 0x54, 0x6f, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x15, 0x73, 0x74,
|
||||
0x72, 0x54, 0x6f, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x4d, 0x61, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x67, 0x65, 0x44, 0x69, 0x73, 0x63,
|
||||
0x72, 0x65, 0x74, 0x65, 0x57, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x73, 0x74, 0x61,
|
||||
0x67, 0x65, 0x44, 0x69, 0x73, 0x63, 0x72, 0x65, 0x74, 0x65, 0x57, 0x12, 0x26, 0x0a, 0x0e, 0x73,
|
||||
0x74, 0x61, 0x67, 0x65, 0x44, 0x69, 0x73, 0x63, 0x72, 0x65, 0x74, 0x65, 0x48, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x67, 0x65, 0x44, 0x69, 0x73, 0x63, 0x72, 0x65,
|
||||
0x74, 0x65, 0x48, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6c, 0x65,
|
||||
0x57, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69,
|
||||
0x6c, 0x65, 0x57, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6c, 0x65,
|
||||
0x48, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69,
|
||||
0x6c, 0x65, 0x48, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54,
|
||||
0x6f, 0x50, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x6f, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x15, 0x77,
|
||||
0x69, 0x6c, 0x6c, 0x4b, 0x69, 0x63, 0x6b, 0x49, 0x66, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76,
|
||||
0x65, 0x46, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x77, 0x69, 0x6c, 0x6c,
|
||||
0x4b, 0x69, 0x63, 0x6b, 0x49, 0x66, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x6f,
|
||||
0x72, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64,
|
||||
0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f,
|
||||
0x6d, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x14, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x14, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c,
|
||||
0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x0d,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x46, 0x70, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x65,
|
||||
0x72, 0x76, 0x65, 0x72, 0x46, 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x44, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x10, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x61, 0x6c,
|
||||
0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x69,
|
||||
0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12,
|
||||
0x26, 0x0a, 0x0e, 0x6e, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x61,
|
||||
0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x1e, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x44, 0x65, 0x6c, 0x61, 0x79,
|
||||
0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x1e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e,
|
||||
0x63, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12,
|
||||
0x48, 0x0a, 0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e,
|
||||
0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61,
|
||||
0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
|
||||
0x50, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x6c, 0x61,
|
||||
0x79, 0x65, 0x72, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x14,
|
||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x42, 0x61, 0x74, 0x74,
|
||||
0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x19, 0x72, 0x6f, 0x6c, 0x6c, 0x62,
|
||||
0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d, 0x69,
|
||||
0x6c, 0x6c, 0x69, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x01, 0x52, 0x19, 0x72, 0x6f, 0x6c, 0x6c,
|
||||
0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d,
|
||||
0x69, 0x6c, 0x6c, 0x69, 0x73, 0x12, 0x3a, 0x0a, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e, 0x6f,
|
||||
0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e, 0x6f,
|
||||
0x73, 0x12, 0x38, 0x0a, 0x17, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x54, 0x6f, 0x56, 0x69, 0x72, 0x74,
|
||||
0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x17, 0x20, 0x01,
|
||||
0x28, 0x01, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x54, 0x6f, 0x56, 0x69, 0x72, 0x74, 0x75,
|
||||
0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x38, 0x0a, 0x17, 0x76,
|
||||
0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x54, 0x6f, 0x57, 0x6f, 0x72, 0x6c,
|
||||
0x64, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x18, 0x20, 0x01, 0x28, 0x01, 0x52, 0x17, 0x76, 0x69,
|
||||
0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x54, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64,
|
||||
0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x70, 0x41, 0x74, 0x6b, 0x4c, 0x6f,
|
||||
0x6f, 0x6b, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x11, 0x73, 0x70, 0x41, 0x74, 0x6b, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63,
|
||||
0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65,
|
||||
0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x5c, 0x0a,
|
||||
0x10, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
|
||||
0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x6d, 0x65, 0x6c, 0x65, 0x65,
|
||||
0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x5d, 0x0a, 0x16, 0x53,
|
||||
0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x22, 0xf4, 0x01, 0x0a, 0x14,
|
||||
0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x6e, 0x61, 0x70,
|
||||
0x73, 0x68, 0x6f, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65,
|
||||
0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10,
|
||||
0x72, 0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
|
||||
0x12, 0x28, 0x0a, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d,
|
||||
0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x58, 0x0a, 0x19, 0x74, 0x6f,
|
||||
0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f,
|
||||
0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x19, 0x74, 0x6f, 0x53, 0x65, 0x6e,
|
||||
0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73,
|
||||
0x79, 0x6e, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f,
|
||||
0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79,
|
||||
0x6e, 0x63, 0x22, 0xe5, 0x05, 0x0a, 0x0b, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c,
|
||||
0x65, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x4c, 0x6f, 0x63, 0x61,
|
||||
0x6c, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x61, 0x74, 0x74, 0x6c,
|
||||
0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72,
|
||||
0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22,
|
||||
0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x6f,
|
||||
0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x72, 0x65,
|
||||
0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x72, 0x65, 0x63, 0x6f, 0x76,
|
||||
0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x12, 0x30, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x4f, 0x6e, 0x48, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x72,
|
||||
0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x48,
|
||||
0x69, 0x74, 0x12, 0x35, 0x0a, 0x0b, 0x6d, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72,
|
||||
0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x52, 0x0b, 0x6d, 0x6f,
|
||||
0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x68, 0x69, 0x74,
|
||||
0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||
0x0c, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x33, 0x0a,
|
||||
0x0a, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x13, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
|
||||
0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x52, 0x0a, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69,
|
||||
0x7a, 0x65, 0x12, 0x38, 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64,
|
||||
0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x0a, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52,
|
||||
0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0b, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08,
|
||||
0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x65, 0x6c, 0x65,
|
||||
0x61, 0x73, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0e,
|
||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x72, 0x69,
|
||||
0x67, 0x67, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61,
|
||||
0x67, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65,
|
||||
0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e,
|
||||
0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66, 0x66,
|
||||
0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a,
|
||||
0x0a, 0x10, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72,
|
||||
0x49, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64,
|
||||
0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x22, 0xf2, 0x0e, 0x0a, 0x12, 0x42,
|
||||
0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x5f, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x54, 0x6f, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x4d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64,
|
||||
0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x72, 0x54, 0x6f, 0x56, 0x65, 0x63, 0x32,
|
||||
0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x73,
|
||||
0x74, 0x72, 0x54, 0x6f, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x52,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x65, 0x0a, 0x1a, 0x53, 0x74,
|
||||
0x72, 0x54, 0x6f, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x68, 0x61, 0x72,
|
||||
0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e,
|
||||
0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||
0x01, 0x1a, 0x58, 0x0a, 0x15, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74,
|
||||
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd2, 0x02, 0x0a, 0x11,
|
||||
0x12, 0x6b, 0x0a, 0x15, 0x73, 0x74, 0x72, 0x54, 0x6f, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e,
|
||||
0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x35, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43,
|
||||
0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x72, 0x54,
|
||||
0x6f, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61,
|
||||
0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x15, 0x73, 0x74, 0x72, 0x54, 0x6f, 0x50, 0x6f, 0x6c,
|
||||
0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x12, 0x26, 0x0a,
|
||||
0x0e, 0x73, 0x74, 0x61, 0x67, 0x65, 0x44, 0x69, 0x73, 0x63, 0x72, 0x65, 0x74, 0x65, 0x57, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x67, 0x65, 0x44, 0x69, 0x73, 0x63,
|
||||
0x72, 0x65, 0x74, 0x65, 0x57, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x67, 0x65, 0x44, 0x69,
|
||||
0x73, 0x63, 0x72, 0x65, 0x74, 0x65, 0x48, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x73,
|
||||
0x74, 0x61, 0x67, 0x65, 0x44, 0x69, 0x73, 0x63, 0x72, 0x65, 0x74, 0x65, 0x48, 0x12, 0x1e, 0x0a,
|
||||
0x0a, 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6c, 0x65, 0x57, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6c, 0x65, 0x57, 0x12, 0x1e, 0x0a,
|
||||
0x0a, 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6c, 0x65, 0x48, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6c, 0x65, 0x48, 0x12, 0x26, 0x0a,
|
||||
0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x6f, 0x50, 0x69, 0x6e, 0x67, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54,
|
||||
0x6f, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x15, 0x77, 0x69, 0x6c, 0x6c, 0x4b, 0x69, 0x63,
|
||||
0x6b, 0x49, 0x66, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x6f, 0x72, 0x18, 0x09,
|
||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x77, 0x69, 0x6c, 0x6c, 0x4b, 0x69, 0x63, 0x6b, 0x49, 0x66,
|
||||
0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x62,
|
||||
0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x12, 0x32, 0x0a,
|
||||
0x14, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x62, 0x61, 0x74,
|
||||
0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x12, 0x30, 0x0a, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13,
|
||||
0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61,
|
||||
0x6e, 0x6f, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x70, 0x73,
|
||||
0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x70,
|
||||
0x73, 0x12, 0x2a, 0x0a, 0x10, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x69, 0x6e, 0x70,
|
||||
0x75, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2a, 0x0a,
|
||||
0x10, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63,
|
||||
0x61, 0x6c, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x6e, 0x73, 0x74,
|
||||
0x44, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x0e, 0x6e, 0x73, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x12, 0x46, 0x0a, 0x1e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55,
|
||||
0x70, 0x73, 0x79, 0x6e, 0x63, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1e, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x44, 0x65, 0x6c, 0x61, 0x79,
|
||||
0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x1f, 0x6d, 0x61, 0x78,
|
||||
0x43, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x50, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x13, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65,
|
||||
0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50, 0x65, 0x72, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x42, 0x61, 0x74,
|
||||
0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11,
|
||||
0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74,
|
||||
0x65, 0x12, 0x3c, 0x0a, 0x19, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74,
|
||||
0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x15,
|
||||
0x20, 0x01, 0x28, 0x01, 0x52, 0x19, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73,
|
||||
0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x12,
|
||||
0x3a, 0x0a, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d,
|
||||
0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d,
|
||||
0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x38, 0x0a, 0x17, 0x77,
|
||||
0x6f, 0x72, 0x6c, 0x64, 0x54, 0x6f, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69,
|
||||
0x64, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x17, 0x20, 0x01, 0x28, 0x01, 0x52, 0x17, 0x77, 0x6f,
|
||||
0x72, 0x6c, 0x64, 0x54, 0x6f, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64,
|
||||
0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x38, 0x0a, 0x17, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c,
|
||||
0x47, 0x72, 0x69, 0x64, 0x54, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x52, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x18, 0x18, 0x20, 0x01, 0x28, 0x01, 0x52, 0x17, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47,
|
||||
0x72, 0x69, 0x64, 0x54, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12,
|
||||
0x2c, 0x0a, 0x11, 0x73, 0x70, 0x41, 0x74, 0x6b, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x46, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x73, 0x70, 0x41, 0x74,
|
||||
0x6b, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x28, 0x0a,
|
||||
0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65,
|
||||
0x18, 0x1a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61,
|
||||
0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x5c, 0x0a, 0x10, 0x6d, 0x65, 0x6c, 0x65, 0x65,
|
||||
0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x1b, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c,
|
||||
0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4d, 0x65,
|
||||
0x6c, 0x65, 0x65, 0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x10, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x17, 0x73, 0x6e, 0x61, 0x70, 0x49, 0x6e, 0x74,
|
||||
0x6f, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x70,
|
||||
0x18, 0x1c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x17, 0x73, 0x6e, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x6f,
|
||||
0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x70, 0x12,
|
||||
0x3c, 0x0a, 0x19, 0x73, 0x6e, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x6f, 0x50, 0x6c, 0x61, 0x74, 0x66,
|
||||
0x6f, 0x72, 0x6d, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x1d, 0x20, 0x01,
|
||||
0x28, 0x01, 0x52, 0x19, 0x73, 0x6e, 0x61, 0x70, 0x49, 0x6e, 0x74, 0x6f, 0x50, 0x6c, 0x61, 0x74,
|
||||
0x66, 0x6f, 0x72, 0x6d, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x28, 0x0a,
|
||||
0x0f, 0x6a, 0x75, 0x6d, 0x70, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x69, 0x74, 0x56, 0x65, 0x6c, 0x59,
|
||||
0x18, 0x1e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x6a, 0x75, 0x6d, 0x70, 0x69, 0x6e, 0x67, 0x49,
|
||||
0x6e, 0x69, 0x74, 0x56, 0x65, 0x6c, 0x59, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x72, 0x61, 0x76, 0x69,
|
||||
0x74, 0x79, 0x58, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x67, 0x72, 0x61, 0x76, 0x69,
|
||||
0x74, 0x79, 0x58, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x79, 0x59, 0x18,
|
||||
0x20, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x79, 0x59, 0x1a,
|
||||
0x5d, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x54, 0x6f, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x68, 0x61,
|
||||
0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x63, 0x32, 0x44, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x65,
|
||||
0x0a, 0x1a, 0x53, 0x74, 0x72, 0x54, 0x6f, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
|
||||
0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6f, 0x6c,
|
||||
0x79, 0x67, 0x6f, 0x6e, 0x32, 0x44, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x58, 0x0a, 0x15, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x53, 0x6b,
|
||||
0x69, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75,
|
||||
0x6c, 0x6c, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
|
||||
0x80, 0x03, 0x0a, 0x11, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63,
|
||||
0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x40, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e,
|
||||
0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69,
|
||||
0x64, 0x12, 0x40, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, 0x6d,
|
||||
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x50, 0x6c,
|
||||
0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e,
|
||||
0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x6d,
|
||||
0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65,
|
||||
0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c,
|
||||
0x6c, 0x65, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55,
|
||||
0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55, 0x6e, 0x63,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x1a, 0x52, 0x0a, 0x0c,
|
||||
0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f, 0x77,
|
||||
0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
|
||||
0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x5f, 0x73, 0x72, 0x76, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x65, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
|
||||
0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12,
|
||||
0x37, 0x0a, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18,
|
||||
0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d,
|
||||
0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x6d, 0x65, 0x6c, 0x65,
|
||||
0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x62, 0x61, 0x63, 0x6b,
|
||||
0x65, 0x6e, 0x64, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61,
|
||||
0x73, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e,
|
||||
0x64, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b,
|
||||
0x12, 0x2c, 0x0a, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52,
|
||||
0x65, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x68, 0x6f,
|
||||
0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x1a, 0x52,
|
||||
0x0a, 0x0c, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44,
|
||||
0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
|
||||
0x38, 0x01, 0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x5f, 0x73, 0x72, 0x76,
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@@ -265,9 +265,14 @@ func Serve(c *gin.Context) {
|
||||
WorldToVirtualGridRatio: pRoom.WorldToVirtualGridRatio,
|
||||
VirtualGridToWorldRatio: pRoom.VirtualGridToWorldRatio,
|
||||
|
||||
SpAtkLookupFrames: pRoom.SpAtkLookupFrames,
|
||||
RenderCacheSize: pRoom.RenderCacheSize,
|
||||
MeleeSkillConfig: pRoom.MeleeSkillConfig,
|
||||
SpAtkLookupFrames: pRoom.SpAtkLookupFrames,
|
||||
RenderCacheSize: pRoom.RenderCacheSize,
|
||||
MeleeSkillConfig: pRoom.MeleeSkillConfig,
|
||||
SnapIntoPlatformOverlap: pRoom.SnapIntoPlatformOverlap,
|
||||
SnapIntoPlatformThreshold: pRoom.SnapIntoPlatformThreshold,
|
||||
JumpingInitVelY: pRoom.JumpingInitVelY,
|
||||
GravityX: pRoom.GravityX,
|
||||
GravityY: pRoom.GravityY,
|
||||
}
|
||||
|
||||
resp := &pb.WsResp{
|
||||
|
@@ -7,3 +7,10 @@ ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" output.mp4
|
||||
```
|
||||
ffmpeg -ss 12 -t 13 -i input.mp4 -vf "fps=10,scale=480:-1" -loop 0 output.gif
|
||||
```
|
||||
|
||||
# Extract GIF (with alpha channel, e.g. exported from Fighter Factory Studio) to PNG sequence
|
||||
```
|
||||
ffmpeg -vsync vfr -i input.gif output%d.png
|
||||
```
|
||||
|
||||
The `-vsync vfr` tells ffmpeg to disrespect the original delays set within the GIF file, otherwise many duplicate frame will be extracted by the default 60FPS.
|
||||
|
BIN
charts/jump_sync_spedup.gif
Normal file
BIN
charts/jump_sync_spedup.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 MiB |
Binary file not shown.
Before Width: | Height: | Size: 6.0 MiB |
@@ -34,15 +34,19 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
|
||||
spaceOffsetX := float64(spaceW) * 0.5
|
||||
spaceOffsetY := float64(spaceH) * 0.5
|
||||
|
||||
virtualGridToWorldRatio := 0.1
|
||||
playerDefaultSpeed := 20
|
||||
minStep := (int(float64(playerDefaultSpeed)*virtualGridToWorldRatio) << 2)
|
||||
playerColliderRadius := float64(24)
|
||||
worldToVirtualGridRatio := float64(1000)
|
||||
virtualGridToWorldRatio := float64(1) / worldToVirtualGridRatio
|
||||
playerDefaultSpeed := 1 * worldToVirtualGridRatio
|
||||
minStep := (int(float64(playerDefaultSpeed)*virtualGridToWorldRatio) << 3)
|
||||
playerColliderRadius := float64(12)
|
||||
playerColliders := make([]*resolv.Object, len(playerPosList.Eles))
|
||||
snapIntoPlatformOverlap := float64(0.1)
|
||||
space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep)
|
||||
topPadding, bottomPadding, leftPadding, rightPadding := snapIntoPlatformOverlap, snapIntoPlatformOverlap, snapIntoPlatformOverlap, snapIntoPlatformOverlap
|
||||
for i, playerPos := range playerPosList.Eles {
|
||||
playerCollider := GenerateRectCollider(playerPos.X, playerPos.Y, playerColliderRadius*2, playerColliderRadius*2, spaceOffsetX, spaceOffsetY, "Player") // [WARNING] Deliberately not using a circle because "resolv v0.5.1" doesn't yet align circle center with space cell center, regardless of the "specified within-object offset"
|
||||
Logger.Info(fmt.Sprintf("Player Collider#%d: player world pos =(%.2f, %.2f), shape=%v", i, playerPos.X, playerPos.Y, ConvexPolygonStr(playerCollider.Shape.(*resolv.ConvexPolygon))))
|
||||
colliderWidth, colliderHeight := playerColliderRadius*2, playerColliderRadius*4
|
||||
playerCollider := GenerateRectCollider(playerPos.X, playerPos.Y, colliderWidth, colliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, spaceOffsetX, spaceOffsetY, "Player") // [WARNING] Deliberately not using a circle because "resolv v0.5.1" doesn't yet align circle center with space cell center, regardless of the "specified within-object offset"
|
||||
Logger.Info(fmt.Sprintf("Player Collider#%d: player world pos=(%.2f, %.2f), shape=%v", i, playerPos.X, playerPos.Y, ConvexPolygonStr(playerCollider.Shape.(*resolv.ConvexPolygon))))
|
||||
playerColliders[i] = playerCollider
|
||||
space.Add(playerCollider)
|
||||
}
|
||||
@@ -50,33 +54,35 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
|
||||
barrierLocalId := 0
|
||||
for _, barrierUnaligned := range barrierList.Eles {
|
||||
barrierCollider := GenerateConvexPolygonCollider(barrierUnaligned, spaceOffsetX, spaceOffsetY, "Barrier")
|
||||
Logger.Info(fmt.Sprintf("Added barrier: shape=%v", ConvexPolygonStr(barrierCollider.Shape.(*resolv.ConvexPolygon))))
|
||||
Logger.Debug(fmt.Sprintf("Added barrier: shape=%v", ConvexPolygonStr(barrierCollider.Shape.(*resolv.ConvexPolygon))))
|
||||
space.Add(barrierCollider)
|
||||
barrierLocalId++
|
||||
}
|
||||
|
||||
world.Space = space
|
||||
|
||||
moveToCollide := false
|
||||
moveToCollide := true
|
||||
if moveToCollide {
|
||||
newVx, newVy := int32(-2959), int32(-2261)
|
||||
effPushback := Vec2D{X: float64(0), Y: float64(0)}
|
||||
toTestPlayerCollider := playerColliders[0]
|
||||
toTestPlayerCollider.X, toTestPlayerCollider.Y = VirtualGridToPolygonColliderAnchorPos(newVx, newVy, playerColliderRadius, playerColliderRadius, spaceOffsetX, spaceOffsetY, virtualGridToWorldRatio)
|
||||
//colliderWidth, colliderHeight := playerColliderRadius*2, playerColliderRadius*4
|
||||
//newVx, newVy := int32(27999), int32(-420270)
|
||||
//toTestPlayerCollider.X, toTestPlayerCollider.Y = VirtualGridToPolygonColliderBLPos(newVx, newVy, colliderWidth, colliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, spaceOffsetX, spaceOffsetY, virtualGridToWorldRatio)
|
||||
|
||||
Logger.Info(fmt.Sprintf("Checking collision for virtual (%d, %d), now playerShape=%v", newVx, newVy, ConvexPolygonStr(toTestPlayerCollider.Shape.(*resolv.ConvexPolygon))))
|
||||
Logger.Info(fmt.Sprintf("Checking collision for playerShape=%v", ConvexPolygonStr(toTestPlayerCollider.Shape.(*resolv.ConvexPolygon))))
|
||||
|
||||
toTestPlayerCollider.Update()
|
||||
if collision := toTestPlayerCollider.Check(0, 0); collision != nil {
|
||||
playerShape := toTestPlayerCollider.Shape.(*resolv.ConvexPolygon)
|
||||
for _, obj := range collision.Objects {
|
||||
barrierShape := obj.Shape.(*resolv.ConvexPolygon)
|
||||
if overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, barrierShape); overlapped {
|
||||
Logger.Warn(fmt.Sprintf("Overlapped: a=%v, b=%v, pushbackX=%v, pushbackY=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), pushbackX, pushbackY))
|
||||
bShape := obj.Shape.(*resolv.ConvexPolygon)
|
||||
Logger.Warn(fmt.Sprintf("Checking potential: a=%v, b=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(bShape)))
|
||||
if overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, bShape); overlapped {
|
||||
Logger.Warn(fmt.Sprintf("Overlapped: a=%v, b=%v, pushbackX=%v, pushbackY=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(bShape), pushbackX, pushbackY))
|
||||
effPushback.X += pushbackX
|
||||
effPushback.Y += pushbackY
|
||||
} else {
|
||||
Logger.Warn(fmt.Sprintf("Collided BUT not overlapped: a=%v, b=%v, overlapResult=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(barrierShape), overlapResult))
|
||||
Logger.Warn(fmt.Sprintf("Collided BUT not overlapped: a=%v, b=%v, overlapResult=%v", ConvexPolygonStr(playerShape), ConvexPolygonStr(bShape), overlapResult))
|
||||
}
|
||||
}
|
||||
toTestPlayerCollider.X -= effPushback.X
|
||||
@@ -109,13 +115,12 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
|
||||
ReleaseTriggerType: int32(1), // 1: rising-edge, 2: falling-edge
|
||||
Damage: int32(5),
|
||||
}
|
||||
bulletLeftToRight := true
|
||||
bulletLeftToRight := false
|
||||
if bulletLeftToRight {
|
||||
xfac := float64(1.0)
|
||||
offenderWx, offenderWy := playerPosList.Eles[0].X, playerPosList.Eles[0].Y
|
||||
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
||||
|
||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, spaceOffsetX, spaceOffsetY, "MeleeBullet")
|
||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, topPadding, bottomPadding, leftPadding, rightPadding, spaceOffsetX, spaceOffsetY, "MeleeBullet")
|
||||
space.Add(newBulletCollider)
|
||||
bulletShape := newBulletCollider.Shape.(*resolv.ConvexPolygon)
|
||||
Logger.Warn(fmt.Sprintf("bullet ->: Added bullet collider to space: a=%v", ConvexPolygonStr(bulletShape)))
|
||||
@@ -132,13 +137,13 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
|
||||
}
|
||||
}
|
||||
|
||||
bulletRightToLeft := true
|
||||
bulletRightToLeft := false
|
||||
if bulletRightToLeft {
|
||||
xfac := float64(-1.0)
|
||||
offenderWx, offenderWy := playerPosList.Eles[1].X, playerPosList.Eles[1].Y
|
||||
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
||||
|
||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, spaceOffsetX, spaceOffsetY, "MeleeBullet")
|
||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, topPadding, bottomPadding, leftPadding, rightPadding, spaceOffsetX, spaceOffsetY, "MeleeBullet")
|
||||
space.Add(newBulletCollider)
|
||||
bulletShape := newBulletCollider.Shape.(*resolv.ConvexPolygon)
|
||||
Logger.Warn(fmt.Sprintf("bullet <-: Added bullet collider to space: a=%v", ConvexPolygonStr(bulletShape)))
|
||||
@@ -177,7 +182,7 @@ func (world *WorldColliderDisplay) Draw(screen *ebiten.Image) {
|
||||
}
|
||||
}
|
||||
|
||||
world.Game.DebugDraw(screen, world.Space)
|
||||
//world.Game.DebugDraw(screen, world.Space)
|
||||
|
||||
if world.Game.ShowHelpText {
|
||||
|
||||
|
@@ -10,33 +10,33 @@ func NormVec2D(dx, dy float64) Vec2D {
|
||||
}
|
||||
|
||||
func AlignPolygon2DToBoundingBox(input *Polygon2D) *Polygon2D {
|
||||
// Transform again to put "anchor" at the top-left point of the bounding box for "resolv"
|
||||
boundingBoxTL := &Vec2D{
|
||||
// Transform again to put "anchor" at the "bottom-left point (w.r.t. world space)" of the bounding box for "resolv"
|
||||
boundingBoxBL := &Vec2D{
|
||||
X: math.MaxFloat64,
|
||||
Y: math.MaxFloat64,
|
||||
}
|
||||
for _, p := range input.Points {
|
||||
if p.X < boundingBoxTL.X {
|
||||
boundingBoxTL.X = p.X
|
||||
if p.X < boundingBoxBL.X {
|
||||
boundingBoxBL.X = p.X
|
||||
}
|
||||
if p.Y < boundingBoxTL.Y {
|
||||
boundingBoxTL.Y = p.Y
|
||||
if p.Y < boundingBoxBL.Y {
|
||||
boundingBoxBL.Y = p.Y
|
||||
}
|
||||
}
|
||||
|
||||
// Now "input.Anchor" should move to "input.Anchor+boundingBoxTL", thus "boundingBoxTL" is also the value of the negative diff for all "input.Points"
|
||||
// Now "input.Anchor" should move to "input.Anchor+boundingBoxBL", thus "boundingBoxBL" is also the value of the negative diff for all "input.Points"
|
||||
output := &Polygon2D{
|
||||
Anchor: &Vec2D{
|
||||
X: input.Anchor.X + boundingBoxTL.X,
|
||||
Y: input.Anchor.Y + boundingBoxTL.Y,
|
||||
X: input.Anchor.X + boundingBoxBL.X,
|
||||
Y: input.Anchor.Y + boundingBoxBL.Y,
|
||||
},
|
||||
Points: make([]*Vec2D, len(input.Points)),
|
||||
}
|
||||
|
||||
for i, p := range input.Points {
|
||||
output.Points[i] = &Vec2D{
|
||||
X: p.X - boundingBoxTL.X,
|
||||
Y: p.Y - boundingBoxTL.Y,
|
||||
X: p.X - boundingBoxBL.X,
|
||||
Y: p.Y - boundingBoxBL.Y,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -18,13 +18,17 @@ func ConvexPolygonStr(body *resolv.ConvexPolygon) string {
|
||||
return fmt.Sprintf("{\n%s\n}", strings.Join(s, ",\n"))
|
||||
}
|
||||
|
||||
func GenerateRectCollider(origX, origY, w, h, spaceOffsetX, spaceOffsetY float64, tag string) *resolv.Object {
|
||||
cx, cy := WorldToPolygonColliderAnchorPos(origX, origY, w*0.5, h*0.5, spaceOffsetX, spaceOffsetY)
|
||||
return GenerateRectColliderInCollisionSpace(cx, cy, w, h, tag)
|
||||
func RectCenterStr(body *resolv.Object, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding, spaceOffsetX, spaceOffsetY float64) string {
|
||||
return fmt.Sprintf("{%.2f, %.2f}", body.X+leftPadding+halfBoundingW-spaceOffsetX, body.Y+bottomPadding+halfBoundingH-spaceOffsetY)
|
||||
}
|
||||
|
||||
func GenerateRectColliderInCollisionSpace(cx, cy, w, h float64, tag string) *resolv.Object {
|
||||
collider := resolv.NewObject(cx, cy, w, h, tag)
|
||||
func GenerateRectCollider(wx, wy, w, h, topPadding, bottomPadding, leftPadding, rightPadding, spaceOffsetX, spaceOffsetY float64, tag string) *resolv.Object {
|
||||
blX, blY := WorldToPolygonColliderBLPos(wx, wy, w*0.5, h*0.5, topPadding, bottomPadding, leftPadding, rightPadding, spaceOffsetX, spaceOffsetY)
|
||||
return generateRectColliderInCollisionSpace(blX, blY, leftPadding+w+rightPadding, bottomPadding+h+topPadding, tag)
|
||||
}
|
||||
|
||||
func generateRectColliderInCollisionSpace(blX, blY, w, h float64, tag string) *resolv.Object {
|
||||
collider := resolv.NewObject(blX, blY, w, h, tag) // Unlike its frontend counter part, the position of a "resolv.Object" must be specified by "bottom-left point" because "w" and "h" must be positive, see "resolv.Object.BoundsToSpace" for details
|
||||
shape := resolv.NewRectangle(0, 0, w, h)
|
||||
collider.SetShape(shape)
|
||||
return collider
|
||||
@@ -66,6 +70,7 @@ func CalcPushbacks(oldDx, oldDy float64, playerShape, barrierShape *resolv.Conve
|
||||
playerShape.SetPosition(origX, origY)
|
||||
}()
|
||||
playerShape.SetPosition(origX+oldDx, origY+oldDy)
|
||||
|
||||
overlapResult := &SatResult{
|
||||
Overlap: 0,
|
||||
OverlapX: 0,
|
||||
@@ -74,7 +79,7 @@ func CalcPushbacks(oldDx, oldDy float64, playerShape, barrierShape *resolv.Conve
|
||||
BContainedInA: true,
|
||||
Axis: vector.Vector{0, 0},
|
||||
}
|
||||
if overlapped := IsPolygonPairOverlapped(playerShape, barrierShape, overlapResult); overlapped {
|
||||
if overlapped := isPolygonPairOverlapped(playerShape, barrierShape, overlapResult); overlapped {
|
||||
pushbackX, pushbackY := overlapResult.Overlap*overlapResult.OverlapX, overlapResult.Overlap*overlapResult.OverlapY
|
||||
return true, pushbackX, pushbackY, overlapResult
|
||||
} else {
|
||||
@@ -91,16 +96,17 @@ type SatResult struct {
|
||||
Axis vector.Vector
|
||||
}
|
||||
|
||||
func IsPolygonPairOverlapped(a, b *resolv.ConvexPolygon, result *SatResult) bool {
|
||||
func isPolygonPairOverlapped(a, b *resolv.ConvexPolygon, result *SatResult) bool {
|
||||
aCnt, bCnt := len(a.Points), len(b.Points)
|
||||
// Single point case
|
||||
if 1 == aCnt && 1 == bCnt {
|
||||
if nil != result {
|
||||
result.Overlap = 0
|
||||
}
|
||||
return a.Points[0].X() == b.Points[0].X() && a.Points[0].Y() == b.Points[0].Y()
|
||||
return a.Points[0][0] == b.Points[0][0] && a.Points[0][1] == b.Points[0][1]
|
||||
}
|
||||
|
||||
//Logger.Info(fmt.Sprintf("Checking collision between a=%v, b=%v", ConvexPolygonStr(a), ConvexPolygonStr(b)))
|
||||
if 1 < aCnt {
|
||||
for _, axis := range a.SATAxes() {
|
||||
if isPolygonPairSeparatedByDir(a, b, axis.Unit(), result) {
|
||||
@@ -116,6 +122,7 @@ func IsPolygonPairOverlapped(a, b *resolv.ConvexPolygon, result *SatResult) bool
|
||||
}
|
||||
}
|
||||
}
|
||||
//Logger.Info(fmt.Sprintf("a=%v and b=%v are overlapped", ConvexPolygonStr(a), ConvexPolygonStr(b)))
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -137,9 +144,10 @@ func isPolygonPairSeparatedByDir(a, b *resolv.ConvexPolygon, e vector.Vector, re
|
||||
e = (-2.98, 1.49).Unit()
|
||||
*/
|
||||
|
||||
//Logger.Info(fmt.Sprintf("Checking separation between a=%v, b=%v along axis e={%.3f, %.3f}#1", ConvexPolygonStr(a), ConvexPolygonStr(b), e[0], e[1]))
|
||||
var aStart, aEnd, bStart, bEnd float64 = math.MaxFloat64, -math.MaxFloat64, math.MaxFloat64, -math.MaxFloat64
|
||||
for _, p := range a.Points {
|
||||
dot := (p.X()+a.X)*e.X() + (p.Y()+a.Y)*e.Y()
|
||||
dot := (p[0]+a.X)*e[0] + (p[1]+a.Y)*e[1]
|
||||
|
||||
if aStart > dot {
|
||||
aStart = dot
|
||||
@@ -151,7 +159,7 @@ func isPolygonPairSeparatedByDir(a, b *resolv.ConvexPolygon, e vector.Vector, re
|
||||
}
|
||||
|
||||
for _, p := range b.Points {
|
||||
dot := (p.X()+b.X)*e.X() + (p.Y()+b.Y)*e.Y()
|
||||
dot := (p[0]+b.X)*e[0] + (p[1]+b.Y)*e[1]
|
||||
|
||||
if bStart > dot {
|
||||
bStart = dot
|
||||
@@ -168,7 +176,6 @@ func isPolygonPairSeparatedByDir(a, b *resolv.ConvexPolygon, e vector.Vector, re
|
||||
}
|
||||
|
||||
if nil != result {
|
||||
result.Axis = e
|
||||
overlap := float64(0)
|
||||
|
||||
if aStart < bStart {
|
||||
@@ -209,16 +216,19 @@ func isPolygonPairSeparatedByDir(a, b *resolv.ConvexPolygon, e vector.Vector, re
|
||||
absoluteOverlap = -overlap
|
||||
}
|
||||
|
||||
if 0 == currentOverlap || currentOverlap > absoluteOverlap {
|
||||
if (0 == result.Axis[0] && 0 == result.Axis[1]) || currentOverlap > absoluteOverlap {
|
||||
var sign float64 = 1
|
||||
if overlap < 0 {
|
||||
sign = -1
|
||||
}
|
||||
|
||||
result.Overlap = absoluteOverlap
|
||||
result.OverlapX = e.X() * sign
|
||||
result.OverlapY = e.Y() * sign
|
||||
result.OverlapX = e[0] * sign
|
||||
result.OverlapY = e[1] * sign
|
||||
}
|
||||
|
||||
result.Axis = e
|
||||
//Logger.Info(fmt.Sprintf("Checking separation between a=%v, b=%v along axis e={%.3f, %.3f}#2: aStart=%.3f, aEnd=%.3f, bStart=%.3f, bEnd=%.3f, overlap=%.3f, currentOverlap=%.3f, absoluteOverlap=%.3f, result=%v", ConvexPolygonStr(a), ConvexPolygonStr(b), e[0], e[1], aStart, aEnd, bStart, bEnd, overlap, currentOverlap, absoluteOverlap, result))
|
||||
}
|
||||
|
||||
// the specified unit vector "e" doesn't separate "a" and "b", overlap result is generated
|
||||
@@ -240,20 +250,20 @@ func VirtualGridToWorldPos(vx, vy int32, virtualGridToWorldRatio float64) (float
|
||||
return wx, wy
|
||||
}
|
||||
|
||||
func WorldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
||||
return wx - halfBoundingW + collisionSpaceOffsetX, wy - halfBoundingH + collisionSpaceOffsetY
|
||||
func WorldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
||||
return wx - halfBoundingW - leftPadding + collisionSpaceOffsetX, wy - halfBoundingH - bottomPadding + collisionSpaceOffsetY
|
||||
}
|
||||
|
||||
func PolygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
||||
return cx + halfBoundingW - collisionSpaceOffsetX, cy + halfBoundingH - collisionSpaceOffsetY
|
||||
func PolygonColliderBLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
||||
return cx + halfBoundingW + leftPadding - collisionSpaceOffsetX, cy + halfBoundingH + bottomPadding - collisionSpaceOffsetY
|
||||
}
|
||||
|
||||
func PolygonColliderAnchorToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64, worldToVirtualGridRatio float64) (int32, int32) {
|
||||
wx, wy := PolygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
||||
func PolygonColliderBLToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding, collisionSpaceOffsetX, collisionSpaceOffsetY float64, worldToVirtualGridRatio float64) (int32, int32) {
|
||||
wx, wy := PolygonColliderBLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
||||
return WorldToVirtualGridPos(wx, wy, worldToVirtualGridRatio)
|
||||
}
|
||||
|
||||
func VirtualGridToPolygonColliderAnchorPos(vx, vy int32, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64, virtualGridToWorldRatio float64) (float64, float64) {
|
||||
func VirtualGridToPolygonColliderBLPos(vx, vy int32, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding, collisionSpaceOffsetX, collisionSpaceOffsetY float64, virtualGridToWorldRatio float64) (float64, float64) {
|
||||
wx, wy := VirtualGridToWorldPos(vx, vy, virtualGridToWorldRatio)
|
||||
return WorldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
||||
return WorldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
@@ -43,13 +44,13 @@ type TmxOrTsxPolyline struct {
|
||||
|
||||
type TmxOrTsxObject struct {
|
||||
Id int `xml:"id,attr"`
|
||||
Gid *int `xml:"gid,attr"`
|
||||
Gid int `xml:"gid,attr"`
|
||||
X float64 `xml:"x,attr"`
|
||||
Y float64 `xml:"y,attr"`
|
||||
Properties *TmxOrTsxProperties `xml:"properties"`
|
||||
Polyline *TmxOrTsxPolyline `xml:"polyline"`
|
||||
Width *float64 `xml:"width,attr"`
|
||||
Height *float64 `xml:"height,attr"`
|
||||
Width float64 `xml:"width,attr"`
|
||||
Height float64 `xml:"height,attr"`
|
||||
}
|
||||
|
||||
type TmxOrTsxObjectGroup struct {
|
||||
@@ -376,13 +377,37 @@ func ParseTmxLayersAndGroups(pTmxMapIns *TmxMap, gidBoundariesMap map[int]StrToP
|
||||
}
|
||||
|
||||
for _, singleObjInTmxFile := range objGroup.Objects {
|
||||
if nil == singleObjInTmxFile.Polyline {
|
||||
continue
|
||||
}
|
||||
if nil == singleObjInTmxFile.Properties.Property || "boundary_type" != singleObjInTmxFile.Properties.Property[0].Name || "barrier" != singleObjInTmxFile.Properties.Property[0].Value {
|
||||
continue
|
||||
}
|
||||
|
||||
if nil == singleObjInTmxFile.Polyline {
|
||||
pts := make([]*Vec2D, 4)
|
||||
s := make([]string, 0)
|
||||
pts[0] = &Vec2D{
|
||||
X: float64(0),
|
||||
Y: float64(0),
|
||||
}
|
||||
pts[1] = &Vec2D{
|
||||
X: float64(0),
|
||||
Y: singleObjInTmxFile.Height,
|
||||
}
|
||||
pts[2] = &Vec2D{
|
||||
X: singleObjInTmxFile.Width,
|
||||
Y: singleObjInTmxFile.Height,
|
||||
}
|
||||
pts[3] = &Vec2D{
|
||||
X: singleObjInTmxFile.Width,
|
||||
Y: float64(0),
|
||||
}
|
||||
for _, pt := range pts {
|
||||
s = append(s, fmt.Sprintf("%v,%v", pt.X, pt.Y))
|
||||
}
|
||||
singleObjInTmxFile.Polyline = &TmxOrTsxPolyline{
|
||||
Points: strings.Join(s, " "),
|
||||
}
|
||||
}
|
||||
|
||||
thePolygon2DInWorld, err := tmxPolylineToPolygon2D(pTmxMapIns, singleObjInTmxFile, singleObjInTmxFile.Polyline)
|
||||
if nil != err {
|
||||
panic(err)
|
||||
|
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"width":64,"imagePath":"SoldierFireGhost_tex.png","SubTexture":[{"frameWidth":12,"y":42,"frameHeight":11,"width":11,"frameX":-1,"height":11,"name":"biu","frameY":0,"x":16},{"width":5,"y":42,"height":7,"name":"rightArm","x":29},{"frameWidth":15,"y":27,"frameHeight":16,"width":13,"frameX":-1,"height":16,"name":"yinmoqe00","frameY":0,"x":1},{"width":17,"y":1,"height":21,"name":"body","x":28},{"width":5,"y":42,"height":7,"name":"rightShoulder","x":36},{"width":10,"y":45,"height":9,"name":"rightFrontArm","x":1},{"width":7,"y":56,"height":7,"name":"rightHand","x":1},{"width":6,"y":55,"height":6,"name":"leftArm","x":32},{"width":7,"y":55,"height":6,"name":"leftShoulder","x":23},{"width":10,"y":27,"height":11,"name":"leftFrontArm","x":16},{"width":17,"y":24,"height":16,"name":"head","x":28},{"width":25,"y":1,"height":24,"name":"head2","x":1},{"width":8,"y":55,"height":7,"name":"leftHand","x":13},{"frameWidth":4,"y":51,"frameHeight":4,"width":2,"frameX":-1,"height":2,"name":"huomiao01","frameY":-1,"x":29}],"height":64,"name":"SoldierFireGhost"}
|
||||
{"imagePath":"SoldierFireGhost_tex.png","width":64,"height":64,"name":"SoldierFireGhost","SubTexture":[{"frameY":0,"y":42,"frameWidth":12,"frameHeight":11,"width":11,"height":11,"name":"biu","frameX":-1,"x":16},{"width":5,"y":42,"height":7,"name":"rightArm","x":29},{"frameY":0,"y":27,"frameWidth":15,"frameHeight":16,"width":13,"height":16,"name":"yinmoqe00","frameX":-1,"x":1},{"width":17,"y":1,"height":21,"name":"body","x":28},{"width":5,"y":42,"height":7,"name":"rightShoulder","x":36},{"width":10,"y":45,"height":9,"name":"rightFrontArm","x":1},{"width":7,"y":56,"height":7,"name":"rightHand","x":1},{"width":6,"y":55,"height":6,"name":"leftArm","x":32},{"width":7,"y":55,"height":6,"name":"leftShoulder","x":23},{"width":10,"y":27,"height":11,"name":"leftFrontArm","x":16},{"width":25,"y":1,"height":24,"name":"head2","x":1},{"width":17,"y":24,"height":16,"name":"head","x":28},{"width":8,"y":55,"height":7,"name":"leftHand","x":13},{"frameY":-1,"y":51,"frameWidth":4,"frameHeight":4,"width":2,"height":2,"name":"huomiao01","frameX":-1,"x":29}]}
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ver": "1.0.0",
|
||||
"uuid": "4a9187d5-a9ad-4464-a03c-d2f3cc277051",
|
||||
"atlasJson": "{\"width\":64,\"imagePath\":\"SoldierFireGhost_tex.png\",\"SubTexture\":[{\"frameWidth\":12,\"y\":42,\"frameHeight\":11,\"width\":11,\"frameX\":-1,\"height\":11,\"name\":\"biu\",\"frameY\":0,\"x\":16},{\"width\":5,\"y\":42,\"height\":7,\"name\":\"rightArm\",\"x\":29},{\"frameWidth\":15,\"y\":27,\"frameHeight\":16,\"width\":13,\"frameX\":-1,\"height\":16,\"name\":\"yinmoqe00\",\"frameY\":0,\"x\":1},{\"width\":17,\"y\":1,\"height\":21,\"name\":\"body\",\"x\":28},{\"width\":5,\"y\":42,\"height\":7,\"name\":\"rightShoulder\",\"x\":36},{\"width\":10,\"y\":45,\"height\":9,\"name\":\"rightFrontArm\",\"x\":1},{\"width\":7,\"y\":56,\"height\":7,\"name\":\"rightHand\",\"x\":1},{\"width\":6,\"y\":55,\"height\":6,\"name\":\"leftArm\",\"x\":32},{\"width\":7,\"y\":55,\"height\":6,\"name\":\"leftShoulder\",\"x\":23},{\"width\":10,\"y\":27,\"height\":11,\"name\":\"leftFrontArm\",\"x\":16},{\"width\":17,\"y\":24,\"height\":16,\"name\":\"head\",\"x\":28},{\"width\":25,\"y\":1,\"height\":24,\"name\":\"head2\",\"x\":1},{\"width\":8,\"y\":55,\"height\":7,\"name\":\"leftHand\",\"x\":13},{\"frameWidth\":4,\"y\":51,\"frameHeight\":4,\"width\":2,\"frameX\":-1,\"height\":2,\"name\":\"huomiao01\",\"frameY\":-1,\"x\":29}],\"height\":64,\"name\":\"SoldierFireGhost\"}",
|
||||
"atlasJson": "{\"imagePath\":\"SoldierFireGhost_tex.png\",\"width\":64,\"height\":64,\"name\":\"SoldierFireGhost\",\"SubTexture\":[{\"frameY\":0,\"y\":42,\"frameWidth\":12,\"frameHeight\":11,\"width\":11,\"height\":11,\"name\":\"biu\",\"frameX\":-1,\"x\":16},{\"width\":5,\"y\":42,\"height\":7,\"name\":\"rightArm\",\"x\":29},{\"frameY\":0,\"y\":27,\"frameWidth\":15,\"frameHeight\":16,\"width\":13,\"height\":16,\"name\":\"yinmoqe00\",\"frameX\":-1,\"x\":1},{\"width\":17,\"y\":1,\"height\":21,\"name\":\"body\",\"x\":28},{\"width\":5,\"y\":42,\"height\":7,\"name\":\"rightShoulder\",\"x\":36},{\"width\":10,\"y\":45,\"height\":9,\"name\":\"rightFrontArm\",\"x\":1},{\"width\":7,\"y\":56,\"height\":7,\"name\":\"rightHand\",\"x\":1},{\"width\":6,\"y\":55,\"height\":6,\"name\":\"leftArm\",\"x\":32},{\"width\":7,\"y\":55,\"height\":6,\"name\":\"leftShoulder\",\"x\":23},{\"width\":10,\"y\":27,\"height\":11,\"name\":\"leftFrontArm\",\"x\":16},{\"width\":25,\"y\":1,\"height\":24,\"name\":\"head2\",\"x\":1},{\"width\":17,\"y\":24,\"height\":16,\"name\":\"head\",\"x\":28},{\"width\":8,\"y\":55,\"height\":7,\"name\":\"leftHand\",\"x\":13},{\"frameY\":-1,\"y\":51,\"frameWidth\":4,\"frameHeight\":4,\"width\":2,\"height\":2,\"name\":\"huomiao01\",\"frameX\":-1,\"x\":29}]}",
|
||||
"texture": "700d963b-2192-4219-a066-8be5b3db7453",
|
||||
"subMetas": {}
|
||||
}
|
@@ -1,229 +0,0 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Atk1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.5833333333333334,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "7fedc57f-6998-45fc-899d-ea5edd41ab13"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.016666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "d55c2f3c-9110-4627-b8b2-0f9395f0d145"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.03333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "1228879d-d28e-48e4-a3ce-5ceda0d1831f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.05,
|
||||
"value": {
|
||||
"__uuid__": "e88dd5c4-cc5d-46e0-88de-e382e2bcadd7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.06666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "df069f5c-7fc0-4731-bb7f-9d2032498e4c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.08333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "4815763d-64e1-4b15-b795-38900861c651"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.1,
|
||||
"value": {
|
||||
"__uuid__": "0dca4f06-bf25-4e7f-ac3a-1687e284f5d6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.11666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "de8db3c9-affd-45ef-a536-e2d28ebc8094"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.13333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "baaafb8b-9c1a-45ea-ba80-eb8048b61b57"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.15,
|
||||
"value": {
|
||||
"__uuid__": "9ffa7db6-1aec-4a1e-a8a9-118f2a6e50dc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.16666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "f2f296ad-0e19-4b00-b061-8c9edff98d0d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.18333333333333332,
|
||||
"value": {
|
||||
"__uuid__": "3e546607-d27f-40fa-9967-771c55a12590"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2,
|
||||
"value": {
|
||||
"__uuid__": "fece0129-e8ae-45be-b963-e2b821add0d3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.21666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "f5f48bec-3d2a-49de-9416-26cc75d34e32"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.23333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "b083cfc9-a439-4600-b336-b50ca08b68c4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.25,
|
||||
"value": {
|
||||
"__uuid__": "d04003f5-16c1-4510-898b-9148b76eb958"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.26666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "2159f038-bffa-480c-a2bd-c305868f2fd9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "1d3de292-7dd4-4e28-b1d2-23fc38318390"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3,
|
||||
"value": {
|
||||
"__uuid__": "3031ca7c-e1f7-4d14-b29e-5a7102cab245"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.31666666666666665,
|
||||
"value": {
|
||||
"__uuid__": "987e9d14-b6fc-46c7-93ed-8914e42bfa8b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "327db66e-2136-4d52-9727-399d60715a86"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.35,
|
||||
"value": {
|
||||
"__uuid__": "82ab2dcd-22e9-490f-96c4-4786018c91d0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.36666666666666664,
|
||||
"value": {
|
||||
"__uuid__": "36812959-85a6-40fb-9a38-1b4d871eba92"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.38333333333333336,
|
||||
"value": {
|
||||
"__uuid__": "2941d74c-7b9c-43dc-a5c4-45952220d9a2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4,
|
||||
"value": {
|
||||
"__uuid__": "4aed2032-25d5-42fd-983a-4473e2985a99"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "3db216c1-3362-4404-8db6-11615bfa6e64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.43333333333333335,
|
||||
"value": {
|
||||
"__uuid__": "2cf0cb17-cbb0-4d64-9c91-83639a363158"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.45,
|
||||
"value": {
|
||||
"__uuid__": "9c057e2c-1dc4-4c6c-adb7-85bf691cefb5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "49c07a7f-2ace-4e2b-ba4c-724aad12ec5c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.48333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "cec3c067-c958-4988-b113-2f10d7f4f5ea"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5,
|
||||
"value": {
|
||||
"__uuid__": "ad57f789-a25a-411c-b130-62a8ab16177f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "3c2a21a5-7c85-48f3-95ff-0d7a32e5e852"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "fe15eece-07a5-4d15-927b-af980aea7693"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.55,
|
||||
"value": {
|
||||
"__uuid__": "30ac103a-0f2b-45db-9442-461479beeb0d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "76272ec6-0721-4496-941b-5cb6a52b2c35"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
@@ -1,133 +0,0 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Atked1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.31666666666666665,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "6fd7cfcb-95b2-4197-a065-6bc48365f855"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.016666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "39aaeff6-3116-4e12-8ec4-9362a8a2fea2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.03333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "fb4e42e6-0fae-48d4-a600-217e01d43e57"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.05,
|
||||
"value": {
|
||||
"__uuid__": "2af606d7-4b3d-4355-95d1-a3ab673d2a2e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.06666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "be18e65b-346c-4efb-84cb-7f317fcaf8ac"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.08333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "d269af72-8b89-420c-ba9e-6892cda06e80"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.1,
|
||||
"value": {
|
||||
"__uuid__": "30539c9d-6dbb-4409-8562-6c24b12010c2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.11666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "96b655f9-9a90-4cb1-86ab-0be881ad8983"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.13333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "a86f8107-3d8d-426e-9a17-c856c1ab292a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.15,
|
||||
"value": {
|
||||
"__uuid__": "d7f99f14-9257-426a-9e90-a948e7ca8d23"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.16666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "809dcbcf-9edd-4b8b-8bc8-42394ce0a9c2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.18333333333333332,
|
||||
"value": {
|
||||
"__uuid__": "f3e74927-2eea-4306-ba0a-c89972ca88f1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2,
|
||||
"value": {
|
||||
"__uuid__": "af7a23f6-9b5c-4fe8-aa74-741f18500866"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.21666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "4cc6ecdb-3741-4a2e-87a0-a93739a38d37"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.23333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "f809b6d3-6f5b-4cf4-b148-5cf7fdf407a5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.25,
|
||||
"value": {
|
||||
"__uuid__": "b1c9e526-fe26-42a8-9257-7e5549847273"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.26666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "db62c862-7553-4f99-b758-8c4a4aec438a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "55f68905-bff7-48ea-b497-5077f49b2aca"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3,
|
||||
"value": {
|
||||
"__uuid__": "b01f45f9-c394-4706-aae1-d1d26a84f48a"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
@@ -1,432 +0,0 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Idle1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 1.1166666666666667,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 2,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "91bba749-7338-4bdc-b9a2-0450a183378f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.016666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "31b10e1f-7433-4c0d-b9a7-576adc0cdb51"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.03333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "80d4afc7-d21a-4eec-ab5e-ec833e1e905b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.05,
|
||||
"value": {
|
||||
"__uuid__": "d75070b5-3dbe-4d77-886e-8851f31e8ac8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.06666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "a30e880e-1ff1-434d-bdbc-a3a2e0de671b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.08333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "87cec524-adf7-48a6-af37-b1bae14b9317"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.1,
|
||||
"value": {
|
||||
"__uuid__": "d415a590-b4bf-4590-834a-b075705e063a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.11666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "e8b7eb99-0b52-4f01-8dd3-6c1ff23a8552"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.13333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "599c03fd-c5f1-45b1-9cd8-0164f8e82fe0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.15,
|
||||
"value": {
|
||||
"__uuid__": "0f71de95-9947-40da-929f-dd25bf43884e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.16666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "99980a57-3af2-4c23-84b8-87759ee79e10"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.18333333333333332,
|
||||
"value": {
|
||||
"__uuid__": "ab001dd3-587c-4a23-adbc-5f0d3eedccaf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2,
|
||||
"value": {
|
||||
"__uuid__": "9869ec96-1c78-482e-bff8-95d0b064d0f6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.21666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "0863d34e-0116-4134-b17e-32dae8f1589f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.23333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "10454569-56bb-4721-9a94-49015f5e11cc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.25,
|
||||
"value": {
|
||||
"__uuid__": "b13c9ee9-a497-43b3-9b54-83250bc62cc6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.26666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "80e898d9-10a9-4817-988c-7571744173e7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "0e4e927d-0c67-43a1-aade-a6b5ea3fe498"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3,
|
||||
"value": {
|
||||
"__uuid__": "6c327da9-60a2-4b63-89ca-05e7bb9b8c5f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.31666666666666665,
|
||||
"value": {
|
||||
"__uuid__": "9e71217f-0580-481e-b2ea-8886eb7cf492"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "ed851c4e-6a42-4643-8d50-1bac3d55b1ac"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.35,
|
||||
"value": {
|
||||
"__uuid__": "3a4738ba-bf3c-47cf-98f7-7e68aba0c96c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.36666666666666664,
|
||||
"value": {
|
||||
"__uuid__": "d035e717-c8ab-4cdc-b59f-c61c9e85990a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.38333333333333336,
|
||||
"value": {
|
||||
"__uuid__": "4bf6ea06-54bf-4c25-87f7-c7d9dca56fab"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4,
|
||||
"value": {
|
||||
"__uuid__": "a4b324b1-1191-43ee-ac76-a4536d1dbac7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "4e2ac5fa-1c68-4cbd-80e6-a94af579796d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.43333333333333335,
|
||||
"value": {
|
||||
"__uuid__": "64cd0353-429a-4a47-a6fc-b0f12e565e94"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.45,
|
||||
"value": {
|
||||
"__uuid__": "3fa0ae73-f8f8-455f-82c3-24a428379e95"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "a4679596-56d5-44f2-a349-7579ad7fbe33"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.48333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "3293d474-dfb3-412a-aca1-ce76f70a2181"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5,
|
||||
"value": {
|
||||
"__uuid__": "9794aec3-5e18-4df4-bae2-296f7c5ed935"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "4373d7b7-ea22-4ba2-a6df-c0672d4310a2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "89b6617e-2131-4bc6-840a-048af7944bb8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.55,
|
||||
"value": {
|
||||
"__uuid__": "9c267a7b-ab24-49b4-a2f3-26d885799f23"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "df3255ea-00af-47c2-9deb-4ccd27a62706"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5833333333333334,
|
||||
"value": {
|
||||
"__uuid__": "e15242c9-29ba-411a-a93f-dddad5613956"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6,
|
||||
"value": {
|
||||
"__uuid__": "ef3f8029-d5cc-4024-95ca-1f2aa062a0d5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "7b48f205-a1e8-4233-8c72-11ae9c0ccea7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "ffc69bce-fd84-42d8-b8c9-fe05e6c7fa03"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.65,
|
||||
"value": {
|
||||
"__uuid__": "81805795-ab34-47c1-ab45-57f54d28e72f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "adae26a6-7991-4583-966c-4364ba35474d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "ab51a779-10b7-4039-ac45-6ada002e702f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7,
|
||||
"value": {
|
||||
"__uuid__": "173d4746-0af5-40ae-a472-ba6406c700dc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "4054d644-4b5c-473d-ad2c-1c1eb06b01d7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "0f55009f-71dc-4e70-8152-7dbc2a16a17c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.75,
|
||||
"value": {
|
||||
"__uuid__": "d273f52f-4ec1-4ccf-8820-92879682213e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "37c2f336-a3c8-4b46-8031-d48c3f36c675"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "8cee57cb-5e79-4fe9-8368-745b38a37021"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8,
|
||||
"value": {
|
||||
"__uuid__": "4e67aa7d-d6a6-405b-99c4-ef5be609fdf4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "b0b7fc1a-f42a-4977-bfef-93841bdfa2f8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "352bbb78-d87c-425d-b39e-a401432f0070"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.85,
|
||||
"value": {
|
||||
"__uuid__": "9aaadf6a-808f-44f4-b7a8-392138851168"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "a319abd0-a689-400c-8f2a-94ccc70e50f9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "2efd4c0f-10c1-41be-81b5-40b3d10cb863"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9,
|
||||
"value": {
|
||||
"__uuid__": "8b94f28d-7da8-4e83-a9d6-46072b24a847"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9166666666666666,
|
||||
"value": {
|
||||
"__uuid__": "1f153a21-9a57-4bf7-a7bb-fa2a2e3b9484"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "2d3ad677-51b8-4d53-924c-dea3f66f0510"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.95,
|
||||
"value": {
|
||||
"__uuid__": "68aabf9d-5b21-4405-b92d-18a837895c37"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "cb893520-96b5-4ce4-a9dd-90ca4eac1882"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "498ee98f-7211-4495-99fe-662aee098217"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 1,
|
||||
"value": {
|
||||
"__uuid__": "da05be2e-e07f-4081-a99d-9c1b1459b862"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 1.0166666666666666,
|
||||
"value": {
|
||||
"__uuid__": "46e64686-1071-4db2-8f3d-4a0a00dc8e10"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 1.0333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "5a082e4d-d615-411f-880e-b03bda363cea"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 1.05,
|
||||
"value": {
|
||||
"__uuid__": "6d582b00-b973-4397-8866-32f531d4366e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 1.0666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "1de67f2c-e9ea-438d-8f30-b7c40159bc92"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 1.0833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "6e98330a-9709-44e1-8704-aa6430bd8236"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 1.1,
|
||||
"value": {
|
||||
"__uuid__": "b2557433-9168-4b78-a9ac-78b33633b1d8"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"frame": 0,
|
||||
"func": "",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"frame": 0,
|
||||
"func": "",
|
||||
"params": []
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 470 KiB After Width: | Height: | Size: 238 KiB |
@@ -1,385 +0,0 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Walking",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 1.0166666666666666,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 2,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "5a9af6ac-cccc-4964-90a1-7136468d64ae"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.016666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "e62f3718-263c-4a93-8405-55aca440180f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.03333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "700a3fef-00d2-437a-a323-cc79802d76f5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.05,
|
||||
"value": {
|
||||
"__uuid__": "bf8ce5ef-5171-45ab-97dd-8c9da2dbcd5a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.06666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "0894f61a-e4a0-458d-890e-aa3d60e4bf4f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.08333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "1995a986-6421-427c-92fe-4e3bae551e67"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.1,
|
||||
"value": {
|
||||
"__uuid__": "4ca1ce37-410d-4437-8b7a-498292e74bc6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.11666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "1e23a398-6051-4a69-a71d-7ea4909da77e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.13333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "ef18849a-0d4d-4bfe-a707-073958511ca6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.15,
|
||||
"value": {
|
||||
"__uuid__": "f217d368-9fc9-48cd-b635-059a7bc472a4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.16666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "b312cebf-3945-40c7-a367-3bc1d6689109"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.18333333333333332,
|
||||
"value": {
|
||||
"__uuid__": "476ddde6-8fd9-40cc-a789-0a08ebff5352"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2,
|
||||
"value": {
|
||||
"__uuid__": "b27f06dc-217d-4b68-a747-4c1d3c27151f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.21666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "83d15d82-f23d-40c4-b4ef-da4ce6964fc9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.23333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "7cc81715-c432-4ee2-bf67-a77a4dadcd89"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.25,
|
||||
"value": {
|
||||
"__uuid__": "463ae409-a045-40d1-ac44-1f2aac439065"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.26666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "84e68a5e-f23b-4570-ac4f-d85f1eba292c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "ce73c3ce-b543-4f9b-892c-27b76a9c84dc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3,
|
||||
"value": {
|
||||
"__uuid__": "25280250-fab5-464c-b26e-1a5f1733aa09"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.31666666666666665,
|
||||
"value": {
|
||||
"__uuid__": "abf595ad-a861-482c-8f5a-43f243516a5b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "238ce540-4c4a-41c0-967c-32218e3dfd3c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.35,
|
||||
"value": {
|
||||
"__uuid__": "0a3f1bbf-788b-4d78-b737-2ec5364fe5a4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.36666666666666664,
|
||||
"value": {
|
||||
"__uuid__": "c6397500-a2d9-4d68-b874-299bbc4a2173"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.38333333333333336,
|
||||
"value": {
|
||||
"__uuid__": "914aeb36-e7ab-4676-8016-8cf3a4fef6c6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4,
|
||||
"value": {
|
||||
"__uuid__": "1c7a050e-c52b-4402-911d-bc2d9ffed627"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "74eaaf1d-5de5-411d-86d4-839022712426"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.43333333333333335,
|
||||
"value": {
|
||||
"__uuid__": "b42fe407-2c81-4960-a697-0125815e1bc7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.45,
|
||||
"value": {
|
||||
"__uuid__": "9395f625-e627-4a0a-85cb-05f9b3a99d48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.4666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "5805ad62-293f-4d81-ad59-ac290ba2e2d3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.48333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "9c79bea6-dc45-4113-ace8-c7145cc889db"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5,
|
||||
"value": {
|
||||
"__uuid__": "cabc4d77-a49d-4c43-9144-01c5283fe206"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "0514d19b-a3ad-478d-99da-fa91190148b7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "57646810-7598-4723-b12f-5e15e8299aaa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.55,
|
||||
"value": {
|
||||
"__uuid__": "65e5cbd3-15f3-4526-a347-db55ac24bf51"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "1555d6f4-1bdf-4b64-99b2-bb13195257f4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5833333333333334,
|
||||
"value": {
|
||||
"__uuid__": "843e335d-fdb6-4a23-9949-3c81d977fb21"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6,
|
||||
"value": {
|
||||
"__uuid__": "781f66e7-dd7f-4ff5-a38e-9423762b4b52"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "ef990cae-899c-451f-91fd-7a42ac949534"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "a2df488a-e91b-46b0-8c25-2ba8551ab539"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.65,
|
||||
"value": {
|
||||
"__uuid__": "6650a6e0-6ddd-42ec-af68-1a1a032e19b5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "9a54c669-7f7d-41e4-8939-1853967d0dbf"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.6833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "da04432e-3845-465b-9ddf-ce2bd7c7174e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7,
|
||||
"value": {
|
||||
"__uuid__": "aa7a792d-22dc-4d28-8d27-52ddfcd8d147"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "ceb00ecc-d391-4b19-b9d6-e53792590c46"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "33b3fa05-9894-4393-b9ce-f819c5818bf3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.75,
|
||||
"value": {
|
||||
"__uuid__": "972cc5ec-ca1c-4127-8e21-f339df92a4fd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "3874c9de-2b47-4327-b4f8-c61d3896cefe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "4a6f08e6-7f96-4451-8f71-7bee8cd63cf2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8,
|
||||
"value": {
|
||||
"__uuid__": "256f3d2b-4cb9-4523-bf7a-c48380e249bb"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "4c40c070-9cba-44f9-acd6-2408f569f21c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "454bfff4-b8a1-4f90-b708-bbf295b99498"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.85,
|
||||
"value": {
|
||||
"__uuid__": "f0288374-f487-4870-b921-8baf851bb865"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "2fd06c6a-c3de-4b7f-bef7-1cba61c9909c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "d4d08680-1b77-4b44-92bd-be27c03747fa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9,
|
||||
"value": {
|
||||
"__uuid__": "5a85b0ce-7a4e-4d84-b4fb-089cdff45265"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9166666666666666,
|
||||
"value": {
|
||||
"__uuid__": "ac515982-6ac2-462c-b186-c4468b489e39"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "92571718-c75c-4c09-9aac-b1b043bb70a7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.95,
|
||||
"value": {
|
||||
"__uuid__": "a248383c-2cf6-487e-8941-a05f6c08bc60"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "c4f035dc-a01e-4b8e-a1b7-f4faf9515e99"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "a6f9c9b4-1129-4b6a-b4c3-2a3d425c746a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 1,
|
||||
"value": {
|
||||
"__uuid__": "d99d68fa-73c7-4057-98ec-9aa45864c050"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
7
frontend/assets/resources/animation/UltramanTiga.meta
Normal file
7
frontend/assets/resources/animation/UltramanTiga.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"ver": "1.0.1",
|
||||
"uuid": "d7459b4f-ba3f-4ead-9e0d-ec2387c9ee1f",
|
||||
"isSubpackage": false,
|
||||
"subpackageName": "",
|
||||
"subMetas": {}
|
||||
}
|
43
frontend/assets/resources/animation/UltramanTiga/Atk1.anim
Normal file
43
frontend/assets/resources/animation/UltramanTiga/Atk1.anim
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Atk1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.36666666666666664,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "a5607dff-7c39-47bc-8f27-86586f219387"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.11666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "bbcfe7c4-2341-4d58-b758-17920dbc4e0e"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "93e45cd6-652b-4732-8139-587170884ae4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.35,
|
||||
"value": {
|
||||
"__uuid__": "2c65c72d-34c0-424c-9a7e-2d961a68a1b6"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
25
frontend/assets/resources/animation/UltramanTiga/Atked1.anim
Normal file
25
frontend/assets/resources/animation/UltramanTiga/Atked1.anim
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Atked1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.016666666666666666,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "26166514-7b99-4e18-a3ef-515718a7597f"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
54
frontend/assets/resources/animation/UltramanTiga/Idle1.anim
Normal file
54
frontend/assets/resources/animation/UltramanTiga/Idle1.anim
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Idle1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.11666666666666667,
|
||||
"sample": 60,
|
||||
"speed": 0.3,
|
||||
"wrapMode": 2,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "3437907b-f662-4805-9723-78839fd930f5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.03333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "86de4c9c-202c-417b-abdb-7f5d4ae87045"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.06666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "2e8dd9ad-e227-405f-a22a-33079051e709"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.1,
|
||||
"value": {
|
||||
"__uuid__": "03d976f3-4abb-40e9-85b9-ff532009b7ea"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": [
|
||||
{
|
||||
"frame": 0,
|
||||
"func": "",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"frame": 0,
|
||||
"func": "",
|
||||
"params": []
|
||||
}
|
||||
]
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "InAirAtk1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.35,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0.016666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "58e0a91a-e6ce-482d-8668-713867301837"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2,
|
||||
"value": {
|
||||
"__uuid__": "aca5205f-5749-42fa-be3b-4f4888faf766"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "d0f43a74-3f79-42b6-9d1e-a6c17c0cd07f"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"ver": "2.1.0",
|
||||
"uuid": "8710591c-3f5e-4911-83e7-42cc18be6af9",
|
||||
"subMetas": {}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "InAirIdle1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.016666666666666666,
|
||||
"sample": 60,
|
||||
"speed": 0.1,
|
||||
"wrapMode": 2,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "ca385337-356e-49eb-8081-36b1505411a2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"ver": "2.1.0",
|
||||
"uuid": "43dbf141-be76-48c3-bdef-29233ccbe30d",
|
||||
"subMetas": {}
|
||||
}
|
@@ -0,0 +1,551 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>frames</key>
|
||||
<dict>
|
||||
<key>Atk1_1.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{176,366},{74,85}}</string>
|
||||
<key>textureRotated</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Atk1_2.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,375},{74,85}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Atk1_3.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{85,388},{74,85}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Atk1_4.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,449},{74,85}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Atk1_5.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,375},{74,85}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Atk1_6.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{74,85}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{85,462},{74,85}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Atked1_1.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{47,82}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{47,82}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{170,451},{47,82}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Atked1_2.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{47,82}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{47,82}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{170,498},{47,82}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Idle1_1.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{56,86}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{56,86}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{190,194},{56,86}}</string>
|
||||
<key>textureRotated</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Idle1_2.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{56,86}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{56,86}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{185,280},{56,86}}</string>
|
||||
<key>textureRotated</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Idle1_3.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{56,86}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{56,86}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{90,332},{56,86}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Idle1_4.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{56,86}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{56,86}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{185,280},{56,86}}</string>
|
||||
<key>textureRotated</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>InAirAtk1_1.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{104,43},{63,95}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirAtk1_2.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,86},{63,95}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirAtk1_3.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{95,106},{63,95}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirAtk1_4.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,149},{63,95}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirAtk1_5.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{104,43},{63,95}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirAtk1_6.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{95,169},{63,95}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirAtk1_7.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{63,95}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,212},{63,95}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirAtked1_1.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{47,82}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{47,82}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{170,451},{47,82}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirAtked1_2.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{47,82}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{47,82}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{170,498},{47,82}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirIdle1_1.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,0},{43,104}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirIdle1_2.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{104,0},{43,104}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirIdle1_3.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{208,0},{43,104}}</string>
|
||||
<key>textureRotated</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>InAirIdle1_4.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{104,0},{43,104}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirIdle1_5.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,0},{43,104}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>InAirIdle1_6.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{43,104}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,43},{43,104}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Walking_1.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{199,104},{50,90}}</string>
|
||||
<key>textureRotated</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>Walking_2.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{95,232},{50,90}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Walking_3.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,275},{50,90}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Walking_4.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{90,282},{50,90}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Walking_5.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,325},{50,90}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Walking_6.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{90,282},{50,90}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Walking_7.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{0,275},{50,90}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Walking_8.png</key>
|
||||
<dict>
|
||||
<key>aliases</key>
|
||||
<array/>
|
||||
<key>spriteOffset</key>
|
||||
<string>{0,0}</string>
|
||||
<key>spriteSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>spriteSourceSize</key>
|
||||
<string>{50,90}</string>
|
||||
<key>textureRect</key>
|
||||
<string>{{95,232},{50,90}}</string>
|
||||
<key>textureRotated</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>metadata</key>
|
||||
<dict>
|
||||
<key>format</key>
|
||||
<integer>3</integer>
|
||||
<key>pixelFormat</key>
|
||||
<string>RGBA8888</string>
|
||||
<key>premultiplyAlpha</key>
|
||||
<false/>
|
||||
<key>realTextureFileName</key>
|
||||
<string>UltramanTiga.png</string>
|
||||
<key>size</key>
|
||||
<string>{252,545}</string>
|
||||
<key>smartupdate</key>
|
||||
<string>$TexturePacker:SmartUpdate:4a857ca23ea86a140850bef35b0258da:88d012415ccd7dd313108f39b071523a:1c886ab62fdbd8d1a0c538b1b57b3521$</string>
|
||||
<key>textureFileName</key>
|
||||
<string>UltramanTiga.png</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
@@ -0,0 +1,782 @@
|
||||
{
|
||||
"ver": "1.2.4",
|
||||
"uuid": "5d522f7b-359b-4f38-ac35-55fdbee56cae",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"size": {
|
||||
"width": 252,
|
||||
"height": 545
|
||||
},
|
||||
"type": "Texture Packer",
|
||||
"subMetas": {
|
||||
"Atk1_1.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "8e9ca384-97ec-4e75-a285-6d74d64a3c3c",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 176,
|
||||
"trimY": 366,
|
||||
"width": 74,
|
||||
"height": 85,
|
||||
"rawWidth": 74,
|
||||
"rawHeight": 85,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Atk1_2.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "a5607dff-7c39-47bc-8f27-86586f219387",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 375,
|
||||
"width": 74,
|
||||
"height": 85,
|
||||
"rawWidth": 74,
|
||||
"rawHeight": 85,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Atk1_3.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "bbcfe7c4-2341-4d58-b758-17920dbc4e0e",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 85,
|
||||
"trimY": 388,
|
||||
"width": 74,
|
||||
"height": 85,
|
||||
"rawWidth": 74,
|
||||
"rawHeight": 85,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Atk1_4.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "93e45cd6-652b-4732-8139-587170884ae4",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 449,
|
||||
"width": 74,
|
||||
"height": 85,
|
||||
"rawWidth": 74,
|
||||
"rawHeight": 85,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Atk1_5.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "2c65c72d-34c0-424c-9a7e-2d961a68a1b6",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 375,
|
||||
"width": 74,
|
||||
"height": 85,
|
||||
"rawWidth": 74,
|
||||
"rawHeight": 85,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Atk1_6.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "d977ee77-cde3-47be-b63d-82a5b116b69a",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 85,
|
||||
"trimY": 462,
|
||||
"width": 74,
|
||||
"height": 85,
|
||||
"rawWidth": 74,
|
||||
"rawHeight": 85,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Atked1_1.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "26166514-7b99-4e18-a3ef-515718a7597f",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 170,
|
||||
"trimY": 451,
|
||||
"width": 47,
|
||||
"height": 82,
|
||||
"rawWidth": 47,
|
||||
"rawHeight": 82,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Atked1_2.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "98d06843-f140-4d6a-9aa6-0949a1690dca",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 170,
|
||||
"trimY": 498,
|
||||
"width": 47,
|
||||
"height": 82,
|
||||
"rawWidth": 47,
|
||||
"rawHeight": 82,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Idle1_1.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "3437907b-f662-4805-9723-78839fd930f5",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 190,
|
||||
"trimY": 194,
|
||||
"width": 56,
|
||||
"height": 86,
|
||||
"rawWidth": 56,
|
||||
"rawHeight": 86,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Idle1_2.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "86de4c9c-202c-417b-abdb-7f5d4ae87045",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 185,
|
||||
"trimY": 280,
|
||||
"width": 56,
|
||||
"height": 86,
|
||||
"rawWidth": 56,
|
||||
"rawHeight": 86,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Idle1_3.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "2e8dd9ad-e227-405f-a22a-33079051e709",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 90,
|
||||
"trimY": 332,
|
||||
"width": 56,
|
||||
"height": 86,
|
||||
"rawWidth": 56,
|
||||
"rawHeight": 86,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Idle1_4.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "03d976f3-4abb-40e9-85b9-ff532009b7ea",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 185,
|
||||
"trimY": 280,
|
||||
"width": 56,
|
||||
"height": 86,
|
||||
"rawWidth": 56,
|
||||
"rawHeight": 86,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtk1_1.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "d0f43a74-3f79-42b6-9d1e-a6c17c0cd07f",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 104,
|
||||
"trimY": 43,
|
||||
"width": 63,
|
||||
"height": 95,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 95,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtk1_2.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "58e0a91a-e6ce-482d-8668-713867301837",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 86,
|
||||
"width": 63,
|
||||
"height": 95,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 95,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtk1_3.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "aca5205f-5749-42fa-be3b-4f4888faf766",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 95,
|
||||
"trimY": 106,
|
||||
"width": 63,
|
||||
"height": 95,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 95,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtk1_4.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "4b08f81b-4412-4d98-aa39-11fc140b00a2",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 149,
|
||||
"width": 63,
|
||||
"height": 95,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 95,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtk1_5.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "618142b5-4eb9-4b06-948c-9346381af4b4",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 104,
|
||||
"trimY": 43,
|
||||
"width": 63,
|
||||
"height": 95,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 95,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtk1_6.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "caf2aac4-bb75-41f2-8deb-334b20b36cc2",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 95,
|
||||
"trimY": 169,
|
||||
"width": 63,
|
||||
"height": 95,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 95,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtk1_7.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "b5368d17-52da-4a4b-82e9-7808a973a16d",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 212,
|
||||
"width": 63,
|
||||
"height": 95,
|
||||
"rawWidth": 63,
|
||||
"rawHeight": 95,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtked1_1.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "e643e1e4-6a6a-4c73-995c-d49e3c4c750c",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 170,
|
||||
"trimY": 451,
|
||||
"width": 47,
|
||||
"height": 82,
|
||||
"rawWidth": 47,
|
||||
"rawHeight": 82,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirAtked1_2.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "982e48da-cac3-4c1e-96f6-3c659c43ecdd",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 170,
|
||||
"trimY": 498,
|
||||
"width": 47,
|
||||
"height": 82,
|
||||
"rawWidth": 47,
|
||||
"rawHeight": 82,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirIdle1_1.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "55dc7736-f0bc-46b8-9705-efcdb19ddb85",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 43,
|
||||
"height": 104,
|
||||
"rawWidth": 43,
|
||||
"rawHeight": 104,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirIdle1_2.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "5a18d76d-6e98-43c9-8f0a-99111256e1d5",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 104,
|
||||
"trimY": 0,
|
||||
"width": 43,
|
||||
"height": 104,
|
||||
"rawWidth": 43,
|
||||
"rawHeight": 104,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirIdle1_3.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "7c0bb61d-15f8-4d41-9225-2a1f339b80b1",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 208,
|
||||
"trimY": 0,
|
||||
"width": 43,
|
||||
"height": 104,
|
||||
"rawWidth": 43,
|
||||
"rawHeight": 104,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirIdle1_4.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "7cb60116-3f96-44bb-9bf7-6fbfc2ca9772",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 104,
|
||||
"trimY": 0,
|
||||
"width": 43,
|
||||
"height": 104,
|
||||
"rawWidth": 43,
|
||||
"rawHeight": 104,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirIdle1_5.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "e8d32f3e-0b66-4b35-b4ed-7823a047cc88",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 43,
|
||||
"height": 104,
|
||||
"rawWidth": 43,
|
||||
"rawHeight": 104,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"InAirIdle1_6.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "ca385337-356e-49eb-8081-36b1505411a2",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 43,
|
||||
"width": 43,
|
||||
"height": 104,
|
||||
"rawWidth": 43,
|
||||
"rawHeight": 104,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Walking_1.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "b706e9a2-827e-42bc-9920-c0e644eb8a75",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 199,
|
||||
"trimY": 104,
|
||||
"width": 50,
|
||||
"height": 90,
|
||||
"rawWidth": 50,
|
||||
"rawHeight": 90,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Walking_2.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "f9141513-f9b3-4fc8-8900-b793294c82c6",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 95,
|
||||
"trimY": 232,
|
||||
"width": 50,
|
||||
"height": 90,
|
||||
"rawWidth": 50,
|
||||
"rawHeight": 90,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Walking_3.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "6e12b8d0-488c-4885-9b4a-712af055be78",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 275,
|
||||
"width": 50,
|
||||
"height": 90,
|
||||
"rawWidth": 50,
|
||||
"rawHeight": 90,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Walking_4.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "a4be80d2-4593-4d92-994b-de7fc66642f0",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 90,
|
||||
"trimY": 282,
|
||||
"width": 50,
|
||||
"height": 90,
|
||||
"rawWidth": 50,
|
||||
"rawHeight": 90,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Walking_5.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "bc355af2-caa1-4458-be7f-f84184d27c11",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 325,
|
||||
"width": 50,
|
||||
"height": 90,
|
||||
"rawWidth": 50,
|
||||
"rawHeight": 90,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Walking_6.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "4fa095aa-f08d-4baa-84c9-10e8eac6ea01",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 90,
|
||||
"trimY": 282,
|
||||
"width": 50,
|
||||
"height": 90,
|
||||
"rawWidth": 50,
|
||||
"rawHeight": 90,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Walking_7.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "01424fa9-4b4b-472a-ae90-923d0877fb66",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 275,
|
||||
"width": 50,
|
||||
"height": 90,
|
||||
"rawWidth": 50,
|
||||
"rawHeight": 90,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
},
|
||||
"Walking_8.png": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "5d8fe180-61eb-448d-bbcf-100d1763ebc8",
|
||||
"rawTextureUuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": true,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 95,
|
||||
"trimY": 232,
|
||||
"width": 50,
|
||||
"height": 90,
|
||||
"rawWidth": 50,
|
||||
"rawHeight": 90,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"spriteType": "normal",
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ver": "2.3.3",
|
||||
"uuid": "b4ea3971-8f28-4cc7-96a4-83f10dce229f",
|
||||
"type": "raw",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"platformSettings": {},
|
||||
"subMetas": {}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Walking",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.36666666666666664,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 2,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "b706e9a2-827e-42bc-9920-c0e644eb8a75"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.05,
|
||||
"value": {
|
||||
"__uuid__": "f9141513-f9b3-4fc8-8900-b793294c82c6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.1,
|
||||
"value": {
|
||||
"__uuid__": "6e12b8d0-488c-4885-9b4a-712af055be78"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.16666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "a4be80d2-4593-4d92-994b-de7fc66642f0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.21666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "bc355af2-caa1-4458-be7f-f84184d27c11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.26666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "4fa095aa-f08d-4baa-84c9-10e8eac6ea01"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.31666666666666665,
|
||||
"value": {
|
||||
"__uuid__": "01424fa9-4b4b-472a-ae90-923d0877fb66"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.35,
|
||||
"value": {
|
||||
"__uuid__": "5d8fe180-61eb-448d-bbcf-100d1763ebc8"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
@@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.2" tiledversion="1.2.3" orientation="orthogonal" renderorder="right-down" width="128" height="128" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="39">
|
||||
<map version="1.2" tiledversion="1.2.3" orientation="orthogonal" renderorder="right-down" width="128" height="128" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="87">
|
||||
<tileset firstgid="1" source="tiles0.tsx"/>
|
||||
<tileset firstgid="65" source="tiles1.tsx"/>
|
||||
<tileset firstgid="129" source="tiles2.tsx"/>
|
||||
<layer id="2" name="Ground" width="128" height="128">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJzt2q1u22AYhuEo1UhBtYFWKh/bmRRMRYNFPZPxwcKi7jznSInkWk7teG5ex88FLhQD570d5/PP1WazuQIAAAAAAAAAAAAAAAAAgAmu96r3g/N5bjn0fw5U3aGy/3bv0P+p8XDEdoX0f9//GP3Xp93/YaD/9QJa6f95/fvov26773671zeb7jmhupX+5+2fQH/9qztU9v8yQXUz/fXXX3/9a/ovgf7666+//vrrf1n9/4zc7tue/uvq/9Z4PfLZ7vnz38ZP/cv7T53p4Z7i7/+kv/7667/bl/sO/dff/77T3+9ff/3r+38dMGf/Nv1r+w917+v/0vh1okN/67/l9B/b/nFj/X8pxvYf236r/0UZ6t/X+Efj5kj7bv+uxxPpX9e/r/1NS7f7Z/S/a3zXfzH9Pzrvt/vPTf/l9p+yRjyV/ufvP+YY6M5yzr5D5uy/XUCLJfafa8YfmdJe//X0r6Z/9jGgv/7661/doqp/9fyrpV//Vc+/mv7Z9M+mfzb9s+mfTf9s+mfTP5v+2fTPpn82/bPpn03/bPpn0z+b/tn0z6Z/Nv2z6Z/N+9/Z9M+mfzb//9n0z6Z/Nv2z6Z9N/2z6Z9M/m/7Z0vtT3wEAAAAAAAAAAAAAAAA4v39IY4NC
|
||||
eJzt3DFq3EAUgOFlTRoXJiEkkNQpAr5EyuDKVdKl8k1yh9wg94wMK1DEaqXVjvRGel/xgXFh7PnfSBqx+O5wONwBAAAAAAAAAAAAAAAAAMAM9yfRvwfreelo+78kFN0hsv/xpO3/q/E04LhD+v/ff4j++9Pt/zTS/76CVvov1/8c/fft9W//cHJubfrXhOhW+q/bPwP99Y/uENn//QzRzfSP7b+nGdBf/+gOW+xfE/1z9rf/c/cvMQP6b5f9r7/+efuXmAH9y69t+07x942W3vv666//Nvp/OtE/T/9u7+7X+uuvf1z/tyNK9u/SP7b/WPdz/f80flyp7e/5r57+U9s/Hzz/b8XU/lPbH/XflLH+5xo/Nh4G2vf79z1fSf+4/ufaP3T0uy/R/2Pji/7V9L903e/2L03/evvPeUa8lv7r958yA/21LNl3TMn+xwpa1Ni/1BpfMqe9/vvpf82MLPGz9d/GDCxF/9wzoL/+mftHr3+07Oe/6PWPpn9u+uemf27656Z/bvrnpn9u+uemf27656Z/bvrnpn9u+uemf276z7eHzwnpX0//dyPeDNB/H/3t/7r77/Fzovrnpv+6hu7tkf2PFbSouf/Pk/71vv1+9B7Wf9n+l+75+m/XlP5DZ65XY+e1yOv6Nf2jO9Tav+389Qa3ns/1j93/tyrxjkb/5fqXfp821L/WGcjef63936rtPZH+6/ZvZyDq/73oP96/5PP8pfPDEP3r2f+3zsGc/mveJ/SfZu4cfJ7Z/2/ju/7V9J+r6f9tbv/WknOQvT/xHQAAAAAAAAAAAAAAAID1/QPUuKyX
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup id="1" name="PlayerStartingPos">
|
||||
<object id="135" x="1090" y="833.667">
|
||||
<object id="135" x="882" y="1437.33">
|
||||
<point/>
|
||||
</object>
|
||||
<object id="137" x="1215" y="830.5">
|
||||
<object id="137" x="955.333" y="1434.67">
|
||||
<point/>
|
||||
</object>
|
||||
</objectgroup>
|
||||
@@ -20,149 +20,112 @@
|
||||
<properties>
|
||||
<property name="type" value="barrier_and_shelter"/>
|
||||
</properties>
|
||||
<object id="8" x="648.242" y="480.606">
|
||||
<object id="54" x="656" y="1504" width="80" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 0,18.6667 1041.33,21.3333 1041.33,-1.33333"/>
|
||||
</object>
|
||||
<object id="9" x="650.667" y="1604.67">
|
||||
<object id="55" x="735" y="1552" width="113.5" height="15.5">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 0,18.6667 1041.33,21.3333 1041.33,-1.33333"/>
|
||||
</object>
|
||||
<object id="10" x="634.485" y="505.455">
|
||||
<object id="57" x="768" y="1472" width="32" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 4,1110 24,1110 24,-8"/>
|
||||
</object>
|
||||
<object id="11" x="1677.64" y="501.333">
|
||||
<object id="58" x="1040" y="1536" width="80" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 4,1110 24,1110 24,-8"/>
|
||||
</object>
|
||||
<object id="14" x="688.667" y="464">
|
||||
<object id="59" x="1040" y="1568" width="224" height="48">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -0.666667,78 33.3333,78 32,-0.666667"/>
|
||||
</object>
|
||||
<object id="15" x="833.333" y="495.333">
|
||||
<object id="60" x="1216" y="1344" width="224" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -112,1.33333 -111.333,44.6667 -1.33333,44.6667"/>
|
||||
</object>
|
||||
<object id="17" x="832" y="574">
|
||||
<object id="62" x="1040" y="1552" width="208" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -67.3333,0 -67.3333,-76.6667 0.666667,-76"/>
|
||||
</object>
|
||||
<object id="18" x="865.333" y="606.667">
|
||||
<object id="63" x="1040" y="1504" width="48" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -210,-0.666667 -210,143.333 0,142.667"/>
|
||||
</object>
|
||||
<object id="19" x="754.667" y="1055.33">
|
||||
<object id="64" x="1040" y="1520" width="64" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="-2,1.33333 -100,0.666667 -97.3333,-454 -9.33333,-451.333"/>
|
||||
</object>
|
||||
<object id="20" x="769.333" y="747.333">
|
||||
<object id="65" x="1040" y="1488" width="32" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -115.333,0.666667 -114.667,160.667 -2,162"/>
|
||||
</object>
|
||||
<object id="21" x="768" y="960.667">
|
||||
<object id="66" x="1040" y="1472" width="16" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -18,0.666667 -18.6667,95.3333 0,95.3333"/>
|
||||
</object>
|
||||
<object id="23" x="786" y="1058.67">
|
||||
<object id="67" x="784" y="1456" width="256" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 0,-52.6667 -20,-52 -19.3333,-1.33333"/>
|
||||
</object>
|
||||
<object id="24" x="1118.67" y="749.333">
|
||||
<object id="73" x="783.75" y="1567.5" width="96.25" height="15.5">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -0.666667,-94 -254,-93.3333 -256.667,1.33333"/>
|
||||
</object>
|
||||
<object id="25" x="1168" y="975.333">
|
||||
<object id="74" x="815.75" y="1583.75" width="96.25" height="15.5">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 0,16.6667 224.667,17.3333 225.333,-2"/>
|
||||
</object>
|
||||
<object id="28" x="1394.67" y="958">
|
||||
<object id="79" x="640" y="1616" width="1056" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -210.667,1.33333 -210.667,17.3333 -2,18"/>
|
||||
</object>
|
||||
<object id="29" x="1119" y="654.5">
|
||||
<object id="80" x="1296" y="1600">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 0,63.5 272.5,65 273,-1"/>
|
||||
<polyline points="0,0 -32.5,0 -32.25,-16.5 -16.5,-16.5"/>
|
||||
</object>
|
||||
<object id="30" x="1136.5" y="717.5">
|
||||
<object id="82" x="1328" y="1616">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -0.5,17 255,17.5 255,1.5"/>
|
||||
<polyline points="0,0 -64.5,0 -64.0038,-15.75 -16.4734,-15.75"/>
|
||||
</object>
|
||||
<object id="31" x="1152" y="735.667">
|
||||
<object id="83" x="640" y="480" width="1056" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 0,15 80.3333,15.3333 80.3333,-2"/>
|
||||
</object>
|
||||
<object id="32" x="1280.67" y="734.667">
|
||||
<object id="84" x="640" y="480" width="16" height="1152">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -0.666667,64.3333 48,65 48,0"/>
|
||||
</object>
|
||||
<object id="34" x="1329" y="783">
|
||||
<object id="85" x="1680" y="480" width="16" height="1152">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 63.3333,0.333333 63,-48.3333 -0.666667,-48.3333"/>
|
||||
</object>
|
||||
<object id="35" x="1296.67" y="799">
|
||||
<object id="86" x="1104" y="1408" width="96" height="16">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -0.666667,31.3333 31.3333,31.6667 31.3333,-0.333333"/>
|
||||
</object>
|
||||
<object id="36" x="1280" y="848">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 0.333333,62 112,63 111.667,-1.33333"/>
|
||||
</object>
|
||||
<object id="37" x="1392.33" y="911.333">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 -81.3333,-0.666667 -81,45 -0.666667,46.3333"/>
|
||||
</object>
|
||||
<object id="38" x="1344.33" y="800.667">
|
||||
<properties>
|
||||
<property name="boundary_type" value="barrier"/>
|
||||
</properties>
|
||||
<polyline points="0,0 0,46.3333 47,46.3333 47,-1"/>
|
||||
</object>
|
||||
</objectgroup>
|
||||
</map>
|
||||
|
@@ -9,28 +9,32 @@ message PlayerDownsync {
|
||||
int32 virtualGridX = 2;
|
||||
int32 virtualGridY = 3;
|
||||
int32 dirX = 4;
|
||||
int32 dirY = 5;
|
||||
int32 speed = 6; // in terms of virtual grid units
|
||||
int32 battleState = 7;
|
||||
int32 joinIndex = 8;
|
||||
double colliderRadius = 9;
|
||||
bool removed = 10;
|
||||
int32 score = 11;
|
||||
int32 lastMoveGmtMillis = 12;
|
||||
int32 framesToRecover = 13;
|
||||
int32 hp = 14;
|
||||
int32 maxHp = 15;
|
||||
int32 characterState = 16;
|
||||
int32 dirY = 5; // "dirX" and "dirY" determines character facing
|
||||
int32 velX = 6;
|
||||
int32 velY = 7; // "velX" and "velY" is used to record the accumulated effect by accelerations (including gravity)
|
||||
int32 speed = 8; // this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY"
|
||||
int32 battleState = 9;
|
||||
int32 joinIndex = 10;
|
||||
double colliderRadius = 11;
|
||||
bool removed = 12;
|
||||
int32 score = 13;
|
||||
int32 lastMoveGmtMillis = 14;
|
||||
int32 framesToRecover = 15;
|
||||
int32 hp = 16;
|
||||
int32 maxHp = 17;
|
||||
int32 characterState = 18;
|
||||
bool inAir = 19; // by design a standalone field only inferred by the collision result of "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" instead of "characterState", because we need check the transition for "characterState" from this field, i.e. "inAir (prev -> curr)"
|
||||
|
||||
string name = 17;
|
||||
string displayName = 18;
|
||||
string avatar = 19;
|
||||
string name = 20;
|
||||
string displayName = 21;
|
||||
string avatar = 22;
|
||||
}
|
||||
|
||||
message InputFrameDecoded {
|
||||
int32 dx = 1;
|
||||
int32 dy = 2;
|
||||
int32 btnALevel = 3;
|
||||
int32 btnBLevel = 4;
|
||||
}
|
||||
|
||||
message InputFrameUpsync {
|
||||
@@ -72,6 +76,7 @@ message InputsBufferSnapshot {
|
||||
int32 refRenderFrameId = 1;
|
||||
uint64 unconfirmedMask = 2;
|
||||
repeated InputFrameDownsync toSendInputFrameDownsyncs = 3;
|
||||
bool shouldForceResync = 4;
|
||||
}
|
||||
|
||||
message MeleeBullet {
|
||||
@@ -133,6 +138,12 @@ message BattleColliderInfo {
|
||||
int32 renderCacheSize = 26;
|
||||
|
||||
map<int32, MeleeBullet> meleeSkillConfig = 27; // skillId -> skill
|
||||
|
||||
double snapIntoPlatformOverlap = 28;
|
||||
double snapIntoPlatformThreshold = 29;
|
||||
int32 jumpingInitVelY = 30;
|
||||
int32 gravityX = 31;
|
||||
int32 gravityY = 32;
|
||||
}
|
||||
|
||||
message RoomDownsyncFrame {
|
||||
@@ -141,4 +152,5 @@ message RoomDownsyncFrame {
|
||||
int64 countdownNanos = 3;
|
||||
repeated MeleeBullet meleeBullets = 4; // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise
|
||||
uint64 backendUnconfirmedMask = 5; // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
|
||||
bool shouldForceResync = 6;
|
||||
}
|
||||
|
@@ -33,14 +33,14 @@
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 20
|
||||
"__id__": 23
|
||||
},
|
||||
{
|
||||
"__id__": 21
|
||||
"__id__": 24
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 22
|
||||
"__id__": 25
|
||||
},
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
@@ -65,7 +65,7 @@
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
0,
|
||||
3,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -97,7 +97,7 @@
|
||||
"__id__": 1
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_active": false,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 3
|
||||
@@ -116,8 +116,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 46.68,
|
||||
"height": 27.72
|
||||
"width": 28.01,
|
||||
"height": 15.12
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -128,8 +128,8 @@
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
-5,
|
||||
50,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -169,8 +169,8 @@
|
||||
"_useOriginalSize": false,
|
||||
"_string": "(0, 0)",
|
||||
"_N$string": "(0, 0)",
|
||||
"_fontSize": 20,
|
||||
"_lineHeight": 22,
|
||||
"_fontSize": 12,
|
||||
"_lineHeight": 12,
|
||||
"_enableWrapText": true,
|
||||
"_N$file": null,
|
||||
"_isSystemFontUsed": true,
|
||||
@@ -277,7 +277,7 @@
|
||||
"__uuid__": "472df5d3-35e7-4184-9e6c-7f41bee65ee3"
|
||||
},
|
||||
"_texture": null,
|
||||
"_stopped": false,
|
||||
"_stopped": true,
|
||||
"playOnLoad": true,
|
||||
"autoRemoveOnFinish": false,
|
||||
"totalParticles": 200,
|
||||
@@ -395,8 +395,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 76,
|
||||
"height": 84
|
||||
"width": 24,
|
||||
"height": 24
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -408,7 +408,7 @@
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
3,
|
||||
182,
|
||||
60,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -451,7 +451,7 @@
|
||||
"__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821"
|
||||
},
|
||||
"_type": 0,
|
||||
"_sizeMode": 1,
|
||||
"_sizeMode": 0,
|
||||
"_fillType": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -490,12 +490,15 @@
|
||||
},
|
||||
{
|
||||
"__id__": 15
|
||||
},
|
||||
{
|
||||
"__id__": 18
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [],
|
||||
"_prefab": {
|
||||
"__id__": 19
|
||||
"__id__": 22
|
||||
},
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
@@ -584,7 +587,7 @@
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
0,
|
||||
0,
|
||||
-24,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -671,13 +674,128 @@
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 16
|
||||
},
|
||||
{
|
||||
"__id__": 17
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 18
|
||||
"__id__": 17
|
||||
},
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 0,
|
||||
"height": 0
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
0,
|
||||
-24,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "dragonBones.ArmatureDisplay",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 15
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
{
|
||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||
}
|
||||
],
|
||||
"_armatureName": "SoldierFireGhost",
|
||||
"_animationName": "Idle1",
|
||||
"_preCacheMode": 0,
|
||||
"_cacheMode": 0,
|
||||
"playTimes": -1,
|
||||
"premultipliedAlpha": false,
|
||||
"_armatureKey": "36230012-8df3-4e85-afad-76ec47d0e4d7#4a9187d5-a9ad-4464-a03c-d2f3cc277051",
|
||||
"_accTime": 0,
|
||||
"_playCount": 0,
|
||||
"_frameCache": null,
|
||||
"_curFrame": null,
|
||||
"_playing": false,
|
||||
"_armatureCache": null,
|
||||
"_N$dragonAsset": {
|
||||
"__uuid__": "36230012-8df3-4e85-afad-76ec47d0e4d7"
|
||||
},
|
||||
"_N$dragonAtlasAsset": {
|
||||
"__uuid__": "4a9187d5-a9ad-4464-a03c-d2f3cc277051"
|
||||
},
|
||||
"_N$_defaultArmatureIndex": 0,
|
||||
"_N$_animationIndex": 8,
|
||||
"_N$_defaultCacheMode": 0,
|
||||
"_N$timeScale": 1,
|
||||
"_N$debugBones": false,
|
||||
"_N$enableBatch": false,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
|
||||
},
|
||||
"fileId": "3b2LJFABVL7ozO2U81FC4U",
|
||||
"sync": false
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "UltramanTiga",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 11
|
||||
},
|
||||
"_children": [],
|
||||
"_active": false,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 19
|
||||
},
|
||||
{
|
||||
"__id__": 20
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 21
|
||||
},
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
@@ -708,8 +826,8 @@
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0.7,
|
||||
0.7,
|
||||
1
|
||||
]
|
||||
},
|
||||
@@ -731,7 +849,7 @@
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 15
|
||||
"__id__": 18
|
||||
},
|
||||
"_enabled": true,
|
||||
"_defaultClip": null,
|
||||
@@ -745,6 +863,15 @@
|
||||
{
|
||||
"__uuid__": "c738236a-0702-45f8-aa38-99457b051997"
|
||||
},
|
||||
{
|
||||
"__uuid__": "c69bcceb-d7d1-4e33-9623-e2a374a0a6b6"
|
||||
},
|
||||
{
|
||||
"__uuid__": "43dbf141-be76-48c3-bdef-29233ccbe30d"
|
||||
},
|
||||
{
|
||||
"__uuid__": "8710591c-3f5e-4911-83e7-42cc18be6af9"
|
||||
},
|
||||
{
|
||||
"__uuid__": "c69bcceb-d7d1-4e33-9623-e2a374a0a6b6"
|
||||
}
|
||||
@@ -757,7 +884,7 @@
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 15
|
||||
"__id__": 18
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
@@ -780,7 +907,7 @@
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_atlas": {
|
||||
"__uuid__": "145769c8-a259-42bc-8cce-6e035f493c70"
|
||||
"__uuid__": "5d522f7b-359b-4f38-ac35-55fdbee56cae"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
@@ -792,7 +919,7 @@
|
||||
"asset": {
|
||||
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
|
||||
},
|
||||
"fileId": "4c+Ci1MGpP47N3wJ0ujhEm",
|
||||
"fileId": "17JdhftghBYr81MfV9i6cy",
|
||||
"sync": false
|
||||
},
|
||||
{
|
||||
|
@@ -1,151 +0,0 @@
|
||||
[
|
||||
{
|
||||
"__type__": "cc.Prefab",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"data": {
|
||||
"__id__": 1
|
||||
},
|
||||
"optimizationPolicy": 0,
|
||||
"asyncLoadAssets": false,
|
||||
"readonly": false
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "SoldierFireGhost",
|
||||
"_objFlags": 0,
|
||||
"_parent": null,
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 2
|
||||
},
|
||||
{
|
||||
"__id__": 3
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 4
|
||||
},
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 1425,
|
||||
"height": 1024
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Animation",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"_defaultClip": null,
|
||||
"_clips": [
|
||||
{
|
||||
"__uuid__": "252b321f-81f4-485c-85bd-ea44d298cb76"
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
"__uuid__": "c738236a-0702-45f8-aa38-99457b051997"
|
||||
},
|
||||
{
|
||||
"__uuid__": "f51bb583-0010-48f3-a6a1-451a78ac2d65"
|
||||
},
|
||||
{
|
||||
"__uuid__": "c69bcceb-d7d1-4e33-9623-e2a374a0a6b6"
|
||||
}
|
||||
],
|
||||
"playOnLoad": false,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
{
|
||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||
}
|
||||
],
|
||||
"_srcBlendFactor": 770,
|
||||
"_dstBlendFactor": 771,
|
||||
"_spriteFrame": null,
|
||||
"_type": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillType": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_atlas": {
|
||||
"__uuid__": "145769c8-a259-42bc-8cce-6e035f493c70"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "44k8wsxglPsJSrMCX58Yve",
|
||||
"sync": false
|
||||
}
|
||||
]
|
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"ver": "1.2.5",
|
||||
"uuid": "e3fc2487-17d1-4ff9-ae1f-38e974509077",
|
||||
"optimizationPolicy": "AUTO",
|
||||
"asyncLoadAssets": false,
|
||||
"readonly": false,
|
||||
"subMetas": {}
|
||||
}
|
@@ -78,19 +78,19 @@
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 29
|
||||
"__id__": 37
|
||||
},
|
||||
{
|
||||
"__id__": 30
|
||||
"__id__": 38
|
||||
},
|
||||
{
|
||||
"__id__": 31
|
||||
"__id__": 39
|
||||
},
|
||||
{
|
||||
"__id__": 32
|
||||
"__id__": 40
|
||||
},
|
||||
{
|
||||
"__id__": 33
|
||||
"__id__": 41
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -158,7 +158,7 @@
|
||||
"__id__": 5
|
||||
},
|
||||
{
|
||||
"__id__": 28
|
||||
"__id__": 36
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -279,13 +279,13 @@
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 22
|
||||
"__id__": 30
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 27
|
||||
"__id__": 35
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -352,6 +352,12 @@
|
||||
},
|
||||
{
|
||||
"__id__": 20
|
||||
},
|
||||
{
|
||||
"__id__": 22
|
||||
},
|
||||
{
|
||||
"__id__": 26
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
@@ -447,7 +453,7 @@
|
||||
"array": [
|
||||
0,
|
||||
0,
|
||||
216.50635094610968,
|
||||
215.81269742929726,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -1043,10 +1049,10 @@
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "JoystickBG",
|
||||
"_name": "BtnA",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 6
|
||||
"__id__": 7
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
@@ -1054,12 +1060,70 @@
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [],
|
||||
"_prefab": null,
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 200
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
143.689,
|
||||
-584.849,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0.66667,
|
||||
0.66667,
|
||||
0.66667
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "35ITFOFadFX5FVNVNUZbrn"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Background",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 22
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 25
|
||||
"__id__": 24
|
||||
},
|
||||
{
|
||||
"__id__": 26
|
||||
"__id__": 25
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -1073,8 +1137,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 400,
|
||||
"height": 400
|
||||
"width": 200,
|
||||
"height": 200
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -1108,6 +1172,324 @@
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "8f/j+BH3VFzowR9kS36/D8"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 23
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
{
|
||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||
}
|
||||
],
|
||||
"_srcBlendFactor": 770,
|
||||
"_dstBlendFactor": 771,
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "350fd890-3d28-4e53-9dfa-1bf00d857737"
|
||||
},
|
||||
"_type": 1,
|
||||
"_sizeMode": 0,
|
||||
"_fillType": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_atlas": {
|
||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||
},
|
||||
"_id": "bdYe//0u9Dj79RLi8Rt6un"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 23
|
||||
},
|
||||
"_enabled": true,
|
||||
"alignMode": 0,
|
||||
"_target": null,
|
||||
"_alignFlags": 45,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 100,
|
||||
"_originalHeight": 40,
|
||||
"_id": "98p5OL5fdGep1z6jWXKTu9"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "BtnB",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 7
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 27
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [],
|
||||
"_prefab": null,
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 200
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
370.368,
|
||||
-424.647,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0.66667,
|
||||
0.66667,
|
||||
0.66667
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "92c5tbNsZPG7f09UQLXv+j"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Background",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 26
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 28
|
||||
},
|
||||
{
|
||||
"__id__": 29
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 200
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
-1,
|
||||
1
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "96xSPG8lxPZIsW+n65WcbU"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 27
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
{
|
||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||
}
|
||||
],
|
||||
"_srcBlendFactor": 770,
|
||||
"_dstBlendFactor": 771,
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821"
|
||||
},
|
||||
"_type": 1,
|
||||
"_sizeMode": 0,
|
||||
"_fillType": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_atlas": {
|
||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||
},
|
||||
"_id": "2euUQEzg9FdZu2ijWBxgrr"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 27
|
||||
},
|
||||
"_enabled": true,
|
||||
"alignMode": 0,
|
||||
"_target": null,
|
||||
"_alignFlags": 45,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 100,
|
||||
"_originalHeight": 40,
|
||||
"_id": "5bXB50moJH9aH7RcbRuSS5"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "JoystickBG",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 6
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 31
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 33
|
||||
},
|
||||
{
|
||||
"__id__": 34
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 400,
|
||||
"height": 400
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
-380,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "88u3wQvvdO8pbrNWhs3ifP"
|
||||
},
|
||||
{
|
||||
@@ -1115,13 +1497,13 @@
|
||||
"_name": "Joystick",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 22
|
||||
"__id__": 30
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 24
|
||||
"__id__": 32
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -1177,7 +1559,7 @@
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 23
|
||||
"__id__": 31
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
@@ -1211,7 +1593,7 @@
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 22
|
||||
"__id__": 30
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
@@ -1245,7 +1627,7 @@
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 22
|
||||
"__id__": 30
|
||||
},
|
||||
"_enabled": true,
|
||||
"alignMode": 0,
|
||||
@@ -1408,10 +1790,10 @@
|
||||
"__id__": 3
|
||||
},
|
||||
"stickhead": {
|
||||
"__id__": 23
|
||||
"__id__": 31
|
||||
},
|
||||
"base": {
|
||||
"__id__": 22
|
||||
"__id__": 30
|
||||
},
|
||||
"joyStickEps": 0.1,
|
||||
"magicLeanLowerBound": 0.414,
|
||||
@@ -1431,6 +1813,12 @@
|
||||
},
|
||||
"linearMovingEps": 0.1,
|
||||
"scaleByEps": 0.0375,
|
||||
"btnA": {
|
||||
"__id__": 22
|
||||
},
|
||||
"btnB": {
|
||||
"__id__": 26
|
||||
},
|
||||
"_id": "e9oVYTr7ROlpp/IrNjBUmR"
|
||||
}
|
||||
]
|
@@ -440,7 +440,7 @@
|
||||
"array": [
|
||||
0,
|
||||
0,
|
||||
210.14647688706773,
|
||||
216.19964242526865,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
@@ -78,19 +78,19 @@
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 19
|
||||
"__id__": 27
|
||||
},
|
||||
{
|
||||
"__id__": 20
|
||||
"__id__": 28
|
||||
},
|
||||
{
|
||||
"__id__": 21
|
||||
"__id__": 29
|
||||
},
|
||||
{
|
||||
"__id__": 22
|
||||
"__id__": 30
|
||||
},
|
||||
{
|
||||
"__id__": 23
|
||||
"__id__": 31
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -172,8 +172,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 3200,
|
||||
"height": 3200
|
||||
"width": 2048,
|
||||
"height": 2048
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -191,8 +191,8 @@
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
1.5,
|
||||
1.5,
|
||||
1
|
||||
]
|
||||
},
|
||||
@@ -289,13 +289,13 @@
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 13
|
||||
"__id__": 21
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 18
|
||||
"__id__": 26
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -359,6 +359,12 @@
|
||||
},
|
||||
{
|
||||
"__id__": 11
|
||||
},
|
||||
{
|
||||
"__id__": 13
|
||||
},
|
||||
{
|
||||
"__id__": 17
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
@@ -454,7 +460,7 @@
|
||||
"array": [
|
||||
0,
|
||||
0,
|
||||
216.50635094610968,
|
||||
215.81269742929726,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -607,10 +613,10 @@
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "JoystickBG",
|
||||
"_name": "BtnA",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 7
|
||||
"__id__": 8
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
@@ -618,12 +624,70 @@
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [],
|
||||
"_prefab": null,
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 200
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
143.689,
|
||||
-584.849,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0.66667,
|
||||
0.66667,
|
||||
0.66667
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "a5pbciqqBEiYlyy7SLwP4V"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Background",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 13
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 16
|
||||
"__id__": 15
|
||||
},
|
||||
{
|
||||
"__id__": 17
|
||||
"__id__": 16
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -637,8 +701,8 @@
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 400,
|
||||
"height": 400
|
||||
"width": 200,
|
||||
"height": 200
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
@@ -672,6 +736,324 @@
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "ffojLoj41JCpizkLkManxw"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 14
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
{
|
||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||
}
|
||||
],
|
||||
"_srcBlendFactor": 770,
|
||||
"_dstBlendFactor": 771,
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "350fd890-3d28-4e53-9dfa-1bf00d857737"
|
||||
},
|
||||
"_type": 1,
|
||||
"_sizeMode": 0,
|
||||
"_fillType": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_atlas": {
|
||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||
},
|
||||
"_id": "21Oz9QwBZPALzRoJujKVPG"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 14
|
||||
},
|
||||
"_enabled": true,
|
||||
"alignMode": 0,
|
||||
"_target": null,
|
||||
"_alignFlags": 45,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 100,
|
||||
"_originalHeight": 40,
|
||||
"_id": "beUmgK1D1M07I7kTL4NFLK"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "BtnB",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 8
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 18
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [],
|
||||
"_prefab": null,
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 200
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
370.368,
|
||||
-424.647,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0.66667,
|
||||
0.66667,
|
||||
0.66667
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "9eZHUAtItPMKp7OrItdaWA"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Background",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 17
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 19
|
||||
},
|
||||
{
|
||||
"__id__": 20
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 200
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
-1,
|
||||
1
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "e2JXxje+hAC7LjZqzgq8RF"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 18
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
{
|
||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||
}
|
||||
],
|
||||
"_srcBlendFactor": 770,
|
||||
"_dstBlendFactor": 771,
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821"
|
||||
},
|
||||
"_type": 1,
|
||||
"_sizeMode": 0,
|
||||
"_fillType": 0,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_atlas": {
|
||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||
},
|
||||
"_id": "54DvUzQvpKMrmsuRaQRSxf"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 18
|
||||
},
|
||||
"_enabled": true,
|
||||
"alignMode": 0,
|
||||
"_target": null,
|
||||
"_alignFlags": 45,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 100,
|
||||
"_originalHeight": 40,
|
||||
"_id": "5fVLGAIhROj6UDGotnneup"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "JoystickBG",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 7
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 22
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 24
|
||||
},
|
||||
{
|
||||
"__id__": 25
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
"_opacity": 255,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 400,
|
||||
"height": 400
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_trs": {
|
||||
"__type__": "TypedArray",
|
||||
"ctor": "Float64Array",
|
||||
"array": [
|
||||
-380,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
},
|
||||
"_eulerAngles": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_skewX": 0,
|
||||
"_skewY": 0,
|
||||
"_is3DNode": false,
|
||||
"_groupIndex": 0,
|
||||
"groupIndex": 0,
|
||||
"_id": "88u3wQvvdO8pbrNWhs3ifP"
|
||||
},
|
||||
{
|
||||
@@ -679,13 +1061,13 @@
|
||||
"_name": "Joystick",
|
||||
"_objFlags": 0,
|
||||
"_parent": {
|
||||
"__id__": 13
|
||||
"__id__": 21
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 15
|
||||
"__id__": 23
|
||||
}
|
||||
],
|
||||
"_prefab": null,
|
||||
@@ -741,7 +1123,7 @@
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 14
|
||||
"__id__": 22
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
@@ -775,7 +1157,7 @@
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 13
|
||||
"__id__": 21
|
||||
},
|
||||
"_enabled": true,
|
||||
"_materials": [
|
||||
@@ -809,7 +1191,7 @@
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"node": {
|
||||
"__id__": 13
|
||||
"__id__": 21
|
||||
},
|
||||
"_enabled": true,
|
||||
"alignMode": 0,
|
||||
@@ -944,10 +1326,10 @@
|
||||
"__id__": 3
|
||||
},
|
||||
"stickhead": {
|
||||
"__id__": 14
|
||||
"__id__": 22
|
||||
},
|
||||
"base": {
|
||||
"__id__": 13
|
||||
"__id__": 21
|
||||
},
|
||||
"joyStickEps": 0.1,
|
||||
"magicLeanLowerBound": 0.414,
|
||||
@@ -967,6 +1349,12 @@
|
||||
},
|
||||
"linearMovingEps": 0.1,
|
||||
"scaleByEps": 0.0375,
|
||||
"btnA": {
|
||||
"__id__": 13
|
||||
},
|
||||
"btnB": {
|
||||
"__id__": 17
|
||||
},
|
||||
"_id": "e9oVYTr7ROlpp/IrNjBUmR"
|
||||
}
|
||||
]
|
@@ -5,8 +5,33 @@ window.ATK_CHARACTER_STATE = {
|
||||
Walking: [1, "Walking"],
|
||||
Atk1: [2, "Atk1"],
|
||||
Atked1: [3, "Atked1"],
|
||||
InAirIdle1: [4, "InAirIdle1"],
|
||||
InAirAtk1: [5, "Atk1"],
|
||||
InAirAtked1: [6, "Atked1"],
|
||||
};
|
||||
|
||||
window.toInAirConjugate = function(foo) {
|
||||
switch (foo) {
|
||||
case window.ATK_CHARACTER_STATE.Idle1[0]:
|
||||
case window.ATK_CHARACTER_STATE.Walking[0]:
|
||||
return window.ATK_CHARACTER_STATE.InAirIdle1[0];
|
||||
case window.ATK_CHARACTER_STATE.Atk1[0]:
|
||||
return window.ATK_CHARACTER_STATE.InAirAtk1[0];
|
||||
case window.ATK_CHARACTER_STATE.Atked1[0]:
|
||||
return window.ATK_CHARACTER_STATE.InAirAtked1[0];
|
||||
|
||||
case window.ATK_CHARACTER_STATE.InAirIdle1[0]:
|
||||
return window.ATK_CHARACTER_STATE.Idle1[0];
|
||||
case window.ATK_CHARACTER_STATE.InAirAtk1[0]:
|
||||
return window.ATK_CHARACTER_STATE.Atk1[0];
|
||||
case window.ATK_CHARACTER_STATE.InAirAtked1[0]:
|
||||
return window.ATK_CHARACTER_STATE.Atked1[0];
|
||||
default:
|
||||
console.warn(`Invalid characterState ${foo} received, no in air conjugate is available!`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
window.ATK_CHARACTER_STATE_ARR = [];
|
||||
for (let k in window.ATK_CHARACTER_STATE) {
|
||||
window.ATK_CHARACTER_STATE_ARR.push(window.ATK_CHARACTER_STATE[k]);
|
||||
@@ -15,6 +40,12 @@ for (let k in window.ATK_CHARACTER_STATE) {
|
||||
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET = new Set();
|
||||
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.Idle1[0]);
|
||||
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.Walking[0]);
|
||||
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.InAirIdle1[0]);
|
||||
|
||||
window.ATK_CHARACTER_STATE_IN_AIR_SET = new Set();
|
||||
window.ATK_CHARACTER_STATE_IN_AIR_SET.add(window.ATK_CHARACTER_STATE.InAirIdle1[0]);
|
||||
window.ATK_CHARACTER_STATE_IN_AIR_SET.add(window.ATK_CHARACTER_STATE.InAirAtk1[0]);
|
||||
window.ATK_CHARACTER_STATE_IN_AIR_SET.add(window.ATK_CHARACTER_STATE.InAirAtked1[0]);
|
||||
|
||||
/*
|
||||
Kindly note that the use of dragonBones anim is an informed choice for the feasibility of "gotoAndPlayByFrame", which is a required feature by "Map.rollbackAndChase". You might find that "cc.Animation" -- the traditional frame anim -- can also suffice this requirement, yet if we want to develop 3D frontend in the future, working with skeletal anim will make a smoother transition.
|
||||
@@ -37,6 +68,7 @@ cc.Class({
|
||||
this.hp = 100;
|
||||
this.maxHp = 100;
|
||||
this.framesToRecover = 0;
|
||||
this.inAir = true;
|
||||
},
|
||||
|
||||
setSpecies(speciesName) {
|
||||
@@ -49,8 +81,7 @@ cc.Class({
|
||||
this.animComp = this.effAnimNode.getComponent(dragonBones.ArmatureDisplay);
|
||||
if (!this.animComp) {
|
||||
this.animComp = this.effAnimNode.getComponent(cc.Animation);
|
||||
this.effAnimNode.anchorY = 0.0; // Otherwise the frame anim will show with an incorrect y-offset even if the collider boundaries are all correct!
|
||||
}
|
||||
}
|
||||
this.effAnimNode.active = true;
|
||||
},
|
||||
|
||||
@@ -67,7 +98,7 @@ cc.Class({
|
||||
}
|
||||
|
||||
let newCharacterState = rdfPlayer.characterState;
|
||||
const newAnimName = window.ATK_CHARACTER_STATE_ARR[newCharacterState][1];
|
||||
let newAnimName = window.ATK_CHARACTER_STATE_ARR[newCharacterState][1];
|
||||
let playingAnimName = null;
|
||||
let underlyingAnimationCtrl = null;
|
||||
|
||||
@@ -96,7 +127,7 @@ cc.Class({
|
||||
_interruptPlayingAnimAndPlayNewAnimDragonBones(rdfPlayer, prevRdfPlayer, newCharacterState, newAnimName, underlyingAnimationCtrl, playingAnimName) {
|
||||
if (window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.has(newCharacterState)) {
|
||||
// No "framesToRecover"
|
||||
//console.warn(`#DragonBones JoinIndex=${rdfPlayer.joinIndex}, ${playingAnimName} -> ${newAnimName}`);
|
||||
// console.warn(`#DragonBones JoinIndex=${rdfPlayer.joinIndex}, ${playingAnimName} -> ${newAnimName}`);
|
||||
underlyingAnimationCtrl.gotoAndPlayByFrame(newAnimName, 0, -1);
|
||||
} else {
|
||||
const animationData = underlyingAnimationCtrl._animations[newAnimName];
|
||||
@@ -112,7 +143,7 @@ cc.Class({
|
||||
_interruptPlayingAnimAndPlayNewAnimFrameAnim(rdfPlayer, prevRdfPlayer, newCharacterState, newAnimName, playingAnimName) {
|
||||
if (window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.has(newCharacterState)) {
|
||||
// No "framesToRecover"
|
||||
//console.warn(`#DragonBones JoinIndex=${rdfPlayer.joinIndex}, ${playingAnimName} -> ${newAnimName}`);
|
||||
//console.warn(`#FrameAnim JoinIndex=${rdfPlayer.joinIndex}, ${playingAnimName} -> ${newAnimName}`);
|
||||
this.animComp.play(newAnimName, 0);
|
||||
return;
|
||||
}
|
||||
|
@@ -402,6 +402,7 @@ cc.Class({
|
||||
console.log(`Received parsedBattleColliderInfo via ws`);
|
||||
// TODO: Upon reconnection, the backend might have already been sending down data that'd trigger "onRoomDownsyncFrame & onInputFrameDownsyncBatch", but frontend could reject those data due to "battleState != PlayerBattleState.ACTIVE".
|
||||
Object.assign(self, parsedBattleColliderInfo);
|
||||
self.gravityX = parsedBattleColliderInfo.gravityX; // to avoid integer default value 0 accidentally becoming null in "Object.assign(...)"
|
||||
self.tooFastDtIntervalMillis = 0.5 * self.rollbackEstimatedDtMillis;
|
||||
|
||||
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
||||
@@ -426,6 +427,16 @@ cc.Class({
|
||||
mapNode.removeAllChildren();
|
||||
self._resetCurrentMatch();
|
||||
|
||||
if (self.showCriticalCoordinateLabels) {
|
||||
const drawer = new cc.Node();
|
||||
drawer.setPosition(cc.v2(0, 0))
|
||||
safelyAddChild(self.node, drawer);
|
||||
setLocalZOrder(drawer, 999);
|
||||
const g = drawer.addComponent(cc.Graphics);
|
||||
g.lineWidth = 2;
|
||||
self.g = g;
|
||||
}
|
||||
|
||||
tiledMapIns.tmxAsset = tmxAsset;
|
||||
const newMapSize = tiledMapIns.getMapSize();
|
||||
const newTileSize = tiledMapIns.getTileSize();
|
||||
@@ -442,14 +453,19 @@ cc.Class({
|
||||
}
|
||||
|
||||
let barrierIdCounter = 0;
|
||||
const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node);
|
||||
for (let boundaryObj of boundaryObjs.barriers) {
|
||||
const x0 = boundaryObj.anchor.x,
|
||||
y0 = boundaryObj.anchor.y;
|
||||
|
||||
const newBarrierCollider = self.collisionSys.createPolygon(x0, y0, Array.from(boundaryObj, p => {
|
||||
const refBoundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node).barriers;
|
||||
const boundaryObjs = parsedBattleColliderInfo.strToPolygon2DListMap;
|
||||
for (let k = 0; k < boundaryObjs["Barrier"].eles.length; k++) {
|
||||
let boundaryObj = boundaryObjs["Barrier"].eles[k];
|
||||
const refBoundaryObj = refBoundaryObjs[k];
|
||||
// boundaryObj = refBoundaryObj;
|
||||
const [x0, y0] = [boundaryObj.anchor.x, boundaryObj.anchor.y];
|
||||
const newBarrierCollider = self.collisionSys.createPolygon(x0, y0, Array.from(boundaryObj.points, p => {
|
||||
return [p.x, p.y];
|
||||
}));
|
||||
newBarrierCollider.data = {
|
||||
hardPushback: true
|
||||
};
|
||||
|
||||
if (self.showCriticalCoordinateLabels) {
|
||||
for (let i = 0; i < boundaryObj.length; ++i) {
|
||||
@@ -572,12 +588,13 @@ cc.Class({
|
||||
}
|
||||
const shouldForceDumping1 = (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.id);
|
||||
const shouldForceDumping2 = (rdf.id > self.renderFrameId + self.renderFrameIdLagTolerance);
|
||||
const shouldForceResync = rdf.shouldForceResync;
|
||||
|
||||
const [dumpRenderCacheRet, oldStRenderFrameId, oldEdRenderFrameId] = (shouldForceDumping1 || shouldForceDumping2) ? self.recentRenderCache.setByFrameId(rdf, rdf.id) : [window.RING_BUFF_CONSECUTIVE_SET, null, null];
|
||||
const [dumpRenderCacheRet, oldStRenderFrameId, oldEdRenderFrameId] = (shouldForceDumping1 || shouldForceDumping2 || shouldForceResync) ? self.recentRenderCache.setByFrameId(rdf, rdf.id) : [window.RING_BUFF_CONSECUTIVE_SET, null, null];
|
||||
if (window.RING_BUFF_FAILED_TO_SET == dumpRenderCacheRet) {
|
||||
throw `Failed to dump render cache#1 (maybe recentRenderCache too small)! rdf.id=${rdf.id}, lastAllConfirmedRenderFrameId=${self.lastAllConfirmedRenderFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}; recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`;
|
||||
}
|
||||
if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START < rdf.id && window.RING_BUFF_CONSECUTIVE_SET == dumpRenderCacheRet) {
|
||||
if (!shouldForceResync && (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START < rdf.id && window.RING_BUFF_CONSECUTIVE_SET == dumpRenderCacheRet)) {
|
||||
/*
|
||||
Don't change
|
||||
- lastAllConfirmedRenderFrameId, it's updated only in "rollbackAndChase" (except for when RING_BUFF_NON_CONSECUTIVE_SET)
|
||||
@@ -762,18 +779,25 @@ cc.Class({
|
||||
if (1 == joinIndex) {
|
||||
playerScriptIns.setSpecies("SoldierWaterGhost");
|
||||
} else if (2 == joinIndex) {
|
||||
playerScriptIns.setSpecies("SoldierFireGhost");
|
||||
playerScriptIns.setSpecies("UltramanTiga");
|
||||
}
|
||||
|
||||
const [wx, wy] = self.virtualGridToWorldPos(vx, vy);
|
||||
newPlayerNode.setPosition(wx, wy);
|
||||
playerScriptIns.mapNode = self.node;
|
||||
const colliderWidth = playerDownsyncInfo.colliderRadius * 2,
|
||||
colliderHeight = playerDownsyncInfo.colliderRadius * 3;
|
||||
const [x0, y0] = self.virtualGridToPolygonColliderAnchorPos(vx, vy, colliderWidth, colliderHeight),
|
||||
pts = [[0, 0], [colliderWidth, 0], [colliderWidth, colliderHeight], [0, colliderHeight]];
|
||||
const halfColliderWidth = playerDownsyncInfo.colliderRadius,
|
||||
halfColliderHeight = playerDownsyncInfo.colliderRadius + playerDownsyncInfo.colliderRadius; // avoid multiplying
|
||||
const colliderWidth = halfColliderWidth + halfColliderWidth,
|
||||
colliderHeight = halfColliderHeight + halfColliderHeight; // avoid multiplying
|
||||
const leftPadding = self.snapIntoPlatformOverlap,
|
||||
rightPadding = self.snapIntoPlatformOverlap,
|
||||
topPadding = self.snapIntoPlatformOverlap,
|
||||
bottomPadding = self.snapIntoPlatformOverlap;
|
||||
const cpos = self.virtualGridToPolygonColliderBLPos(vx, vy, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding); // the collider center is kept having integer coords
|
||||
const pts = [[0, 0], [leftPadding + colliderWidth + rightPadding, 0], [leftPadding + colliderWidth + rightPadding, bottomPadding + colliderHeight + topPadding], [0, bottomPadding + colliderHeight + topPadding]];
|
||||
|
||||
const newPlayerCollider = self.collisionSys.createPolygon(x0, y0, pts);
|
||||
// [WARNING] The animNode "anchor & offset" are tuned to fit in this collider by "ControlledCharacter prefab & AttackingCharacter.js"!
|
||||
const newPlayerCollider = self.collisionSys.createPolygon(cpos[0], cpos[1], pts);
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
newPlayerCollider.data = playerDownsyncInfo;
|
||||
self.collisionSysMap.set(collisionPlayerIndex, newPlayerCollider);
|
||||
@@ -833,6 +857,7 @@ cc.Class({
|
||||
*/
|
||||
// [WARNING] Don't try to get "prevRdf(i.e. renderFrameId == latest-1)" by "self.recentRenderCache.getByFrameId(...)" here, as the cache might have been updated by asynchronous "onRoomDownsyncFrame(...)" calls!
|
||||
self.applyRoomDownsyncFrameDynamics(rdf, prevRdf);
|
||||
self.showDebugBoundaries(rdf);
|
||||
++self.renderFrameId; // [WARNING] It's important to increment the renderFrameId AFTER all the operations above!!!
|
||||
self.lastRenderFrameIdTriggeredAt = performance.now();
|
||||
let t3 = performance.now();
|
||||
@@ -961,13 +986,13 @@ cc.Class({
|
||||
applyRoomDownsyncFrameDynamics(rdf, prevRdf) {
|
||||
const self = this;
|
||||
for (let [playerId, playerRichInfo] of self.playerRichInfoDict.entries()) {
|
||||
const immediatePlayerInfo = rdf.players[playerId];
|
||||
const currPlayerDownsync = rdf.players[playerId];
|
||||
const prevRdfPlayer = (null == prevRdf ? null : prevRdf.players[playerId]);
|
||||
const [wx, wy] = self.virtualGridToWorldPos(immediatePlayerInfo.virtualGridX, immediatePlayerInfo.virtualGridY);
|
||||
const [wx, wy] = self.virtualGridToWorldPos(currPlayerDownsync.virtualGridX, currPlayerDownsync.virtualGridY);
|
||||
//const justJiggling = (self.jigglingEps1D >= Math.abs(wx - playerRichInfo.node.x) && self.jigglingEps1D >= Math.abs(wy - playerRichInfo.node.y));
|
||||
playerRichInfo.node.setPosition(wx, wy);
|
||||
playerRichInfo.scriptIns.updateSpeed(immediatePlayerInfo.speed);
|
||||
playerRichInfo.scriptIns.updateCharacterAnim(immediatePlayerInfo, prevRdfPlayer, false);
|
||||
playerRichInfo.scriptIns.updateSpeed(currPlayerDownsync.speed);
|
||||
playerRichInfo.scriptIns.updateCharacterAnim(currPlayerDownsync, prevRdfPlayer, false);
|
||||
}
|
||||
|
||||
// Update countdown
|
||||
@@ -977,6 +1002,79 @@ cc.Class({
|
||||
}
|
||||
},
|
||||
|
||||
showDebugBoundaries(rdf) {
|
||||
const self = this;
|
||||
const leftPadding = self.snapIntoPlatformOverlap,
|
||||
rightPadding = self.snapIntoPlatformOverlap,
|
||||
topPadding = self.snapIntoPlatformOverlap,
|
||||
bottomPadding = self.snapIntoPlatformOverlap;
|
||||
if (self.showCriticalCoordinateLabels) {
|
||||
let g = self.g;
|
||||
g.clear();
|
||||
|
||||
for (let k in self.collisionSys._bvh._bodies) {
|
||||
const body = self.collisionSys._bvh._bodies[k];
|
||||
if (!body._polygon) continue;
|
||||
if (null != body.data && null != body.data.joinIndex) {
|
||||
// character
|
||||
if (1 == body.data.joinIndex) {
|
||||
g.strokeColor = cc.Color.BLUE;
|
||||
} else {
|
||||
g.strokeColor = cc.Color.RED;
|
||||
}
|
||||
} else {
|
||||
// barrier
|
||||
g.strokeColor = cc.Color.WHITE;
|
||||
}
|
||||
g.moveTo(body.x, body.y);
|
||||
const cnt = body._coords.length;
|
||||
for (let j = 0; j < cnt; j += 2) {
|
||||
const x = body._coords[j],
|
||||
y = body._coords[j + 1];
|
||||
g.lineTo(x, y);
|
||||
}
|
||||
g.lineTo(body.x, body.y);
|
||||
g.stroke();
|
||||
}
|
||||
// For convenience of recovery upon reconnection, active bullets are always created & immediately removed from "collisionSys" within "applyInputFrameDownsyncDynamicsOnSingleRenderFrame"
|
||||
|
||||
for (let k in rdf.meleeBullets) {
|
||||
const meleeBullet = rdf.meleeBullets[k];
|
||||
if (
|
||||
meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames <= rdf.id
|
||||
&&
|
||||
meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames + meleeBullet.activeFrames > rdf.id
|
||||
) {
|
||||
const offender = rdf.players[meleeBullet.offenderPlayerId];
|
||||
if (1 == offender.joinIndex) {
|
||||
g.strokeColor = cc.Color.BLUE;
|
||||
} else {
|
||||
g.strokeColor = cc.Color.RED;
|
||||
}
|
||||
|
||||
let xfac = 1; // By now, straight Punch offset doesn't respect "y-axis"
|
||||
if (0 > offender.dirX) {
|
||||
xfac = -1;
|
||||
}
|
||||
const [offenderWx, offenderWy] = self.virtualGridToWorldPos(offender.virtualGridX, offender.virtualGridY);
|
||||
const bulletWx = offenderWx + xfac * meleeBullet.hitboxOffset;
|
||||
const bulletWy = offenderWy;
|
||||
const halfColliderWidth = meleeBullet.hitboxSize.x * 0.5,
|
||||
halfColliderHeight = meleeBullet.hitboxSize.y * 0.5; // avoid multiplying
|
||||
const bulletCpos = self.worldToPolygonColliderBLPos(bulletWx, bulletWy, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding);
|
||||
const pts = [[0, 0], [leftPadding + meleeBullet.hitboxSize.x + rightPadding, 0], [leftPadding + meleeBullet.hitboxSize.x + rightPadding, bottomPadding + meleeBullet.hitboxSize.y + topPadding], [0, bottomPadding + meleeBullet.hitboxSize.y + topPadding]];
|
||||
|
||||
g.moveTo(bulletCpos[0], bulletCpos[1]);
|
||||
for (let j = 0; j < pts.length; j += 1) {
|
||||
g.lineTo(pts[j][0] + bulletCpos[0], pts[j][1] + bulletCpos[1]);
|
||||
}
|
||||
g.lineTo(bulletCpos[0], bulletCpos[1]);
|
||||
g.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getCachedInputFrameDownsyncWithPrediction(inputFrameId) {
|
||||
const self = this;
|
||||
const inputFrameDownsync = self.recentInputCache.getByFrameId(inputFrameId);
|
||||
@@ -994,6 +1092,10 @@ cc.Class({
|
||||
// TODO: Write unit-test for this function to compare with its backend counter part
|
||||
applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputFrame, currRenderFrame, collisionSys, collisionSysMap) {
|
||||
const self = this;
|
||||
const leftPadding = self.snapIntoPlatformOverlap,
|
||||
rightPadding = self.snapIntoPlatformOverlap,
|
||||
topPadding = self.snapIntoPlatformOverlap,
|
||||
bottomPadding = self.snapIntoPlatformOverlap;
|
||||
const nextRenderFramePlayers = {};
|
||||
for (let playerId in currRenderFrame.players) {
|
||||
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||
@@ -1003,7 +1105,10 @@ cc.Class({
|
||||
virtualGridY: currPlayerDownsync.virtualGridY,
|
||||
dirX: currPlayerDownsync.dirX,
|
||||
dirY: currPlayerDownsync.dirY,
|
||||
velX: currPlayerDownsync.velX,
|
||||
velY: currPlayerDownsync.velY,
|
||||
characterState: currPlayerDownsync.characterState,
|
||||
inAir: true,
|
||||
speed: currPlayerDownsync.speed,
|
||||
battleState: currPlayerDownsync.battleState,
|
||||
score: currPlayerDownsync.score,
|
||||
@@ -1016,27 +1121,108 @@ cc.Class({
|
||||
}
|
||||
|
||||
const nextRenderFrameMeleeBullets = [];
|
||||
const effPushbacks = new Array(self.playerRichInfoArr.length);
|
||||
const hardPushbackNorms = new Array(self.playerRichInfoArr.length);
|
||||
|
||||
const bulletPushbacks = new Array(self.playerRichInfoArr.length); // Guaranteed determinism regardless of traversal order
|
||||
const effPushbacks = new Array(self.playerRichInfoArr.length); // Guaranteed determinism regardless of traversal order
|
||||
// 1. Process player inputs
|
||||
/*
|
||||
[WARNING] Player input alone WOULD NOT take "characterState" into any "ATK_CHARACTER_STATE_IN_AIR_SET", only after the calculation of "effPushbacks" do we know exactly whether or not a player is "inAir", the finalize the transition of "thatPlayerInNextFrame.characterState".
|
||||
*/
|
||||
if (null != delayedInputFrame) {
|
||||
const delayedInputFrameForPrevRenderFrame = self.getCachedInputFrameDownsyncWithPrediction(self._convertToInputFrameId(currRenderFrame.id - 1, self.inputDelayFrames));
|
||||
const inputList = delayedInputFrame.inputList;
|
||||
for (let j in self.playerRichInfoArr) {
|
||||
const joinIndex = parseInt(j) + 1;
|
||||
const playerRichInfo = self.playerRichInfoArr[j];
|
||||
const playerId = playerRichInfo.id;
|
||||
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||
if (0 < thatPlayerInNextFrame.framesToRecover) {
|
||||
// No need to process inputs for this player, but there might be bullet pushbacks on this player
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reset playerCollider position from the "virtual grid position"
|
||||
const decodedInput = self.ctrl.decodeInput(inputList[joinIndex - 1]);
|
||||
const prevDecodedInput = (null == delayedInputFrameForPrevRenderFrame ? null : self.ctrl.decodeInput(delayedInputFrameForPrevRenderFrame.inputList[joinIndex - 1]));
|
||||
const prevBtnALevel = (null == prevDecodedInput ? 0 : prevDecodedInput.btnALevel);
|
||||
const prevBtnBLevel = (null == prevDecodedInput ? 0 : prevDecodedInput.btnBLevel);
|
||||
if (1 == decodedInput.btnBLevel && 0 == prevBtnBLevel) {
|
||||
const characStateAlreadyInAir = window.ATK_CHARACTER_STATE_IN_AIR_SET.has(thatPlayerInNextFrame.characterState);
|
||||
const characStateIsInterruptWaivable = window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.has(thatPlayerInNextFrame.characterState);
|
||||
if (
|
||||
!characStateAlreadyInAir
|
||||
&&
|
||||
characStateIsInterruptWaivable
|
||||
) {
|
||||
thatPlayerInNextFrame.velY = self.jumpingInitVelY;
|
||||
if (1 == joinIndex) {
|
||||
console.log(`playerId=${playerId}, joinIndex=${joinIndex} jumped at {renderFrame.id: ${currRenderFrame.id}, virtualX: ${currPlayerDownsync.virtualGridX}, virtualY: ${currPlayerDownsync.virtualGridY}, nextVelX: ${thatPlayerInNextFrame.velX}, nextVelY: ${thatPlayerInNextFrame.velY}}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == decodedInput.btnALevel && 0 == prevBtnALevel) {
|
||||
const punchSkillId = 1;
|
||||
const punch = window.pb.protos.MeleeBullet.create(self.meleeSkillConfig[punchSkillId]);
|
||||
thatPlayerInNextFrame.framesToRecover = punch.recoveryFrames;
|
||||
punch.battleLocalId = self.bulletBattleLocalIdCounter++;
|
||||
punch.offenderJoinIndex = joinIndex;
|
||||
punch.offenderPlayerId = playerId;
|
||||
punch.originatedRenderFrameId = currRenderFrame.id;
|
||||
nextRenderFrameMeleeBullets.push(punch);
|
||||
// console.log(`playerId=${playerId}, joinIndex=${joinIndex} triggered a rising-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`);
|
||||
|
||||
thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atk1[0];
|
||||
if (false == currPlayerDownsync.inAir) {
|
||||
thatPlayerInNextFrame.velX = 0; // prohibits simultaneous movement with Atk1 on the ground
|
||||
}
|
||||
} else if (0 == decodedInput.btnALevel && 1 == prevBtnALevel) {
|
||||
// console.log(`playerId=${playerId} triggered a falling-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`);
|
||||
} else {
|
||||
// No bullet trigger, process joystick movement inputs.
|
||||
if (0 != decodedInput.dx || 0 != decodedInput.dy) {
|
||||
// Update directions and thus would eventually update moving animation accordingly
|
||||
thatPlayerInNextFrame.dirX = decodedInput.dx;
|
||||
thatPlayerInNextFrame.dirY = decodedInput.dy;
|
||||
thatPlayerInNextFrame.velX = decodedInput.dx * currPlayerDownsync.speed;
|
||||
thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Walking[0];
|
||||
} else {
|
||||
thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Idle1[0];
|
||||
thatPlayerInNextFrame.velX = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Process player movement
|
||||
for (let j in self.playerRichInfoArr) {
|
||||
const joinIndex = parseInt(j) + 1;
|
||||
bulletPushbacks[joinIndex - 1] = [0.0, 0.0];
|
||||
effPushbacks[joinIndex - 1] = [0.0, 0.0];
|
||||
const playerRichInfo = self.playerRichInfoArr[j];
|
||||
const playerId = playerRichInfo.id;
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||
// Reset playerCollider position from the "virtual grid position"
|
||||
const newVpos = [currPlayerDownsync.virtualGridX + currPlayerDownsync.velX, currPlayerDownsync.virtualGridY + currPlayerDownsync.velY];
|
||||
if (thatPlayerInNextFrame.velY == self.jumpingInitVelY) {
|
||||
// This step can be waived, but putting the jumping inclination here makes it easier to read logs.
|
||||
newVpos[1] += self.jumpingInitVelY;
|
||||
}
|
||||
const halfColliderWidth = self.playerRichInfoArr[j].colliderRadius,
|
||||
halfColliderHeight = self.playerRichInfoArr[j].colliderRadius + self.playerRichInfoArr[j].colliderRadius; // avoid multiplying
|
||||
const newCpos = self.virtualGridToPolygonColliderBLPos(newVpos[0], newVpos[1], halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding);
|
||||
playerCollider.x = newCpos[0];
|
||||
playerCollider.y = newCpos[1];
|
||||
|
||||
const newVx = currPlayerDownsync.virtualGridX;
|
||||
const newVy = currPlayerDownsync.virtualGridY;
|
||||
[playerCollider.x, playerCollider.y] = self.virtualGridToPolygonColliderAnchorPos(newVx, newVy, self.playerRichInfoArr[joinIndex - 1].colliderRadius, self.playerRichInfoArr[joinIndex - 1].colliderRadius);
|
||||
if (currPlayerDownsync.inAir) {
|
||||
thatPlayerInNextFrame.velX += self.gravityX;
|
||||
thatPlayerInNextFrame.velY += self.gravityY;
|
||||
}
|
||||
}
|
||||
|
||||
// Check bullet-anything collisions first, because the pushbacks caused by bullets might later be reverted by player-barrier collision
|
||||
// 3. Add bullet colliders into collision system
|
||||
const bulletColliders = new Map(); // Will all be removed at the end of `applyInputFrameDownsyncDynamicsOnSingleRenderFrame` due to the need for being rollback-compatible
|
||||
const removedBulletsAtCurrFrame = new Set();
|
||||
for (let k in currRenderFrame.meleeBullets) {
|
||||
@@ -1058,38 +1244,148 @@ cc.Class({
|
||||
const [offenderWx, offenderWy] = self.virtualGridToWorldPos(offender.virtualGridX, offender.virtualGridY);
|
||||
const bulletWx = offenderWx + xfac * meleeBullet.hitboxOffset;
|
||||
const bulletWy = offenderWy;
|
||||
const [bulletCx, bulletCy] = self.worldToPolygonColliderAnchorPos(bulletWx, bulletWy, meleeBullet.hitboxSize.x * 0.5, meleeBullet.hitboxSize.y * 0.5),
|
||||
pts = [[0, 0], [meleeBullet.hitboxSize.x, 0], [meleeBullet.hitboxSize.x, meleeBullet.hitboxSize.y], [0, meleeBullet.hitboxSize.y]];
|
||||
const newBulletCollider = collisionSys.createPolygon(bulletCx, bulletCy, pts);
|
||||
const halfColliderWidth = meleeBullet.hitboxSize.x * 0.5,
|
||||
halfColliderHeight = meleeBullet.hitboxSize.y * 0.5;
|
||||
const bulletCpos = self.worldToPolygonColliderBLPos(bulletWx, bulletWy, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding);
|
||||
const pts = [[0, 0], [leftPadding + meleeBullet.hitboxSize.x + rightPadding, 0], [leftPadding + meleeBullet.hitboxSize.x + rightPadding, bottomPadding + meleeBullet.hitboxSize.y + topPadding], [0, bottomPadding + meleeBullet.hitboxSize.y + topPadding]];
|
||||
const newBulletCollider = collisionSys.createPolygon(bulletCpos[0], bulletCpos[1], pts);
|
||||
newBulletCollider.data = meleeBullet;
|
||||
collisionSysMap.set(collisionBulletIndex, newBulletCollider);
|
||||
bulletColliders.set(collisionBulletIndex, newBulletCollider);
|
||||
// console.log(`A meleeBullet is added to collisionSys at currRenderFrame.id=${currRenderFrame.id} as start-up frames ended and active frame is not yet ended: ${JSON.stringify(meleeBullet)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Invoke collision system stepping
|
||||
collisionSys.update();
|
||||
const result1 = collisionSys.createResult(); // Can I reuse a "self.collisionSysResult" object throughout the whole battle?
|
||||
const result = collisionSys.createResult(); // Can I reuse a "self.collisionSysResult" object throughout the whole battle?
|
||||
|
||||
// 5. Calc pushbacks for each player (after its movement) w/o bullets
|
||||
for (let j in self.playerRichInfoArr) {
|
||||
const joinIndex = parseInt(j) + 1;
|
||||
const playerRichInfo = self.playerRichInfoArr[j];
|
||||
const playerId = playerRichInfo.id;
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||
const potentials = playerCollider.potentials();
|
||||
hardPushbackNorms[joinIndex - 1] = self.calcHardPushbacksNorms(playerCollider, potentials, result, self.snapIntoPlatformOverlap, effPushbacks[joinIndex - 1]);
|
||||
|
||||
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||
const halfColliderWidth = self.playerRichInfoArr[j].colliderRadius,
|
||||
halfColliderHeight = self.playerRichInfoArr[j].colliderRadius + self.playerRichInfoArr[j].colliderRadius; // avoid multiplying
|
||||
|
||||
let fallStopping = false;
|
||||
let possiblyFallStoppedOnAnotherPlayer = false;
|
||||
for (const potential of potentials) {
|
||||
let [isBarrier, isAnotherPlayer, isBullet] = [true == potential.data.hardPushback, null != potential.data.joinIndex, null != potential.data.offenderJoinIndex];
|
||||
// ignore bullets for this step
|
||||
if (isBullet) continue;
|
||||
// Test if the player collides with the wall/another player
|
||||
if (!playerCollider.collides(potential, result)) continue;
|
||||
|
||||
const normAlignmentWithGravity = (result.overlap_x * 0 + result.overlap_y * (-1.0));
|
||||
const landedOnGravityPushback = (self.snapIntoPlatformThreshold < normAlignmentWithGravity); // prevents false snapping on the lateral sides
|
||||
let pushback = [result.overlap * result.overlap_x, result.overlap * result.overlap_y];
|
||||
if (landedOnGravityPushback) {
|
||||
// kindly note that one player might land on top of another player
|
||||
pushback = [(result.overlap - self.snapIntoPlatformOverlap) * result.overlap_x, (result.overlap - self.snapIntoPlatformOverlap) * result.overlap_y];
|
||||
thatPlayerInNextFrame.inAir = false;
|
||||
}
|
||||
if (isAnotherPlayer) {
|
||||
/*
|
||||
[WARNING] The "zero overlap collision" might be randomly detected/missed on either frontend or backend, to have deterministic result we added paddings to all sides of a playerCollider. As each velocity component of (velX, velY) being a multiple of 0.5 at any renderFrame, each position component of (x, y) can only be a multiple of 0.5 too, thus whenever a 1-dimensional collision happens between players from [player#1: i*0.5, player#2: j*0.5, not collided yet] to [player#1: (i+k)*0.5, player#2: j*0.5, collided], the overlap becomes (i+k-j)*0.5+2*s, and after snapping subtraction the effPushback magnitude for each player is (i+k-j)*0.5, resulting in 0.5-multiples-position for the next renderFrame.
|
||||
*/
|
||||
pushback = [(result.overlap - self.snapIntoPlatformOverlap * 2) * result.overlap_x, (result.overlap - self.snapIntoPlatformOverlap * 2) * result.overlap_y]; // will overwrite the previous pushback value if "landedOnGravityPushback" is also true
|
||||
}
|
||||
for (let hardPushbackNorm of hardPushbackNorms[joinIndex - 1]) {
|
||||
// remove pushback component on the directions of "hardPushbackNorms[joinIndex-1]" (by now those hardPushbacks are already accounted in "effPushbacks[joinIndex-1]")
|
||||
const projectedMagnitude = pushback[0] * hardPushbackNorm[0] + pushback[1] * hardPushbackNorm[1];
|
||||
if (isBarrier
|
||||
||
|
||||
(isAnotherPlayer && 0 > projectedMagnitude)
|
||||
) {
|
||||
// [WARNING] Pushing by another player is different from pushing by barrier!
|
||||
// Otherwise the player couldn't be pushed by another player to opposite dir of a side wall
|
||||
pushback[0] -= projectedMagnitude * hardPushbackNorm[0];
|
||||
pushback[1] -= projectedMagnitude * hardPushbackNorm[1];
|
||||
}
|
||||
}
|
||||
|
||||
effPushbacks[joinIndex - 1][0] += pushback[0];
|
||||
effPushbacks[joinIndex - 1][1] += pushback[1];
|
||||
// It's not meaningful to log the virtual positions and velocities inside this step.
|
||||
if (currPlayerDownsync.inAir && landedOnGravityPushback) {
|
||||
fallStopping = true;
|
||||
if (isAnotherPlayer) {
|
||||
possiblyFallStoppedOnAnotherPlayer = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == joinIndex) {
|
||||
if (fallStopping) {
|
||||
console.info(`playerId=${playerId}, joinIndex=${thatPlayerInNextFrame.joinIndex} fallStopping#1:
|
||||
{renderFrame.id: ${currRenderFrame.id}, possiblyFallStoppedOnAnotherPlayer: ${possiblyFallStoppedOnAnotherPlayer}}
|
||||
playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}, overlayMag=${result.overlap.toFixed(4)}`);
|
||||
} else if (currPlayerDownsync.inAir && isBarrier && !landedOnGravityPushback) {
|
||||
console.warn(`playerId=${playerId}, joinIndex=${currPlayerDownsync.joinIndex} inAir & pushed back by barrier & not landed:
|
||||
{renderFrame.id: ${currRenderFrame.id}}
|
||||
playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}, overlayMag=${result.overlap.toFixed(4)}, len(hardPushbackNorms)=${hardPushbackNorms.length}`);
|
||||
} else if (currPlayerDownsync.inAir && isAnotherPlayer) {
|
||||
console.warn(`playerId=${playerId}, joinIndex=${currPlayerDownsync.joinIndex} inAir and pushed back by another player
|
||||
{renderFrame.id: ${currRenderFrame.id}}
|
||||
playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, anotherPlayerColliderPos=${self.stringifyColliderCenterInWorld(potential, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}, landedOnGravityPushback=${landedOnGravityPushback}, fallStopping=${fallStopping}, overlayMag=${result.overlap.toFixed(4)}, len(hardPushbackNorms)=${hardPushbackNorms.length}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fallStopping) {
|
||||
thatPlayerInNextFrame.velX = 0;
|
||||
thatPlayerInNextFrame.velY = 0;
|
||||
thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Idle1[0];
|
||||
thatPlayerInNextFrame.framesToRecover = 0;
|
||||
}
|
||||
if (currPlayerDownsync.inAir) {
|
||||
thatPlayerInNextFrame.characterState = window.toInAirConjugate(thatPlayerInNextFrame.characterState);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Check bullet-anything collisions
|
||||
bulletColliders.forEach((bulletCollider, collisionBulletIndex) => {
|
||||
const potentials = bulletCollider.potentials();
|
||||
const offender = currRenderFrame.players[bulletCollider.data.offenderPlayerId];
|
||||
let shouldRemove = false;
|
||||
for (const potential of potentials) {
|
||||
if (null != potential.data && potential.data.joinIndex == bulletCollider.data.offenderJoinIndex) continue;
|
||||
if (!bulletCollider.collides(potential, result1)) continue;
|
||||
if (null != potential.data && null !== potential.data.joinIndex) {
|
||||
if (!bulletCollider.collides(potential, result)) continue;
|
||||
if (null != potential.data && null != potential.data.joinIndex) {
|
||||
const playerId = potential.data.id;
|
||||
const joinIndex = potential.data.joinIndex;
|
||||
let xfac = 1;
|
||||
if (0 > offender.dirX) {
|
||||
xfac = -1;
|
||||
}
|
||||
bulletPushbacks[joinIndex - 1][0] += xfac * bulletCollider.data.pushback; // Only for straight punch, there's no y-pushback
|
||||
bulletPushbacks[joinIndex - 1][1] += 0;
|
||||
const thatAckedPlayerInNextFrame = nextRenderFramePlayers[potential.data.id];
|
||||
thatAckedPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atked1[0];
|
||||
const oldFramesToRecover = thatAckedPlayerInNextFrame.framesToRecover;
|
||||
thatAckedPlayerInNextFrame.framesToRecover = (oldFramesToRecover > bulletCollider.data.hitStunFrames ? oldFramesToRecover : bulletCollider.data.hitStunFrames); // In case the hit player is already stun, we extend it
|
||||
// Only for straight punch, there's no y-pushback
|
||||
let bulletPushback = [-xfac * bulletCollider.data.pushback, 0];
|
||||
// console.log(`playerId=${playerId}, joinIndex=${joinIndex} is supposed to be pushed back by meleeBullet for bulletPushback=${JSON.stringify(bulletPushback)} at renderFrame.id=${currRenderFrame.id}`);
|
||||
for (let hardPushbackNorm of hardPushbackNorms[joinIndex - 1]) {
|
||||
const projectedMagnitude = bulletPushback[0] * hardPushbackNorm[0] + bulletPushback[1] * hardPushbackNorm[1];
|
||||
if (0 > projectedMagnitude) {
|
||||
// Otherwise when smashing into a wall the atked player would be pushed into the wall first and only got back in the next renderFrame, not what I want here
|
||||
bulletPushback[0] -= (projectedMagnitude * hardPushbackNorm[0]);
|
||||
bulletPushback[1] -= (projectedMagnitude * hardPushbackNorm[1]);
|
||||
// console.log(`playerId=${playerId}, joinIndex=${joinIndex} reducing bulletPushback=${JSON.stringify(bulletPushback)} by ${JSON.stringify([projectedMagnitude * hardPushbackNorm[0], projectedMagnitude * hardPushbackNorm[1]])} where hardPushbackNorm=${JSON.stringify(hardPushbackNorm)}, projectedMagnitude=${projectedMagnitude} at renderFrame.id=${currRenderFrame.id}`);
|
||||
}
|
||||
}
|
||||
// console.log(`playerId=${playerId}, joinIndex=${joinIndex} is actually pushed back by meleeBullet for bulletPushback=${JSON.stringify(bulletPushback)} at renderFrame.id=${currRenderFrame.id}`);
|
||||
effPushbacks[joinIndex - 1][0] += bulletPushback[0];
|
||||
effPushbacks[joinIndex - 1][1] += bulletPushback[1];
|
||||
const [atkedPlayerInCurFrame, atkedPlayerInNextFrame] = [currRenderFrame.players[potential.data.id], nextRenderFramePlayers[potential.data.id]];
|
||||
atkedPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atked1[0];
|
||||
if (atkedPlayerInCurFrame.inAir) {
|
||||
atkedPlayerInNextFrame.characterState = window.toInAirConjugate(atkedPlayerInNextFrame.characterState);
|
||||
}
|
||||
const oldFramesToRecover = atkedPlayerInNextFrame.framesToRecover;
|
||||
atkedPlayerInNextFrame.framesToRecover = (oldFramesToRecover > bulletCollider.data.hitStunFrames ? oldFramesToRecover : bulletCollider.data.hitStunFrames); // In case the hit player is already stun, we extend it
|
||||
}
|
||||
shouldRemove = true;
|
||||
}
|
||||
@@ -1111,95 +1407,38 @@ cc.Class({
|
||||
nextRenderFrameMeleeBullets.push(meleeBullet);
|
||||
}
|
||||
|
||||
// Process player inputs
|
||||
if (null != delayedInputFrame) {
|
||||
const delayedInputFrameForPrevRenderFrame = self.getCachedInputFrameDownsyncWithPrediction(self._convertToInputFrameId(currRenderFrame.id - 1, self.inputDelayFrames));
|
||||
const inputList = delayedInputFrame.inputList;
|
||||
for (let j in self.playerRichInfoArr) {
|
||||
const joinIndex = parseInt(j) + 1;
|
||||
effPushbacks[joinIndex - 1] = [0.0, 0.0];
|
||||
const playerRichInfo = self.playerRichInfoArr[j];
|
||||
const playerId = playerRichInfo.id;
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||
if (0 < thatPlayerInNextFrame.framesToRecover) {
|
||||
// No need to process inputs for this player, but there might be bullet pushbacks on this player
|
||||
playerCollider.x += bulletPushbacks[joinIndex - 1][0];
|
||||
playerCollider.y += bulletPushbacks[joinIndex - 1][1];
|
||||
if (0 != bulletPushbacks[joinIndex - 1][0] || 0 != bulletPushbacks[joinIndex - 1][1]) {
|
||||
console.log(`playerId=${playerId}, joinIndex=${joinIndex} is pushbacked back by ${bulletPushbacks[joinIndex - 1]} by bullet impacts, now its framesToRecover is ${thatPlayerInNextFrame.framesToRecover}`);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 7. Get players out of stuck barriers if there's any
|
||||
for (let j in self.playerRichInfoArr) {
|
||||
const joinIndex = parseInt(j) + 1;
|
||||
const playerId = self.playerRichInfoArr[j].id;
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||
// Update "virtual grid position"
|
||||
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||
const halfColliderWidth = self.playerRichInfoArr[j].colliderRadius,
|
||||
halfColliderHeight = self.playerRichInfoArr[j].colliderRadius + self.playerRichInfoArr[j].colliderRadius; // avoid multiplying
|
||||
const newVpos = self.polygonColliderBLToVirtualGridPos(playerCollider.x - effPushbacks[joinIndex - 1][0], playerCollider.y - effPushbacks[joinIndex - 1][1], halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding);
|
||||
thatPlayerInNextFrame.virtualGridX = newVpos[0];
|
||||
thatPlayerInNextFrame.virtualGridY = newVpos[1];
|
||||
|
||||
const decodedInput = self.ctrl.decodeInput(inputList[joinIndex - 1]);
|
||||
|
||||
const prevDecodedInput = (null == delayedInputFrameForPrevRenderFrame ? null : self.ctrl.decodeInput(delayedInputFrameForPrevRenderFrame.inputList[joinIndex - 1]));
|
||||
const prevBtnALevel = (null == prevDecodedInput ? 0 : prevDecodedInput.btnALevel);
|
||||
|
||||
if (1 == decodedInput.btnALevel && 0 == prevBtnALevel) {
|
||||
// console.log(`playerId=${playerId} triggered a rising-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`);
|
||||
if (self.bulletTriggerEnabled) {
|
||||
const punchSkillId = 1;
|
||||
const punch = window.pb.protos.MeleeBullet.create(self.meleeSkillConfig[punchSkillId]);
|
||||
thatPlayerInNextFrame.framesToRecover = punch.recoveryFrames;
|
||||
punch.battleLocalId = self.bulletBattleLocalIdCounter++;
|
||||
punch.offenderJoinIndex = joinIndex;
|
||||
punch.offenderPlayerId = playerId;
|
||||
punch.originatedRenderFrameId = currRenderFrame.id;
|
||||
nextRenderFrameMeleeBullets.push(punch);
|
||||
// console.log(`A rising-edge of meleeBullet is created at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}: ${self._stringifyRecentInputCache(true)}`);
|
||||
// console.log(`A rising-edge of meleeBullet is created at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`);
|
||||
|
||||
thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atk1[0];
|
||||
}
|
||||
} else if (0 == decodedInput.btnALevel && 1 == prevBtnALevel) {
|
||||
// console.log(`playerId=${playerId} triggered a falling-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`);
|
||||
} else {
|
||||
// No bullet trigger, process movement inputs
|
||||
if (0 != decodedInput.dx || 0 != decodedInput.dy) {
|
||||
// Update directions and thus would eventually update moving animation accordingly
|
||||
thatPlayerInNextFrame.dirX = decodedInput.dx;
|
||||
thatPlayerInNextFrame.dirY = decodedInput.dy;
|
||||
thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Walking[0];
|
||||
} else {
|
||||
thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Idle1[0];
|
||||
}
|
||||
const [movementX, movementY] = self.virtualGridToWorldPos(decodedInput.dx + currPlayerDownsync.speed * decodedInput.dx, decodedInput.dy + currPlayerDownsync.speed * decodedInput.dy);
|
||||
playerCollider.x += movementX;
|
||||
playerCollider.y += movementY;
|
||||
if (1 == thatPlayerInNextFrame.joinIndex) {
|
||||
if (currPlayerDownsync.inAir && !thatPlayerInNextFrame.inAir) {
|
||||
console.warn(`playerId=${playerId}, joinIndex=${thatPlayerInNextFrame.joinIndex} fallStopping#2:
|
||||
{nextRenderFrame.id: ${currRenderFrame.id + 1}, nextVirtualX: ${thatPlayerInNextFrame.virtualGridX}, nextVirtualY: ${thatPlayerInNextFrame.virtualGridY}, nextVelX: ${thatPlayerInNextFrame.velX}, nextVelY: ${thatPlayerInNextFrame.velY}}
|
||||
calculated from <- playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}`);
|
||||
} else if (!currPlayerDownsync.inAir && thatPlayerInNextFrame.inAir) {
|
||||
console.warn(`playerId=${playerId}, joinIndex=${thatPlayerInNextFrame.joinIndex} took off:
|
||||
{nextRenderFrame.id: ${currRenderFrame.id + 1}, nextVirtualX: ${thatPlayerInNextFrame.virtualGridX}, nextVirtualY: ${thatPlayerInNextFrame.virtualGridY}, nextVelX: ${thatPlayerInNextFrame.velX}, nextVelY: ${thatPlayerInNextFrame.velY}}
|
||||
calculated from <- playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}`);
|
||||
} else if (thatPlayerInNextFrame.inAir && 0 != thatPlayerInNextFrame.velY) {
|
||||
/*
|
||||
console.log(`playerId=${playerId}, joinIndex=${thatPlayerInNextFrame.joinIndex} inAir trajectory:
|
||||
{nextRenderFrame.id: ${currRenderFrame.id + 1}, nextVirtualX: ${thatPlayerInNextFrame.virtualGridX}, nextVirtualY: ${thatPlayerInNextFrame.virtualGridY}, nextVelX: ${thatPlayerInNextFrame.velX}, nextVelY: ${thatPlayerInNextFrame.velY}};
|
||||
calculated from <- playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}`);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
collisionSys.update(); // by now all "bulletCollider"s are removed
|
||||
const result2 = collisionSys.createResult(); // Can I reuse a "self.collisionSysResult" object throughout the whole battle?
|
||||
|
||||
for (let j in self.playerRichInfoArr) {
|
||||
const joinIndex = parseInt(j) + 1;
|
||||
const playerId = self.playerRichInfoArr[j].id;
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||
const potentials = playerCollider.potentials();
|
||||
for (const potential of potentials) {
|
||||
// Test if the player collides with the wall
|
||||
if (!playerCollider.collides(potential, result2)) continue;
|
||||
// Push the player out of the wall
|
||||
effPushbacks[joinIndex - 1][0] += result2.overlap * result2.overlap_x;
|
||||
effPushbacks[joinIndex - 1][1] += result2.overlap * result2.overlap_y;
|
||||
}
|
||||
}
|
||||
|
||||
for (let j in self.playerRichInfoArr) {
|
||||
const joinIndex = parseInt(j) + 1;
|
||||
const playerId = self.playerRichInfoArr[j].id;
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||
[thatPlayerInNextFrame.virtualGridX, thatPlayerInNextFrame.virtualGridY] = self.polygonColliderAnchorToVirtualGridPos(playerCollider.x - effPushbacks[joinIndex - 1][0], playerCollider.y - effPushbacks[joinIndex - 1][1], self.playerRichInfoArr[j].colliderRadius, self.playerRichInfoArr[j].colliderRadius);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return window.pb.protos.RoomDownsyncFrame.create({
|
||||
@@ -1214,11 +1453,10 @@ cc.Class({
|
||||
This function eventually calculates a "RoomDownsyncFrame" where "RoomDownsyncFrame.id == renderFrameIdEd" if not interruptted.
|
||||
*/
|
||||
const self = this;
|
||||
let i = renderFrameIdSt,
|
||||
prevLatestRdf = null,
|
||||
let prevLatestRdf = null,
|
||||
latestRdf = null;
|
||||
|
||||
do {
|
||||
for (let i = renderFrameIdSt; i < renderFrameIdEd; i++) {
|
||||
latestRdf = self.recentRenderCache.getByFrameId(i); // typed "RoomDownsyncFrame"; [WARNING] When "true == isChasing", this function can be interruptted by "onRoomDownsyncFrame(rdf)" asynchronously anytime, making this line return "null"!
|
||||
if (null == latestRdf) {
|
||||
console.warn(`Couldn't find renderFrame for i=${i} to rollback, self.renderFrameId=${self.renderFrameId}, lastAllConfirmedRenderFrameId=${self.lastAllConfirmedRenderFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, might've been interruptted by onRoomDownsyncFrame`);
|
||||
@@ -1250,8 +1488,7 @@ cc.Class({
|
||||
self.chaserRenderFrameId = latestRdf.id;
|
||||
}
|
||||
self.recentRenderCache.setByFrameId(latestRdf, latestRdf.id);
|
||||
++i;
|
||||
} while (i < renderFrameIdEd);
|
||||
}
|
||||
|
||||
return [prevLatestRdf, latestRdf];
|
||||
},
|
||||
@@ -1264,16 +1501,16 @@ cc.Class({
|
||||
const immediatePlayerInfo = players[playerId];
|
||||
self.playerRichInfoDict.set(playerId, immediatePlayerInfo);
|
||||
|
||||
const [theNode, theScriptIns] = self.spawnPlayerNode(immediatePlayerInfo.joinIndex, immediatePlayerInfo.virtualGridX, immediatePlayerInfo.virtualGridY, immediatePlayerInfo);
|
||||
const nodeAndScriptIns = self.spawnPlayerNode(immediatePlayerInfo.joinIndex, immediatePlayerInfo.virtualGridX, immediatePlayerInfo.virtualGridY, immediatePlayerInfo);
|
||||
|
||||
Object.assign(self.playerRichInfoDict.get(playerId), {
|
||||
node: theNode,
|
||||
scriptIns: theScriptIns,
|
||||
node: nodeAndScriptIns[0],
|
||||
scriptIns: nodeAndScriptIns[1],
|
||||
});
|
||||
|
||||
if (self.selfPlayerInfo.id == playerId) {
|
||||
self.selfPlayerInfo = Object.assign(self.selfPlayerInfo, immediatePlayerInfo);
|
||||
theScriptIns.showArrowTipNode();
|
||||
nodeAndScriptIns[1].showArrowTipNode();
|
||||
}
|
||||
}
|
||||
self.playerRichInfoArr = new Array(self.playerRichInfoDict.size);
|
||||
@@ -1320,28 +1557,47 @@ cc.Class({
|
||||
virtualGridToWorldPos(vx, vy) {
|
||||
// No loss of precision
|
||||
const self = this;
|
||||
let wx = parseFloat(vx) * self.virtualGridToWorldRatio;
|
||||
let wy = parseFloat(vy) * self.virtualGridToWorldRatio;
|
||||
return [wx, wy];
|
||||
return [vx * self.virtualGridToWorldRatio, vy * self.virtualGridToWorldRatio];
|
||||
},
|
||||
|
||||
worldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH) {
|
||||
return [wx - halfBoundingW, wy - halfBoundingH];
|
||||
worldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) {
|
||||
return [wx - halfBoundingW - leftPadding, wy - halfBoundingH - bottomPadding];
|
||||
},
|
||||
|
||||
polygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH) {
|
||||
return [cx + halfBoundingW, cy + halfBoundingH];
|
||||
polygonColliderBLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) {
|
||||
return [cx + halfBoundingW + leftPadding, cy + halfBoundingH + bottomPadding];
|
||||
},
|
||||
|
||||
polygonColliderAnchorToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH) {
|
||||
polygonColliderBLToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) {
|
||||
const self = this;
|
||||
const [wx, wy] = self.polygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH);
|
||||
const [wx, wy] = self.polygonColliderBLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding);
|
||||
return self.worldToVirtualGridPos(wx, wy)
|
||||
},
|
||||
|
||||
virtualGridToPolygonColliderAnchorPos(vx, vy, halfBoundingW, halfBoundingH) {
|
||||
virtualGridToPolygonColliderBLPos(vx, vy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) {
|
||||
const self = this;
|
||||
const [wx, wy] = self.virtualGridToWorldPos(vx, vy);
|
||||
return self.worldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH)
|
||||
return self.worldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding)
|
||||
},
|
||||
|
||||
stringifyColliderCenterInWorld(playerCollider, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) {
|
||||
return `{${(playerCollider.x + leftPadding + halfBoundingW).toFixed(2)}, ${(playerCollider.y + bottomPadding + halfBoundingH).toFixed(2)}}`;
|
||||
},
|
||||
|
||||
calcHardPushbacksNorms(collider, potentials, result, snapIntoPlatformOverlap, effPushback) {
|
||||
const self = this;
|
||||
let ret = [];
|
||||
for (const potential of potentials) {
|
||||
if (null == potential.data || !(true == potential.data.hardPushback)) continue;
|
||||
if (!collider.collides(potential, result)) continue;
|
||||
// ALWAY snap into hardPushbacks!
|
||||
// [overlay_x, overlap_y] is the unit vector that points into the platform
|
||||
const pushback = [(result.overlap - snapIntoPlatformOverlap) * result.overlap_x, (result.overlap - snapIntoPlatformOverlap) * result.overlap_y];
|
||||
ret.push([result.overlap_x, result.overlap_y]);
|
||||
effPushback[0] += pushback[0];
|
||||
effPushback[1] += pushback[1];
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
});
|
||||
|
@@ -13,6 +13,7 @@ cc.Class({
|
||||
onLoad() {
|
||||
const self = this;
|
||||
window.mapIns = self;
|
||||
self.showCriticalCoordinateLabels = true;
|
||||
|
||||
cc.director.getCollisionManager().enabled = false;
|
||||
|
||||
@@ -34,9 +35,11 @@ cc.Class({
|
||||
self.inputFrameUpsyncDelayTolerance = 2;
|
||||
|
||||
self.renderCacheSize = 1024;
|
||||
self.serverFps = 60;
|
||||
self.rollbackEstimatedDt = 0.016667;
|
||||
self.rollbackEstimatedDtMillis = 16.667;
|
||||
self.rollbackEstimatedDtNanos = 16666666;
|
||||
self.tooFastDtIntervalMillis = 0.5 * self.rollbackEstimatedDtMillis;
|
||||
|
||||
self.worldToVirtualGridRatio = 1000;
|
||||
self.virtualGridToWorldRatio = 1.0 / self.worldToVirtualGridRatio;
|
||||
@@ -44,7 +47,7 @@ cc.Class({
|
||||
1: {
|
||||
// for offender
|
||||
startupFrames: 10,
|
||||
activeFrames: 3,
|
||||
activeFrames: 20,
|
||||
recoveryFrames: 34, // usually but not always "startupFrames+activeFrames", I hereby set it to be 1 frame more than the actual animation to avoid critical transition, i.e. when the animation is 1 frame from ending but "rdfPlayer.framesToRecover" is already counted 0 and the player triggers an other same attack, making an effective bullet trigger but no animation is played due to same animName is still playing
|
||||
recoveryFramesOnBlock: 34,
|
||||
recoveryFramesOnHit: 34,
|
||||
@@ -67,6 +70,16 @@ cc.Class({
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
[WARNING] As when a character is standing on a barrier, if not carefully curated there MIGHT BE a bouncing sequence of "[(inAir -> dropIntoBarrier ->), (notInAir -> pushedOutOfBarrier ->)], [(inAir -> ..."
|
||||
|
||||
Moreover, "snapIntoPlatformOverlap" should be small enough such that the walking "velX" or jumping initial "velY" can escape from it by 1 renderFrame (when jumping is triggered, the character is waived from snappig for 1 renderFrame).
|
||||
*/
|
||||
self.snapIntoPlatformOverlap = 0.1;
|
||||
self.snapIntoPlatformThreshold = 0.5; // a platform must be "horizontal enough" for a character to "stand on"
|
||||
self.jumpingInitVelY = 7 * self.worldToVirtualGridRatio; // unit: (virtual grid length/renderFrame)
|
||||
[self.gravityX, self.gravityY] = [0, -0.5*self.worldToVirtualGridRatio]; // unit: (virtual grid length/renderFrame^2)
|
||||
|
||||
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
||||
|
||||
const fullPathOfTmxFile = cc.js.formatStr("map/%s/map", "dungeon");
|
||||
@@ -80,6 +93,17 @@ cc.Class({
|
||||
mapNode.removeAllChildren();
|
||||
self._resetCurrentMatch();
|
||||
|
||||
if (self.showCriticalCoordinateLabels) {
|
||||
const drawer = new cc.Node();
|
||||
drawer.setPosition(cc.v2(0, 0))
|
||||
safelyAddChild(self.node, drawer);
|
||||
setLocalZOrder(drawer, 999);
|
||||
const g = drawer.addComponent(cc.Graphics);
|
||||
g.lineWidth = 2;
|
||||
self.g = g;
|
||||
}
|
||||
|
||||
|
||||
tiledMapIns.tmxAsset = tmxAsset;
|
||||
const newMapSize = tiledMapIns.getMapSize();
|
||||
const newTileSize = tiledMapIns.getTileSize();
|
||||
@@ -95,8 +119,11 @@ cc.Class({
|
||||
const newBarrier = self.collisionSys.createPolygon(x0, y0, Array.from(boundaryObj, p => {
|
||||
return [p.x, p.y];
|
||||
}));
|
||||
newBarrier.data = {
|
||||
hardPushback: true
|
||||
};
|
||||
|
||||
if (self.showCriticalCoordinateLabels) {
|
||||
if (false && self.showCriticalCoordinateLabels) {
|
||||
for (let i = 0; i < boundaryObj.length; ++i) {
|
||||
const barrierVertLabelNode = new cc.Node();
|
||||
switch (i % 4) {
|
||||
@@ -136,30 +163,36 @@ cc.Class({
|
||||
const startRdf = window.pb.protos.RoomDownsyncFrame.create({
|
||||
id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START,
|
||||
players: {
|
||||
10: {
|
||||
10: window.pb.protos.PlayerDownsync.create({
|
||||
id: 10,
|
||||
joinIndex: 1,
|
||||
virtualGridX: 0,
|
||||
virtualGridY: 0,
|
||||
virtualGridX: self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y)[0],
|
||||
virtualGridY: self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y)[1],
|
||||
speed: 1 * self.worldToVirtualGridRatio,
|
||||
colliderRadius: 12,
|
||||
characterState: window.ATK_CHARACTER_STATE.Idle1[0],
|
||||
characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0],
|
||||
framesToRecover: 0,
|
||||
dirX: 0,
|
||||
dirY: 0,
|
||||
},
|
||||
11: {
|
||||
velX: 0,
|
||||
velY: 0,
|
||||
inAir: true,
|
||||
}),
|
||||
11: window.pb.protos.PlayerDownsync.create({
|
||||
id: 11,
|
||||
joinIndex: 2,
|
||||
virtualGridX: 80 * self.worldToVirtualGridRatio,
|
||||
virtualGridY: 0 * self.worldToVirtualGridRatio,
|
||||
virtualGridX: self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y)[0],
|
||||
virtualGridY: self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y)[1],
|
||||
speed: 1 * self.worldToVirtualGridRatio,
|
||||
colliderRadius: 12,
|
||||
characterState: window.ATK_CHARACTER_STATE.Idle1[0],
|
||||
characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0],
|
||||
framesToRecover: 0,
|
||||
dirX: 0,
|
||||
dirY: 0,
|
||||
},
|
||||
velX: 0,
|
||||
velY: 0,
|
||||
inAir: true,
|
||||
}),
|
||||
}
|
||||
});
|
||||
self.selfPlayerInfo = {
|
||||
@@ -177,7 +210,8 @@ cc.Class({
|
||||
const self = this;
|
||||
if (ALL_BATTLE_STATES.IN_BATTLE == self.battleState) {
|
||||
const elapsedMillisSinceLastFrameIdTriggered = performance.now() - self.lastRenderFrameIdTriggeredAt;
|
||||
if (elapsedMillisSinceLastFrameIdTriggered < (self.rollbackEstimatedDtMillis)) {
|
||||
if (elapsedMillisSinceLastFrameIdTriggered < self.tooFastDtIntervalMillis) {
|
||||
// [WARNING] We should avoid a frontend ticking too fast to prevent cheating, as well as ticking too slow to cause a "resync avalanche" that impacts user experience!
|
||||
// console.debug("Avoiding too fast frame@renderFrameId=", self.renderFrameId, ": elapsedMillisSinceLastFrameIdTriggered=", elapsedMillisSinceLastFrameIdTriggered);
|
||||
return;
|
||||
}
|
||||
@@ -194,11 +228,12 @@ cc.Class({
|
||||
|
||||
const [prevRdf, rdf] = self.rollbackAndChase(self.renderFrameId, self.renderFrameId + 1, self.collisionSys, self.collisionSysMap, false);
|
||||
self.applyRoomDownsyncFrameDynamics(rdf, prevRdf);
|
||||
self.showDebugBoundaries(rdf);
|
||||
++self.renderFrameId;
|
||||
self.lastRenderFrameIdTriggeredAt = performance.now();
|
||||
let t3 = performance.now();
|
||||
} catch (err) {
|
||||
console.error("Error during Map.update", err);
|
||||
} finally {
|
||||
++self.renderFrameId; // [WARNING] It's important to increment the renderFrameId AFTER all the operations above!!!
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -108,6 +108,7 @@ TileCollisionManager.prototype.continuousMapNodePosToContinuousObjLayerOffset =
|
||||
window.battleEntityTypeNameToGlobalGid = {};
|
||||
TileCollisionManager.prototype.extractBoundaryObjects = function(withTiledMapNode) {
|
||||
let toRet = {
|
||||
playerStartingPositions: [],
|
||||
barriers: [],
|
||||
};
|
||||
const tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap); // This is a magic name.
|
||||
@@ -115,6 +116,18 @@ TileCollisionManager.prototype.extractBoundaryObjects = function(withTiledMapNod
|
||||
const allObjectGroups = tiledMapIns.getObjectGroups();
|
||||
for (let i = 0; i < allObjectGroups.length; ++i) {
|
||||
var objectGroup = allObjectGroups[i];
|
||||
if ("PlayerStartingPos" == objectGroup.getGroupName()) {
|
||||
var allObjects = objectGroup.getObjects();
|
||||
for (let j = 0; j < allObjects.length; ++j) {
|
||||
const cccMaskedX = allObjects[j].x,
|
||||
cccMaskedY = allObjects[j].y;
|
||||
const origX = cccMaskedX,
|
||||
origY = withTiledMapNode.getContentSize().height - cccMaskedY; // FIXME: I don't know why CocosCreator did this, it's stupid and MIGHT NOT WORK IN ISOMETRIC orientation!
|
||||
let wpos = this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, cc.v2(origX, origY));
|
||||
toRet.playerStartingPositions.push(wpos);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ("barrier_and_shelter" != objectGroup.getProperty("type")) continue;
|
||||
var allObjects = objectGroup.getObjects();
|
||||
for (let j = 0; j < allObjects.length; ++j) {
|
||||
@@ -123,21 +136,33 @@ TileCollisionManager.prototype.extractBoundaryObjects = function(withTiledMapNod
|
||||
if (0 < gid) {
|
||||
continue;
|
||||
}
|
||||
const polylinePoints = object.polylinePoints;
|
||||
if (null == polylinePoints) {
|
||||
continue
|
||||
}
|
||||
const boundaryType = object.boundary_type;
|
||||
let toPushBarriers = [];
|
||||
toPushBarriers.boundaryType = boundaryType;
|
||||
let toPushBarrier = [];
|
||||
toPushBarrier.boundaryType = boundaryType;
|
||||
switch (boundaryType) {
|
||||
case "barrier":
|
||||
let polylinePoints = object.polylinePoints;
|
||||
if (null == polylinePoints) {
|
||||
polylinePoints = [{
|
||||
x: 0,
|
||||
y: 0
|
||||
}, {
|
||||
x: object.width,
|
||||
y: 0
|
||||
}, {
|
||||
x: object.width,
|
||||
y: -object.height
|
||||
}, {
|
||||
x: 0,
|
||||
y: -object.height
|
||||
}];
|
||||
}
|
||||
for (let k = 0; k < polylinePoints.length; ++k) {
|
||||
/* Since CocosCreatorv2.1.3, the Y-coord of object polylines is inverted compared to that of the tmx file. */
|
||||
toPushBarriers.push(this.continuousObjLayerVecToContinuousMapNodeVec(withTiledMapNode, cc.v2(polylinePoints[k].x, -polylinePoints[k].y)));
|
||||
toPushBarrier.push(this.continuousObjLayerVecToContinuousMapNodeVec(withTiledMapNode, cc.v2(polylinePoints[k].x, -polylinePoints[k].y)));
|
||||
}
|
||||
toPushBarriers.anchor = this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, object.offset); // DON'T use "(object.x, object.y)" which are wrong/meaningless!
|
||||
toRet.barriers.push(toPushBarriers);
|
||||
toPushBarrier.anchor = this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, object.offset); // DON'T use "(object.x, object.y)" which are wrong/meaningless!
|
||||
toRet.barriers.push(toPushBarrier);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@@ -88,6 +88,14 @@ cc.Class({
|
||||
default: 0.0375,
|
||||
type: cc.Float
|
||||
},
|
||||
btnA: {
|
||||
default: null,
|
||||
type: cc.Node
|
||||
},
|
||||
btnB: {
|
||||
default: null,
|
||||
type: cc.Node
|
||||
},
|
||||
},
|
||||
|
||||
start() {},
|
||||
@@ -99,6 +107,7 @@ cc.Class({
|
||||
this.cachedBtnLeftLevel = 0;
|
||||
this.cachedBtnRightLevel = 0;
|
||||
this.cachedBtnALevel = 0;
|
||||
this.cachedBtnBLevel = 0;
|
||||
|
||||
this.canvasNode = this.mapNode.parent;
|
||||
this.mainCameraNode = this.canvasNode.getChildByName("Main Camera"); // Cannot drag and assign the `mainCameraNode` from CocosCreator EDITOR directly, otherwise it'll cause an infinite loading time, till v2.1.0.
|
||||
@@ -136,6 +145,7 @@ cc.Class({
|
||||
});
|
||||
translationListenerNode.inTouchPoints = new Map();
|
||||
|
||||
/*
|
||||
zoomingListenerNode.on(cc.Node.EventType.TOUCH_START, function(event) {
|
||||
self._touchStartEvent(event);
|
||||
});
|
||||
@@ -149,6 +159,37 @@ cc.Class({
|
||||
self._touchEndEvent(event);
|
||||
});
|
||||
zoomingListenerNode.inTouchPoints = new Map();
|
||||
*/
|
||||
|
||||
if (self.btnA) {
|
||||
self.btnA.on(cc.Node.EventType.TOUCH_START, function(evt) {
|
||||
self.cachedBtnALevel = 1;
|
||||
evt.target.runAction(cc.scaleTo(0.1, 0.3));
|
||||
});
|
||||
self.btnA.on(cc.Node.EventType.TOUCH_END, function(evt) {
|
||||
self.cachedBtnALevel = 0;
|
||||
evt.target.runAction(cc.scaleTo(0.1, 1.0));
|
||||
});
|
||||
self.btnA.on(cc.Node.EventType.TOUCH_CANCEL, function(evt) {
|
||||
self.cachedBtnALevel = 0;
|
||||
evt.target.runAction(cc.scaleTo(0.1, 1.0));
|
||||
});
|
||||
}
|
||||
|
||||
if (self.btnB) {
|
||||
self.btnB.on(cc.Node.EventType.TOUCH_START, function(evt) {
|
||||
self.cachedBtnBLevel = 1;
|
||||
evt.target.runAction(cc.scaleTo(0.1, 0.3));
|
||||
});
|
||||
self.btnB.on(cc.Node.EventType.TOUCH_END, function(evt) {
|
||||
self.cachedBtnBLevel = 0;
|
||||
evt.target.runAction(cc.scaleTo(0.1, 1.0));
|
||||
});
|
||||
self.btnB.on(cc.Node.EventType.TOUCH_CANCEL, function(evt) {
|
||||
self.cachedBtnBLevel = 0;
|
||||
evt.target.runAction(cc.scaleTo(0.1, 1.0));
|
||||
});
|
||||
}
|
||||
|
||||
// Setup keyboard controls for the ease of attach debugging
|
||||
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, function(evt) {
|
||||
@@ -168,6 +209,9 @@ cc.Class({
|
||||
case cc.macro.KEY.h:
|
||||
self.cachedBtnALevel = 1;
|
||||
break;
|
||||
case cc.macro.KEY.j:
|
||||
self.cachedBtnBLevel = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -190,6 +234,9 @@ cc.Class({
|
||||
case cc.macro.KEY.h:
|
||||
self.cachedBtnALevel = 0;
|
||||
break;
|
||||
case cc.macro.KEY.j:
|
||||
self.cachedBtnBLevel = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -400,7 +447,8 @@ cc.Class({
|
||||
getEncodedInput() {
|
||||
const discretizedDir = this.discretizeDirection(this.stickhead.x, this.stickhead.y, this.joyStickEps).encodedIdx; // There're only 9 dirs, thus using only the lower 4-bits
|
||||
const btnALevel = (this.cachedBtnALevel << 4);
|
||||
return (btnALevel + discretizedDir);
|
||||
const btnBLevel = (this.cachedBtnBLevel << 5);
|
||||
return (btnBLevel + btnALevel + discretizedDir);
|
||||
},
|
||||
|
||||
decodeInput(encodedInput) {
|
||||
@@ -410,10 +458,12 @@ cc.Class({
|
||||
console.error("Unexpected encodedDirection = ", encodedDirection);
|
||||
}
|
||||
const btnALevel = ((encodedInput >> 4) & 1);
|
||||
const btnBLevel = ((encodedInput >> 5) & 1);
|
||||
return window.pb.protos.InputFrameDecoded.create({
|
||||
dx: mappedDirection[0],
|
||||
dy: mappedDirection[1],
|
||||
btnALevel: btnALevel,
|
||||
btnBLevel: btnBLevel,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@@ -146,7 +146,7 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
|
||||
}
|
||||
try {
|
||||
const resp = window.pb.protos.WsResp.decode(new Uint8Array(evt.data));
|
||||
// console.log(`Got non-empty onmessage decoded: resp.act=${resp.act}`);
|
||||
//console.log(`Got non-empty onmessage decoded: resp.act=${resp.act}`);
|
||||
switch (resp.act) {
|
||||
case window.DOWNSYNC_MSG_ACT_HB_REQ:
|
||||
window.handleHbRequirements(resp);
|
||||
|
@@ -1196,6 +1196,8 @@ $root.protos = (function() {
|
||||
* @property {number|null} [virtualGridY] PlayerDownsync virtualGridY
|
||||
* @property {number|null} [dirX] PlayerDownsync dirX
|
||||
* @property {number|null} [dirY] PlayerDownsync dirY
|
||||
* @property {number|null} [velX] PlayerDownsync velX
|
||||
* @property {number|null} [velY] PlayerDownsync velY
|
||||
* @property {number|null} [speed] PlayerDownsync speed
|
||||
* @property {number|null} [battleState] PlayerDownsync battleState
|
||||
* @property {number|null} [joinIndex] PlayerDownsync joinIndex
|
||||
@@ -1207,6 +1209,7 @@ $root.protos = (function() {
|
||||
* @property {number|null} [hp] PlayerDownsync hp
|
||||
* @property {number|null} [maxHp] PlayerDownsync maxHp
|
||||
* @property {number|null} [characterState] PlayerDownsync characterState
|
||||
* @property {boolean|null} [inAir] PlayerDownsync inAir
|
||||
* @property {string|null} [name] PlayerDownsync name
|
||||
* @property {string|null} [displayName] PlayerDownsync displayName
|
||||
* @property {string|null} [avatar] PlayerDownsync avatar
|
||||
@@ -1267,6 +1270,22 @@ $root.protos = (function() {
|
||||
*/
|
||||
PlayerDownsync.prototype.dirY = 0;
|
||||
|
||||
/**
|
||||
* PlayerDownsync velX.
|
||||
* @member {number} velX
|
||||
* @memberof protos.PlayerDownsync
|
||||
* @instance
|
||||
*/
|
||||
PlayerDownsync.prototype.velX = 0;
|
||||
|
||||
/**
|
||||
* PlayerDownsync velY.
|
||||
* @member {number} velY
|
||||
* @memberof protos.PlayerDownsync
|
||||
* @instance
|
||||
*/
|
||||
PlayerDownsync.prototype.velY = 0;
|
||||
|
||||
/**
|
||||
* PlayerDownsync speed.
|
||||
* @member {number} speed
|
||||
@@ -1355,6 +1374,14 @@ $root.protos = (function() {
|
||||
*/
|
||||
PlayerDownsync.prototype.characterState = 0;
|
||||
|
||||
/**
|
||||
* PlayerDownsync inAir.
|
||||
* @member {boolean} inAir
|
||||
* @memberof protos.PlayerDownsync
|
||||
* @instance
|
||||
*/
|
||||
PlayerDownsync.prototype.inAir = false;
|
||||
|
||||
/**
|
||||
* PlayerDownsync name.
|
||||
* @member {string} name
|
||||
@@ -1413,34 +1440,40 @@ $root.protos = (function() {
|
||||
writer.uint32(/* id 4, wireType 0 =*/32).int32(message.dirX);
|
||||
if (message.dirY != null && Object.hasOwnProperty.call(message, "dirY"))
|
||||
writer.uint32(/* id 5, wireType 0 =*/40).int32(message.dirY);
|
||||
if (message.velX != null && Object.hasOwnProperty.call(message, "velX"))
|
||||
writer.uint32(/* id 6, wireType 0 =*/48).int32(message.velX);
|
||||
if (message.velY != null && Object.hasOwnProperty.call(message, "velY"))
|
||||
writer.uint32(/* id 7, wireType 0 =*/56).int32(message.velY);
|
||||
if (message.speed != null && Object.hasOwnProperty.call(message, "speed"))
|
||||
writer.uint32(/* id 6, wireType 0 =*/48).int32(message.speed);
|
||||
writer.uint32(/* id 8, wireType 0 =*/64).int32(message.speed);
|
||||
if (message.battleState != null && Object.hasOwnProperty.call(message, "battleState"))
|
||||
writer.uint32(/* id 7, wireType 0 =*/56).int32(message.battleState);
|
||||
writer.uint32(/* id 9, wireType 0 =*/72).int32(message.battleState);
|
||||
if (message.joinIndex != null && Object.hasOwnProperty.call(message, "joinIndex"))
|
||||
writer.uint32(/* id 8, wireType 0 =*/64).int32(message.joinIndex);
|
||||
writer.uint32(/* id 10, wireType 0 =*/80).int32(message.joinIndex);
|
||||
if (message.colliderRadius != null && Object.hasOwnProperty.call(message, "colliderRadius"))
|
||||
writer.uint32(/* id 9, wireType 1 =*/73).double(message.colliderRadius);
|
||||
writer.uint32(/* id 11, wireType 1 =*/89).double(message.colliderRadius);
|
||||
if (message.removed != null && Object.hasOwnProperty.call(message, "removed"))
|
||||
writer.uint32(/* id 10, wireType 0 =*/80).bool(message.removed);
|
||||
writer.uint32(/* id 12, wireType 0 =*/96).bool(message.removed);
|
||||
if (message.score != null && Object.hasOwnProperty.call(message, "score"))
|
||||
writer.uint32(/* id 11, wireType 0 =*/88).int32(message.score);
|
||||
writer.uint32(/* id 13, wireType 0 =*/104).int32(message.score);
|
||||
if (message.lastMoveGmtMillis != null && Object.hasOwnProperty.call(message, "lastMoveGmtMillis"))
|
||||
writer.uint32(/* id 12, wireType 0 =*/96).int32(message.lastMoveGmtMillis);
|
||||
writer.uint32(/* id 14, wireType 0 =*/112).int32(message.lastMoveGmtMillis);
|
||||
if (message.framesToRecover != null && Object.hasOwnProperty.call(message, "framesToRecover"))
|
||||
writer.uint32(/* id 13, wireType 0 =*/104).int32(message.framesToRecover);
|
||||
writer.uint32(/* id 15, wireType 0 =*/120).int32(message.framesToRecover);
|
||||
if (message.hp != null && Object.hasOwnProperty.call(message, "hp"))
|
||||
writer.uint32(/* id 14, wireType 0 =*/112).int32(message.hp);
|
||||
writer.uint32(/* id 16, wireType 0 =*/128).int32(message.hp);
|
||||
if (message.maxHp != null && Object.hasOwnProperty.call(message, "maxHp"))
|
||||
writer.uint32(/* id 15, wireType 0 =*/120).int32(message.maxHp);
|
||||
writer.uint32(/* id 17, wireType 0 =*/136).int32(message.maxHp);
|
||||
if (message.characterState != null && Object.hasOwnProperty.call(message, "characterState"))
|
||||
writer.uint32(/* id 16, wireType 0 =*/128).int32(message.characterState);
|
||||
writer.uint32(/* id 18, wireType 0 =*/144).int32(message.characterState);
|
||||
if (message.inAir != null && Object.hasOwnProperty.call(message, "inAir"))
|
||||
writer.uint32(/* id 19, wireType 0 =*/152).bool(message.inAir);
|
||||
if (message.name != null && Object.hasOwnProperty.call(message, "name"))
|
||||
writer.uint32(/* id 17, wireType 2 =*/138).string(message.name);
|
||||
writer.uint32(/* id 20, wireType 2 =*/162).string(message.name);
|
||||
if (message.displayName != null && Object.hasOwnProperty.call(message, "displayName"))
|
||||
writer.uint32(/* id 18, wireType 2 =*/146).string(message.displayName);
|
||||
writer.uint32(/* id 21, wireType 2 =*/170).string(message.displayName);
|
||||
if (message.avatar != null && Object.hasOwnProperty.call(message, "avatar"))
|
||||
writer.uint32(/* id 19, wireType 2 =*/154).string(message.avatar);
|
||||
writer.uint32(/* id 22, wireType 2 =*/178).string(message.avatar);
|
||||
return writer;
|
||||
};
|
||||
|
||||
@@ -1496,58 +1529,70 @@ $root.protos = (function() {
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
message.speed = reader.int32();
|
||||
message.velX = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
message.battleState = reader.int32();
|
||||
message.velY = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
message.joinIndex = reader.int32();
|
||||
message.speed = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 9: {
|
||||
message.colliderRadius = reader.double();
|
||||
message.battleState = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 10: {
|
||||
message.removed = reader.bool();
|
||||
message.joinIndex = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 11: {
|
||||
message.score = reader.int32();
|
||||
message.colliderRadius = reader.double();
|
||||
break;
|
||||
}
|
||||
case 12: {
|
||||
message.lastMoveGmtMillis = reader.int32();
|
||||
message.removed = reader.bool();
|
||||
break;
|
||||
}
|
||||
case 13: {
|
||||
message.framesToRecover = reader.int32();
|
||||
message.score = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 14: {
|
||||
message.hp = reader.int32();
|
||||
message.lastMoveGmtMillis = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 15: {
|
||||
message.maxHp = reader.int32();
|
||||
message.framesToRecover = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
message.characterState = reader.int32();
|
||||
message.hp = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 17: {
|
||||
message.name = reader.string();
|
||||
message.maxHp = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
message.displayName = reader.string();
|
||||
message.characterState = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 19: {
|
||||
message.inAir = reader.bool();
|
||||
break;
|
||||
}
|
||||
case 20: {
|
||||
message.name = reader.string();
|
||||
break;
|
||||
}
|
||||
case 21: {
|
||||
message.displayName = reader.string();
|
||||
break;
|
||||
}
|
||||
case 22: {
|
||||
message.avatar = reader.string();
|
||||
break;
|
||||
}
|
||||
@@ -1601,6 +1646,12 @@ $root.protos = (function() {
|
||||
if (message.dirY != null && message.hasOwnProperty("dirY"))
|
||||
if (!$util.isInteger(message.dirY))
|
||||
return "dirY: integer expected";
|
||||
if (message.velX != null && message.hasOwnProperty("velX"))
|
||||
if (!$util.isInteger(message.velX))
|
||||
return "velX: integer expected";
|
||||
if (message.velY != null && message.hasOwnProperty("velY"))
|
||||
if (!$util.isInteger(message.velY))
|
||||
return "velY: integer expected";
|
||||
if (message.speed != null && message.hasOwnProperty("speed"))
|
||||
if (!$util.isInteger(message.speed))
|
||||
return "speed: integer expected";
|
||||
@@ -1634,6 +1685,9 @@ $root.protos = (function() {
|
||||
if (message.characterState != null && message.hasOwnProperty("characterState"))
|
||||
if (!$util.isInteger(message.characterState))
|
||||
return "characterState: integer expected";
|
||||
if (message.inAir != null && message.hasOwnProperty("inAir"))
|
||||
if (typeof message.inAir !== "boolean")
|
||||
return "inAir: boolean expected";
|
||||
if (message.name != null && message.hasOwnProperty("name"))
|
||||
if (!$util.isString(message.name))
|
||||
return "name: string expected";
|
||||
@@ -1668,6 +1722,10 @@ $root.protos = (function() {
|
||||
message.dirX = object.dirX | 0;
|
||||
if (object.dirY != null)
|
||||
message.dirY = object.dirY | 0;
|
||||
if (object.velX != null)
|
||||
message.velX = object.velX | 0;
|
||||
if (object.velY != null)
|
||||
message.velY = object.velY | 0;
|
||||
if (object.speed != null)
|
||||
message.speed = object.speed | 0;
|
||||
if (object.battleState != null)
|
||||
@@ -1690,6 +1748,8 @@ $root.protos = (function() {
|
||||
message.maxHp = object.maxHp | 0;
|
||||
if (object.characterState != null)
|
||||
message.characterState = object.characterState | 0;
|
||||
if (object.inAir != null)
|
||||
message.inAir = Boolean(object.inAir);
|
||||
if (object.name != null)
|
||||
message.name = String(object.name);
|
||||
if (object.displayName != null)
|
||||
@@ -1718,6 +1778,8 @@ $root.protos = (function() {
|
||||
object.virtualGridY = 0;
|
||||
object.dirX = 0;
|
||||
object.dirY = 0;
|
||||
object.velX = 0;
|
||||
object.velY = 0;
|
||||
object.speed = 0;
|
||||
object.battleState = 0;
|
||||
object.joinIndex = 0;
|
||||
@@ -1729,6 +1791,7 @@ $root.protos = (function() {
|
||||
object.hp = 0;
|
||||
object.maxHp = 0;
|
||||
object.characterState = 0;
|
||||
object.inAir = false;
|
||||
object.name = "";
|
||||
object.displayName = "";
|
||||
object.avatar = "";
|
||||
@@ -1743,6 +1806,10 @@ $root.protos = (function() {
|
||||
object.dirX = message.dirX;
|
||||
if (message.dirY != null && message.hasOwnProperty("dirY"))
|
||||
object.dirY = message.dirY;
|
||||
if (message.velX != null && message.hasOwnProperty("velX"))
|
||||
object.velX = message.velX;
|
||||
if (message.velY != null && message.hasOwnProperty("velY"))
|
||||
object.velY = message.velY;
|
||||
if (message.speed != null && message.hasOwnProperty("speed"))
|
||||
object.speed = message.speed;
|
||||
if (message.battleState != null && message.hasOwnProperty("battleState"))
|
||||
@@ -1765,6 +1832,8 @@ $root.protos = (function() {
|
||||
object.maxHp = message.maxHp;
|
||||
if (message.characterState != null && message.hasOwnProperty("characterState"))
|
||||
object.characterState = message.characterState;
|
||||
if (message.inAir != null && message.hasOwnProperty("inAir"))
|
||||
object.inAir = message.inAir;
|
||||
if (message.name != null && message.hasOwnProperty("name"))
|
||||
object.name = message.name;
|
||||
if (message.displayName != null && message.hasOwnProperty("displayName"))
|
||||
@@ -1812,6 +1881,7 @@ $root.protos = (function() {
|
||||
* @property {number|null} [dx] InputFrameDecoded dx
|
||||
* @property {number|null} [dy] InputFrameDecoded dy
|
||||
* @property {number|null} [btnALevel] InputFrameDecoded btnALevel
|
||||
* @property {number|null} [btnBLevel] InputFrameDecoded btnBLevel
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -1853,6 +1923,14 @@ $root.protos = (function() {
|
||||
*/
|
||||
InputFrameDecoded.prototype.btnALevel = 0;
|
||||
|
||||
/**
|
||||
* InputFrameDecoded btnBLevel.
|
||||
* @member {number} btnBLevel
|
||||
* @memberof protos.InputFrameDecoded
|
||||
* @instance
|
||||
*/
|
||||
InputFrameDecoded.prototype.btnBLevel = 0;
|
||||
|
||||
/**
|
||||
* Creates a new InputFrameDecoded instance using the specified properties.
|
||||
* @function create
|
||||
@@ -1883,6 +1961,8 @@ $root.protos = (function() {
|
||||
writer.uint32(/* id 2, wireType 0 =*/16).int32(message.dy);
|
||||
if (message.btnALevel != null && Object.hasOwnProperty.call(message, "btnALevel"))
|
||||
writer.uint32(/* id 3, wireType 0 =*/24).int32(message.btnALevel);
|
||||
if (message.btnBLevel != null && Object.hasOwnProperty.call(message, "btnBLevel"))
|
||||
writer.uint32(/* id 4, wireType 0 =*/32).int32(message.btnBLevel);
|
||||
return writer;
|
||||
};
|
||||
|
||||
@@ -1929,6 +2009,10 @@ $root.protos = (function() {
|
||||
message.btnALevel = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
message.btnBLevel = reader.int32();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
reader.skipType(tag & 7);
|
||||
break;
|
||||
@@ -1973,6 +2057,9 @@ $root.protos = (function() {
|
||||
if (message.btnALevel != null && message.hasOwnProperty("btnALevel"))
|
||||
if (!$util.isInteger(message.btnALevel))
|
||||
return "btnALevel: integer expected";
|
||||
if (message.btnBLevel != null && message.hasOwnProperty("btnBLevel"))
|
||||
if (!$util.isInteger(message.btnBLevel))
|
||||
return "btnBLevel: integer expected";
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1994,6 +2081,8 @@ $root.protos = (function() {
|
||||
message.dy = object.dy | 0;
|
||||
if (object.btnALevel != null)
|
||||
message.btnALevel = object.btnALevel | 0;
|
||||
if (object.btnBLevel != null)
|
||||
message.btnBLevel = object.btnBLevel | 0;
|
||||
return message;
|
||||
};
|
||||
|
||||
@@ -2014,6 +2103,7 @@ $root.protos = (function() {
|
||||
object.dx = 0;
|
||||
object.dy = 0;
|
||||
object.btnALevel = 0;
|
||||
object.btnBLevel = 0;
|
||||
}
|
||||
if (message.dx != null && message.hasOwnProperty("dx"))
|
||||
object.dx = message.dx;
|
||||
@@ -2021,6 +2111,8 @@ $root.protos = (function() {
|
||||
object.dy = message.dy;
|
||||
if (message.btnALevel != null && message.hasOwnProperty("btnALevel"))
|
||||
object.btnALevel = message.btnALevel;
|
||||
if (message.btnBLevel != null && message.hasOwnProperty("btnBLevel"))
|
||||
object.btnBLevel = message.btnBLevel;
|
||||
return object;
|
||||
};
|
||||
|
||||
@@ -3562,6 +3654,7 @@ $root.protos = (function() {
|
||||
* @property {number|null} [refRenderFrameId] InputsBufferSnapshot refRenderFrameId
|
||||
* @property {number|Long|null} [unconfirmedMask] InputsBufferSnapshot unconfirmedMask
|
||||
* @property {Array.<protos.InputFrameDownsync>|null} [toSendInputFrameDownsyncs] InputsBufferSnapshot toSendInputFrameDownsyncs
|
||||
* @property {boolean|null} [shouldForceResync] InputsBufferSnapshot shouldForceResync
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -3604,6 +3697,14 @@ $root.protos = (function() {
|
||||
*/
|
||||
InputsBufferSnapshot.prototype.toSendInputFrameDownsyncs = $util.emptyArray;
|
||||
|
||||
/**
|
||||
* InputsBufferSnapshot shouldForceResync.
|
||||
* @member {boolean} shouldForceResync
|
||||
* @memberof protos.InputsBufferSnapshot
|
||||
* @instance
|
||||
*/
|
||||
InputsBufferSnapshot.prototype.shouldForceResync = false;
|
||||
|
||||
/**
|
||||
* Creates a new InputsBufferSnapshot instance using the specified properties.
|
||||
* @function create
|
||||
@@ -3635,6 +3736,8 @@ $root.protos = (function() {
|
||||
if (message.toSendInputFrameDownsyncs != null && message.toSendInputFrameDownsyncs.length)
|
||||
for (var i = 0; i < message.toSendInputFrameDownsyncs.length; ++i)
|
||||
$root.protos.InputFrameDownsync.encode(message.toSendInputFrameDownsyncs[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
|
||||
if (message.shouldForceResync != null && Object.hasOwnProperty.call(message, "shouldForceResync"))
|
||||
writer.uint32(/* id 4, wireType 0 =*/32).bool(message.shouldForceResync);
|
||||
return writer;
|
||||
};
|
||||
|
||||
@@ -3683,6 +3786,10 @@ $root.protos = (function() {
|
||||
message.toSendInputFrameDownsyncs.push($root.protos.InputFrameDownsync.decode(reader, reader.uint32()));
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
message.shouldForceResync = reader.bool();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
reader.skipType(tag & 7);
|
||||
break;
|
||||
@@ -3733,6 +3840,9 @@ $root.protos = (function() {
|
||||
return "toSendInputFrameDownsyncs." + error;
|
||||
}
|
||||
}
|
||||
if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync"))
|
||||
if (typeof message.shouldForceResync !== "boolean")
|
||||
return "shouldForceResync: boolean expected";
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -3769,6 +3879,8 @@ $root.protos = (function() {
|
||||
message.toSendInputFrameDownsyncs[i] = $root.protos.InputFrameDownsync.fromObject(object.toSendInputFrameDownsyncs[i]);
|
||||
}
|
||||
}
|
||||
if (object.shouldForceResync != null)
|
||||
message.shouldForceResync = Boolean(object.shouldForceResync);
|
||||
return message;
|
||||
};
|
||||
|
||||
@@ -3794,6 +3906,7 @@ $root.protos = (function() {
|
||||
object.unconfirmedMask = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
|
||||
} else
|
||||
object.unconfirmedMask = options.longs === String ? "0" : 0;
|
||||
object.shouldForceResync = false;
|
||||
}
|
||||
if (message.refRenderFrameId != null && message.hasOwnProperty("refRenderFrameId"))
|
||||
object.refRenderFrameId = message.refRenderFrameId;
|
||||
@@ -3807,6 +3920,8 @@ $root.protos = (function() {
|
||||
for (var j = 0; j < message.toSendInputFrameDownsyncs.length; ++j)
|
||||
object.toSendInputFrameDownsyncs[j] = $root.protos.InputFrameDownsync.toObject(message.toSendInputFrameDownsyncs[j], options);
|
||||
}
|
||||
if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync"))
|
||||
object.shouldForceResync = message.shouldForceResync;
|
||||
return object;
|
||||
};
|
||||
|
||||
@@ -4453,6 +4568,11 @@ $root.protos = (function() {
|
||||
* @property {number|null} [spAtkLookupFrames] BattleColliderInfo spAtkLookupFrames
|
||||
* @property {number|null} [renderCacheSize] BattleColliderInfo renderCacheSize
|
||||
* @property {Object.<string,protos.MeleeBullet>|null} [meleeSkillConfig] BattleColliderInfo meleeSkillConfig
|
||||
* @property {number|null} [snapIntoPlatformOverlap] BattleColliderInfo snapIntoPlatformOverlap
|
||||
* @property {number|null} [snapIntoPlatformThreshold] BattleColliderInfo snapIntoPlatformThreshold
|
||||
* @property {number|null} [jumpingInitVelY] BattleColliderInfo jumpingInitVelY
|
||||
* @property {number|null} [gravityX] BattleColliderInfo gravityX
|
||||
* @property {number|null} [gravityY] BattleColliderInfo gravityY
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -4681,6 +4801,46 @@ $root.protos = (function() {
|
||||
*/
|
||||
BattleColliderInfo.prototype.meleeSkillConfig = $util.emptyObject;
|
||||
|
||||
/**
|
||||
* BattleColliderInfo snapIntoPlatformOverlap.
|
||||
* @member {number} snapIntoPlatformOverlap
|
||||
* @memberof protos.BattleColliderInfo
|
||||
* @instance
|
||||
*/
|
||||
BattleColliderInfo.prototype.snapIntoPlatformOverlap = 0;
|
||||
|
||||
/**
|
||||
* BattleColliderInfo snapIntoPlatformThreshold.
|
||||
* @member {number} snapIntoPlatformThreshold
|
||||
* @memberof protos.BattleColliderInfo
|
||||
* @instance
|
||||
*/
|
||||
BattleColliderInfo.prototype.snapIntoPlatformThreshold = 0;
|
||||
|
||||
/**
|
||||
* BattleColliderInfo jumpingInitVelY.
|
||||
* @member {number} jumpingInitVelY
|
||||
* @memberof protos.BattleColliderInfo
|
||||
* @instance
|
||||
*/
|
||||
BattleColliderInfo.prototype.jumpingInitVelY = 0;
|
||||
|
||||
/**
|
||||
* BattleColliderInfo gravityX.
|
||||
* @member {number} gravityX
|
||||
* @memberof protos.BattleColliderInfo
|
||||
* @instance
|
||||
*/
|
||||
BattleColliderInfo.prototype.gravityX = 0;
|
||||
|
||||
/**
|
||||
* BattleColliderInfo gravityY.
|
||||
* @member {number} gravityY
|
||||
* @memberof protos.BattleColliderInfo
|
||||
* @instance
|
||||
*/
|
||||
BattleColliderInfo.prototype.gravityY = 0;
|
||||
|
||||
/**
|
||||
* Creates a new BattleColliderInfo instance using the specified properties.
|
||||
* @function create
|
||||
@@ -4766,6 +4926,16 @@ $root.protos = (function() {
|
||||
writer.uint32(/* id 27, wireType 2 =*/218).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]);
|
||||
$root.protos.MeleeBullet.encode(message.meleeSkillConfig[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim();
|
||||
}
|
||||
if (message.snapIntoPlatformOverlap != null && Object.hasOwnProperty.call(message, "snapIntoPlatformOverlap"))
|
||||
writer.uint32(/* id 28, wireType 1 =*/225).double(message.snapIntoPlatformOverlap);
|
||||
if (message.snapIntoPlatformThreshold != null && Object.hasOwnProperty.call(message, "snapIntoPlatformThreshold"))
|
||||
writer.uint32(/* id 29, wireType 1 =*/233).double(message.snapIntoPlatformThreshold);
|
||||
if (message.jumpingInitVelY != null && Object.hasOwnProperty.call(message, "jumpingInitVelY"))
|
||||
writer.uint32(/* id 30, wireType 0 =*/240).int32(message.jumpingInitVelY);
|
||||
if (message.gravityX != null && Object.hasOwnProperty.call(message, "gravityX"))
|
||||
writer.uint32(/* id 31, wireType 0 =*/248).int32(message.gravityX);
|
||||
if (message.gravityY != null && Object.hasOwnProperty.call(message, "gravityY"))
|
||||
writer.uint32(/* id 32, wireType 0 =*/256).int32(message.gravityY);
|
||||
return writer;
|
||||
};
|
||||
|
||||
@@ -4961,6 +5131,26 @@ $root.protos = (function() {
|
||||
message.meleeSkillConfig[key] = value;
|
||||
break;
|
||||
}
|
||||
case 28: {
|
||||
message.snapIntoPlatformOverlap = reader.double();
|
||||
break;
|
||||
}
|
||||
case 29: {
|
||||
message.snapIntoPlatformThreshold = reader.double();
|
||||
break;
|
||||
}
|
||||
case 30: {
|
||||
message.jumpingInitVelY = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 31: {
|
||||
message.gravityX = reader.int32();
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
message.gravityY = reader.int32();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
reader.skipType(tag & 7);
|
||||
break;
|
||||
@@ -5099,6 +5289,21 @@ $root.protos = (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (message.snapIntoPlatformOverlap != null && message.hasOwnProperty("snapIntoPlatformOverlap"))
|
||||
if (typeof message.snapIntoPlatformOverlap !== "number")
|
||||
return "snapIntoPlatformOverlap: number expected";
|
||||
if (message.snapIntoPlatformThreshold != null && message.hasOwnProperty("snapIntoPlatformThreshold"))
|
||||
if (typeof message.snapIntoPlatformThreshold !== "number")
|
||||
return "snapIntoPlatformThreshold: number expected";
|
||||
if (message.jumpingInitVelY != null && message.hasOwnProperty("jumpingInitVelY"))
|
||||
if (!$util.isInteger(message.jumpingInitVelY))
|
||||
return "jumpingInitVelY: integer expected";
|
||||
if (message.gravityX != null && message.hasOwnProperty("gravityX"))
|
||||
if (!$util.isInteger(message.gravityX))
|
||||
return "gravityX: integer expected";
|
||||
if (message.gravityY != null && message.hasOwnProperty("gravityY"))
|
||||
if (!$util.isInteger(message.gravityY))
|
||||
return "gravityY: integer expected";
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -5204,6 +5409,16 @@ $root.protos = (function() {
|
||||
message.meleeSkillConfig[keys[i]] = $root.protos.MeleeBullet.fromObject(object.meleeSkillConfig[keys[i]]);
|
||||
}
|
||||
}
|
||||
if (object.snapIntoPlatformOverlap != null)
|
||||
message.snapIntoPlatformOverlap = Number(object.snapIntoPlatformOverlap);
|
||||
if (object.snapIntoPlatformThreshold != null)
|
||||
message.snapIntoPlatformThreshold = Number(object.snapIntoPlatformThreshold);
|
||||
if (object.jumpingInitVelY != null)
|
||||
message.jumpingInitVelY = object.jumpingInitVelY | 0;
|
||||
if (object.gravityX != null)
|
||||
message.gravityX = object.gravityX | 0;
|
||||
if (object.gravityY != null)
|
||||
message.gravityY = object.gravityY | 0;
|
||||
return message;
|
||||
};
|
||||
|
||||
@@ -5257,6 +5472,11 @@ $root.protos = (function() {
|
||||
object.virtualGridToWorldRatio = 0;
|
||||
object.spAtkLookupFrames = 0;
|
||||
object.renderCacheSize = 0;
|
||||
object.snapIntoPlatformOverlap = 0;
|
||||
object.snapIntoPlatformThreshold = 0;
|
||||
object.jumpingInitVelY = 0;
|
||||
object.gravityX = 0;
|
||||
object.gravityY = 0;
|
||||
}
|
||||
if (message.stageName != null && message.hasOwnProperty("stageName"))
|
||||
object.stageName = message.stageName;
|
||||
@@ -5326,6 +5546,16 @@ $root.protos = (function() {
|
||||
for (var j = 0; j < keys2.length; ++j)
|
||||
object.meleeSkillConfig[keys2[j]] = $root.protos.MeleeBullet.toObject(message.meleeSkillConfig[keys2[j]], options);
|
||||
}
|
||||
if (message.snapIntoPlatformOverlap != null && message.hasOwnProperty("snapIntoPlatformOverlap"))
|
||||
object.snapIntoPlatformOverlap = options.json && !isFinite(message.snapIntoPlatformOverlap) ? String(message.snapIntoPlatformOverlap) : message.snapIntoPlatformOverlap;
|
||||
if (message.snapIntoPlatformThreshold != null && message.hasOwnProperty("snapIntoPlatformThreshold"))
|
||||
object.snapIntoPlatformThreshold = options.json && !isFinite(message.snapIntoPlatformThreshold) ? String(message.snapIntoPlatformThreshold) : message.snapIntoPlatformThreshold;
|
||||
if (message.jumpingInitVelY != null && message.hasOwnProperty("jumpingInitVelY"))
|
||||
object.jumpingInitVelY = message.jumpingInitVelY;
|
||||
if (message.gravityX != null && message.hasOwnProperty("gravityX"))
|
||||
object.gravityX = message.gravityX;
|
||||
if (message.gravityY != null && message.hasOwnProperty("gravityY"))
|
||||
object.gravityY = message.gravityY;
|
||||
return object;
|
||||
};
|
||||
|
||||
@@ -5369,6 +5599,7 @@ $root.protos = (function() {
|
||||
* @property {number|Long|null} [countdownNanos] RoomDownsyncFrame countdownNanos
|
||||
* @property {Array.<protos.MeleeBullet>|null} [meleeBullets] RoomDownsyncFrame meleeBullets
|
||||
* @property {number|Long|null} [backendUnconfirmedMask] RoomDownsyncFrame backendUnconfirmedMask
|
||||
* @property {boolean|null} [shouldForceResync] RoomDownsyncFrame shouldForceResync
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -5428,6 +5659,14 @@ $root.protos = (function() {
|
||||
*/
|
||||
RoomDownsyncFrame.prototype.backendUnconfirmedMask = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
|
||||
|
||||
/**
|
||||
* RoomDownsyncFrame shouldForceResync.
|
||||
* @member {boolean} shouldForceResync
|
||||
* @memberof protos.RoomDownsyncFrame
|
||||
* @instance
|
||||
*/
|
||||
RoomDownsyncFrame.prototype.shouldForceResync = false;
|
||||
|
||||
/**
|
||||
* Creates a new RoomDownsyncFrame instance using the specified properties.
|
||||
* @function create
|
||||
@@ -5466,6 +5705,8 @@ $root.protos = (function() {
|
||||
$root.protos.MeleeBullet.encode(message.meleeBullets[i], writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
|
||||
if (message.backendUnconfirmedMask != null && Object.hasOwnProperty.call(message, "backendUnconfirmedMask"))
|
||||
writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.backendUnconfirmedMask);
|
||||
if (message.shouldForceResync != null && Object.hasOwnProperty.call(message, "shouldForceResync"))
|
||||
writer.uint32(/* id 6, wireType 0 =*/48).bool(message.shouldForceResync);
|
||||
return writer;
|
||||
};
|
||||
|
||||
@@ -5541,6 +5782,10 @@ $root.protos = (function() {
|
||||
message.backendUnconfirmedMask = reader.uint64();
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
message.shouldForceResync = reader.bool();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
reader.skipType(tag & 7);
|
||||
break;
|
||||
@@ -5608,6 +5853,9 @@ $root.protos = (function() {
|
||||
if (message.backendUnconfirmedMask != null && message.hasOwnProperty("backendUnconfirmedMask"))
|
||||
if (!$util.isInteger(message.backendUnconfirmedMask) && !(message.backendUnconfirmedMask && $util.isInteger(message.backendUnconfirmedMask.low) && $util.isInteger(message.backendUnconfirmedMask.high)))
|
||||
return "backendUnconfirmedMask: integer|Long expected";
|
||||
if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync"))
|
||||
if (typeof message.shouldForceResync !== "boolean")
|
||||
return "shouldForceResync: boolean expected";
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -5663,6 +5911,8 @@ $root.protos = (function() {
|
||||
message.backendUnconfirmedMask = object.backendUnconfirmedMask;
|
||||
else if (typeof object.backendUnconfirmedMask === "object")
|
||||
message.backendUnconfirmedMask = new $util.LongBits(object.backendUnconfirmedMask.low >>> 0, object.backendUnconfirmedMask.high >>> 0).toNumber(true);
|
||||
if (object.shouldForceResync != null)
|
||||
message.shouldForceResync = Boolean(object.shouldForceResync);
|
||||
return message;
|
||||
};
|
||||
|
||||
@@ -5695,6 +5945,7 @@ $root.protos = (function() {
|
||||
object.backendUnconfirmedMask = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
|
||||
} else
|
||||
object.backendUnconfirmedMask = options.longs === String ? "0" : 0;
|
||||
object.shouldForceResync = false;
|
||||
}
|
||||
if (message.id != null && message.hasOwnProperty("id"))
|
||||
object.id = message.id;
|
||||
@@ -5719,6 +5970,8 @@ $root.protos = (function() {
|
||||
object.backendUnconfirmedMask = options.longs === String ? String(message.backendUnconfirmedMask) : message.backendUnconfirmedMask;
|
||||
else
|
||||
object.backendUnconfirmedMask = options.longs === String ? $util.Long.prototype.toString.call(message.backendUnconfirmedMask) : options.longs === Number ? new $util.LongBits(message.backendUnconfirmedMask.low >>> 0, message.backendUnconfirmedMask.high >>> 0).toNumber(true) : message.backendUnconfirmedMask;
|
||||
if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync"))
|
||||
object.shouldForceResync = message.shouldForceResync;
|
||||
return object;
|
||||
};
|
||||
|
||||
|
@@ -11,24 +11,28 @@ function polygonStr(body) {
|
||||
return JSON.stringify(coords);
|
||||
}
|
||||
|
||||
const playerCollider = collisionSys.createPolygon(1269.665, 1353.335, [[0, 0], [64, 0], [64, 64], [0, 64]]);
|
||||
const playerCollider1 = collisionSys.createPolygon(944.000, 676.000, [[0, 0], [24, 0], [24, 48], [0, 48]]);
|
||||
playerCollider1.data = {isPlayer: true};
|
||||
const playerCollider2 = collisionSys.createPolygon(958.000, 724.000, [[0, 0], [24, 0], [24, 48], [0, 48]]);
|
||||
playerCollider2.data = {isPlayer: true};
|
||||
|
||||
const barrierCollider1 = collisionSys.createPolygon(1277.7159000000001, 1570.5575, [[642.5696, 319.159], [0, 319.15680000000003], [5.7286, 0], [643.7451, 0.9014999999999986]]);
|
||||
const barrierCollider2 = collisionSys.createPolygon(1289.039, 1318.0805, [[628.626, 54.254500000000064], [0, 56.03250000000003], [0.42449999999999477, 1.1229999999999905], [625.9715000000001, 0]]);
|
||||
const barrierCollider3 = collisionSys.createPolygon(1207, 1310, [[69, 581], [0, 579], [8, 3], [79, 0]]);
|
||||
|
||||
playerCollider.x += -2.98;
|
||||
playerCollider.y += -50.0;
|
||||
collisionSys.update();
|
||||
|
||||
const effPushback = [0.0, 0.0];
|
||||
|
||||
const result = collisionSys.createResult();
|
||||
|
||||
const potentials = playerCollider.potentials();
|
||||
|
||||
for (const barrier of potentials) {
|
||||
if (!playerCollider.collides(barrier, result)) continue;
|
||||
// Check collision for player1
|
||||
const potentials = playerCollider1.potentials();
|
||||
for (const potential of potentials) {
|
||||
if (null == potential.data || true != potential.data.isPlayer) continue;
|
||||
console.log(`Collided player potential of a=${polygonStr(playerCollider1)}: b=${polygonStr(potential)}`);
|
||||
if (!playerCollider1.collides(potential, result)) continue;
|
||||
console.log(`Collided player of a=${polygonStr(playerCollider1)}: b=${polygonStr(potential)}`);
|
||||
const pushbackX = result.overlap * result.overlap_x;
|
||||
const pushbackY = result.overlap * result.overlap_y;
|
||||
console.log(`Overlapped: a=${polygonStr(result.a)}, b=${polygonStr(result.b)}, pushbackX=${pushbackX}, pushbackY=${pushbackY}`);
|
||||
|
Reference in New Issue
Block a user