Compare commits

...

15 Commits

Author SHA1 Message Date
genxium
89c31e8944 Updated README. 2023-01-13 15:13:27 +08:00
genxium
45380d170f Fixed fireball rollback sync. 2023-01-13 14:55:56 +08:00
genxium
dd9c03404e Fixed fireball rollback mechanism. 2023-01-13 12:10:06 +08:00
genxium
29e402ea71 Integrated onwall movements to multiplayer battle. 2023-01-12 18:09:02 +08:00
genxium
b1e3d6525c Fixes for wall jumping. 2023-01-12 16:09:20 +08:00
genxium
845282db50 Minor fix. 2023-01-12 12:55:57 +08:00
genxium
71a5a7b727 Drafted anti-air attack for Monk. 2023-01-11 22:24:31 +08:00
genxium
934a495d47 Updates for fireball bullet. 2023-01-11 18:42:57 +08:00
genxium
9725fb9df2 Minor updates. 2023-01-10 12:47:05 +08:00
Wing
7d922aab0b Merge pull request #18 from genxium/npc
Emergency fix for bullet lifecycle handling.
2023-01-10 12:40:35 +08:00
genxium
823624d95d Implemented basic fireball collision. 2023-01-10 12:37:38 +08:00
genxium
ab122a7bc8 Drafted new character as NPC. 2023-01-08 20:34:29 +08:00
genxium
5b9b3a0b55 Updated documentation. 2023-01-07 22:51:06 +08:00
genxium
24e980c17f Simplified backend input prediction. 2023-01-05 14:07:59 +08:00
genxium
ab6a04693d Enhanced backend input prediction alignment with the frontend counterpart. 2023-01-05 12:14:55 +08:00
80 changed files with 13362 additions and 1286 deletions

View File

@@ -2,11 +2,13 @@
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.5x for file size reduction, kindly note that animations are resumed from a partial progress)_
_(the following gifs are sped up to ~1.5x for file size reduction, kindly note that animations are resumed from a partial progress)_
![gif_demo](./charts/internet_fireball_wallmoveset_spedup.gif)
![gif_demo](./charts/jump_sync_spedup.gif)
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.
Please also checkout [this demo video](https://pan.baidu.com/s/1_DAEuE66s5Obf2GwtVul4Q?pwd=mfpq) 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.
@@ -27,7 +29,8 @@ _(how rollback-and-chase in this project roughly works)_
## 1.1 Tools to install
### Backend
- [Command Line Tools for Xcode](https://developer.apple.com/download/all/?q=command%20line%20tools) (on OSX) or [TDM-GCC](https://jmeubank.github.io/tdm-gcc/download/) (on Windows) (a `make` executable mandatory)
- [Golang1.18.6](https://golang.org/dl/) (brought down to 1.18 for GopherJs support, mandatory, in China please try a mirror site like [that of ustc](https://mirrors.ustc.edu.cn/golang/))
- [Golang1.18.6](https://golang.org/dl/) (brought down to 1.18 for _GopherJs_ support, mandatory, in China please try a mirror site like [that of ustc](https://mirrors.ustc.edu.cn/golang/))
- [GopherJs1.18.0-beta1](https://github.com/gopherjs/gopherjs/tree/v1.18.0-beta1) (optional, only for developemnt)
- [MySQL 5.7](https://dev.mysql.com/downloads/windows/installer/5.7.html) (mandatory, for OSX not all versions of 5.7 can be found thus 5.7.24 is recommended)
- [Redis 3.0.503 or above](https://redis.io/download/) (mandatory)
- [skeema](https://www.skeema.io/) (optional, only for convenient MySQL schema provisioning)

View File

@@ -12,7 +12,9 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
ret := &pb.RoomDownsyncFrame{
Id: rdf.Id,
PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)),
BulletLocalIdCounter: rdf.BulletLocalIdCounter,
MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)),
FireballBullets: make([]*pb.FireballBullet, len(rdf.FireballBullets), len(rdf.FireballBullets)),
CountdownNanos: rdf.CountdownNanos,
BackendUnconfirmedMask: rdf.BackendUnconfirmedMask,
ShouldForceResync: rdf.ShouldForceResync,
@@ -20,61 +22,108 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
for i, last := range rdf.PlayersArr {
pbPlayer := &pb.PlayerDownsync{
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
JoinIndex: last.JoinIndex,
Hp: last.Hp,
MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
Hp: last.Hp,
MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
}
ret.PlayersArr[i] = pbPlayer
}
for i, last := range rdf.MeleeBullets {
pbBullet := &pb.MeleeBullet{
OriginatedRenderFrameId: last.OriginatedRenderFrameId,
OffenderJoinIndex: last.OffenderJoinIndex,
BulletLocalId: last.BattleAttr.BulletLocalId,
OriginatedRenderFrameId: last.BattleAttr.OriginatedRenderFrameId,
OffenderJoinIndex: last.BattleAttr.OffenderJoinIndex,
TeamId: last.BattleAttr.TeamId,
StartupFrames: last.StartupFrames,
CancellableStFrame: last.CancellableStFrame,
CancellableEdFrame: last.CancellableEdFrame,
ActiveFrames: last.ActiveFrames,
StartupFrames: last.Bullet.StartupFrames,
CancellableStFrame: last.Bullet.CancellableStFrame,
CancellableEdFrame: last.Bullet.CancellableEdFrame,
ActiveFrames: last.Bullet.ActiveFrames,
HitStunFrames: last.HitStunFrames,
BlockStunFrames: last.BlockStunFrames,
PushbackVelX: last.PushbackVelX,
PushbackVelY: last.PushbackVelY,
Damage: last.Damage,
HitStunFrames: last.Bullet.HitStunFrames,
BlockStunFrames: last.Bullet.BlockStunFrames,
PushbackVelX: last.Bullet.PushbackVelX,
PushbackVelY: last.Bullet.PushbackVelY,
Damage: last.Bullet.Damage,
SelfLockVelX: last.SelfLockVelX,
SelfLockVelY: last.SelfLockVelY,
SelfLockVelX: last.Bullet.SelfLockVelX,
SelfLockVelY: last.Bullet.SelfLockVelY,
HitboxOffsetX: last.HitboxOffsetX,
HitboxOffsetY: last.HitboxOffsetY,
HitboxSizeX: last.HitboxSizeX,
HitboxSizeY: last.HitboxSizeY,
HitboxOffsetX: last.Bullet.HitboxOffsetX,
HitboxOffsetY: last.Bullet.HitboxOffsetY,
HitboxSizeX: last.Bullet.HitboxSizeX,
HitboxSizeY: last.Bullet.HitboxSizeY,
BlowUp: last.BlowUp,
BlowUp: last.Bullet.BlowUp,
}
ret.MeleeBullets[i] = pbBullet
}
for i, last := range rdf.FireballBullets {
pbBullet := &pb.FireballBullet{
BulletLocalId: last.BattleAttr.BulletLocalId,
OriginatedRenderFrameId: last.BattleAttr.OriginatedRenderFrameId,
OffenderJoinIndex: last.BattleAttr.OffenderJoinIndex,
TeamId: last.BattleAttr.TeamId,
StartupFrames: last.Bullet.StartupFrames,
CancellableStFrame: last.Bullet.CancellableStFrame,
CancellableEdFrame: last.Bullet.CancellableEdFrame,
ActiveFrames: last.Bullet.ActiveFrames,
HitStunFrames: last.Bullet.HitStunFrames,
BlockStunFrames: last.Bullet.BlockStunFrames,
PushbackVelX: last.Bullet.PushbackVelX,
PushbackVelY: last.Bullet.PushbackVelY,
Damage: last.Bullet.Damage,
SelfLockVelX: last.Bullet.SelfLockVelX,
SelfLockVelY: last.Bullet.SelfLockVelY,
HitboxOffsetX: last.Bullet.HitboxOffsetX,
HitboxOffsetY: last.Bullet.HitboxOffsetY,
HitboxSizeX: last.Bullet.HitboxSizeX,
HitboxSizeY: last.Bullet.HitboxSizeY,
BlowUp: last.Bullet.BlowUp,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
Speed: last.Speed,
SpeciesId: last.SpeciesId,
}
ret.FireballBullets[i] = pbBullet
}
return ret
}
@@ -86,26 +135,31 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
for _, last := range modelInstances {
pbPlayer := &pb.PlayerDownsync{
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
JoinIndex: last.JoinIndex,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
}
if withMetaInfo {
pbPlayer.Name = last.Name
@@ -126,28 +180,33 @@ func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
for _, last := range modelInstances {
toRet[last.JoinIndex-1] = &battle.PlayerDownsync{
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
JoinIndex: last.JoinIndex,
Hp: last.Hp,
MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius,
InAir: last.InAir,
Score: last.Score,
Removed: last.Removed,
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
Hp: last.Hp,
MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius,
InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
Score: last.Score,
Removed: last.Removed,
}
}

View File

@@ -46,9 +46,10 @@ type Player struct {
TutorialStage int `db:"tutorial_stage"`
// other in-battle info fields
LastSentInputFrameId int32
AckingFrameId int32
AckingInputFrameId int32
LastReceivedInputFrameId int32
LastSentInputFrameId int32
AckingFrameId int32
AckingInputFrameId int32
}
func ExistPlayerByName(name string) (bool, error) {

View File

@@ -128,7 +128,7 @@ type Room struct {
EffectivePlayerCount int32
DismissalWaitGroup sync.WaitGroup
InputsBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange]
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange, LastIndividuallyConfirmedInputList, player.LastReceivedInputFrameId]
RenderFrameBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
LatestPlayerUpsyncedInputFrameId int32
LastAllConfirmedInputFrameId int32
@@ -148,7 +148,8 @@ type Room struct {
TmxPointsMap StrToVec2DListMap
TmxPolygonsMap StrToPolygon2DListMap
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
LastIndividuallyConfirmedInputList []uint64
}
func (pR *Room) updateScore() {
@@ -172,6 +173,7 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
pPlayerFromDbInit.AckingFrameId = -1
pPlayerFromDbInit.AckingInputFrameId = -1
pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
pPlayerFromDbInit.LastReceivedInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
pPlayerFromDbInit.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
@@ -333,7 +335,20 @@ func (pR *Room) playerDownsyncStr(player *battle.PlayerDownsync) string {
if player.InAir {
inAirInt = 1
}
s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d}", player.JoinIndex, player.VirtualGridX, player.VirtualGridY, player.VelX, player.VelY, player.FramesToRecover, inAirInt)
onWallInt := 0
if player.OnWall {
onWallInt = 1
}
s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d,%d}", player.JoinIndex, player.VirtualGridX, player.VirtualGridY, player.VelX, player.VelY, player.FramesToRecover, inAirInt, onWallInt)
return s
}
func (pR *Room) fireballDownsyncStr(fireball *battle.FireballBullet) string {
if nil == fireball {
return ""
}
s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d}", fireball.BattleAttr.BulletLocalId, fireball.BattleAttr.OriginatedRenderFrameId, fireball.BattleAttr.OffenderJoinIndex, fireball.VirtualGridX, fireball.VirtualGridY, fireball.VelX, fireball.VelY, fireball.DirX, fireball.DirY, fireball.Bullet.HitboxSizeX, fireball.Bullet.HitboxSizeY)
return s
}
@@ -363,7 +378,11 @@ func (pR *Room) rdfIdToActuallyUsedInputString() string {
for _, player := range rdf.PlayersArr {
playersStrBldr = append(playersStrBldr, pR.playerDownsyncStr(player))
}
s = append(s, fmt.Sprintf("rdfId:%d\nplayers:[%v]\nactuallyUsedinputList:{%v}", rdfId, strings.Join(playersStrBldr, ","), pR.inputFrameDownsyncStr(pR.rdfIdToActuallyUsedInput[rdfId])))
fireballsStrBldr := make([]string, 0, len(rdf.FireballBullets))
for _, fireball := range rdf.FireballBullets {
fireballsStrBldr = append(fireballsStrBldr, pR.fireballDownsyncStr(fireball))
}
s = append(s, fmt.Sprintf("rdfId:%d\nplayers:[%v]\nfireballs:[%v]\nactuallyUsedinputList:{%v}", rdfId, strings.Join(playersStrBldr, ","), strings.Join(fireballsStrBldr, ","), pR.inputFrameDownsyncStr(pR.rdfIdToActuallyUsedInput[rdfId])))
}
return strings.Join(s, "\n")
@@ -379,6 +398,9 @@ func (pR *Room) StartBattle() {
for _, player := range pR.Players {
speciesId := int(player.JoinIndex - 1) // FIXME: Hardcoded the values for now
if player.JoinIndex == 1 {
speciesId = 4096
}
chosenCh := battle.Characters[speciesId]
pR.CharacterConfigsArr[player.JoinIndex-1] = chosenCh
pR.SpeciesIdList[player.JoinIndex-1] = int32(speciesId)
@@ -740,6 +762,7 @@ func (pR *Room) OnDismissed() {
pR.RenderFrameBuffer = battle.NewRingBuffer(pR.RenderCacheSize)
pR.InputsBuffer = battle.NewRingBuffer((pR.RenderCacheSize >> 1) + 1)
pR.rdfIdToActuallyUsedInput = make(map[int32]*pb.InputFrameDownsync)
pR.LastIndividuallyConfirmedInputList = make([]uint64, pR.Capacity)
pR.LatestPlayerUpsyncedInputFrameId = -1
pR.LastAllConfirmedInputFrameId = -1
@@ -1016,12 +1039,7 @@ func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputF
func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputFrameDownsync {
/*
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked.
Kindly note that on backend the prefab is much simpler than its frontend counterpart, because frontend will upsync its latest command immediately if there's any change w.r.t. its own prev cmd, thus if no upsync received from a frontend,
- EITHER it's due to local lag and bad network,
- OR there's no change w.r.t. to its prev cmd.
*/
var currInputFrameDownsync *battle.InputFrameDownsync = nil
tmp1 := pR.InputsBuffer.GetByFrameId(inputFrameId) // Would be nil if "pR.InputsBuffer.EdFrameId <= inputFrameId", else if "pR.InputsBuffer.EdFrameId > inputFrameId" is already met, then by now we can just return "tmp1.(*InputFrameDownsync)"
if nil == tmp1 {
@@ -1033,18 +1051,26 @@ func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputF
ConfirmedList: uint64(0),
}
j2 := j - 1
tmp2 := pR.InputsBuffer.GetByFrameId(j2)
if nil != tmp2 {
prevInputFrameDownsync := tmp2.(*battle.InputFrameDownsync)
for i, _ := range currInputFrameDownsync.InputList {
currInputFrameDownsync.InputList[i] = prevInputFrameDownsync.InputList[i]
}
}
/*
[WARNING] Don't reference "pR.InputsBuffer.GetByFrameId(j-1)" to prefab here!
Otherwise if an ActiveSlowTicker got a forced confirmation sequence like
```
inputFrame#42 {dx: -2} upsynced;
inputFrame#43-50 {dx: +2} ignored by [type#1 forceConfirmation];
inputFrame#51 {dx: +2} upsynced;
inputFrame#52-60 {dx: +2} ignored by [type#1 forceConfirmation];
inputFrame#61 {dx: +2} upsynced;
...there would be more [type#1 forceConfirmation]s for this ActiveSlowTicker if it doesn't catch up the upsync pace...
```
, the backend might've been prefabbing TOO QUICKLY and thus still replicating "inputFrame#42" by now for this ActiveSlowTicker, making its graphics inconsistent upon "[type#1 forceConfirmation] at inputFrame#52-60", i.e. as if always dragged to the left while having been controlled to the right for a few frames -- what's worse, the same graphical inconsistence could even impact later "[type#1 forceConfirmation]s" if this ActiveSlowTicker doesn't catch up with the upsync pace!
*/
for i, _ := range currInputFrameDownsync.InputList {
// [WARNING] The use of "InputsBufferLock" guarantees that by now "inputFrameId >= pR.InputsBuffer.EdFrameId >= pR.LatestPlayerUpsyncedInputFrameId", thus it's safe to use "pR.LastIndividuallyConfirmedInputList" for prediction.
// Don't predict "btnA & btnB"!
currInputFrameDownsync.InputList[i] = (currInputFrameDownsync.InputList[i] & uint64(15))
currInputFrameDownsync.InputList[i] = (pR.LastIndividuallyConfirmedInputList[i] & uint64(15))
}
pR.InputsBuffer.Put(currInputFrameDownsync)
@@ -1066,8 +1092,8 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#1: roomId=%v, playerId=%v, clientInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, pR.InputsBufferString(false)))
continue
}
if clientInputFrameId < pR.LastAllConfirmedInputFrameId {
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#2: roomId=%v, playerId=%v, clientInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, pR.InputsBufferString(false)))
if clientInputFrameId < player.LastReceivedInputFrameId {
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#2: roomId=%v, playerId=%v, clientInputFrameId=%v, playerLastReceivedInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, player.LastReceivedInputFrameId, pR.InputsBufferString(false)))
continue
}
if clientInputFrameId > pR.InputsBuffer.EdFrameId {
@@ -1079,6 +1105,9 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
targetInputFrameDownsync.InputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
targetInputFrameDownsync.ConfirmedList |= uint64(1 << uint32(player.JoinIndex-1))
player.LastReceivedInputFrameId = clientInputFrameId
pR.LastIndividuallyConfirmedInputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
if clientInputFrameId > pR.LatestPlayerUpsyncedInputFrameId {
pR.LatestPlayerUpsyncedInputFrameId = clientInputFrameId
}

View File

@@ -49,6 +49,11 @@ type PlayerDownsync struct {
ActiveSkillId int32 `protobuf:"varint,21,opt,name=activeSkillId,proto3" json:"activeSkillId,omitempty"`
ActiveSkillHit int32 `protobuf:"varint,22,opt,name=activeSkillHit,proto3" json:"activeSkillHit,omitempty"`
FramesInvinsible int32 `protobuf:"varint,23,opt,name=framesInvinsible,proto3" json:"framesInvinsible,omitempty"`
BulletTeamId int32 `protobuf:"varint,24,opt,name=bulletTeamId,proto3" json:"bulletTeamId,omitempty"`
ChCollisionTeamId int32 `protobuf:"varint,25,opt,name=chCollisionTeamId,proto3" json:"chCollisionTeamId,omitempty"`
OnWall bool `protobuf:"varint,26,opt,name=onWall,proto3" json:"onWall,omitempty"` // like "inAir", its 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. "onWall (prev -> curr)"
OnWallNormX int32 `protobuf:"varint,27,opt,name=onWallNormX,proto3" json:"onWallNormX,omitempty"`
OnWallNormY int32 `protobuf:"varint,28,opt,name=onWallNormY,proto3" json:"onWallNormY,omitempty"`
Name string `protobuf:"bytes,997,opt,name=name,proto3" json:"name,omitempty"`
DisplayName string `protobuf:"bytes,998,opt,name=displayName,proto3" json:"displayName,omitempty"`
Avatar string `protobuf:"bytes,999,opt,name=avatar,proto3" json:"avatar,omitempty"`
@@ -247,6 +252,41 @@ func (x *PlayerDownsync) GetFramesInvinsible() int32 {
return 0
}
func (x *PlayerDownsync) GetBulletTeamId() int32 {
if x != nil {
return x.BulletTeamId
}
return 0
}
func (x *PlayerDownsync) GetChCollisionTeamId() int32 {
if x != nil {
return x.ChCollisionTeamId
}
return 0
}
func (x *PlayerDownsync) GetOnWall() bool {
if x != nil {
return x.OnWall
}
return false
}
func (x *PlayerDownsync) GetOnWallNormX() int32 {
if x != nil {
return x.OnWallNormX
}
return 0
}
func (x *PlayerDownsync) GetOnWallNormY() int32 {
if x != nil {
return x.OnWallNormY
}
return 0
}
func (x *PlayerDownsync) GetName() string {
if x != nil {
return x.Name
@@ -789,6 +829,8 @@ type MeleeBullet struct {
HitboxSizeX int32 `protobuf:"varint,16,opt,name=hitboxSizeX,proto3" json:"hitboxSizeX,omitempty"`
HitboxSizeY int32 `protobuf:"varint,17,opt,name=hitboxSizeY,proto3" json:"hitboxSizeY,omitempty"`
BlowUp bool `protobuf:"varint,18,opt,name=blowUp,proto3" json:"blowUp,omitempty"`
TeamId int32 `protobuf:"varint,19,opt,name=teamId,proto3" json:"teamId,omitempty"`
BulletLocalId int32 `protobuf:"varint,20,opt,name=bulletLocalId,proto3" json:"bulletLocalId,omitempty"`
}
func (x *MeleeBullet) Reset() {
@@ -949,6 +991,283 @@ func (x *MeleeBullet) GetBlowUp() bool {
return false
}
func (x *MeleeBullet) GetTeamId() int32 {
if x != nil {
return x.TeamId
}
return 0
}
func (x *MeleeBullet) GetBulletLocalId() int32 {
if x != nil {
return x.BulletLocalId
}
return 0
}
type FireballBullet struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
OriginatedRenderFrameId int32 `protobuf:"varint,1,opt,name=originatedRenderFrameId,proto3" json:"originatedRenderFrameId,omitempty"`
OffenderJoinIndex int32 `protobuf:"varint,2,opt,name=offenderJoinIndex,proto3" json:"offenderJoinIndex,omitempty"`
StartupFrames int32 `protobuf:"varint,3,opt,name=startupFrames,proto3" json:"startupFrames,omitempty"`
CancellableStFrame int32 `protobuf:"varint,4,opt,name=cancellableStFrame,proto3" json:"cancellableStFrame,omitempty"`
CancellableEdFrame int32 `protobuf:"varint,5,opt,name=cancellableEdFrame,proto3" json:"cancellableEdFrame,omitempty"`
ActiveFrames int32 `protobuf:"varint,6,opt,name=activeFrames,proto3" json:"activeFrames,omitempty"`
HitStunFrames int32 `protobuf:"varint,7,opt,name=hitStunFrames,proto3" json:"hitStunFrames,omitempty"`
BlockStunFrames int32 `protobuf:"varint,8,opt,name=blockStunFrames,proto3" json:"blockStunFrames,omitempty"`
PushbackVelX int32 `protobuf:"varint,9,opt,name=pushbackVelX,proto3" json:"pushbackVelX,omitempty"`
PushbackVelY int32 `protobuf:"varint,10,opt,name=pushbackVelY,proto3" json:"pushbackVelY,omitempty"`
Damage int32 `protobuf:"varint,11,opt,name=damage,proto3" json:"damage,omitempty"`
SelfLockVelX int32 `protobuf:"varint,12,opt,name=selfLockVelX,proto3" json:"selfLockVelX,omitempty"`
SelfLockVelY int32 `protobuf:"varint,13,opt,name=selfLockVelY,proto3" json:"selfLockVelY,omitempty"`
HitboxOffsetX int32 `protobuf:"varint,14,opt,name=hitboxOffsetX,proto3" json:"hitboxOffsetX,omitempty"`
HitboxOffsetY int32 `protobuf:"varint,15,opt,name=hitboxOffsetY,proto3" json:"hitboxOffsetY,omitempty"`
HitboxSizeX int32 `protobuf:"varint,16,opt,name=hitboxSizeX,proto3" json:"hitboxSizeX,omitempty"`
HitboxSizeY int32 `protobuf:"varint,17,opt,name=hitboxSizeY,proto3" json:"hitboxSizeY,omitempty"`
BlowUp bool `protobuf:"varint,18,opt,name=blowUp,proto3" json:"blowUp,omitempty"`
TeamId int32 `protobuf:"varint,19,opt,name=teamId,proto3" json:"teamId,omitempty"`
BulletLocalId int32 `protobuf:"varint,20,opt,name=bulletLocalId,proto3" json:"bulletLocalId,omitempty"`
SpeciesId int32 `protobuf:"varint,21,opt,name=speciesId,proto3" json:"speciesId,omitempty"`
VirtualGridX int32 `protobuf:"varint,999,opt,name=virtualGridX,proto3" json:"virtualGridX,omitempty"`
VirtualGridY int32 `protobuf:"varint,1000,opt,name=virtualGridY,proto3" json:"virtualGridY,omitempty"`
DirX int32 `protobuf:"varint,1001,opt,name=dirX,proto3" json:"dirX,omitempty"`
DirY int32 `protobuf:"varint,1002,opt,name=dirY,proto3" json:"dirY,omitempty"`
VelX int32 `protobuf:"varint,1003,opt,name=velX,proto3" json:"velX,omitempty"`
VelY int32 `protobuf:"varint,1004,opt,name=velY,proto3" json:"velY,omitempty"`
Speed int32 `protobuf:"varint,1005,opt,name=speed,proto3" json:"speed,omitempty"`
}
func (x *FireballBullet) Reset() {
*x = FireballBullet{}
if protoimpl.UnsafeEnabled {
mi := &file_room_downsync_frame_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *FireballBullet) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FireballBullet) ProtoMessage() {}
func (x *FireballBullet) ProtoReflect() protoreflect.Message {
mi := &file_room_downsync_frame_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use FireballBullet.ProtoReflect.Descriptor instead.
func (*FireballBullet) Descriptor() ([]byte, []int) {
return file_room_downsync_frame_proto_rawDescGZIP(), []int{9}
}
func (x *FireballBullet) GetOriginatedRenderFrameId() int32 {
if x != nil {
return x.OriginatedRenderFrameId
}
return 0
}
func (x *FireballBullet) GetOffenderJoinIndex() int32 {
if x != nil {
return x.OffenderJoinIndex
}
return 0
}
func (x *FireballBullet) GetStartupFrames() int32 {
if x != nil {
return x.StartupFrames
}
return 0
}
func (x *FireballBullet) GetCancellableStFrame() int32 {
if x != nil {
return x.CancellableStFrame
}
return 0
}
func (x *FireballBullet) GetCancellableEdFrame() int32 {
if x != nil {
return x.CancellableEdFrame
}
return 0
}
func (x *FireballBullet) GetActiveFrames() int32 {
if x != nil {
return x.ActiveFrames
}
return 0
}
func (x *FireballBullet) GetHitStunFrames() int32 {
if x != nil {
return x.HitStunFrames
}
return 0
}
func (x *FireballBullet) GetBlockStunFrames() int32 {
if x != nil {
return x.BlockStunFrames
}
return 0
}
func (x *FireballBullet) GetPushbackVelX() int32 {
if x != nil {
return x.PushbackVelX
}
return 0
}
func (x *FireballBullet) GetPushbackVelY() int32 {
if x != nil {
return x.PushbackVelY
}
return 0
}
func (x *FireballBullet) GetDamage() int32 {
if x != nil {
return x.Damage
}
return 0
}
func (x *FireballBullet) GetSelfLockVelX() int32 {
if x != nil {
return x.SelfLockVelX
}
return 0
}
func (x *FireballBullet) GetSelfLockVelY() int32 {
if x != nil {
return x.SelfLockVelY
}
return 0
}
func (x *FireballBullet) GetHitboxOffsetX() int32 {
if x != nil {
return x.HitboxOffsetX
}
return 0
}
func (x *FireballBullet) GetHitboxOffsetY() int32 {
if x != nil {
return x.HitboxOffsetY
}
return 0
}
func (x *FireballBullet) GetHitboxSizeX() int32 {
if x != nil {
return x.HitboxSizeX
}
return 0
}
func (x *FireballBullet) GetHitboxSizeY() int32 {
if x != nil {
return x.HitboxSizeY
}
return 0
}
func (x *FireballBullet) GetBlowUp() bool {
if x != nil {
return x.BlowUp
}
return false
}
func (x *FireballBullet) GetTeamId() int32 {
if x != nil {
return x.TeamId
}
return 0
}
func (x *FireballBullet) GetBulletLocalId() int32 {
if x != nil {
return x.BulletLocalId
}
return 0
}
func (x *FireballBullet) GetSpeciesId() int32 {
if x != nil {
return x.SpeciesId
}
return 0
}
func (x *FireballBullet) GetVirtualGridX() int32 {
if x != nil {
return x.VirtualGridX
}
return 0
}
func (x *FireballBullet) GetVirtualGridY() int32 {
if x != nil {
return x.VirtualGridY
}
return 0
}
func (x *FireballBullet) GetDirX() int32 {
if x != nil {
return x.DirX
}
return 0
}
func (x *FireballBullet) GetDirY() int32 {
if x != nil {
return x.DirY
}
return 0
}
func (x *FireballBullet) GetVelX() int32 {
if x != nil {
return x.VelX
}
return 0
}
func (x *FireballBullet) GetVelY() int32 {
if x != nil {
return x.VelY
}
return 0
}
func (x *FireballBullet) GetSpeed() int32 {
if x != nil {
return x.Speed
}
return 0
}
type BattleColliderInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -967,13 +1286,13 @@ type BattleColliderInfo struct {
SpaceOffsetX float64 `protobuf:"fixed64,11,opt,name=spaceOffsetX,proto3" json:"spaceOffsetX,omitempty"`
SpaceOffsetY float64 `protobuf:"fixed64,12,opt,name=spaceOffsetY,proto3" json:"spaceOffsetY,omitempty"`
CollisionMinStep int32 `protobuf:"varint,13,opt,name=collisionMinStep,proto3" json:"collisionMinStep,omitempty"`
FrameDataLoggingEnabled bool `protobuf:"varint,999,opt,name=frameDataLoggingEnabled,proto3" json:"frameDataLoggingEnabled,omitempty"`
FrameDataLoggingEnabled bool `protobuf:"varint,1024,opt,name=frameDataLoggingEnabled,proto3" json:"frameDataLoggingEnabled,omitempty"`
}
func (x *BattleColliderInfo) Reset() {
*x = BattleColliderInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_room_downsync_frame_proto_msgTypes[9]
mi := &file_room_downsync_frame_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -986,7 +1305,7 @@ func (x *BattleColliderInfo) String() string {
func (*BattleColliderInfo) ProtoMessage() {}
func (x *BattleColliderInfo) ProtoReflect() protoreflect.Message {
mi := &file_room_downsync_frame_proto_msgTypes[9]
mi := &file_room_downsync_frame_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -999,7 +1318,7 @@ func (x *BattleColliderInfo) ProtoReflect() protoreflect.Message {
// Deprecated: Use BattleColliderInfo.ProtoReflect.Descriptor instead.
func (*BattleColliderInfo) Descriptor() ([]byte, []int) {
return file_room_downsync_frame_proto_rawDescGZIP(), []int{9}
return file_room_downsync_frame_proto_rawDescGZIP(), []int{10}
}
func (x *BattleColliderInfo) GetStageName() string {
@@ -1108,16 +1427,18 @@ type RoomDownsyncFrame struct {
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
PlayersArr []*PlayerDownsync `protobuf:"bytes,2,rep,name=playersArr,proto3" json:"playersArr,omitempty"`
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"`
SpeciesIdList []int32 `protobuf:"varint,7,rep,packed,name=speciesIdList,proto3" json:"speciesIdList,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
FireballBullets []*FireballBullet `protobuf:"bytes,5,rep,name=fireballBullets,proto3" json:"fireballBullets,omitempty"`
BackendUnconfirmedMask uint64 `protobuf:"varint,1024,opt,name=backendUnconfirmedMask,proto3" json:"backendUnconfirmedMask,omitempty"` // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
ShouldForceResync bool `protobuf:"varint,1025,opt,name=shouldForceResync,proto3" json:"shouldForceResync,omitempty"`
SpeciesIdList []int32 `protobuf:"varint,1026,rep,packed,name=speciesIdList,proto3" json:"speciesIdList,omitempty"`
BulletLocalIdCounter int32 `protobuf:"varint,1027,opt,name=bulletLocalIdCounter,proto3" json:"bulletLocalIdCounter,omitempty"`
}
func (x *RoomDownsyncFrame) Reset() {
*x = RoomDownsyncFrame{}
if protoimpl.UnsafeEnabled {
mi := &file_room_downsync_frame_proto_msgTypes[10]
mi := &file_room_downsync_frame_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1130,7 +1451,7 @@ func (x *RoomDownsyncFrame) String() string {
func (*RoomDownsyncFrame) ProtoMessage() {}
func (x *RoomDownsyncFrame) ProtoReflect() protoreflect.Message {
mi := &file_room_downsync_frame_proto_msgTypes[10]
mi := &file_room_downsync_frame_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1143,7 +1464,7 @@ func (x *RoomDownsyncFrame) ProtoReflect() protoreflect.Message {
// Deprecated: Use RoomDownsyncFrame.ProtoReflect.Descriptor instead.
func (*RoomDownsyncFrame) Descriptor() ([]byte, []int) {
return file_room_downsync_frame_proto_rawDescGZIP(), []int{10}
return file_room_downsync_frame_proto_rawDescGZIP(), []int{11}
}
func (x *RoomDownsyncFrame) GetId() int32 {
@@ -1174,6 +1495,13 @@ func (x *RoomDownsyncFrame) GetMeleeBullets() []*MeleeBullet {
return nil
}
func (x *RoomDownsyncFrame) GetFireballBullets() []*FireballBullet {
if x != nil {
return x.FireballBullets
}
return nil
}
func (x *RoomDownsyncFrame) GetBackendUnconfirmedMask() uint64 {
if x != nil {
return x.BackendUnconfirmedMask
@@ -1195,13 +1523,20 @@ func (x *RoomDownsyncFrame) GetSpeciesIdList() []int32 {
return nil
}
func (x *RoomDownsyncFrame) GetBulletLocalIdCounter() int32 {
if x != nil {
return x.BulletLocalIdCounter
}
return 0
}
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, 0x97, 0x06, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x6f,
0x6f, 0x74, 0x6f, 0x22, 0xc5, 0x07, 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,
@@ -1245,199 +1580,283 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
0x52, 0x0e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x48, 0x69, 0x74,
0x12, 0x2a, 0x0a, 0x10, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x49, 0x6e, 0x76, 0x69, 0x6e, 0x73,
0x69, 0x62, 0x6c, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x66, 0x72, 0x61, 0x6d,
0x65, 0x73, 0x49, 0x6e, 0x76, 0x69, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x12, 0x13, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0xe5, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x12, 0x21, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65,
0x18, 0xe6, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79,
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0xe7,
0x07, 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, 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, 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, 0xbf, 0x05, 0x0a, 0x0b, 0x4d, 0x65,
0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 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, 0x01, 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, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a,
0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11,
0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65,
0x78, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75,
0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65,
0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20,
0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65,
0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65,
0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20,
0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65,
0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76,
0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61,
0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x68,
0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x07, 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, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70,
0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x09, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12,
0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18,
0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56,
0x65, 0x6c, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20,
0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73,
0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x0c, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12,
0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18,
0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56,
0x65, 0x6c, 0x59, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66,
0x73, 0x65, 0x74, 0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62,
0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74,
0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x12,
0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x18, 0x10,
0x65, 0x73, 0x49, 0x6e, 0x76, 0x69, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c,
0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x18, 0x18, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0c, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64,
0x12, 0x2c, 0x0a, 0x11, 0x63, 0x68, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54,
0x65, 0x61, 0x6d, 0x49, 0x64, 0x18, 0x19, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x68, 0x43,
0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x16,
0x0a, 0x06, 0x6f, 0x6e, 0x57, 0x61, 0x6c, 0x6c, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06,
0x6f, 0x6e, 0x57, 0x61, 0x6c, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x6e, 0x57, 0x61, 0x6c, 0x6c,
0x4e, 0x6f, 0x72, 0x6d, 0x58, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f, 0x6e, 0x57,
0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x58, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x6e, 0x57, 0x61,
0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x59, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f,
0x6e, 0x57, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x59, 0x12, 0x13, 0x0a, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0xe5, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x21, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0xe6,
0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61,
0x6d, 0x65, 0x12, 0x17, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0xe7, 0x07, 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, 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, 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, 0xfd, 0x05, 0x0a, 0x0b, 0x4d, 0x65, 0x6c, 0x65,
0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 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, 0x01, 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, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69,
0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66,
0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c,
0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c,
0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74,
0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74,
0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x07, 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, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53,
0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73,
0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a,
0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c,
0x59, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28,
0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c,
0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a,
0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0d, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c,
0x59, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65,
0x74, 0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78,
0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f,
0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d,
0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x12, 0x20, 0x0a,
0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x18, 0x10, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x12,
0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x59, 0x18, 0x11,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65,
0x58, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x59,
0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69,
0x7a, 0x65, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x18, 0x12, 0x20,
0x01, 0x28, 0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x22, 0xc9, 0x05, 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, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x6f, 0x50, 0x69,
0x6e, 0x67, 0x18, 0x02, 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, 0x03, 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, 0x04, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64,
0x12, 0x30, 0x0a, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x05, 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, 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, 0x06, 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, 0x07, 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, 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, 0x08, 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, 0x09,
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, 0x28,
0x0a, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a,
0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43,
0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x70, 0x61, 0x63,
0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c,
0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x22, 0x0a, 0x0c,
0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0c, 0x20, 0x01,
0x28, 0x01, 0x52, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59,
0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e,
0x53, 0x74, 0x65, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x63, 0x6f, 0x6c, 0x6c,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x12, 0x39, 0x0a, 0x17,
0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0xe7, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17,
0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xc8, 0x02, 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, 0x36, 0x0a,
0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 0x18, 0x02, 0x20, 0x03, 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, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65,
0x72, 0x73, 0x41, 0x72, 0x72, 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, 0x12, 0x24, 0x0a, 0x0d,
0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x07, 0x20,
0x03, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c, 0x69,
0x73, 0x74, 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,
0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28,
0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x61,
0x6d, 0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49,
0x64, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74,
0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x22, 0xd3, 0x07, 0x0a, 0x0e, 0x46, 0x69, 0x72, 0x65,
0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 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, 0x01, 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, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72,
0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64,
0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61,
0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74,
0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63,
0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c,
0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63,
0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05,
0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c,
0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69,
0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c,
0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d,
0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x07, 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, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f,
0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c,
0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x09, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58,
0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59,
0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b,
0x56, 0x65, 0x6c, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0b,
0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c,
0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x0c, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58,
0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59,
0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b,
0x56, 0x65, 0x6c, 0x59, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66,
0x66, 0x73, 0x65, 0x74, 0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74,
0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69,
0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0f, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59,
0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x18,
0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a,
0x65, 0x58, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65,
0x59, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53,
0x69, 0x7a, 0x65, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x18, 0x12,
0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x12, 0x16, 0x0a, 0x06,
0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x74, 0x65,
0x61, 0x6d, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f,
0x63, 0x61, 0x6c, 0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x75, 0x6c,
0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x70,
0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73,
0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74,
0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x18, 0xe7, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x12, 0x23, 0x0a,
0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x18, 0xe8, 0x07,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69,
0x64, 0x59, 0x12, 0x13, 0x0a, 0x04, 0x64, 0x69, 0x72, 0x58, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28,
0x05, 0x52, 0x04, 0x64, 0x69, 0x72, 0x58, 0x12, 0x13, 0x0a, 0x04, 0x64, 0x69, 0x72, 0x59, 0x18,
0xea, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x69, 0x72, 0x59, 0x12, 0x13, 0x0a, 0x04,
0x76, 0x65, 0x6c, 0x58, 0x18, 0xeb, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x76, 0x65, 0x6c,
0x58, 0x12, 0x13, 0x0a, 0x04, 0x76, 0x65, 0x6c, 0x59, 0x18, 0xec, 0x07, 0x20, 0x01, 0x28, 0x05,
0x52, 0x04, 0x76, 0x65, 0x6c, 0x59, 0x12, 0x15, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18,
0xed, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0xc9, 0x05,
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, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x6f,
0x50, 0x69, 0x6e, 0x67, 0x18, 0x02, 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, 0x03, 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,
0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d,
0x49, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x05, 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, 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, 0x06, 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,
0x07, 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, 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, 0x08, 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, 0x09, 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, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53,
0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65,
0x72, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x70,
0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01,
0x52, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x22,
0x0a, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0c,
0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65,
0x74, 0x59, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d,
0x69, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x63, 0x6f,
0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x12, 0x39,
0x0a, 0x17, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x67, 0x69,
0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x80, 0x08, 0x20, 0x01, 0x28, 0x08,
0x52, 0x17, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x67, 0x69,
0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xc2, 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,
0x36, 0x0a, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 0x18, 0x02, 0x20,
0x03, 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, 0x0a, 0x70, 0x6c, 0x61,
0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 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, 0x40, 0x0a, 0x0f, 0x66, 0x69, 0x72, 0x65,
0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x72, 0x65, 0x62,
0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0f, 0x66, 0x69, 0x72, 0x65, 0x62,
0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x37, 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, 0x80, 0x08, 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, 0x2d, 0x0a, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72,
0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x81, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52,
0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79,
0x6e, 0x63, 0x12, 0x25, 0x0a, 0x0d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c,
0x69, 0x73, 0x74, 0x18, 0x82, 0x08, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x70, 0x65, 0x63,
0x69, 0x65, 0x73, 0x49, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x14, 0x62, 0x75, 0x6c,
0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
0x72, 0x18, 0x83, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74,
0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 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 (
@@ -1452,7 +1871,7 @@ func file_room_downsync_frame_proto_rawDescGZIP() []byte {
return file_room_downsync_frame_proto_rawDescData
}
var file_room_downsync_frame_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_room_downsync_frame_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_room_downsync_frame_proto_goTypes = []interface{}{
(*PlayerDownsync)(nil), // 0: protos.PlayerDownsync
(*InputFrameDecoded)(nil), // 1: protos.InputFrameDecoded
@@ -1463,23 +1882,25 @@ var file_room_downsync_frame_proto_goTypes = []interface{}{
(*WsResp)(nil), // 6: protos.WsResp
(*InputsBufferSnapshot)(nil), // 7: protos.InputsBufferSnapshot
(*MeleeBullet)(nil), // 8: protos.MeleeBullet
(*BattleColliderInfo)(nil), // 9: protos.BattleColliderInfo
(*RoomDownsyncFrame)(nil), // 10: protos.RoomDownsyncFrame
(*FireballBullet)(nil), // 9: protos.FireballBullet
(*BattleColliderInfo)(nil), // 10: protos.BattleColliderInfo
(*RoomDownsyncFrame)(nil), // 11: protos.RoomDownsyncFrame
}
var file_room_downsync_frame_proto_depIdxs = []int32{
2, // 0: protos.WsReq.inputFrameUpsyncBatch:type_name -> protos.InputFrameUpsync
4, // 1: protos.WsReq.hb:type_name -> protos.HeartbeatUpsync
10, // 2: protos.WsResp.rdf:type_name -> protos.RoomDownsyncFrame
11, // 2: protos.WsResp.rdf:type_name -> protos.RoomDownsyncFrame
3, // 3: protos.WsResp.inputFrameDownsyncBatch:type_name -> protos.InputFrameDownsync
9, // 4: protos.WsResp.bciFrame:type_name -> protos.BattleColliderInfo
10, // 4: protos.WsResp.bciFrame:type_name -> protos.BattleColliderInfo
3, // 5: protos.InputsBufferSnapshot.toSendInputFrameDownsyncs:type_name -> protos.InputFrameDownsync
0, // 6: protos.RoomDownsyncFrame.playersArr:type_name -> protos.PlayerDownsync
8, // 7: protos.RoomDownsyncFrame.meleeBullets:type_name -> protos.MeleeBullet
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
9, // 8: protos.RoomDownsyncFrame.fireballBullets:type_name -> protos.FireballBullet
9, // [9:9] is the sub-list for method output_type
9, // [9:9] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name
}
func init() { file_room_downsync_frame_proto_init() }
@@ -1597,7 +2018,7 @@ func file_room_downsync_frame_proto_init() {
}
}
file_room_downsync_frame_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BattleColliderInfo); i {
switch v := v.(*FireballBullet); i {
case 0:
return &v.state
case 1:
@@ -1609,6 +2030,18 @@ func file_room_downsync_frame_proto_init() {
}
}
file_room_downsync_frame_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BattleColliderInfo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_room_downsync_frame_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RoomDownsyncFrame); i {
case 0:
return &v.state
@@ -1627,7 +2060,7 @@ func file_room_downsync_frame_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_room_downsync_frame_proto_rawDesc,
NumEnums: 0,
NumMessages: 11,
NumMessages: 12,
NumExtensions: 0,
NumServices: 0,
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

View File

@@ -4,8 +4,10 @@ go 1.18
require (
resolv v0.0.0
jsexport v0.0.0
)
replace (
resolv => ../resolv_tailored
jsexport => ../jsexport
)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
{
"ver": "1.0.1",
"uuid": "b07a911d-2d61-486d-9edc-1b3ba53c9911",
"isSubpackage": false,
"subpackageName": "",
"subMetas": {}
}

View File

@@ -0,0 +1,145 @@
{
"__type__": "cc.AnimationClip",
"_name": "Fireball1",
"_objFlags": 0,
"_native": "",
"_duration": 0.35,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "dbe67025-9878-4e13-8f3d-81e04734810a"
}
},
{
"frame": 0.016666666666666666,
"value": {
"__uuid__": "e92702d5-d5fd-49e6-ab6b-2296b43fa6d6"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "e1a89340-0b92-4e6b-93f2-e983302d70ce"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "b0bb4a7a-4ae3-48fc-9913-3b6d1d36c56f"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "b44d585b-8e18-4767-b263-ed3a53cd3250"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "a87a9ea8-2d84-4a3b-83e3-a4d7b8ac96b8"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "a1604f9d-c0ea-4f92-b09b-3608245bda8e"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "4372818f-1e44-4180-a0ce-4a34cee4fc5b"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "dbe67025-9878-4e13-8f3d-81e04734810a"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "5d867617-7f50-4fa8-804d-ce28c47ea407"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "824c9bee-42b7-4a94-86f8-6356f11aee16"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "6389164e-93bb-4d4d-9740-5e2d5cdb1029"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "d184a083-6043-4ca6-bd14-8db1b6be1d2e"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "361b1722-e362-46e5-939e-e2d1666df374"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "662fbe4f-a1f4-46f7-83e4-eafd021432da"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "5e509118-a44b-4e7f-9686-c6bb0b30f0b0"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "bc1110c7-4423-4c43-965c-0cb3dd8e31ff"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "33cc8d11-1568-47a7-b4f1-cef4888302e5"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "83bb5dd3-510c-4fce-b393-840f14efb8cd"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "1db706f5-366a-421c-843f-a4bb016f80ec"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "41a4f35a-01c0-4a22-b5cc-7bfe25ed4501"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "ba12416b-eec3-4260-8402-7fc25b125624",
"subMetas": {}
}

View File

@@ -0,0 +1,61 @@
{
"__type__": "cc.AnimationClip",
"_name": "Dashing",
"_objFlags": 0,
"_native": "",
"_duration": 0.35,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "cf396dac-50c9-4389-90c0-55f49fd3276d"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "b9e4b5d5-c296-48c8-aa60-d22db0e5a632"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "e456c710-69f5-4dcc-9f5d-dd486a9198a1"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "ec6df76f-0004-4216-9b83-449487fe0cda"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "26032d0f-845c-4b96-89a6-d88113ed7827"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "e3e0169c-3c56-4206-a20e-35e4d0471873"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "80b98036-c5de-492b-b0e8-f1703f3a7d20"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "38b2c892-347b-4009-93f8-65b2ab1614f0",
"subMetas": {}
}

View File

@@ -15,9 +15,9 @@
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{824,544},{112,128}}</string>
<string>{{806,750},{112,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Atk1_1.png</key>
<dict>
@@ -30,9 +30,9 @@
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{0,1200},{112,128}}</string>
<string>{{0,1076},{112,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Atk1_10.png</key>
<dict>
@@ -60,7 +60,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{940,0},{80,128}}</string>
<string>{{528,515},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -75,7 +75,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{940,128},{80,128}}</string>
<string>{{934,640},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -90,9 +90,9 @@
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{0,964},{112,128}}</string>
<string>{{128,1076},{112,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Atk1_4.png</key>
<dict>
@@ -105,9 +105,9 @@
<key>spriteSourceSize</key>
<string>{112,128}</string>
<key>textureRect</key>
<string>{{112,964},{112,128}}</string>
<string>{{678,862},{112,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Atk1_5.png</key>
<dict>
@@ -120,7 +120,7 @@
<key>spriteSourceSize</key>
<string>{96,128}</string>
<key>textureRect</key>
<string>{{840,288},{96,128}}</string>
<string>{{512,643},{96,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -135,7 +135,7 @@
<key>spriteSourceSize</key>
<string>{96,128}</string>
<key>textureRect</key>
<string>{{840,416},{96,128}}</string>
<string>{{512,771},{96,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -150,7 +150,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{940,256},{80,128}}</string>
<string>{{934,768},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -165,7 +165,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{936,384},{80,128}}</string>
<string>{{934,896},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -180,9 +180,9 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{936,512},{80,128}}</string>
<string>{{806,958},{80,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>Atk2_0.png</key>
<dict>
@@ -195,7 +195,7 @@
<key>spriteSourceSize</key>
<string>{80,128}</string>
<key>textureRect</key>
<string>{{936,640},{80,128}}</string>
<string>{{934,1024},{80,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -210,7 +210,7 @@
<key>spriteSourceSize</key>
<string>{96,128}</string>
<key>textureRect</key>
<string>{{582,531},{96,128}}</string>
<string>{{512,899},{96,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -225,7 +225,7 @@
<key>spriteSourceSize</key>
<string>{128,112}</string>
<key>textureRect</key>
<string>{{326,871},{128,112}}</string>
<string>{{128,964},{128,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -240,7 +240,7 @@
<key>spriteSourceSize</key>
<string>{96,96}</string>
<key>textureRect</key>
<string>{{696,1200},{96,96}}</string>
<string>{{912,1152},{96,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -255,7 +255,7 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{416,983},{96,112}}</string>
<string>{{340,1197},{96,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -270,7 +270,7 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{656,1092},{96,112}}</string>
<string>{{452,1196},{96,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -285,9 +285,9 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{528,1113},{96,112}}</string>
<string>{{564,1155},{96,112}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>Atk2_5.png</key>
<dict>
@@ -300,9 +300,9 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{392,1207},{96,112}}</string>
<string>{{608,1043},{96,112}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>Atk2_6.png</key>
<dict>
@@ -330,7 +330,7 @@
<key>spriteSourceSize</key>
<string>{128,112}</string>
<key>textureRect</key>
<string>{{454,871},{128,112}}</string>
<string>{{678,750},{128,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -525,7 +525,7 @@
<key>spriteSourceSize</key>
<string>{96,128}</string>
<key>textureRect</key>
<string>{{582,659},{96,128}}</string>
<string>{{512,1027},{96,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -540,7 +540,7 @@
<key>spriteSourceSize</key>
<string>{112,112}</string>
<key>textureRect</key>
<string>{{240,1081},{112,112}}</string>
<string>{{448,1293},{112,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -555,7 +555,7 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{504,1209},{96,112}}</string>
<string>{{660,1155},{96,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -570,7 +570,7 @@
<key>spriteSourceSize</key>
<string>{128,112}</string>
<key>textureRect</key>
<string>{{678,980},{128,112}}</string>
<string>{{384,988},{128,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -634,6 +634,111 @@
<key>textureRotated</key>
<false/>
</dict>
<key>Dashing_1.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{114,112}</string>
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{0,1188},{114,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>Dashing_2.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{114,112}</string>
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{114,1188},{114,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>Dashing_3.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{114,112}</string>
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{0,1300},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>Dashing_4.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{114,112}</string>
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{112,1300},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>Dashing_5.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{114,112}</string>
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{0,1300},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>Dashing_6.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{114,112}</string>
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{224,1300},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>Dashing_7.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{114,112}</string>
<key>spriteSourceSize</key>
<string>{114,112}</string>
<key>textureRect</key>
<string>{{336,1293},{114,112}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>GetUp1_1.png</key>
<dict>
<key>aliases</key>
@@ -645,7 +750,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{806,791},{128,118}}</string>
<string>{{384,634},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -660,7 +765,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{0,846},{128,118}}</string>
<string>{{384,752},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -675,7 +780,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{128,846},{128,118}}</string>
<string>{{256,753},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -690,7 +795,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{326,753},{128,118}}</string>
<string>{{128,846},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -705,7 +810,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{454,753},{128,118}}</string>
<string>{{0,958},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -720,7 +825,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{678,862},{128,118}}</string>
<string>{{384,870},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -735,7 +840,7 @@
<key>spriteSourceSize</key>
<string>{128,118}</string>
<key>textureRect</key>
<string>{{806,909},{128,118}}</string>
<string>{{256,871},{128,118}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -750,7 +855,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{256,489},{70,128}}</string>
<string>{{940,0},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -765,7 +870,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{256,617},{70,128}}</string>
<string>{{940,128},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -780,7 +885,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{256,745},{70,128}}</string>
<string>{{940,256},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -795,7 +900,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{256,873},{70,128}}</string>
<string>{{937,384},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -810,7 +915,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{112,1200},{70,128}}</string>
<string>{{936,512},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -825,7 +930,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{182,1200},{70,128}}</string>
<string>{{608,531},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -840,7 +945,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{252,1200},{70,128}}</string>
<string>{{608,659},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -855,7 +960,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{252,1200},{70,128}}</string>
<string>{{608,659},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -870,7 +975,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{182,1200},{70,128}}</string>
<string>{{608,531},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -885,7 +990,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{112,1200},{70,128}}</string>
<string>{{936,512},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -900,7 +1005,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{256,873},{70,128}}</string>
<string>{{937,384},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -915,7 +1020,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{256,745},{70,128}}</string>
<string>{{940,256},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -930,7 +1035,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{256,617},{70,128}}</string>
<string>{{940,128},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -945,7 +1050,7 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{322,1200},{70,128}}</string>
<string>{{608,787},{70,128}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -960,9 +1065,9 @@
<key>spriteSourceSize</key>
<string>{70,128}</string>
<key>textureRect</key>
<string>{{528,1043},{70,128}}</string>
<string>{{608,915},{70,128}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>InAirAtk1_0.png</key>
<dict>
@@ -975,7 +1080,7 @@
<key>spriteSourceSize</key>
<string>{112,96}</string>
<key>textureRect</key>
<string>{{128,1092},{112,96}}</string>
<string>{{228,1197},{112,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1005,7 +1110,7 @@
<key>spriteSourceSize</key>
<string>{144,112}</string>
<key>textureRect</key>
<string>{{680,512},{144,112}}</string>
<string>{{0,489},{144,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1020,7 +1125,7 @@
<key>spriteSourceSize</key>
<string>{128,112}</string>
<key>textureRect</key>
<string>{{806,1027},{128,112}}</string>
<string>{{256,989},{128,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1035,7 +1140,7 @@
<key>spriteSourceSize</key>
<string>{96,96}</string>
<key>textureRect</key>
<string>{{792,1139},{96,96}}</string>
<string>{{672,1363},{96,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1050,7 +1155,7 @@
<key>spriteSourceSize</key>
<string>{80,96}</string>
<key>textureRect</key>
<string>{{934,1104},{80,96}}</string>
<string>{{672,1267},{80,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1065,7 +1170,7 @@
<key>spriteSourceSize</key>
<string>{112,112}</string>
<key>textureRect</key>
<string>{{352,1081},{112,112}}</string>
<string>{{560,1292},{112,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1080,7 +1185,7 @@
<key>spriteSourceSize</key>
<string>{128,96}</string>
<key>textureRect</key>
<string>{{0,1092},{128,96}}</string>
<string>{{384,1100},{128,96}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1095,9 +1200,9 @@
<key>spriteSourceSize</key>
<string>{80,112}</string>
<key>textureRect</key>
<string>{{934,768},{80,112}}</string>
<string>{{800,1038},{80,112}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_1.png</key>
<dict>
@@ -1110,9 +1215,9 @@
<key>spriteSourceSize</key>
<string>{80,112}</string>
<key>textureRect</key>
<string>{{934,880},{80,112}}</string>
<string>{{800,1118},{80,112}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_2.png</key>
<dict>
@@ -1125,9 +1230,9 @@
<key>spriteSourceSize</key>
<string>{64,128}</string>
<key>textureRect</key>
<string>{{464,1079},{64,128}}</string>
<string>{{678,974},{64,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_3.png</key>
<dict>
@@ -1140,9 +1245,9 @@
<key>spriteSourceSize</key>
<string>{80,112}</string>
<key>textureRect</key>
<string>{{934,992},{80,112}}</string>
<string>{{756,1198},{80,112}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_4.png</key>
<dict>
@@ -1155,7 +1260,7 @@
<key>spriteSourceSize</key>
<string>{80,96}</string>
<key>textureRect</key>
<string>{{224,1001},{80,96}}</string>
<string>{{752,1278},{80,96}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1170,9 +1275,9 @@
<key>spriteSourceSize</key>
<string>{80,96}</string>
<key>textureRect</key>
<string>{{320,1001},{80,96}}</string>
<string>{{768,1358},{80,96}}</string>
<key>textureRotated</key>
<true/>
<false/>
</dict>
<key>InAirIdle1_6.png</key>
<dict>
@@ -1185,9 +1290,9 @@
<key>spriteSourceSize</key>
<string>{80,96}</string>
<key>textureRect</key>
<string>{{792,1235},{80,96}}</string>
<string>{{868,1248},{80,96}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_7.png</key>
<dict>
@@ -1200,7 +1305,7 @@
<key>spriteSourceSize</key>
<string>{96,112}</string>
<key>textureRect</key>
<string>{{600,1209},{96,112}}</string>
<string>{{704,1038},{96,112}}</string>
<key>textureRotated</key>
<false/>
</dict>
@@ -1215,9 +1320,9 @@
<key>spriteSourceSize</key>
<string>{96,128}</string>
<key>textureRect</key>
<string>{{582,787},{96,128}}</string>
<string>{{256,1101},{96,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>InAirIdle1_9.png</key>
<dict>
@@ -1230,9 +1335,9 @@
<key>spriteSourceSize</key>
<string>{96,128}</string>
<key>textureRect</key>
<string>{{582,915},{96,128}}</string>
<string>{{806,862},{96,128}}</string>
<key>textureRotated</key>
<false/>
<true/>
</dict>
<key>LayDown1_1.png</key>
<dict>
@@ -1264,6 +1369,51 @@
<key>textureRotated</key>
<false/>
</dict>
<key>OnWall1_1.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{112,97}</string>
<key>spriteSourceSize</key>
<string>{112,97}</string>
<key>textureRect</key>
<string>{{840,288},{112,97}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>OnWall1_2.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{112,97}</string>
<key>spriteSourceSize</key>
<string>{112,97}</string>
<key>textureRect</key>
<string>{{840,400},{112,97}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>OnWall1_3.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{112,97}</string>
<key>spriteSourceSize</key>
<string>{112,97}</string>
<key>textureRect</key>
<string>{{840,400},{112,97}}</string>
<key>textureRotated</key>
<true/>
</dict>
<key>Walking_1.png</key>
<dict>
<key>aliases</key>
@@ -1275,7 +1425,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{0,489},{119,128}}</string>
<string>{{144,489},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1290,7 +1440,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{128,489},{119,128}}</string>
<string>{{0,601},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1305,7 +1455,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{0,608},{119,128}}</string>
<string>{{680,512},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1320,7 +1470,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{128,608},{119,128}}</string>
<string>{{808,512},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1335,7 +1485,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{326,515},{119,128}}</string>
<string>{{272,515},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1350,7 +1500,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{454,515},{119,128}}</string>
<string>{{128,608},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1365,7 +1515,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{678,624},{119,128}}</string>
<string>{{0,720},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1380,7 +1530,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{806,672},{119,128}}</string>
<string>{{400,515},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1395,7 +1545,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{0,727},{119,128}}</string>
<string>{{678,631},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1410,7 +1560,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{128,727},{119,128}}</string>
<string>{{806,631},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1425,7 +1575,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{326,634},{119,128}}</string>
<string>{{256,634},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1440,7 +1590,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{454,634},{119,128}}</string>
<string>{{128,727},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1455,7 +1605,7 @@
<key>spriteSourceSize</key>
<string>{119,128}</string>
<key>textureRect</key>
<string>{{678,743},{119,128}}</string>
<string>{{0,839},{119,128}}</string>
<key>textureRotated</key>
<true/>
</dict>
@@ -1471,9 +1621,9 @@
<key>realTextureFileName</key>
<string>KnifeGirl.png</string>
<key>size</key>
<string>{1020,1331}</string>
<string>{1014,1459}</string>
<key>smartupdate</key>
<string>$TexturePacker:SmartUpdate:9514b6b35473e14baf98f68515bcb817:1aae9dd4a8024ce783fdab093a39672a:1ae107e0c6667a1ecb5ed98687517e0e$</string>
<string>$TexturePacker:SmartUpdate:4ca72309f7dc04bba6be361462471d91:9a48d10caa37a76ff8c43fb72bce6103:1ae107e0c6667a1ecb5ed98687517e0e$</string>
<key>textureFileName</key>
<string>KnifeGirl.png</string>
</dict>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

@@ -0,0 +1,37 @@
{
"__type__": "cc.AnimationClip",
"_name": "OnWall",
"_objFlags": 0,
"_native": "",
"_duration": 0.26666666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "c18886db-8116-4602-84f2-51652a90269a"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "0d81cbf0-dff8-4672-99b3-2ec8055c6931"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "a183e740-3c2d-4890-8430-39a00f55f446"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "411f964a-4dd8-424c-b2e2-d92b10474ce2",
"subMetas": {}
}

View File

@@ -0,0 +1,7 @@
{
"ver": "1.0.1",
"uuid": "e0e9bbc6-e22a-4277-b674-1308432d9734",
"isSubpackage": false,
"subpackageName": "",
"subMetas": {}
}

View File

@@ -0,0 +1,61 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk1",
"_objFlags": 0,
"_native": "",
"_duration": 0.5,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "c7107ebe-c5c1-4ba6-8ef4-6eb768f7faf9"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "e0e20918-ff59-43bc-aeaf-035087934092"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "5896a135-36da-4fa9-9257-a9042ba4b546"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "4a16667a-f3b3-405c-8565-d65a4281cfc8"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "5ad9858c-52aa-4742-be68-d680210e0d0a"
}
},
{
"frame": 0.43333333333333335,
"value": {
"__uuid__": "e54dbc94-3eeb-450a-9206-655e960771d2"
}
},
{
"frame": 0.48333333333333334,
"value": {
"__uuid__": "f79260b7-7702-4f15-8f12-eb19f018aff1"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "d044ab74-be6a-49a2-85ab-eba41922c2cd",
"subMetas": {}
}

View File

@@ -0,0 +1,103 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk2",
"_objFlags": 0,
"_native": "",
"_duration": 0.6166666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "549e581f-5121-4cbb-96e9-b3b8b5b0f227"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "0355243d-755f-497b-b1ff-4ec105f4efe7"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "22386328-484b-441e-9675-6553ede6118c"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "1ed0eb22-5a20-405f-a15e-8a66348bd025"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "6e12225f-2300-4e0e-bcf6-00049bfbc48f"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "08e1ec2a-500f-4a16-a19d-383de218cc14"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "024b3ae9-7d24-4057-83d7-4b58f8651ce0"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "57f241ae-ce40-49ed-bf63-71d016e41e2f"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "d2685f61-3365-4c14-9fb1-d7b2311871c4"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "59587d34-25af-42bd-ba0c-747c5f5fa697"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "3bceacb5-309a-41e0-bdad-26e85bcf859a"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "57f6da9e-f131-4fab-9a3d-f2e894d203aa"
}
},
{
"frame": 0.55,
"value": {
"__uuid__": "c35454f3-535b-4aec-b408-b8174a74556a"
}
},
{
"frame": 0.6,
"value": {
"__uuid__": "24f5b898-42dc-4f67-b6fc-946cdb5e369f"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "2cab337d-df23-476d-8a98-b5f115a52d04",
"subMetas": {}
}

View File

@@ -0,0 +1,91 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk3",
"_objFlags": 0,
"_native": "",
"_duration": 0.5333333333333333,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "d97f6a5f-8e63-40d7-bd14-9dc71e15e5db"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "196bcbf9-e89f-4b26-b736-73e2fa787e50"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "3229e023-e63d-4a4e-af72-2b1409ea43c5"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "e2d6e8b8-b468-4edb-b8c3-860bd85ebeae"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "318745eb-06b1-4e7f-88d1-e23e02d99e67"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "bba6f088-0e1f-4a12-9872-41670be1152a"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "2c5de5b2-9009-48fa-bef4-ae34cc94f876"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "6f27b252-6eaf-4b4b-9c5a-46ba899e4845"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "4ebd5c60-efa6-4950-a4c8-74a7a8517333"
}
},
{
"frame": 0.4166666666666667,
"value": {
"__uuid__": "a207290f-4556-4adb-8a11-e1d5ba342550"
}
},
{
"frame": 0.4666666666666667,
"value": {
"__uuid__": "e9d442d2-981d-437d-87c0-085162017de7"
}
},
{
"frame": 0.5166666666666667,
"value": {
"__uuid__": "9b4d5c8c-5ec0-4fd7-a45e-6b0bc8ff9119"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "504dd9c8-7850-44e8-a944-bbdb2260b18a",
"subMetas": {}
}

View File

@@ -0,0 +1,115 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk4",
"_objFlags": 0,
"_native": "",
"_duration": 0.6833333333333333,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "a4f724de-140f-472a-be83-731520d3da38"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "3594a12d-5b5c-4dc6-8138-1b48eacf0798"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "cdef413d-f009-45d3-aeb6-423652fc366d"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "688682c4-ea77-4d2c-b1e4-079f5880d3cd"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "ca9f0a44-9977-4b24-8243-ac5536f14bc8"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "6b4dbc7c-a872-40d6-be0e-4d1a96eddd44"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "b43c8a38-1d55-4d6b-b6a1-fc888a9e53b5"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "0eb3d73a-a724-46f3-b1f1-56d315150320"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "ddac83f4-f0bf-460e-9a83-cc75c69ef024"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "8e673fdc-2cc8-435c-8a0d-38dcfc7b8600"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "7a345895-6501-4388-88f6-984992a3799b"
}
},
{
"frame": 0.4666666666666667,
"value": {
"__uuid__": "99b4e340-52ca-4f3e-a86f-ca385ff8797a"
}
},
{
"frame": 0.5166666666666667,
"value": {
"__uuid__": "554d0862-0d1c-4f61-8d47-03362cd9eb1d"
}
},
{
"frame": 0.5666666666666667,
"value": {
"__uuid__": "cd15a283-cf0d-48d4-9162-2d72202baf82"
}
},
{
"frame": 0.6166666666666667,
"value": {
"__uuid__": "b2bb7fdf-2532-408f-a3d1-fe8bf0e34f61"
}
},
{
"frame": 0.6666666666666666,
"value": {
"__uuid__": "435c0195-a5c3-4a8f-9d44-e6f026649b70"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "7e0a1e98-ee5a-446f-bec2-7d72b6916503",
"subMetas": {}
}

View File

@@ -0,0 +1,85 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk5",
"_objFlags": 0,
"_native": "",
"_duration": 1.0166666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "6aa88bb9-0427-496f-ae7d-dc06410e904e"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "cdc65f83-c526-48b6-8a96-758b098568fe"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "927636af-2d1d-4801-a546-857f5eeb256d"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "2aeeb833-9151-4160-9775-9e08a376fd63"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "2bd1de9e-30e5-4bc5-b6c3-5c286754b0b7"
}
},
{
"frame": 0.4666666666666667,
"value": {
"__uuid__": "15a6ebb3-289a-46fb-ac94-f6efa0d90510"
}
},
{
"frame": 0.5833333333333334,
"value": {
"__uuid__": "6ca922c0-cb62-4b1b-8773-79685a58bbd6"
}
},
{
"frame": 0.7,
"value": {
"__uuid__": "d60ceb6f-3a45-47dd-8d3f-bcfe8c919d85"
}
},
{
"frame": 0.8,
"value": {
"__uuid__": "c313f6a1-e0fa-4321-8336-c32f471b2592"
}
},
{
"frame": 0.9,
"value": {
"__uuid__": "bb886d03-7f3e-45c8-acfd-393091f09adb"
}
},
{
"frame": 1,
"value": {
"__uuid__": "1be255c3-f8c9-43ae-be68-2e500e7f1125"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "0abbd156-980e-475e-9994-3c958bd913fc",
"subMetas": {}
}

View File

@@ -0,0 +1,31 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atked1",
"_objFlags": 0,
"_native": "",
"_duration": 0.06666666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "7ceb8a79-f5bf-4918-afa1-d76a85a571b0"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "23ce7632-8b44-4138-b3b2-3e296ba9184c"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "488ad635-2683-4884-9e93-d1ee67bd0e49",
"subMetas": {}
}

View File

@@ -0,0 +1,133 @@
{
"__type__": "cc.AnimationClip",
"_name": "BlownUp1",
"_objFlags": 0,
"_native": "",
"_duration": 0.55,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "ba708108-b18f-4ec0-81f6-0e516e4f832b"
}
},
{
"frame": 0.016666666666666666,
"value": {
"__uuid__": "aeeaa976-f3b4-4b77-a18b-b08ddd28d812"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "89d06edf-8838-4ab4-adbd-059acf21dc8c"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "c2f38b89-f7a0-477b-921c-f56ee385b737"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "90186972-a736-449d-8e64-d15c4ebcbfd1"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "1d64b1f5-5f08-4247-a43c-ffe2d58e09df"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "cf158505-bb9c-4836-b45f-2b253dfef117"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "a2984de9-99db-40bf-9969-0b163a97d9eb"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "66f0b5dc-4e0e-4597-a7f9-b9ee6752bc98"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "3cf0f5bd-0104-4315-a750-55b5fb26e1ec"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "a31b8683-ca31-4268-80d6-5b117af86ee6"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "a7ab4cb1-2221-4aba-8ced-dc93d8dca2f3"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "2ac3a00d-059a-4e15-a9cb-378bd671c9f3"
}
},
{
"frame": 0.38333333333333336,
"value": {
"__uuid__": "2b5cab9a-420c-406a-bef4-6aaee4ae6e8f"
}
},
{
"frame": 0.4166666666666667,
"value": {
"__uuid__": "6df0a35f-062b-49ec-aa73-146f8b2207a7"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "afaac620-4293-4336-9a44-bf7927c6751c"
}
},
{
"frame": 0.48333333333333334,
"value": {
"__uuid__": "410823b3-14e4-475b-b658-dc4d5325f307"
}
},
{
"frame": 0.5166666666666667,
"value": {
"__uuid__": "34a43c48-497b-4495-97c9-8de53cbcc229"
}
},
{
"frame": 0.5333333333333333,
"value": {
"__uuid__": "c7ffc314-70ae-4a2b-9238-db1778a336d1"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "8e17dfc6-68d0-47fe-af06-d30dc2790a6b",
"subMetas": {}
}

View File

@@ -0,0 +1,91 @@
{
"__type__": "cc.AnimationClip",
"_name": "GetUp1",
"_objFlags": 0,
"_native": "",
"_duration": 0.5166666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "ec0d05f4-3c30-4107-b9b4-3ccff5fb9a02"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "3e0fa075-ffdc-490f-872c-b77e202df224"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "f3c8e924-c86a-426b-a3de-ffc6e19060f3"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "35b847f0-f3f7-4ec9-ba93-5616f763d658"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "a018eecc-27e6-4d60-973f-ed9fe86a147e"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "3d70f10e-a3f7-4b7a-aedb-a010ad946abe"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "b860cb8a-2445-49bc-96f0-aac4396be922"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "bddec025-747e-4602-9352-6fc3bf921dc0"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "22053496-5240-40d3-98bd-49e16d05f7f9"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "9de8f787-3059-403d-bdcb-f7d4bd59ba65"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "471de8d2-34ee-4605-b8c5-9f3983db8a04"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "a4cb5179-60eb-41f8-bcef-56ce3299da19"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "da6a7cc1-9709-42f4-b6d0-17c1917a08a3",
"subMetas": {}
}

View File

@@ -0,0 +1,67 @@
{
"__type__": "cc.AnimationClip",
"_name": "Idle1",
"_objFlags": 0,
"_native": "",
"_duration": 0.8333333333333334,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "2c5f2d24-01f1-4a0f-8ddc-eacfbc9b6208"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "fd29846b-1998-49ba-89f6-f665b9ea7002"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "e3b30506-3a86-462e-b265-e7f6c7c09dc5"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "84f15682-b73e-443d-8d9f-f530f152bcce"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "45249fea-e7e7-4b68-8971-49d825960248"
}
},
{
"frame": 0.6166666666666667,
"value": {
"__uuid__": "ca561428-9e45-41a9-8d66-c0468d4c85d9"
}
},
{
"frame": 0.7166666666666667,
"value": {
"__uuid__": "062f3bd5-beca-435a-8d82-524fd51a88a0"
}
},
{
"frame": 0.8166666666666667,
"value": {
"__uuid__": "23068811-a6e5-4ef5-960f-7e6dea328c84"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "2d402c67-e47d-4de0-8a80-40bc12073ffc",
"subMetas": {}
}

View File

@@ -0,0 +1,79 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirAtk1",
"_objFlags": 0,
"_native": "",
"_duration": 0.6,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "70adb814-3dca-492f-a0fe-36d4d6b37e01"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "7c67ab61-96e0-4c43-a2d8-742fa1021107"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "beb4bc62-b6bf-4a07-973e-1b91e3942ab3"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "422441bd-8551-46d3-9383-162553035080"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "312f8dd2-7d02-4a80-a960-17d197c96da4"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "42597d6a-b982-43aa-90bd-2e9a01063628"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "487b65c3-44e3-4b0e-9350-e0d1c952785b"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "9a5357ae-a160-4198-a6d5-cc9631fde754"
}
},
{
"frame": 0.5333333333333333,
"value": {
"__uuid__": "d08fc3b2-f6e8-4ff8-bba4-69ce3eb771df"
}
},
{
"frame": 0.5833333333333334,
"value": {
"__uuid__": "9f8ef3e0-6f56-41d2-97d1-ac7f3cc690ee"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "5035ddfe-ff75-4dff-a506-89cbb26220da",
"subMetas": {}
}

View File

@@ -0,0 +1,49 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirAtked1",
"_objFlags": 0,
"_native": "",
"_duration": 0.25,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "39c94369-a78d-459d-9305-13a2b9c15225"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "c85b7940-7bb2-4597-a309-155b7a116f94"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "78f498f8-6517-4e28-91f9-b70ee87beff9"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "02247899-3345-411a-aaa3-65e2f5e0b3e6"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "bec5291d-8f6e-426c-8e16-1d0239a69bad"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "ac0fa38d-d3ad-4dff-841d-4d98ee5017db",
"subMetas": {}
}

View File

@@ -0,0 +1,91 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirIdle1ByJump",
"_objFlags": 0,
"_native": "",
"_duration": 0.5833333333333334,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "493a132d-af22-4621-842a-9fdc645b3e43"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "06d18871-0cb6-41eb-a484-5c6a4c04d5d5"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "f298ff82-ad9d-4945-ab19-14c3e3d54c95"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "bb5924a6-40cf-4e43-8c94-e51b27861656"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "fc4b5181-77af-44ec-836e-c14eec8d20c4"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "5ddd3db3-79b2-4f0c-bb76-2446801ff665"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "032785ce-c911-479b-be1c-2e0899a586d0"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "d651269d-1c08-49f8-bc38-d301bf26b0e1"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "e270563e-d98d-4a80-82db-837183053ae3"
}
},
{
"frame": 0.43333333333333335,
"value": {
"__uuid__": "aec31ef8-46dc-4f0e-9cba-18f6c96c5c33"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "e64b3a8d-41a9-45f6-9aeb-9e49b6317080"
}
},
{
"frame": 0.5666666666666667,
"value": {
"__uuid__": "cf886091-24a9-4cfb-8cb9-e3db977035ab"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "a4315723-e7b6-40e7-9a3c-bac959378b90",
"subMetas": {}
}

View File

@@ -0,0 +1,31 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirIdle1NoJump",
"_objFlags": 0,
"_native": "",
"_duration": 0.2833333333333333,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "e64b3a8d-41a9-45f6-9aeb-9e49b6317080"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "cf886091-24a9-4cfb-8cb9-e3db977035ab"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "53b0ae11-f77f-4c3a-9e6d-76159d135c2c",
"subMetas": {}
}

View File

@@ -0,0 +1,97 @@
{
"__type__": "cc.AnimationClip",
"_name": "LayDown1",
"_objFlags": 0,
"_native": "",
"_duration": 0.23333333333333334,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "b521e99d-b206-4453-bcb7-55d0049a229a"
}
},
{
"frame": 0.016666666666666666,
"value": {
"__uuid__": "04656482-51fb-4a3d-aa3a-28c682ff4852"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "44b85e26-64bb-47d9-90ba-4ae8c10fd9f1"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "2afb056b-e83a-4074-ac6c-ac6edaa0ff37"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "0ca0d5ca-01d3-4013-8819-1f79be60fa91"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "50902f57-47ef-4e07-beec-f633a96c5116"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "78914b1e-5202-4b2a-86b8-696bc989d43a"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "5dd8649a-7fd4-4c82-b4c9-17739901e637"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "76fcd7e0-0841-4308-a152-a561aec76659"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "32b61366-3f7e-4e83-88f1-9c63d6fb45de"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "8b692f1c-570e-4c35-a40d-e3b6b5973396"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "756ff6b2-3c2d-4a5b-87f3-1e37073d80e5"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "dc43217f-afeb-42fb-bdea-04b18ffee56f"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "e4faa04d-28f5-40b0-b1a5-99cd902e5fd6",
"subMetas": {}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

View File

@@ -0,0 +1,12 @@
{
"ver": "2.3.3",
"uuid": "6e1dbec7-ad55-413b-8108-0ac881c76a8b",
"type": "raw",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"platformSettings": {},
"subMetas": {}
}

View File

@@ -0,0 +1,85 @@
{
"__type__": "cc.AnimationClip",
"_name": "Walking",
"_objFlags": 0,
"_native": "",
"_duration": 0.85,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "a47f518e-62fb-4549-8897-4f2d387bd145"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "2b694de4-addf-4960-a765-b422da36e3a7"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "7cc4b946-7646-4377-b2ac-b75c047dfe1c"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "758814fe-7feb-4daa-8ecf-f0ba412f87dc"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "3794c342-1ddb-423e-85ca-09f14fbd2cfb"
}
},
{
"frame": 0.4166666666666667,
"value": {
"__uuid__": "c3899480-a64e-4e16-897b-562b76d0d85c"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "509a8985-2442-4326-9cd9-d77cad6e4e66"
}
},
{
"frame": 0.5833333333333334,
"value": {
"__uuid__": "bdb51693-f9cc-4828-ab25-e131939b358d"
}
},
{
"frame": 0.6666666666666666,
"value": {
"__uuid__": "c47e6d89-5e15-4f9c-a4ee-ec10e3b04295"
}
},
{
"frame": 0.75,
"value": {
"__uuid__": "e919100a-50ba-46ce-9ddb-e29f524da610"
}
},
{
"frame": 0.8333333333333334,
"value": {
"__uuid__": "c6e2cfeb-1d9d-4793-86fa-bc9a2f80f67a"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "18d10aad-93ee-44e8-9048-1f26c136492b",
"subMetas": {}
}

View File

@@ -1,18 +1,57 @@
<?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="4" nextobjectid="107">
<map version="1.2" tiledversion="1.2.3" orientation="orthogonal" renderorder="right-down" width="128" height="64" tilewidth="16" tileheight="16" infinite="0" nextlayerid="7" nextobjectid="135">
<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">
<layer id="6" name="Ground" width="128" height="64">
<data encoding="base64" compression="zlib">
eJzt3LGK1EAcwOGwYnPF4SEKWl8h+BLWV52Ndlb3AqKNVoL4ADYW9r6nu5BAXHeS7OwkM8l8xQfH3RLu8vtPLhOWfdQ0zSMAAAAAAAAAAAAAAAAAAIhw1cr9e7Cch56u/0OFcnfI2X/X6vp/2LsL2G2Q/v/2D9F/e/r970b6XxXQSv/5+p+i/7Yd/vZnrVPn5viakLuV/sv2r4H++ufukLP/0wi5m+mft/+WZkB//XN3WGP/kuhfZ3/rv+7+KWZA//Wy/vXXv97+KWZA//Tntnum+P1Cc699/fXXfx39X7T0r6d/v3f/a/311z9f/ycjUvbv0z9v/7Hup/r/2nt3pq6/+79y+k9tf9+4/1+Lqf2ntt/pvypj/U81fr13HWh/3P/Y/Zn0z9f/VPvrnuPuc/R/vnerfzH9h677/f6p6V9u/5h7xHPpv3z/KTNwfC5T9h2Tsv+ugBYl9k91jofEtNd/O/3PmZE5jq3/5TPwJ1GLVMfRP13/KTOg/zrpr39J3XL1z91Bf/3X3P9nQvqvr/+a6V83/eumf930r5v+ddO/bvrXTf+66V83/eumf930r5v+5boN0L+M/nO9XzTUfY450L+c/jcjHgfov43+Oegf31v/dSv9/k//7fUP/W/vfv42of4xQ9cn7/8e9751fL3vvp97DV+6/vUfNvQ/f039T10j9B8W2nMdjO3XbiYcP2f7rn/uDqX27zq/usCl+/M52+s//7lP8Yxmrvb6p3+eFuqfYwam7BFq77/U+u8s9Zxo6h5R/2X7dzMw5+e9nPOMQP//pbyfH9o/hHyLENNe//F+l85BTP+YGfgRSf9pYufgZRPX//BZAJ8DrTtf9z62r9V/3v6x9v3fxPY/+NSE+3/pve7Q8ndL/+n9yd8BAAAAAAAAAAAAAAAAWN5f3AoF6w==
eJzt2ztuAjEURmELlIYuiKRHyk4iGjo2wP6XkRDGUmThxwx3fC3+U3wNw8v3eEyabEMIWwAAAAAAAAAAAADo4IQ/3h08+3t/B2/KM1BeOzPQXjsz0F47M6iv/c3oc6zeh/7+/Q+NHr1P6z7YGz2H/svWXur1TP/SvqL/OP1LnSz6t7Qt9a1dp//4/VvOgJJeM3hlLf2tzNljI83glY2+9vcMpRko9E/PgFz3NfbBKDNQ7r+kvdU+GHEGHv2/Gl9zNHrOKOh/t5vQX8dt7d+JeC19PDo2yr1+NHEG3i28+m8m8f6//jpnbAzkfsNr15eqfR/1+z/tfxP/Fvj/mFX/0dD/7pz0fsR69p8rmHv20D9vl5mZ1flb67VkP81pT/8QPialmT1z/5f2QK/7v7Q/6Z/vb6F0DvToXzuf1PvDv4Nn/4s4+mujvzb6a6O/Nvpro782+mujvzb6a6O/Nvpro782+mujvzb6a6O/Nvpro782+mujvzb6a6O/tvg/UN4t6E9/+tO/d3+s1/8HUhSy6A==
</data>
</layer>
<objectgroup id="1" name="PlayerStartingPos">
<object id="135" x="1040.33" y="1081">
<object id="135" x="1140" y="488">
<point/>
</object>
<object id="137" x="1134.67" y="1081.67">
<object id="137" x="1527" y="488">
<point/>
</object>
</objectgroup>
<objectgroup id="4" name="NpcStartingPos">
<object id="108" x="927.333" y="535">
<properties>
<property name="dirX" value="-2"/>
<property name="speciesId" value="4196"/>
</properties>
<point/>
</object>
</objectgroup>
<objectgroup id="5" name="NpcPatrolCue">
<object id="109" x="774.67" y="556.67">
<properties>
<property name="flAct" value="36"/>
<property name="frAct" value="35"/>
</properties>
<point/>
</object>
<object id="110" x="729.333" y="588">
<properties>
<property name="flAct" value="4"/>
<property name="frAct" value="35"/>
</properties>
<point/>
</object>
<object id="111" x="669.333" y="588">
<properties>
<property name="flAct" value="3"/>
<property name="frAct" value="3"/>
</properties>
<point/>
</object>
<object id="112" x="985.333" y="535">
<properties>
<property name="flAct" value="4"/>
<property name="frAct" value="4"/>
</properties>
<point/>
</object>
</objectgroup>
@@ -20,197 +59,147 @@
<properties>
<property name="type" value="barrier_and_shelter"/>
</properties>
<object id="54" x="656" y="1504" width="80" height="16">
<object id="57" x="768" y="560" width="32" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="55" x="736" y="1552" width="112" height="16">
<object id="60" x="1232" y="432" width="208" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="57" x="768" y="1472" width="32" height="16">
<object id="65" x="1040" y="576" width="32" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="58" x="1040" y="1536" width="80" height="16">
<object id="66" x="1040" y="560" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="59" x="1040" y="1568" width="224" height="48">
<object id="67" x="784" y="544" width="256" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="60" x="1216" y="1344" width="224" height="16">
<object id="84" x="640" y="224" width="16" height="800">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="62" x="1040" y="1552" width="208" height="16">
<object id="85" x="1680" y="224" width="16" height="800">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="63" x="1040" y="1504" width="48" height="16">
<object id="86" x="1104" y="496" width="96" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="64" x="1040" y="1520" width="64" height="16">
<object id="90" x="1232" y="496" width="320" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="65" x="1040" y="1488" width="32" height="16">
<object id="97" x="1248" y="416" width="158" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="66" x="1040" y="1472" width="16" height="16">
<object id="98" x="1280" y="400" width="96" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="67" x="784" y="1456" width="256" height="16">
<object id="100" x="1552" y="576" width="128" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="73" x="784" y="1568" width="96" height="16">
<object id="101" x="1568" y="560" width="112" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="74" x="816" y="1584" width="96" height="16">
<object id="102" x="1584" y="544" width="96" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="79" x="640" y="1616" width="1056" height="16">
<object id="103" x="1600" y="528" width="80" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="83" x="640" y="480" width="1056" height="16">
<object id="104" x="768" y="382" width="304" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="84" x="640" y="480" width="16" height="1152">
<object id="105" x="768" y="302" width="16" height="96">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="85" x="1680" y="480" width="16" height="1152">
<object id="106" x="1056" y="302" width="16" height="96">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="86" x="1104" y="1408" width="96" height="16">
<object id="113" x="640" y="1008" width="1056" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="87" x="1456" y="1568" width="224" height="48">
<object id="114" x="640" y="224" width="1056" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="88" x="1264" y="1584" width="16" height="32">
<object id="119" x="656" y="592" width="1024" height="416">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="89" x="1280" y="1600" width="16" height="16">
<object id="120" x="736" y="512" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="90" x="1232" y="1408" width="304" height="16">
<object id="121" x="736" y="336" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="91" x="1440" y="1584" width="16" height="32">
<object id="125" x="688" y="448" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="92" x="1424" y="1600" width="16" height="16">
<object id="127" x="1088" y="320" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="93" x="1488" y="1552" width="192" height="16">
<object id="128" x="1120" y="336" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="94" x="1504" y="1536" width="176" height="16">
<object id="129" x="1136" y="368" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="95" x="1520" y="1520" width="160" height="16">
<object id="130" x="1168" y="384" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="96" x="1568" y="1408" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="97" x="1248" y="1328" width="158" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="98" x="1280" y="1312" width="96" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="99" x="1536" y="1504" width="144" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="100" x="1552" y="1488" width="128" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="101" x="1568" y="1472" width="112" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="102" x="1584" y="1456" width="96" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="103" x="1600" y="1440" width="80" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="104" x="928" y="1088" width="304" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="105" x="928" y="1008" width="16" height="96">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>
</object>
<object id="106" x="1216" y="1008" width="16" height="96">
<object id="132" x="1184" y="416" width="16" height="16">
<properties>
<property name="boundary_type" value="barrier"/>
</properties>

View File

@@ -29,6 +29,13 @@ message PlayerDownsync {
int32 activeSkillHit = 22;
int32 framesInvinsible = 23;
int32 bulletTeamId = 24;
int32 chCollisionTeamId = 25;
bool onWall = 26; // like "inAir", its 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. "onWall (prev -> curr)"
int32 onWallNormX = 27;
int32 onWallNormY = 28;
string name = 997;
string displayName = 998;
string avatar = 999;
@@ -111,6 +118,47 @@ message MeleeBullet {
int32 hitboxSizeY = 17;
bool blowUp = 18;
int32 teamId = 19;
int32 bulletLocalId = 20;
}
message FireballBullet {
int32 originatedRenderFrameId = 1;
int32 offenderJoinIndex = 2;
int32 startupFrames = 3;
int32 cancellableStFrame = 4;
int32 cancellableEdFrame = 5;
int32 activeFrames = 6;
int32 hitStunFrames = 7;
int32 blockStunFrames = 8;
int32 pushbackVelX = 9;
int32 pushbackVelY = 10;
int32 damage = 11;
int32 selfLockVelX = 12;
int32 selfLockVelY = 13;
int32 hitboxOffsetX = 14;
int32 hitboxOffsetY = 15;
int32 hitboxSizeX = 16;
int32 hitboxSizeY = 17;
bool blowUp = 18;
int32 teamId = 19;
int32 bulletLocalId = 20;
int32 speciesId = 21;
int32 virtualGridX = 999;
int32 virtualGridY = 1000;
int32 dirX = 1001;
int32 dirY = 1002;
int32 velX = 1003;
int32 velY = 1004;
int32 speed = 1005;
}
message BattleColliderInfo {
@@ -130,7 +178,7 @@ message BattleColliderInfo {
double spaceOffsetY = 12;
int32 collisionMinStep = 13;
bool frameDataLoggingEnabled = 999;
bool frameDataLoggingEnabled = 1024;
}
message RoomDownsyncFrame {
@@ -138,7 +186,11 @@ message RoomDownsyncFrame {
repeated PlayerDownsync playersArr = 2;
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;
repeated int32 speciesIdList = 7;
repeated FireballBullet fireballBullets = 5;
uint64 backendUnconfirmedMask = 1024; // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
bool shouldForceResync = 1025;
repeated int32 speciesIdList = 1026;
int32 bulletLocalIdCounter = 1027;
}

View File

@@ -25,16 +25,10 @@
},
{
"__id__": 8
},
{
"__id__": 11
}
],
"_active": true,
"_components": [
{
"__id__": 21
},
{
"__id__": 22
}
@@ -194,180 +188,6 @@
"fileId": "5apzDmIE9IuaMOyF3z06sc",
"sync": false
},
{
"__type__": "cc.Node",
"_name": "particlesystem",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": false,
"_components": [
{
"__id__": 6
}
],
"_prefab": {
"__id__": 7
},
"_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,
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.ParticleSystem",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 5
},
"_enabled": true,
"_materials": [],
"_srcBlendFactor": 770,
"_dstBlendFactor": 1,
"_custom": true,
"_file": {
"__uuid__": "b2687ac4-099e-403c-a192-ff477686f4f5"
},
"_spriteFrame": {
"__uuid__": "472df5d3-35e7-4184-9e6c-7f41bee65ee3"
},
"_texture": null,
"_stopped": true,
"playOnLoad": true,
"autoRemoveOnFinish": false,
"totalParticles": 200,
"duration": -1,
"emissionRate": 999.999985098839,
"life": 0.20000000298023224,
"lifeVar": 0.5,
"_startColor": {
"__type__": "cc.Color",
"r": 202,
"g": 200,
"b": 86,
"a": 163
},
"_startColorVar": {
"__type__": "cc.Color",
"r": 229,
"g": 255,
"b": 173,
"a": 198
},
"_endColor": {
"__type__": "cc.Color",
"r": 173,
"g": 161,
"b": 19,
"a": 214
},
"_endColorVar": {
"__type__": "cc.Color",
"r": 107,
"g": 249,
"b": 249,
"a": 188
},
"angle": 360,
"angleVar": 360,
"startSize": 3.369999885559082,
"startSizeVar": 50,
"endSize": 30.31999969482422,
"endSizeVar": 0,
"startSpin": -47.369998931884766,
"startSpinVar": 0,
"endSpin": -47.369998931884766,
"endSpinVar": -142.11000061035156,
"sourcePos": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"posVar": {
"__type__": "cc.Vec2",
"x": 7,
"y": 7
},
"_positionType": 1,
"positionType": 1,
"emitterMode": 0,
"gravity": {
"__type__": "cc.Vec2",
"x": 0.25,
"y": 0.8600000143051147
},
"speed": 0,
"speedVar": 190.7899932861328,
"tangentialAccel": -92.11000061035156,
"tangentialAccelVar": 65.79000091552734,
"radialAccel": -671.0499877929688,
"radialAccelVar": 65.79000091552734,
"rotationIsDir": false,
"startRadius": 0,
"startRadiusVar": 0,
"endRadius": 0,
"endRadiusVar": 0,
"rotatePerS": 0,
"rotatePerSVar": 0,
"_N$preview": true,
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
},
"fileId": "04uxaznclAmLRL13XKszPJ",
"sync": false
},
{
"__type__": "cc.Node",
"_name": "arrowTip",
@@ -379,11 +199,11 @@
"_active": true,
"_components": [
{
"__id__": 9
"__id__": 6
}
],
"_prefab": {
"__id__": 10
"__id__": 7
},
"_opacity": 255,
"_color": {
@@ -437,7 +257,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 8
"__id__": 5
},
"_enabled": true,
"_materials": [
@@ -486,16 +306,19 @@
},
"_children": [
{
"__id__": 12
"__id__": 9
},
{
"__id__": 16
"__id__": 13
},
{
"__id__": 17
}
],
"_active": true,
"_components": [],
"_prefab": {
"__id__": 20
"__id__": 21
},
"_opacity": 255,
"_color": {
@@ -549,20 +372,20 @@
"_name": "MonkGirl",
"_objFlags": 0,
"_parent": {
"__id__": 11
"__id__": 8
},
"_children": [],
"_active": false,
"_components": [
{
"__id__": 13
"__id__": 10
},
{
"__id__": 14
"__id__": 11
}
],
"_prefab": {
"__id__": 15
"__id__": 12
},
"_opacity": 255,
"_color": {
@@ -616,7 +439,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 12
"__id__": 9
},
"_enabled": true,
"_defaultClip": null,
@@ -669,7 +492,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 12
"__id__": 9
},
"_enabled": true,
"_materials": [
@@ -712,20 +535,20 @@
"_name": "KnifeGirl",
"_objFlags": 0,
"_parent": {
"__id__": 11
"__id__": 8
},
"_children": [],
"_active": false,
"_components": [
{
"__id__": 17
"__id__": 14
},
{
"__id__": 18
"__id__": 15
}
],
"_prefab": {
"__id__": 19
"__id__": 16
},
"_opacity": 255,
"_color": {
@@ -779,7 +602,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 16
"__id__": 13
},
"_enabled": true,
"_defaultClip": null,
@@ -822,6 +645,14 @@
},
{
"__uuid__": "9b500cb0-8048-4715-81db-cc975c914225"
},
null,
null,
{
"__uuid__": "38b2c892-347b-4009-93f8-65b2ab1614f0"
},
{
"__uuid__": "411f964a-4dd8-424c-b2e2-d92b10474ce2"
}
],
"playOnLoad": false,
@@ -832,7 +663,7 @@
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 16
"__id__": 13
},
"_enabled": true,
"_materials": [
@@ -870,6 +701,171 @@
"fileId": "bdCx1wrTtJ1KaGHUmgL7iA",
"sync": false
},
{
"__type__": "cc.Node",
"_name": "Monk",
"_objFlags": 0,
"_parent": {
"__id__": 8
},
"_children": [],
"_active": false,
"_components": [
{
"__id__": 18
},
{
"__id__": 19
}
],
"_prefab": {
"__id__": 20
},
"_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
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
-24,
0,
0,
0,
0,
1,
0.65,
0.55,
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__": 17
},
"_enabled": true,
"_defaultClip": null,
"_clips": [
{
"__uuid__": "2d402c67-e47d-4de0-8a80-40bc12073ffc"
},
{
"__uuid__": "18d10aad-93ee-44e8-9048-1f26c136492b"
},
{
"__uuid__": "d044ab74-be6a-49a2-85ab-eba41922c2cd"
},
{
"__uuid__": "488ad635-2683-4884-9e93-d1ee67bd0e49"
},
{
"__uuid__": "53b0ae11-f77f-4c3a-9e6d-76159d135c2c"
},
{
"__uuid__": "a4315723-e7b6-40e7-9a3c-bac959378b90"
},
{
"__uuid__": "5035ddfe-ff75-4dff-a506-89cbb26220da"
},
{
"__uuid__": "ac0fa38d-d3ad-4dff-841d-4d98ee5017db"
},
{
"__uuid__": "8e17dfc6-68d0-47fe-af06-d30dc2790a6b"
},
{
"__uuid__": "e4faa04d-28f5-40b0-b1a5-99cd902e5fd6"
},
{
"__uuid__": "da6a7cc1-9709-42f4-b6d0-17c1917a08a3"
},
{
"__uuid__": "2cab337d-df23-476d-8a98-b5f115a52d04"
},
{
"__uuid__": "504dd9c8-7850-44e8-a944-bbdb2260b18a"
},
{
"__uuid__": "7e0a1e98-ee5a-446f-bec2-7d72b6916503"
},
{
"__uuid__": "0abbd156-980e-475e-9994-3c958bd913fc"
}
],
"playOnLoad": false,
"_id": ""
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 17
},
"_enabled": true,
"_materials": [],
"_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__": "6dcd5722-8ef9-47fd-9520-861d2713e274"
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
},
"fileId": "45OnfvPXBMSb4XkS+kny9/",
"sync": false
},
{
"__type__": "cc.PrefabInfo",
"root": {
@@ -881,32 +877,6 @@
"fileId": "7aN7Gcc/tBw5EGlTJVBj2+",
"sync": false
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"_materials": [],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": null,
"_type": 0,
"_sizeMode": 0,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": ""
},
{
"__type__": "b74b05YDqZFRo4OkZRFZX8k",
"_name": "",
@@ -917,10 +887,10 @@
"_enabled": true,
"lastMovedAt": 0,
"animNode": {
"__id__": 11
"__id__": 8
},
"arrowTipNode": {
"__id__": 8
"__id__": 5
},
"coordLabel": {
"__id__": 3

View File

@@ -0,0 +1,308 @@
[
{
"__type__": "cc.Prefab",
"_name": "",
"_objFlags": 0,
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"asyncLoadAssets": false,
"readonly": false
},
{
"__type__": "cc.Node",
"_name": "Root",
"_objFlags": 0,
"_parent": null,
"_children": [
{
"__id__": 2
}
],
"_active": true,
"_components": [
{
"__id__": 8
}
],
"_prefab": {
"__id__": 9
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 120,
"height": 120
},
"_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": 2,
"groupIndex": 2,
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "animNode",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [
{
"__id__": 3
}
],
"_active": true,
"_components": [],
"_prefab": {
"__id__": 7
},
"_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,
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.Node",
"_name": "Fireball1",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_children": [],
"_active": false,
"_components": [
{
"__id__": 4
},
{
"__id__": 5
}
],
"_prefab": {
"__id__": 6
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 117,
"height": 55
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
-32,
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.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 3
},
"_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__": "6dcd5722-8ef9-47fd-9520-861d2713e274"
},
"_id": ""
},
{
"__type__": "cc.Animation",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 3
},
"_enabled": true,
"_defaultClip": {
"__uuid__": "ba12416b-eec3-4260-8402-7fc25b125624"
},
"_clips": [
{
"__uuid__": "ba12416b-eec3-4260-8402-7fc25b125624"
}
],
"playOnLoad": false,
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
},
"fileId": "5f1s6pDt5F3rknJTu0gQW7",
"sync": false
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
},
"fileId": "3824oBeVVL1KOAQ6Zd9CC5",
"sync": false
},
{
"__type__": "e66a2qRmRZGnqSyVMwLy6Pw",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"animNode": {
"__id__": 2
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
},
"fileId": "4cx75uwJJFa7U8QL187QCL",
"sync": false
}
]

View File

@@ -0,0 +1,8 @@
{
"ver": "1.2.5",
"uuid": "d92d4831-cd65-4eb5-90bd-b77021aec35b",
"optimizationPolicy": "AUTO",
"asyncLoadAssets": false,
"readonly": false,
"subMetas": {}
}

View File

@@ -0,0 +1,597 @@
[
{
"__type__": "cc.Prefab",
"_name": "",
"_objFlags": 0,
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"asyncLoadAssets": false,
"readonly": false
},
{
"__type__": "cc.Node",
"_name": "Root",
"_objFlags": 0,
"_parent": null,
"_children": [
{
"__id__": 2
},
{
"__id__": 5
},
{
"__id__": 8
}
],
"_active": true,
"_components": [
{
"__id__": 14
},
{
"__id__": 15
}
],
"_prefab": {
"__id__": 16
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 120,
"height": 120
},
"_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": 2,
"groupIndex": 2,
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "CoordinateLabel",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 3
}
],
"_prefab": {
"__id__": 4
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 28.01,
"height": 15.12
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
45,
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.Label",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 2
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_useOriginalSize": false,
"_string": "(0, 0)",
"_N$string": "(0, 0)",
"_fontSize": 12,
"_lineHeight": 12,
"_enableWrapText": true,
"_N$file": null,
"_isSystemFontUsed": true,
"_spacingX": 0,
"_batchAsBitmap": false,
"_N$horizontalAlign": 1,
"_N$verticalAlign": 1,
"_N$fontFamily": "Arial",
"_N$overflow": 0,
"_N$cacheMode": 0,
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "4c12c853-b743-4c11-a452-e384834a1c18"
},
"fileId": "5apzDmIE9IuaMOyF3z06sc",
"sync": false
},
{
"__type__": "cc.Node",
"_name": "arrowTip",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 6
}
],
"_prefab": {
"__id__": 7
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 24,
"height": 24
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
3,
60,
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.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 5
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "a2170e4c-df31-41ef-be73-f4f605e75821"
},
"_type": 0,
"_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": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "4c12c853-b743-4c11-a452-e384834a1c18"
},
"fileId": "e4mum5GwxNiZ0T8ouw95jJ",
"sync": false
},
{
"__type__": "cc.Node",
"_name": "animNode",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [
{
"__id__": 9
}
],
"_active": true,
"_components": [],
"_prefab": {
"__id__": 13
},
"_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,
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.Node",
"_name": "Monk",
"_objFlags": 0,
"_parent": {
"__id__": 8
},
"_children": [],
"_active": false,
"_components": [
{
"__id__": 10
},
{
"__id__": 11
}
],
"_prefab": {
"__id__": 12
},
"_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
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
-24,
0,
0,
0,
0,
1,
0.65,
0.55,
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__": 9
},
"_enabled": true,
"_defaultClip": null,
"_clips": [
{
"__uuid__": "2d402c67-e47d-4de0-8a80-40bc12073ffc"
},
{
"__uuid__": "18d10aad-93ee-44e8-9048-1f26c136492b"
},
{
"__uuid__": "d044ab74-be6a-49a2-85ab-eba41922c2cd"
},
{
"__uuid__": "488ad635-2683-4884-9e93-d1ee67bd0e49"
},
{
"__uuid__": "53b0ae11-f77f-4c3a-9e6d-76159d135c2c"
},
{
"__uuid__": "a4315723-e7b6-40e7-9a3c-bac959378b90"
},
{
"__uuid__": "5035ddfe-ff75-4dff-a506-89cbb26220da"
},
{
"__uuid__": "ac0fa38d-d3ad-4dff-841d-4d98ee5017db"
},
{
"__uuid__": "8e17dfc6-68d0-47fe-af06-d30dc2790a6b"
},
{
"__uuid__": "e4faa04d-28f5-40b0-b1a5-99cd902e5fd6"
},
{
"__uuid__": "da6a7cc1-9709-42f4-b6d0-17c1917a08a3"
},
{
"__uuid__": "2cab337d-df23-476d-8a98-b5f115a52d04"
},
{
"__uuid__": "504dd9c8-7850-44e8-a944-bbdb2260b18a"
},
{
"__uuid__": "7e0a1e98-ee5a-446f-bec2-7d72b6916503"
}
],
"playOnLoad": false,
"_id": ""
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 9
},
"_enabled": true,
"_materials": [],
"_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__": "6dcd5722-8ef9-47fd-9520-861d2713e274"
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "4c12c853-b743-4c11-a452-e384834a1c18"
},
"fileId": "c51nwF45ZA/LZDNZ0GKpTi",
"sync": false
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "4c12c853-b743-4c11-a452-e384834a1c18"
},
"fileId": "7aN7Gcc/tBw5EGlTJVBj2+",
"sync": false
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"_materials": [],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": null,
"_type": 0,
"_sizeMode": 0,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": ""
},
{
"__type__": "b74b05YDqZFRo4OkZRFZX8k",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"lastMovedAt": 0,
"animNode": {
"__id__": 8
},
"arrowTipNode": {
"__id__": 5
},
"coordLabel": {
"__id__": 3
},
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__uuid__": "4c12c853-b743-4c11-a452-e384834a1c18"
},
"fileId": "4cx75uwJJFa7U8QL187QCL",
"sync": false
}
]

View File

@@ -0,0 +1,8 @@
{
"ver": "1.2.5",
"uuid": "4c12c853-b743-4c11-a452-e384834a1c18",
"optimizationPolicy": "AUTO",
"asyncLoadAssets": false,
"readonly": false,
"subMetas": {}
}

View File

@@ -191,8 +191,8 @@
0,
0,
1,
1.5,
1.5,
1.2,
1.2,
1
]
},
@@ -234,6 +234,9 @@
"controlledCharacterPrefab": {
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
},
"fireballPrefab": {
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
},
"joystickInputControllerNode": {
"__id__": 6
},
@@ -268,6 +271,7 @@
"renderFrameIdLagTolerance": 4,
"jigglingEps1D": 0.001,
"bulletTriggerEnabled": true,
"closeOnForcedtoResyncNotSelf": true,
"_id": "d12gkAmppNlIzqcRDELa91"
},
{
@@ -453,7 +457,7 @@
"array": [
0,
0,
215.81269742929726,
209.57814771583418,
0,
0,
0,

View File

@@ -440,7 +440,7 @@
"array": [
0,
0,
216.50635094610968,
209.57814771583418,
0,
0,
0,

View File

@@ -191,8 +191,8 @@
0,
0,
1,
1.5,
1.5,
1.2,
1.2,
1
]
},
@@ -262,6 +262,9 @@
"controlledCharacterPrefab": {
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
},
"fireballPrefab": {
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
},
"joystickInputControllerNode": {
"__id__": 7
},
@@ -461,7 +464,7 @@
"array": [
0,
0,
217.36724690689908,
209.57814771583418,
0,
0,
0,

View File

@@ -12,8 +12,12 @@ window.ATK_CHARACTER_STATE = {
BlownUp1: [8, "BlownUp1"],
LayDown1: [9, "LayDown1"], // The last frame of "LayDown1" should have a simliar boundingbox with the first frame of "GetUp1", otherwise the animation would seem odd
GetUp1: [10, "GetUp1"],
Atk2: [11, "Atk2"],
Atk3: [12, "Atk3"],
Atk2: [11, "Atk2"],
Atk3: [12, "Atk3"],
Atk4: [13, "Atk4"],
Atk5: [14, "Atk5"],
Dashing: [15, "Dashing"],
OnWall: [16, "OnWall"],
};
window.ATK_CHARACTER_STATE_ARR = [];
@@ -29,6 +33,8 @@ window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.In
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.BlownUp1[0]);
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.LayDown1[0]);
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.GetUp1[0]);
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.Dashing[0]);
window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.add(window.ATK_CHARACTER_STATE.OnWall[0]);
window.ATK_CHARACTER_STATE_IN_AIR_SET = new Set();
window.ATK_CHARACTER_STATE_IN_AIR_SET.add(window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0]);
@@ -36,6 +42,7 @@ window.ATK_CHARACTER_STATE_IN_AIR_SET.add(window.ATK_CHARACTER_STATE.InAirIdle1B
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]);
window.ATK_CHARACTER_STATE_IN_AIR_SET.add(window.ATK_CHARACTER_STATE.BlownUp1[0]);
window.ATK_CHARACTER_STATE_IN_AIR_SET.add(window.ATK_CHARACTER_STATE.OnWall[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.
@@ -77,16 +84,24 @@ cc.Class({
updateCharacterAnim(rdfPlayer, prevRdfPlayer, forceAnimSwitch, chConfig) {
// As this function might be called after many frames of a rollback, it's possible that the playing animation was predicted, different from "prevRdfPlayer.CharacterState" but same as "newCharacterState". More granular checks are needed to determine whether we should interrupt the playing animation.
let newCharacterState = rdfPlayer.CharacterState;
// Update directions
if (this.animComp && this.animComp.node) {
if (0 > rdfPlayer.DirX) {
this.animNode.scaleX = (-1.0);
} else if (0 < rdfPlayer.DirX) {
this.animNode.scaleX = (1.0);
this.animNode.scaleX = (+1.0);
}
if (ATK_CHARACTER_STATE.OnWall[0] == newCharacterState) {
if (0 < rdfPlayer.OnWallNormX) {
this.animNode.scaleX = (-1.0);
} else {
this.animNode.scaleX = (+1.0);
}
}
}
let newCharacterState = rdfPlayer.CharacterState;
let newAnimName = window.ATK_CHARACTER_STATE_ARR[newCharacterState][1];
let playingAnimName = null;
let underlyingAnimationCtrl = null;
@@ -137,7 +152,7 @@ cc.Class({
let frameIdxInAnim = rdfPlayer.FramesInChState;
if (window.ATK_CHARACTER_STATE.InAirIdle1ByJump == newCharacterState && null != chConfig) {
frameIdxInAnim = chConfig.InAirIdleFrameIdxTurningPoint + (frameIdxInAnim - chConfig.InAirIdleFrameIdxTurningPoint) % chConfig.InAirIdleFrameIdxTurnedCycle; // TODO: Anyway to avoid using division here?
}
}
let fromTime = (frameIdxInAnim / targetClip.sample); // TODO: Anyway to avoid using division here?
this.animComp.play(newAnimName, fromTime);
},

View File

@@ -1,37 +1,34 @@
cc.Class({
extends: cc.Component,
extends: cc.Component,
properties: {
mapNode: {
type: cc.Node,
default: null
},
speed: {
type: cc.Float,
default: 500
},
properties: {
mapNode: {
type: cc.Node,
default: null
},
onLoad () {
this.mainCamera = this.mapNode.parent.getChildByName("Main Camera").getComponent(cc.Camera);
this.mapScriptIns = this.mapNode.getComponent("Map");
speed: {
type: cc.Float,
default: 500
},
},
start() {},
onLoad() {
this.mainCamera = this.mapNode.parent.getChildByName("Main Camera").getComponent(cc.Camera);
this.mapScriptIns = this.mapNode.getComponent("Map");
},
update(dt) {
const self = this;
if (!self.mainCamera) return;
if (!self.mapScriptIns) return;
if (!self.mapScriptIns.selfPlayerInfo) return;
if (!self.mapScriptIns.playerRichInfoDict) return;
const selfPlayerRichInfo = self.mapScriptIns.playerRichInfoDict.get(self.mapScriptIns.selfPlayerInfo.Id);
if (!selfPlayerRichInfo) return;
const selfPlayerNode = selfPlayerRichInfo.node;
if (!selfPlayerNode) return;
const pDiff = selfPlayerNode.position.sub(self.mainCamera.node.position);
pDiff.normalizeSelf();
const newCamPos = self.mainCamera.node.position.add(pDiff.mul(dt*self.speed));
self.mainCamera.node.setPosition(newCamPos);
}
start() {},
update(dt) {
const self = this;
if (!self.mainCamera) return;
if (!self.mapScriptIns) return;
if (!self.mapScriptIns.selfPlayerInfo) return;
if (!self.mapScriptIns.playerRichInfoDict) return;
const selfPlayerRichInfo = self.mapScriptIns.playerRichInfoDict.get(self.mapScriptIns.selfPlayerInfo.Id);
if (!selfPlayerRichInfo) return;
const selfPlayerNode = selfPlayerRichInfo.node;
if (!selfPlayerNode) return;
self.mapNode.setPosition(cc.v2().sub(selfPlayerNode.position));
}
});

View File

@@ -0,0 +1,48 @@
cc.Class({
extends: cc.Component,
properties: {
animNode: {
type: cc.Node,
default: null
},
},
ctor() {
this.lastUsed = -1;
this.bulletLocalId = -1;
this.speciesName = null;
},
setSpecies(speciesName, fireballBullet, rdf) {
if (speciesName == this.speciesName) return;
if (null != this.speciesName) {
for (let k in this.animNode.children) {
const child = this.children[k];
if (!child.active) continue;
if (child == effAnimNode || child.name == speciesName) continue;
child.active = false;
}
}
this.speciesName = speciesName;
this.effAnimNode = this.animNode.getChildByName(this.speciesName);
this.effAnimNode.active = true;
this.updateAnim(speciesName, fireballBullet, rdf);
},
onLoad() {},
updateAnim(speciesName, fireballBullet, rdf) {
this.animComp = this.effAnimNode.getComponent(cc.Animation);
// Update directions
if (this.animComp && this.animComp.node) {
if (0 > fireballBullet.DirX) {
this.animNode.scaleX = (-1.0);
} else if (0 < fireballBullet.DirX) {
this.animNode.scaleX = (1.0);
}
}
this.animComp.play(speciesName);
},
});

View File

@@ -1,6 +1,6 @@
{
"ver": "1.0.5",
"uuid": "247b7613-6c6e-4f01-b1d6-5f8f041b5688",
"uuid": "e66a2a91-9916-469e-a4b2-54cc0bcba3f0",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,

View File

@@ -2,6 +2,7 @@ const i18n = require('LanguageData');
i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
const RingBuffer = require('./RingBuffer');
const PriorityQueue = require("./PriorityQueue");
window.ALL_MAP_STATES = {
VISUAL: 0, // For free dragging & zooming.
@@ -44,6 +45,10 @@ cc.Class({
type: cc.Prefab,
default: null,
},
fireballPrefab: {
type: cc.Prefab,
default: null,
},
joystickInputControllerNode: {
type: cc.Node,
default: null
@@ -287,6 +292,30 @@ cc.Class({
self.playerRichInfoDict = new Map();
// Clearing previous info of all players. [ENDS]
// Clearing cached fireball rendering nodes [BEGINS]
if (null != self.cachedFireballs) {
while (!self.cachedFireballs.isEmpty()) {
const v = self.cachedFireballs.pop();
if (v && v.node && v.node.parent) {
v.node.parent.removeChild(v.node);
}
}
} else {
self.cachedFireballs = new PriorityQueue();
}
for (let k = 0; k < 1000; k++) {
const newFireballNode = cc.instantiate(self.fireballPrefab);
const newFireball = newFireballNode.getComponent("Fireball");
newFireballNode.setPosition(cc.v2(Number.MAX_VALUE, Number.MAX_VALUE));
safelyAddChild(self.node, newFireballNode);
setLocalZOrder(newFireballNode, 5);
newFireball.lastUsed = -1;
newFireball.bulletLocalId = -1;
const initLookupKey = -(k + 1); // there's definitely no suck "bulletLocalId"
self.cachedFireballs.push(newFireball.lastUsed, newFireball, initLookupKey);
}
// Clearing cached fireball rendering nodes [ENDS]
self.renderFrameId = 0; // After battle started
self.bulletBattleLocalIdCounter = 0;
self.lastAllConfirmedInputFrameId = -1;
@@ -575,21 +604,27 @@ cc.Class({
},
onRoomDownsyncFrame(pbRdf /* pb.RoomDownsyncFrame */ , accompaniedInputFrameDownsyncBatch /* pb.InputFrameDownsyncBatch */ ) {
const jsPlayersArr = new Array().fill(null);
for (let k in pbRdf.playersArr) {
const jsPlayersArr = new Array(pbRdf.playersArr.length).fill(null);
for (let k = 0; k < pbRdf.playersArr.length; ++k) {
const pbPlayer = pbRdf.playersArr[k];
const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.framesToRecover, pbPlayer.framesInChState, pbPlayer.activeSkillId, pbPlayer.activeSkillHit, pbPlayer.framesInvinsible, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.colliderRadius, pbPlayer.inAir);
const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.framesToRecover, pbPlayer.framesInChState, pbPlayer.activeSkillId, pbPlayer.activeSkillHit, pbPlayer.framesInvinsible, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.colliderRadius, pbPlayer.inAir, pbPlayer.onWall, pbPlayer.onWallNormX, pbPlayer.onWallNormY, pbPlayer.bulletTeamId, pbPlayer.chCollisionTeamId);
jsPlayersArr[k] = jsPlayer;
}
const jsMeleeBulletsArr = [];
for (let k in pbRdf.meleeBullets) {
const jsMeleeBulletsArr = new Array(pbRdf.meleeBullets.length).fill(null);
for (let k = 0; k < pbRdf.meleeBullets.length; ++k) {
const pbBullet = pbRdf.meleeBullets[k];
const jsBullet = gopkgs.NewMeleeBulletJs(pbBullet.originatedRenderFrameId, pbBullet.offenderJoinIndex, pbBullet.startupFrames, pbBullet.cancellableStFrame, pbBullet.cancellableEdFrame, pbBullet.activeFrames, pbBullet.hitStunFrames, pbBullet.blockStunFrames, pbBullet.pushbackVelX, pbBullet.pushbackVelY, pbBullet.damage, pbBullet.selfLockVelX, pbBullet.selfLockVelY, pbBullet.hitboxOffsetX, pbBullet.hitboxOffsetY, pbBullet.hitboxSizeX, pbBullet.hitboxSizeY, pbBullet.blowUp);
jsMeleeBulletsArr.push(jsBullet);
const jsMeleeBullet = gopkgs.NewMeleeBulletJs(pbBullet.bulletLocalId, pbBullet.originatedRenderFrameId, pbBullet.offenderJoinIndex, pbBullet.startupFrames, pbBullet.cancellableStFrame, pbBullet.cancellableEdFrame, pbBullet.activeFrames, pbBullet.hitStunFrames, pbBullet.blockStunFrames, pbBullet.pushbackVelX, pbBullet.pushbackVelY, pbBullet.damage, pbBullet.selfLockVelX, pbBullet.selfLockVelY, pbBullet.hitboxOffsetX, pbBullet.hitboxOffsetY, pbBullet.hitboxSizeX, pbBullet.hitboxSizeY, pbBullet.blowUp, pbBullet.teamId);
jsMeleeBulletsArr[k] = jsMeleeBullet;
}
const jsFireballBulletsArr = new Array(pbRdf.fireballBullets.length).fill(null);
for (let k = 0; k < pbRdf.fireballBullets.length; ++k) {
const pbBullet = pbRdf.fireballBullets[k];
const jsFireballBullet = gopkgs.NewFireballBulletJs(pbBullet.bulletLocalId, pbBullet.originatedRenderFrameId, pbBullet.offenderJoinIndex, pbBullet.startupFrames, pbBullet.cancellableStFrame, pbBullet.cancellableEdFrame, pbBullet.activeFrames, pbBullet.hitStunFrames, pbBullet.blockStunFrames, pbBullet.pushbackVelX, pbBullet.pushbackVelY, pbBullet.damage, pbBullet.selfLockVelX, pbBullet.selfLockVelY, pbBullet.hitboxOffsetX, pbBullet.hitboxOffsetY, pbBullet.hitboxSizeX, pbBullet.hitboxSizeY, pbBullet.blowUp, pbBullet.teamId, pbBullet.virtualGridX, pbBullet.virtualGridY, pbBullet.dirX, pbBullet.dirY, pbBullet.velX, pbBullet.velY, pbBullet.speed, pbBullet.speciesId);
jsFireballBulletsArr[k] = jsFireballBullet;
}
// This function is also applicable to "re-joining".
const rdf = gopkgs.NewRoomDownsyncFrameJs(pbRdf.id, jsPlayersArr, jsMeleeBulletsArr);
const rdf = gopkgs.NewRoomDownsyncFrameJs(pbRdf.id, jsPlayersArr, pbRdf.bulletLocalIdCounter, jsMeleeBulletsArr, jsFireballBulletsArr);
const self = window.mapIns;
self.onInputFrameDownsyncBatch(accompaniedInputFrameDownsyncBatch); // Important to do this step before setting IN_BATTLE
if (!self.recentRenderCache) {
@@ -685,6 +720,8 @@ cc.Class({
equalPlayers(lhs, rhs) {
if (null == lhs || null == rhs) return false;
if (null == lhs && null != rhs) return false;
if (null != lhs && null == rhs) return false;
if (lhs.VirtualGridX != rhs.VirtualGridX) return false;
if (lhs.VirtualGridY != rhs.VirtualGridY) return false;
if (lhs.DirX != rhs.DirX) return false;
@@ -703,20 +740,44 @@ cc.Class({
equalMeleeBullets(lhs, rhs) {
if (null == lhs || null == rhs) return false;
if (lhs.battleLocalId != rhs.battleLocalId) return false;
if (lhs.offenderPlayerId != rhs.offenderPlayerId) return false;
if (lhs.offenderJoinIndex != rhs.offenderJoinIndex) return false;
if (lhs.originatedRenderFrameId != rhs.originatedRenderFrameId) return false;
if (null == lhs && null != rhs) return false;
if (null != lhs && null == rhs) return false;
if (lhs.BattleAttr.BulletLocalId != rhs.BattleAttr.BulletLocalId) return false;
if (lhs.BattleAttr.OffenderJoinIndex != rhs.BattleAttr.OffenderJoinIndex) return false;
if (lhs.BattleAttr.OriginatedRenderFrameId != rhs.BattleAttr.OriginatedRenderFrameId) return false;
return true;
},
equalFireballBullets(lhs, rhs) {
if (null == lhs || null == rhs) return false;
if (null == lhs && null != rhs) return false;
if (null != lhs && null == rhs) return false;
if (lhs.BattleAttr.BulletLocalId != rhs.BattleAttr.BulletLocalId) return false;
if (lhs.BattleAttr.OffenderJoinIndex != rhs.BattleAttr.OffenderJoinIndex) return false;
if (lhs.BattleAttr.OriginatedRenderFrameId != rhs.BattleAttr.OriginatedRenderFrameId) return false;
if (lhs.VirtualGridX != rhs.Bullet.VirtualGridX) return false;
if (lhs.VirtualGridY != rhs.Bullet.VirtualGridY) return false;
if (lhs.DirX != rhs.DirX) return false;
if (lhs.DirY != rhs.DirY) return false;
if (lhs.VelX != rhs.VelX) return false;
if (lhs.VelY != rhs.VelY) return false;
if (lhs.Speed != rhs.Speed) return false;
if (lhs.SpeciesId != rhs.SpeciesId) return false;
return true;
},
equalRoomDownsyncFrames(lhs, rhs) {
if (null == lhs || null == rhs) return false;
for (let k in lhs.players) {
if (!this.equalPlayers(lhs.players[k], rhs.players[k])) return false;
for (let k in lhs.PlayersArr) {
if (!this.equalPlayers(lhs.PlayersArr[k], rhs.PlayersArr[k])) return false;
}
for (let k in lhs.meleeBullets) {
if (!this.equalMeleeBullets(lhs.meleeBullets[k], rhs.meleeBullets[k])) return false;
for (let k in lhs.MeleeBullets) {
if (!this.equalMeleeBullets(lhs.MeleeBullets[k], rhs.MeleeBullets[k])) return false;
}
for (let k in lhs.fireballBullet) {
if (!this.equalFireballBullets(lhs.FireballBullets[k], rhs.FireballBullets[k])) return false;
}
return true;
},
@@ -893,17 +954,17 @@ batchInputFrameIdRange=[${batch[0].inputFrameId}, ${batch[batch.length - 1].inpu
}
*/
// [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!
if (self.othersForcedDownsyncRenderFrameDict.has(rdf.id)) {
const delayedInputFrameId = gopkgs.ConvertToDelayedInputFrameId(rdf.id);
const othersForcedDownsyncRenderFrame = self.othersForcedDownsyncRenderFrameDict.get(rdf.id);
if (self.othersForcedDownsyncRenderFrameDict.has(rdf.Id)) {
const delayedInputFrameId = gopkgs.ConvertToDelayedInputFrameId(rdf.Id);
const othersForcedDownsyncRenderFrame = self.othersForcedDownsyncRenderFrameDict.get(rdf.Id);
if (self.lastAllConfirmedInputFrameId >= delayedInputFrameId && !self.equalRoomDownsyncFrames(othersForcedDownsyncRenderFrame, rdf)) {
console.warn(`Mismatched render frame@rdf.id=${rdf.id} w/ inputFrameId=${delayedInputFrameId}:
console.warn(`Mismatched render frame@rdf.id=${rdf.Id} w/ inputFrameId=${delayedInputFrameId}:
rdf=${JSON.stringify(rdf)}
othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame)}`);
// closeWSConnection(constants.RET_CODE.CLIENT_MISMATCHED_RENDER_FRAME, "");
// self.onManualRejoinRequired("[DEBUG] CLIENT_MISMATCHED_RENDER_FRAME");
rdf = othersForcedDownsyncRenderFrame;
self.othersForcedDownsyncRenderFrameDict.delete(rdf.id);
self.othersForcedDownsyncRenderFrameDict.delete(rdf.Id);
}
}
self.applyRoomDownsyncFrameDynamics(rdf, prevRdf);
@@ -1047,6 +1108,41 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
playerRichInfo.scriptIns.updateCharacterAnim(currPlayerDownsync, prevRdfPlayer, false, chConfig);
}
// Move all to infinitely far away first
for (let k in self.cachedFireballs.list) {
const pqNode = self.cachedFireballs.list[k];
const fireball = pqNode.value;
fireball.node.setPosition(cc.v2(Number.MAX_VALUE, Number.MAX_VALUE));
}
for (let k in rdf.FireballBullets) {
const fireballBullet = rdf.FireballBullets[k];
if (
fireballBullet.BattleAttr.OriginatedRenderFrameId + fireballBullet.Bullet.StartupFrames <= rdf.Id
&&
fireballBullet.BattleAttr.OriginatedRenderFrameId + fireballBullet.Bullet.StartupFrames + fireballBullet.Bullet.ActiveFrames > rdf.Id
) {
let pqNode = self.cachedFireballs.popAny(fireballBullet.BattleAttr.BulletLocalId);
const speciesName = `Fireball${fireballBullet.SpeciesId}`;
const [wx, wy] = gopkgs.VirtualGridToWorldPos(fireballBullet.VirtualGridX, fireballBullet.VirtualGridY);
if (null == pqNode) {
pqNode = self.cachedFireballs.pop();
//console.log(`@rdf.Id=${rdf.Id}, origRdfId=${fireballBullet.BattleAttr.OriginatedRenderFrameId}, startupFrames=${fireballBullet.Bullet.StartupFrames}, using a new fireball node for rendering for bulletLocalId=${fireballBullet.BattleAttr.BulletLocalId} at wpos=(${wx},${wy})`);
} else {
//console.log(`@rdf.Id=${rdf.Id}, origRdfId=${fireballBullet.BattleAttr.OriginatedRenderFrameId}, startupFrames=${fireballBullet.Bullet.StartupFrames}, using a cached fireball node for rendering for bulletLocalId=${fireballBullet.BattleAttr.BulletLocalId} at wpos=(${wx},${wy})`);
}
const cachedFireball = pqNode.value;
cachedFireball.setSpecies(speciesName, fireballBullet, rdf);
cachedFireball.lastUsed = self.renderFrameId;
cachedFireball.bulletLocalId = fireballBullet.BattleAttr.BulletLocalId;
cachedFireball.node.setPosition(cc.v2(wx, wy));
self.cachedFireballs.push(cachedFireball.lastUsed, cachedFireball, fireballBullet.BattleAttr.BulletLocalId);
} else {
//console.log(`@rdf.Id=${rdf.Id}, origRdfId=${fireballBullet.BattleAttr.OriginatedRenderFrameId}, startupFrames=${fireballBullet.Bullet.StartupFrames}, activeFrames=${fireballBullet.Bullet.ActiveFrames}, not rendering fireball node for bulletLocalId=${fireballBullet.BattleAttr.BulletLocalId}`);
}
}
// Update countdown
self.countdownNanos = self.battleDurationNanos - self.renderFrameId * self.rollbackEstimatedDtNanos;
if (self.countdownNanos <= 0) {
@@ -1082,14 +1178,6 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
}
const nextRdf = gopkgs.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(self.recentInputCache, currRdf, collisionSys, collisionSysMap, self.spaceOffsetX, self.spaceOffsetY, self.chConfigsOrderedByJoinIndex);
if (3 == nextRdf.PlayersArr[0].ActiveSkillId && 3 != currRdf.PlayersArr[0].ActiveSkillId) {
console.log(`Started skill 3 at rdf.Id=${nextRdf.Id}`);
self.lastSkill3Started = nextRdf.Id;
}
if (3 != nextRdf.PlayersArr[0].ActiveSkillId && 3 == currRdf.PlayersArr[0].ActiveSkillId) {
console.log(`Stopped skill 3 at rdf.Id=${nextRdf.Id}, duration = ${nextRdf.Id-self.lastSkill3Started}`);
}
if (true == isChasing) {
// [WARNING] Move the cursor "self.chaserRenderFrameId" when "true == isChasing", keep in mind that "self.chaserRenderFrameId" is not monotonic!
self.chaserRenderFrameId = nextRdf.Id;
@@ -1176,7 +1264,12 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
playerDownsyncStr(playerDownsync) {
if (null == playerDownsync) return "";
return `{${playerDownsync.JoinIndex},${playerDownsync.VirtualGridX},${playerDownsync.VirtualGridY},${playerDownsync.VelX},${playerDownsync.VelY},${playerDownsync.FramesToRecover},${playerDownsync.InAir ? 1 : 0}}`;
return `{${playerDownsync.JoinIndex},${playerDownsync.VirtualGridX},${playerDownsync.VirtualGridY},${playerDownsync.VelX},${playerDownsync.VelY},${playerDownsync.FramesToRecover},${playerDownsync.InAir ? 1 : 0},${playerDownsync.OnWall ? 1 : 0}}`;
},
fireballDownsyncStr(fireball) {
if (null == fireball) return "";
return `{${fireball.BattleAttr.BulletLocalId},${fireball.BattleAttr.OriginatedRenderFrameId},${fireball.BattleAttr.OffenderJoinIndex},${fireball.VirtualGridX},${fireball.VirtualGridY},${fireball.VelX},${fireball.VelY},${fireball.DirX},${fireball.DirY},${fireball.Bullet.HitboxSizeX},${fireball.Bullet.HitboxSizeY}}`;
},
inputFrameDownsyncStr(inputFrameDownsync) {
@@ -1205,8 +1298,13 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
for (let k in rdf.PlayersArr) {
playersStrBldr.push(self.playerDownsyncStr(rdf.PlayersArr[k]));
}
const fireballsStrBldr = [];
for (let k in rdf.FireballBullets) {
fireballsStrBldr.push(self.fireballDownsyncStr(rdf.FireballBullets[k]));
}
s.push(`rdfId:${i}
players:[${playersStrBldr.join(',')}]
fireballs:[${fireballsStrBldr.join(',')}]
actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
}
@@ -1244,6 +1342,7 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
case ATK_CHARACTER_STATE.BlownUp1[0]:
case ATK_CHARACTER_STATE.InAirIdle1NoJump[0]:
case ATK_CHARACTER_STATE.InAirIdle1ByJump[0]:
case ATK_CHARACTER_STATE.OnWall[0]:
[colliderWidth, colliderHeight] = [player.ColliderRadius * 2, player.ColliderRadius * 2];
break;
}
@@ -1265,11 +1364,11 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
for (let k in rdf.MeleeBullets) {
const meleeBullet = rdf.MeleeBullets[k];
if (
meleeBullet.Bullet.OriginatedRenderFrameId + meleeBullet.Bullet.StartupFrames <= rdf.Id
meleeBullet.BattleAttr.OriginatedRenderFrameId + meleeBullet.Bullet.StartupFrames <= rdf.Id
&&
meleeBullet.Bullet.OriginatedRenderFrameId + meleeBullet.Bullet.StartupFrames + meleeBullet.Bullet.ActiveFrames > rdf.Id
meleeBullet.BattleAttr.OriginatedRenderFrameId + meleeBullet.Bullet.StartupFrames + meleeBullet.Bullet.ActiveFrames > rdf.Id
) {
const offender = rdf.PlayersArr[meleeBullet.Bullet.OffenderJoinIndex - 1];
const offender = rdf.PlayersArr[meleeBullet.BattleAttr.OffenderJoinIndex - 1];
if (1 == offender.JoinIndex) {
g2.strokeColor = cc.Color.BLUE;
} else {
@@ -1293,6 +1392,34 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
g2.stroke();
}
}
for (let k in rdf.FireballBullets) {
const fireballBullet = rdf.FireballBullets[k];
if (
fireballBullet.BattleAttr.OriginatedRenderFrameId + fireballBullet.Bullet.StartupFrames <= rdf.Id
&&
fireballBullet.BattleAttr.OriginatedRenderFrameId + fireballBullet.Bullet.StartupFrames + fireballBullet.Bullet.ActiveFrames > rdf.Id
) {
const offender = rdf.PlayersArr[fireballBullet.BattleAttr.OffenderJoinIndex - 1];
if (1 == offender.JoinIndex) {
g2.strokeColor = cc.Color.BLUE;
} else {
g2.strokeColor = cc.Color.RED;
}
const [bulletWx, bulletWy] = gopkgs.VirtualGridToWorldPos(fireballBullet.VirtualGridX, fireballBullet.VirtualGridY);
const [halfColliderWidth, halfColliderHeight] = gopkgs.VirtualGridToWorldPos((fireballBullet.Bullet.HitboxSizeX >> 1), (fireballBullet.Bullet.HitboxSizeY >> 1));
const [bulletCx, bulletCy] = gopkgs.WorldToPolygonColliderBLPos(bulletWx, bulletWy, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, 0, 0);
const pts = [[0, 0], [leftPadding + halfColliderWidth * 2 + rightPadding, 0], [leftPadding + halfColliderWidth * 2 + rightPadding, bottomPadding + halfColliderHeight * 2 + topPadding], [0, bottomPadding + halfColliderHeight * 2 + topPadding]];
g2.moveTo(bulletCx, bulletCy);
for (let j = 0; j < pts.length; j += 1) {
g2.lineTo(pts[j][0] + bulletCx, pts[j][1] + bulletCy);
}
g2.lineTo(bulletCx, bulletCy);
g2.stroke();
}
}
}
},
});

View File

@@ -13,7 +13,7 @@ cc.Class({
onLoad() {
const self = this;
window.mapIns = self;
self.showCriticalCoordinateLabels = false;
self.showCriticalCoordinateLabels = true;
const mapNode = self.node;
const canvasNode = mapNode.parent;
@@ -29,7 +29,7 @@ cc.Class({
/** Init required prefab ended. */
self.inputFrameUpsyncDelayTolerance = 2;
self.collisionMinStep = 8;
self.collisionMinStep = 2;
self.renderCacheSize = 1024;
self.serverFps = 60;
@@ -92,9 +92,11 @@ cc.Class({
const p1Vpos = gopkgs.WorldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y);
const p2Vpos = gopkgs.WorldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y);
const speedV = gopkgs.WorldToVirtualGridPos(1.0, 0);
const colliderRadiusV = gopkgs.WorldToVirtualGridPos(12.0, 0);
const speciesIdList = [4096, 1];
const chConfigsOrderedByJoinIndex = gopkgs.GetCharacterConfigsOrderedByJoinIndex(speciesIdList);
const startRdf = window.pb.protos.RoomDownsyncFrame.create({
id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START,
playersArr: [
@@ -103,7 +105,7 @@ cc.Class({
joinIndex: 1,
virtualGridX: p1Vpos[0],
virtualGridY: p1Vpos[1],
speed: speedV[0],
speed: chConfigsOrderedByJoinIndex[0].Speed,
colliderRadius: colliderRadiusV[0],
characterState: window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0],
framesToRecover: 0,
@@ -112,13 +114,14 @@ cc.Class({
velX: 0,
velY: 0,
inAir: true,
onWall: false,
}),
window.pb.protos.PlayerDownsync.create({
id: 11,
joinIndex: 2,
virtualGridX: p2Vpos[0],
virtualGridY: p2Vpos[1],
speed: speedV[0],
speed: chConfigsOrderedByJoinIndex[1].Speed,
colliderRadius: colliderRadiusV[0],
characterState: window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0],
framesToRecover: 0,
@@ -127,9 +130,10 @@ cc.Class({
velX: 0,
velY: 0,
inAir: true,
onWall: false,
}),
],
speciesIdList: [1, 0],
speciesIdList: speciesIdList,
});
self.selfPlayerInfo = {

View File

@@ -12,32 +12,15 @@ var BinaryHeap = function (customCompare) {
* @private
*/
this.list = [];
this.lookupKeyToIndex = {};
if (customCompare) {
this.compare = customCompare;
}
};
/**
* Builds a heap with the provided keys and values, this will discard the
* heap's current data.
*
* @param {Array} keys An array of keys.
* @param {Array} values An array of values. This must be the same size as the
* key array.
*/
BinaryHeap.prototype.buildHeap = function (keys, values) {
if (typeof values !== 'undefined' && values.length !== keys.length) {
throw new Error('Key array must be the same length as value array');
}
var nodeArray = [];
for (var i = 0; i < keys.length; i++) {
nodeArray.push(new Node(keys[i], values ? values[i] : undefined));
}
buildHeapFromNodeArray(this, nodeArray);
BinaryHeap.prototype.contains = function (lookupKey) {
return null != this.lookupKeyToIndex[lookupKey];
};
/**
@@ -45,6 +28,7 @@ BinaryHeap.prototype.buildHeap = function (keys, values) {
*/
BinaryHeap.prototype.clear = function () {
this.list.length = 0;
this.lookupKeyToIndex = null;
};
/**
@@ -53,15 +37,20 @@ BinaryHeap.prototype.clear = function () {
* @return {Node} node The heap's minimum node or undefined if the heap is
* empty.
*/
BinaryHeap.prototype.extractMinimum = function () {
if (!this.list.length) {
return undefined;
BinaryHeap.prototype.pop = function () {
if (0 == this.list.length) {
return null;
}
if (this.list.length === 1) {
if (1 == this.list.length) {
delete this.lookupKeyToIndex[Object.keys(this.lookupKeyToIndex)[0]];
return this.list.shift();
}
var min = this.list[0];
delete this.lookupKeyToIndex[min.lookupKey];
this.list[0] = this.list.pop();
this.lookupKeyToIndex[this.list[0].lookupKey] = 0;
heapify(this, 0);
return min;
};
@@ -72,8 +61,8 @@ BinaryHeap.prototype.extractMinimum = function () {
* @return {Node} node The heap's minimum node or undefined if the heap is
* empty.
*/
BinaryHeap.prototype.findMinimum = function () {
return this.isEmpty() ? undefined : this.list[0];
BinaryHeap.prototype.top = function () {
return this.isEmpty() ? null : this.list[0];
};
/**
@@ -83,25 +72,79 @@ BinaryHeap.prototype.findMinimum = function () {
* @param {Object} value The value to insert.
* @return {Node} node The inserted node.
*/
BinaryHeap.prototype.insert = function (key, value) {
BinaryHeap.prototype.push = function (key, value, lookupKey) {
var i = this.list.length;
var node = new Node(key, value);
var node = new Node(key, value, lookupKey);
this.list.push(node);
var parent = getParent(i);
while (typeof parent !== 'undefined' &&
this.compare(this.list[i], this.list[parent]) < 0) {
swap(this.list, i, parent);
i = parent;
parent = getParent(i);
this.lookupKeyToIndex[lookupKey] = i;
let u = getParent(i);
while (null != u && this.compare(this.list[i], this.list[u]) < 0) {
swap(this.list, i, u, this.lookupKeyToIndex);
i = u;
u = getParent(i);
}
return node;
};
BinaryHeap.prototype.update = function (lookupKey, newKey, newValue) {
if (null == this.lookupKeyToIndex[lookupKey]) return null;
var i = this.lookupKeyToIndex[lookupKey];
this.list[i].key = newKey;
this.list[i].value = newValue;
let u = getParent(i);
if (null != u && this.compare(this.list[i], this.list[u]) < 0) {
while (null != u && this.compare(this.list[i], this.list[u]) < 0) {
swap(this.list, i, u, this.lookupKeyToIndex);
i = u;
u = getParent(i);
}
} else {
heapify(this, i);
}
};
BinaryHeap.prototype.popAny = function (lookupKey) {
if (null == this.lookupKeyToIndex[lookupKey]) return null;
if (0 == this.list.length) {
return null;
}
if (1 == this.list.length) {
delete this.lookupKeyToIndex[Object.keys(this.lookupKeyToIndex)[0]];
return this.list.shift();
}
var i = this.lookupKeyToIndex[lookupKey];
var old = this.list[i];
delete this.lookupKeyToIndex[old.lookupKey];
this.list[i] = this.list.pop();
this.lookupKeyToIndex[this.list[i].lookupKey] = i;
let u = getParent(i);
if (null != u && this.compare(this.list[i], this.list[u]) < 0) {
while (null != u && this.compare(this.list[i], this.list[u]) < 0) {
swap(this.list, i, u, this.lookupKeyToIndex);
i = u;
u = getParent(i);
}
} else {
heapify(this, i);
}
return old;
};
/**
* @return {boolean} Whether the heap is empty.
*/
BinaryHeap.prototype.isEmpty = function () {
return !this.list.length;
return 0 == this.list.length;
};
/**
@@ -111,16 +154,6 @@ BinaryHeap.prototype.size = function () {
return this.list.length;
};
/**
* Joins another heap to this one.
*
* @param {BinaryHeap} otherHeap The other heap.
*/
BinaryHeap.prototype.union = function (otherHeap) {
var array = this.list.concat(otherHeap.list);
buildHeapFromNodeArray(this, array);
};
/**
* Compares two nodes with each other.
*
@@ -147,34 +180,27 @@ BinaryHeap.prototype.compare = function (a, b) {
* @param {number} i The index of the node to heapify.
*/
function heapify(heap, i) {
var l = getLeft(i);
var r = getRight(i);
var smallest = i;
if (l < heap.list.length &&
heap.compare(heap.list[l], heap.list[i]) < 0) {
smallest = l;
}
if (r < heap.list.length &&
heap.compare(heap.list[r], heap.list[smallest]) < 0) {
smallest = r;
}
if (smallest !== i) {
swap(heap.list, i, smallest);
heapify(heap, smallest);
}
}
let cur = i;
let smallest = -1;
while (cur != smallest) {
const l = getLeft(cur);
const r = getRight(cur);
smallest = cur;
if (l < heap.list.length &&
heap.compare(heap.list[l], heap.list[smallest]) < 0) {
smallest = l;
}
if (r < heap.list.length &&
heap.compare(heap.list[r], heap.list[smallest]) < 0) {
smallest = r;
}
/**
* Builds a heap from a node array, this will discard the heap's current data.
*
* @private
* @param {BinaryHeap} heap The heap to override.
* @param {Node[]} nodeArray The array of nodes for the new heap.
*/
function buildHeapFromNodeArray(heap, nodeArray) {
heap.list = nodeArray;
for (var i = Math.floor(heap.list.length / 2); i >= 0; i--) {
heapify(heap, i);
if (smallest !== cur) {
swap(heap.list, cur, smallest, heap.lookupKeyToIndex);
cur = smallest;
smallest = -1;
}
}
}
@@ -186,10 +212,16 @@ function buildHeapFromNodeArray(heap, nodeArray) {
* @param {number} a The index of the first element.
* @param {number} b The index of the second element.
*/
function swap(array, a, b) {
function swap(array, a, b, lookupKeyToIndex) {
var aLookupKey = array[a].lookupKey;
var bLookupKey = array[b].lookupKey;
var temp = array[a];
array[a] = array[b];
array[b] = temp;
lookupKeyToIndex[aLookupKey] = b;
lookupKeyToIndex[bLookupKey] = a;
}
/**
@@ -200,8 +232,8 @@ function swap(array, a, b) {
* @return {number} The index of the node's parent.
*/
function getParent(i) {
if (i === 0) {
return undefined;
if (0 == i) {
return null;
}
return Math.floor((i - 1) / 2);
}
@@ -235,9 +267,10 @@ function getRight(i) {
* @param {Object} key The key of the new node.
* @param {Object} value The value of the new node.
*/
function Node(key, value) {
function Node(key, value, lookupKey) {
this.key = key;
this.value = value;
this.lookupKey = lookupKey;
}
module.exports = BinaryHeap;

View File

@@ -0,0 +1,9 @@
{
"ver": "1.0.5",
"uuid": "20a75b4a-e220-42cd-bab4-9fc63a289b3f",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -110,6 +110,8 @@ TileCollisionManager.prototype.extractBoundaryObjects = function(withTiledMapNod
let toRet = {
playerStartingPositions: [],
barriers: [],
npcStartingPositions: [],
npcPatrolCues: [],
};
const tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap); // This is a magic name.
@@ -128,6 +130,38 @@ TileCollisionManager.prototype.extractBoundaryObjects = function(withTiledMapNod
toRet.playerStartingPositions.push(wpos);
}
break;
case "NpcPatrolCue":
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;
let wpos = this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, cc.v2(origX, origY));
const cue = {
x: wpos.x,
y: wpos.y,
flAct: parseInt(allObjects[j].flAct),
frAct: parseInt(allObjects[j].frAct),
};
toRet.npcPatrolCues.push(cue);
}
break;
case "NpcStartingPos":
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;
let wpos = this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, cc.v2(origX, origY));
const npc = {
x: wpos.x,
y: wpos.y,
speciesId: parseInt(allObjects[j].speciesId),
dirX: parseInt(allObjects[j].dirX),
};
toRet.npcStartingPositions.push(npc);
}
break;
case "Barrier":
for (let j = 0; j < allObjects.length; ++j) {
let object = allObjects[j];
@@ -205,30 +239,6 @@ TileCollisionManager.prototype.initMapNodeByTiledBoundaries = function(mapScript
mapScriptIns.barrierColliders.push(newBarrierColliderIns);
mapScriptIns.node.addChild(newBarrier);
}
const allLayers = tiledMapIns.getLayers();
for (let layer of allLayers) {
const layerType = layer.getProperty("type");
switch (layerType) {
case "barrier_and_shelter":
setLocalZOrder(layer.node, 3);
break;
default:
break;
}
}
const allObjectGroups = tiledMapIns.getObjectGroups();
for (let objectGroup of allObjectGroups) {
const objectGroupType = objectGroup.getProperty("type");
switch (objectGroupType) {
case "barrier_and_shelter":
setLocalZOrder(objectGroup.node, 3);
break;
default:
break;
}
}
}
window.tileCollisionManager = new TileCollisionManager();

View File

@@ -195,15 +195,31 @@ cc.Class({
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, function(evt) {
switch (evt.keyCode) {
case cc.macro.KEY.w:
self.cachedBtnUpLevel = 0;
self.cachedBtnDownLevel = 0;
self.cachedBtnLeftLevel = 0;
self.cachedBtnRightLevel = 0;
self.cachedBtnUpLevel = 1;
break;
case cc.macro.KEY.s:
self.cachedBtnUpLevel = 0;
self.cachedBtnDownLevel = 0;
self.cachedBtnLeftLevel = 0;
self.cachedBtnRightLevel = 0;
self.cachedBtnDownLevel = 1;
break;
case cc.macro.KEY.a:
self.cachedBtnUpLevel = 0;
self.cachedBtnDownLevel = 0;
self.cachedBtnLeftLevel = 0;
self.cachedBtnRightLevel = 0;
self.cachedBtnLeftLevel = 1;
break;
case cc.macro.KEY.d:
self.cachedBtnUpLevel = 0;
self.cachedBtnDownLevel = 0;
self.cachedBtnLeftLevel = 0;
self.cachedBtnRightLevel = 0;
self.cachedBtnRightLevel = 1;
break;
case cc.macro.KEY.h:

View File

@@ -68,7 +68,7 @@
"shelter_z_reducer",
"shelter"
],
"last-module-event-record-time": 1672287736326,
"last-module-event-record-time": 1673325961305,
"simulator-orientation": false,
"simulator-resolution": {
"height": 640,

View File

@@ -1,4 +1,4 @@
GopherJs is supposed to be run by `go run`.
GopherJs is NOT supposed to be run by `go run` but `gopherjs <args>` instead.
If on-the-fly compilation is needed, run `gopherjs serve jsexport` and then visit `http://localhost:8080/jsexport.js` -- if 404 not found is responded, run `gopherjs build` to check syntax errors.

View File

@@ -3,6 +3,7 @@ package battle
import (
"math"
"resolv"
//"fmt"
)
const (
@@ -21,7 +22,7 @@ const (
GRAVITY_X = int32(0)
GRAVITY_Y = -int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO) // makes all "playerCollider.Y" a multiple of 0.5 in all cases
INPUT_DELAY_FRAMES = int32(8) // in the count of render frames
INPUT_DELAY_FRAMES = int32(4) // in the count of render frames
INPUT_SCALE_FRAMES = uint32(2) // inputDelayedAndScaledFrameId = ((originalFrameId - InputDelayFrames) >> InputScaleFrames)
NST_DELAY_FRAMES = int32(16) // network-single-trip delay in the count of render frames, proposed to be (InputDelayFrames >> 1) because we expect a round-trip delay to be exactly "InputDelayFrames"
@@ -29,6 +30,7 @@ const (
SNAP_INTO_PLATFORM_OVERLAP = float64(0.1)
SNAP_INTO_PLATFORM_THRESHOLD = float64(0.5)
VERTICAL_PLATFORM_THRESHOLD = float64(0.9)
NO_SKILL = -1
NO_SKILL_HIT = -1
@@ -64,6 +66,11 @@ const (
ATK_CHARACTER_STATE_ATK2 = int32(11)
ATK_CHARACTER_STATE_ATK3 = int32(12)
ATK_CHARACTER_STATE_ATK4 = int32(13)
ATK_CHARACTER_STATE_ATK5 = int32(14)
ATK_CHARACTER_STATE_DASHING = int32(15)
ATK_CHARACTER_STATE_ONWALL = int32(16)
)
var inAirSet = map[int32]bool{
@@ -72,6 +79,7 @@ var inAirSet = map[int32]bool{
ATK_CHARACTER_STATE_INAIR_ATK1: true,
ATK_CHARACTER_STATE_INAIR_ATKED1: true,
ATK_CHARACTER_STATE_BLOWN_UP1: true,
ATK_CHARACTER_STATE_ONWALL: true,
}
var noOpSet = map[int32]bool{
@@ -100,6 +108,13 @@ var nonAttackingSet = map[int32]bool{
ATK_CHARACTER_STATE_GET_UP1: true,
}
func intAbs(x int32) int32 {
if x < 0 {
return -x
}
return x
}
func ShouldPrefabInputFrameDownsync(prevRenderFrameId int32, renderFrameId int32) (bool, int32) {
for i := prevRenderFrameId + 1; i <= renderFrameId; i++ {
if (0 <= i) && (0 == (i & ((1 << INPUT_SCALE_FRAMES) - 1))) {
@@ -153,7 +168,7 @@ type SatResult struct {
Axis resolv.Vector
}
func CalcPushbacks(oldDx, oldDy float64, playerShape, barrierShape *resolv.ConvexPolygon) (bool, float64, float64, *SatResult) {
func calcPushbacks(oldDx, oldDy float64, playerShape, barrierShape *resolv.ConvexPolygon) (bool, float64, float64, *SatResult) {
origX, origY := playerShape.Position()
defer func() {
playerShape.SetPosition(origX, origY)
@@ -314,8 +329,8 @@ func isPolygonPairSeparatedByDir(a, b *resolv.ConvexPolygon, e resolv.Vector, re
func WorldToVirtualGridPos(wx, wy float64) (int32, int32) {
// [WARNING] Introduces loss of precision!
// In JavaScript floating numbers suffer from seemingly non-deterministic arithmetics, and even if certain libs solved this issue by approaches such as fixed-point-number, they might not be used in other libs -- e.g. the "collision libs" we're interested in -- thus couldn't kill all pains.
var virtualGridX int32 = int32(math.Floor(wx * WORLD_TO_VIRTUAL_GRID_RATIO))
var virtualGridY int32 = int32(math.Floor(wy * WORLD_TO_VIRTUAL_GRID_RATIO))
var virtualGridX int32 = int32(math.Round(wx * WORLD_TO_VIRTUAL_GRID_RATIO))
var virtualGridY int32 = int32(math.Round(wy * WORLD_TO_VIRTUAL_GRID_RATIO))
return virtualGridX, virtualGridY
}
@@ -344,9 +359,25 @@ func VirtualGridToPolygonColliderBLPos(vx, vy int32, halfBoundingW, halfBounding
return WorldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding, collisionSpaceOffsetX, collisionSpaceOffsetY)
}
func calcHardPushbacksNorms(joinIndex int32, playerCollider *resolv.Object, playerShape *resolv.ConvexPolygon, snapIntoPlatformOverlap float64, pEffPushback *Vec2D) *[]Vec2D {
func calcHardPushbacksNorms(joinIndex int32, currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync, 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)
virtualGripToWall := float64(0)
if ATK_CHARACTER_STATE_ONWALL == currPlayerDownsync.CharacterState && 0 == thatPlayerInNextFrame.VelX && currPlayerDownsync.DirX == thatPlayerInNextFrame.DirX {
/*
I'm not sure whether this is a bug of "resolv_tailored" (maybe due to my changes), on the x-axis a playerCollider whose right edge reaches "1680.1" is not deemed collided with a side wall whose left edge is "1680.0", while the same extent of intersection is OK in y-axis.
The workaround here is to grant a "virtualGripToWall" in x-axis to guarantee that if
- "currPlayerDownsync" is on wall, and
- "thatPlayerInNextFrame.VelX" is 0 (i.e. no proactive move against the wall), and
- there's no change in player facing direction
*/
xfac := float64(1)
if 0 > thatPlayerInNextFrame.DirX {
xfac = -xfac
}
virtualGripToWall = xfac * float64(currPlayerDownsync.Speed) * VIRTUAL_GRID_TO_WORLD_RATIO
}
collision := playerCollider.Check(virtualGripToWall, 0)
if nil == collision {
return &ret
}
@@ -356,10 +387,9 @@ func calcHardPushbacksNorms(joinIndex int32, playerCollider *resolv.Object, play
for _, obj := range collision.Objects {
isBarrier := false
switch obj.Data.(type) {
case *PlayerDownsync:
case *MeleeBullet:
case *PlayerDownsync, *MeleeBullet, *FireballBullet:
default:
// By default it's a regular barrier, even if data is nil, note that Golang syntax of switch-case is kind of confusing, this "default" condition is met only if "!*PlayerDownsync && !*MeleeBullet".
// By default it's a regular barrier, even if data is nil, note that Golang syntax of switch-case is kind of confusing, this "default" condition is met only if "!*PlayerDownsync && !*MeleeBullet && !*FireballBullet".
isBarrier = true
}
@@ -367,7 +397,7 @@ func calcHardPushbacksNorms(joinIndex int32, playerCollider *resolv.Object, play
continue
}
barrierShape := obj.Shape.(*resolv.ConvexPolygon)
overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, barrierShape)
overlapped, pushbackX, pushbackY, overlapResult := calcPushbacks(0, 0, playerShape, barrierShape)
if !overlapped {
continue
}
@@ -418,13 +448,21 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
if decodedInput.BtnBLevel > prevBtnBLevel {
if _, existent := inAirSet[currPlayerDownsync.CharacterState]; !existent {
jumpedOrNot = true
} else if ATK_CHARACTER_STATE_ONWALL == currPlayerDownsync.CharacterState {
jumpedOrNot = true
}
}
}
patternId := PATTERN_ID_NO_OP
if decodedInput.BtnALevel > prevBtnALevel {
patternId = 1
if 0 > effDy {
patternId = 3
} else if 0 < effDy {
patternId = 2
} else {
patternId = 1
}
}
return patternId, jumpedOrNot, effDx, effDy
@@ -447,6 +485,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
VelY: currPlayerDownsync.VelY,
CharacterState: currPlayerDownsync.CharacterState,
InAir: true,
OnWall: false,
Speed: currPlayerDownsync.Speed,
BattleState: currPlayerDownsync.BattleState,
Score: currPlayerDownsync.Score,
@@ -460,6 +499,8 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
ActiveSkillHit: currPlayerDownsync.ActiveSkillHit,
FramesInvinsible: currPlayerDownsync.FramesInvinsible - 1,
ColliderRadius: currPlayerDownsync.ColliderRadius,
OnWallNormX: currPlayerDownsync.OnWallNormX,
OnWallNormY: currPlayerDownsync.OnWallNormY,
}
if nextRenderFramePlayers[i].FramesToRecover < 0 {
nextRenderFramePlayers[i].FramesToRecover = 0
@@ -469,65 +510,100 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
}
}
// [WARNING] For rollback compatibility, MeleeBullets are composed of only static BulletConfig data and move along with the offenders, therefore they can just be copies of the pointers in "RenderFrameBuffer", however, FireballBullets move on their own and must be copies of instances for each RenderFrame!
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?
nextRenderFrameFireballBullets := make([]*FireballBullet, 0, len(currRenderFrame.FireballBullets))
effPushbacks := make([]Vec2D, roomCapacity)
hardPushbackNorms := make([]*[]Vec2D, roomCapacity)
jumpedOrNotList := make([]bool, roomCapacity)
bulletLocalId := currRenderFrame.BulletLocalIdCounter
// 1. Process player inputs
for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
jumpedOrNotList[i] = false
chConfig := chConfigsOrderedByJoinIndex[i]
thatPlayerInNextFrame := nextRenderFramePlayers[i]
patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, inputsBuffer)
if jumpedOrNot {
thatPlayerInNextFrame.VelY = int32(chConfig.JumpingInitVelY)
jumpedOrNotList[i] = true
}
jumpedOrNotList[i] = jumpedOrNot
joinIndex := currPlayerDownsync.JoinIndex
skillId := chConfig.SkillMapper(patternId, currPlayerDownsync)
if skillConfig, existent := skills[skillId]; existent {
thatPlayerInNextFrame.ActiveSkillId = int32(skillId)
thatPlayerInNextFrame.ActiveSkillHit = 0
thatPlayerInNextFrame.FramesToRecover = skillConfig.RecoveryFrames
xfac := int32(1)
if 0 > thatPlayerInNextFrame.DirX {
xfac = -xfac
}
hasLockVel := false
// Hardcoded to use only the first hit for now
switch v := skillConfig.Hits[thatPlayerInNextFrame.ActiveSkillHit].(type) {
case *MeleeBullet:
var newBullet MeleeBullet = *v // Copied primitive fields into an onstack variable
newBullet.OriginatedRenderFrameId = currRenderFrame.Id
newBullet.OffenderJoinIndex = joinIndex
newBullet.BattleAttr = &BulletBattleAttr{
BulletLocalId: bulletLocalId,
OriginatedRenderFrameId: currRenderFrame.Id,
OffenderJoinIndex: joinIndex,
TeamId: currPlayerDownsync.BulletTeamId,
}
bulletLocalId++
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, &newBullet)
thatPlayerInNextFrame.FramesToRecover = skillConfig.RecoveryFrames
hasLockVel := false
if NO_LOCK_VEL != v.SelfLockVelX {
if NO_LOCK_VEL != v.Bullet.SelfLockVelX {
hasLockVel = true
xfac := int32(1)
if 0 > thatPlayerInNextFrame.DirX {
xfac = -xfac
}
thatPlayerInNextFrame.VelX = xfac * v.SelfLockVelX
thatPlayerInNextFrame.VelX = xfac * v.Bullet.SelfLockVelX
}
if NO_LOCK_VEL != v.SelfLockVelY {
if NO_LOCK_VEL != v.Bullet.SelfLockVelY {
hasLockVel = true
thatPlayerInNextFrame.VelY = v.SelfLockVelY
thatPlayerInNextFrame.VelY = v.Bullet.SelfLockVelY
}
if false == hasLockVel {
if false == currPlayerDownsync.InAir {
thatPlayerInNextFrame.VelX = 0
}
case *FireballBullet:
var newBullet FireballBullet = *v // Copied primitive fields into an onstack variable
newBullet.BattleAttr = &BulletBattleAttr{
BulletLocalId: bulletLocalId,
OriginatedRenderFrameId: currRenderFrame.Id,
OffenderJoinIndex: joinIndex,
TeamId: currPlayerDownsync.BulletTeamId,
}
bulletLocalId++
newBullet.VirtualGridX, newBullet.VirtualGridY = currPlayerDownsync.VirtualGridX+xfac*newBullet.Bullet.HitboxOffsetX, currPlayerDownsync.VirtualGridY+newBullet.Bullet.HitboxOffsetY
newBullet.DirX = xfac
newBullet.DirY = 0
newBullet.VelX = newBullet.Speed * xfac
newBullet.VelY = 0
nextRenderFrameFireballBullets = append(nextRenderFrameFireballBullets, &newBullet)
//fmt.Printf("Created new fireball @currRenderFrame.Id=%d, %p, bulletLocalId=%d, virtualGridX=%d, virtualGridY=%d, offenderVpos=(%d,%d)\n", currRenderFrame.Id, &newBullet, bulletLocalId, newBullet.VirtualGridX, newBullet.VirtualGridY, currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY)
if NO_LOCK_VEL != v.Bullet.SelfLockVelX {
hasLockVel = true
thatPlayerInNextFrame.VelX = xfac * v.Bullet.SelfLockVelX
}
if NO_LOCK_VEL != v.Bullet.SelfLockVelY {
hasLockVel = true
thatPlayerInNextFrame.VelY = v.Bullet.SelfLockVelY
}
}
if false == hasLockVel && false == currPlayerDownsync.InAir {
thatPlayerInNextFrame.VelX = 0
}
thatPlayerInNextFrame.CharacterState = skillConfig.BoundChState
continue // Don't allow movement if skill is used
}
if 0 == currPlayerDownsync.FramesToRecover {
if 0 != effDx || 0 != effDy {
thatPlayerInNextFrame.DirX, thatPlayerInNextFrame.DirY = effDx, effDy
thatPlayerInNextFrame.VelX = effDx * currPlayerDownsync.Speed
if 0 != effDx {
xfac := int32(1)
if 0 > effDx {
xfac = -xfac
}
thatPlayerInNextFrame.DirX = effDx
thatPlayerInNextFrame.DirY = effDy
thatPlayerInNextFrame.VelX = xfac * currPlayerDownsync.Speed
if intAbs(thatPlayerInNextFrame.VelX) < intAbs(currPlayerDownsync.VelX) {
// Wall jumping
thatPlayerInNextFrame.VelX = xfac * intAbs(currPlayerDownsync.VelX)
}
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_WALKING
} else {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
@@ -541,12 +617,31 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
joinIndex := currPlayerDownsync.JoinIndex
effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y = float64(0), float64(0)
thatPlayerInNextFrame := nextRenderFramePlayers[i]
chConfig := chConfigsOrderedByJoinIndex[i]
// Reset playerCollider position from the "virtual grid position"
newVx, newVy := currPlayerDownsync.VirtualGridX+currPlayerDownsync.VelX, currPlayerDownsync.VirtualGridY+currPlayerDownsync.VelY
if jumpedOrNotList[i] {
newVy += chConfig.JumpingInitVelY // Immediately gets out of any snapping
// We haven't proceeded with "OnWall" calculation for "thatPlayerInNextFrame", thus use "currPlayerDownsync.OnWall" for checking
if ATK_CHARACTER_STATE_ONWALL == currPlayerDownsync.CharacterState {
if 0 < currPlayerDownsync.VelX*currPlayerDownsync.OnWallNormX {
newVx -= currPlayerDownsync.VelX // Cancel the alleged horizontal movement pointing to same direction of wall inward norm first
}
xfac := int32(-1)
if 0 > currPlayerDownsync.OnWallNormX {
// Always jump to the opposite direction of wall inward norm
xfac = -xfac
}
newVx += xfac * chConfig.WallJumpingInitVelX
newVy += chConfig.WallJumpingInitVelY
thatPlayerInNextFrame.VelX = int32(xfac * chConfig.WallJumpingInitVelX)
thatPlayerInNextFrame.VelY = int32(chConfig.WallJumpingInitVelY)
thatPlayerInNextFrame.FramesToRecover = chConfig.WallJumpingFramesToRecover
} else {
thatPlayerInNextFrame.VelY = int32(chConfig.JumpingInitVelY)
newVy += chConfig.JumpingInitVelY // Immediately gets out of any snapping
}
}
wx, wy := VirtualGridToWorldPos(newVx, newVy)
@@ -554,7 +649,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
switch currPlayerDownsync.CharacterState {
case ATK_CHARACTER_STATE_LAY_DOWN1:
colliderWidth, colliderHeight = currPlayerDownsync.ColliderRadius*4, currPlayerDownsync.ColliderRadius*2
case ATK_CHARACTER_STATE_BLOWN_UP1, ATK_CHARACTER_STATE_INAIR_IDLE1_NO_JUMP, ATK_CHARACTER_STATE_INAIR_IDLE1_BY_JUMP:
case ATK_CHARACTER_STATE_BLOWN_UP1, ATK_CHARACTER_STATE_INAIR_IDLE1_NO_JUMP, ATK_CHARACTER_STATE_INAIR_IDLE1_BY_JUMP, ATK_CHARACTER_STATE_ONWALL:
colliderWidth, colliderHeight = currPlayerDownsync.ColliderRadius*2, currPlayerDownsync.ColliderRadius*2
}
@@ -566,40 +661,69 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
// Add to collision system
collisionSys.Add(playerCollider)
thatPlayerInNextFrame := nextRenderFramePlayers[i]
if currPlayerDownsync.InAir {
thatPlayerInNextFrame.VelX += GRAVITY_X
thatPlayerInNextFrame.VelY += GRAVITY_Y
if ATK_CHARACTER_STATE_ONWALL == currPlayerDownsync.CharacterState && !jumpedOrNotList[i] {
thatPlayerInNextFrame.VelX += GRAVITY_X
thatPlayerInNextFrame.VelY = chConfig.WallSlidingVelY
} else {
thatPlayerInNextFrame.VelX += GRAVITY_X
thatPlayerInNextFrame.VelY += GRAVITY_Y
}
}
}
// 3. Add bullet colliders into collision system
bulletColliders := make([]*resolv.Object, 0, len(currRenderFrame.MeleeBullets)) // Will all be removed at the end of this function due to the need for being rollback-compatible
for _, meleeBullet := range currRenderFrame.MeleeBullets {
if (meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames <= currRenderFrame.Id) && (meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames+meleeBullet.ActiveFrames > currRenderFrame.Id) {
offender := currRenderFrame.PlayersArr[meleeBullet.OffenderJoinIndex-1]
if (meleeBullet.BattleAttr.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames <= currRenderFrame.Id) && (meleeBullet.BattleAttr.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames+meleeBullet.Bullet.ActiveFrames > currRenderFrame.Id) {
offender := currRenderFrame.PlayersArr[meleeBullet.BattleAttr.OffenderJoinIndex-1]
xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
if 0 > offender.DirX {
xfac = -xfac
}
bulletWx, bulletWy := VirtualGridToWorldPos(offender.VirtualGridX+xfac*meleeBullet.HitboxOffsetX, offender.VirtualGridY)
hitboxSizeWx, hitboxSizeWy := VirtualGridToWorldPos(meleeBullet.HitboxSizeX, meleeBullet.HitboxSizeY)
bulletWx, bulletWy := VirtualGridToWorldPos(offender.VirtualGridX+xfac*meleeBullet.Bullet.HitboxOffsetX, offender.VirtualGridY)
hitboxSizeWx, hitboxSizeWy := VirtualGridToWorldPos(meleeBullet.Bullet.HitboxSizeX, meleeBullet.Bullet.HitboxSizeY)
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, hitboxSizeWx, hitboxSizeWy, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, collisionSpaceOffsetX, collisionSpaceOffsetY, meleeBullet, "MeleeBullet")
collisionSys.Add(newBulletCollider)
bulletColliders = append(bulletColliders, newBulletCollider)
} else {
} else if meleeBullet.BattleAttr.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames+meleeBullet.Bullet.ActiveFrames > currRenderFrame.Id {
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, meleeBullet)
}
}
for _, prevFireball := range currRenderFrame.FireballBullets {
fireballBullet := &FireballBullet{
VirtualGridX: prevFireball.VirtualGridX,
VirtualGridY: prevFireball.VirtualGridY,
DirX: prevFireball.DirX,
DirY: prevFireball.DirY,
VelX: prevFireball.VelX,
VelY: prevFireball.VelY,
Speed: prevFireball.Speed,
SpeciesId: prevFireball.SpeciesId,
Bullet: prevFireball.Bullet,
BattleAttr: prevFireball.BattleAttr,
}
if (fireballBullet.BattleAttr.OriginatedRenderFrameId+fireballBullet.Bullet.StartupFrames < currRenderFrame.Id) && (fireballBullet.BattleAttr.OriginatedRenderFrameId+fireballBullet.Bullet.StartupFrames+fireballBullet.Bullet.ActiveFrames > currRenderFrame.Id) {
bulletWx, bulletWy := VirtualGridToWorldPos(fireballBullet.VirtualGridX, fireballBullet.VirtualGridY)
hitboxSizeWx, hitboxSizeWy := VirtualGridToWorldPos(fireballBullet.Bullet.HitboxSizeX, fireballBullet.Bullet.HitboxSizeY)
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, hitboxSizeWx, hitboxSizeWy, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, collisionSpaceOffsetX, collisionSpaceOffsetY, fireballBullet, "FireballBullet")
collisionSys.Add(newBulletCollider)
bulletColliders = append(bulletColliders, newBulletCollider)
} else if fireballBullet.BattleAttr.OriginatedRenderFrameId+fireballBullet.Bullet.StartupFrames+fireballBullet.Bullet.ActiveFrames > currRenderFrame.Id {
// fmt.Printf("Pushing static fireball to next frame @currRenderFrame.Id=%d, bulletLocalId=%d, virtualGridX=%d, virtualGridY=%d\n", currRenderFrame.Id, fireballBullet.BattleAttr.BulletLocalId, fireballBullet.VirtualGridX, fireballBullet.VirtualGridY)
nextRenderFrameFireballBullets = append(nextRenderFrameFireballBullets, fireballBullet)
}
}
// 4. Calc pushbacks for each player (after its movement) w/o bullets
for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
joinIndex := currPlayerDownsync.JoinIndex
playerCollider := playerColliders[i]
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
hardPushbackNorms[joinIndex-1] = calcHardPushbacksNorms(joinIndex, playerCollider, playerShape, SNAP_INTO_PLATFORM_OVERLAP, &(effPushbacks[joinIndex-1]))
thatPlayerInNextFrame := nextRenderFramePlayers[i]
hardPushbackNorms[joinIndex-1] = calcHardPushbacksNorms(joinIndex, currPlayerDownsync, thatPlayerInNextFrame, playerCollider, playerShape, SNAP_INTO_PLATFORM_OVERLAP, &(effPushbacks[joinIndex-1]))
chConfig := chConfigsOrderedByJoinIndex[i]
landedOnGravityPushback := false
@@ -609,7 +733,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
switch obj.Data.(type) {
case *PlayerDownsync:
isAnotherPlayer = true
case *MeleeBullet:
case *MeleeBullet, *FireballBullet:
isBullet = true
default:
// By default it's a regular barrier, even if data is nil
@@ -620,7 +744,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
continue
}
bShape := obj.Shape.(*resolv.ConvexPolygon)
overlapped, pushbackX, pushbackY, overlapResult := CalcPushbacks(0, 0, playerShape, bShape)
overlapped, pushbackX, pushbackY, overlapResult := calcPushbacks(0, 0, playerShape, bShape)
if !overlapped {
continue
}
@@ -648,24 +772,27 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
}
if landedOnGravityPushback {
thatPlayerInNextFrame.InAir = false
if currPlayerDownsync.InAir && 0 >= currPlayerDownsync.VelY {
// fallStopping
fallStopping := (currPlayerDownsync.InAir && 0 >= currPlayerDownsync.VelY)
if fallStopping {
thatPlayerInNextFrame.VelY = 0
thatPlayerInNextFrame.VelX = 0
if _, existent := nonAttackingSet[thatPlayerInNextFrame.CharacterState]; existent {
if ATK_CHARACTER_STATE_BLOWN_UP1 == thatPlayerInNextFrame.CharacterState {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_LAY_DOWN1
thatPlayerInNextFrame.FramesToRecover = chConfig.LayDownFramesToRecover
} else {
if ATK_CHARACTER_STATE_BLOWN_UP1 == thatPlayerInNextFrame.CharacterState {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_LAY_DOWN1
thatPlayerInNextFrame.FramesToRecover = chConfig.LayDownFramesToRecover
} else {
switch currPlayerDownsync.CharacterState {
case ATK_CHARACTER_STATE_BLOWN_UP1, ATK_CHARACTER_STATE_INAIR_IDLE1_NO_JUMP, ATK_CHARACTER_STATE_INAIR_IDLE1_BY_JUMP, ATK_CHARACTER_STATE_ONWALL:
// [WARNING] To prevent bouncing due to abrupt change of collider shape, it's important that we check "currPlayerDownsync" instead of "thatPlayerInNextFrame" here!
halfColliderWidthDiff, halfColliderHeightDiff := int32(0), currPlayerDownsync.ColliderRadius
_, halfColliderWorldHeightDiff := VirtualGridToWorldPos(halfColliderWidthDiff, halfColliderHeightDiff)
effPushbacks[joinIndex-1].Y -= halfColliderWorldHeightDiff // To prevent bouncing due to abrupt change of collider shape
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
effPushbacks[joinIndex-1].Y -= halfColliderWorldHeightDiff
}
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
thatPlayerInNextFrame.FramesToRecover = 0
}
} else {
// landedOnGravityPushback not fallStopping, could be in LayDown or GetUp
if _, existent := nonAttackingSet[thatPlayerInNextFrame.CharacterState]; existent {
// not fallStopping, could be in LayDown or GetUp
if ATK_CHARACTER_STATE_LAY_DOWN1 == thatPlayerInNextFrame.CharacterState {
if 0 == thatPlayerInNextFrame.FramesToRecover {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_GET_UP1
@@ -680,56 +807,140 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
}
}
}
if chConfig.OnWallEnabled {
if thatPlayerInNextFrame.InAir {
// [WARNING] Sticking to wall MUST BE based on "InAir", otherwise we would get gravity reduction from ground up incorrectly!
if _, existent := noOpSet[currPlayerDownsync.CharacterState]; !existent {
// [WARNING] Sticking to wall could only be triggered by proactive player input
for _, hardPushbackNorm := range *hardPushbackNorms[joinIndex-1] {
normAlignmentWithHorizon1 := (hardPushbackNorm.X*float64(1.0) + hardPushbackNorm.Y*float64(0.0))
normAlignmentWithHorizon2 := (hardPushbackNorm.X*float64(-1.0) + hardPushbackNorm.Y*float64(0.0))
if VERTICAL_PLATFORM_THRESHOLD < normAlignmentWithHorizon1 {
thatPlayerInNextFrame.OnWall = true
thatPlayerInNextFrame.OnWallNormX, thatPlayerInNextFrame.OnWallNormY = int32(hardPushbackNorm.X), int32(hardPushbackNorm.Y)
break
}
if VERTICAL_PLATFORM_THRESHOLD < normAlignmentWithHorizon2 {
thatPlayerInNextFrame.OnWall = true
thatPlayerInNextFrame.OnWallNormX, thatPlayerInNextFrame.OnWallNormY = int32(hardPushbackNorm.X), int32(hardPushbackNorm.Y)
break
}
}
if !currPlayerDownsync.OnWall && thatPlayerInNextFrame.OnWall {
// To avoid mysterious climbing up the wall after sticking on it
thatPlayerInNextFrame.VelY = 0
}
}
}
if !thatPlayerInNextFrame.OnWall {
thatPlayerInNextFrame.OnWallNormX, thatPlayerInNextFrame.OnWallNormY = 0, 0
}
}
}
// 5. Check bullet-anything collisions
for _, bulletCollider := range bulletColliders {
collision := bulletCollider.Check(0, 0)
bulletCollider.Space.Remove(bulletCollider) // Make sure that the bulletCollider is always removed for each renderFrame
switch v := bulletCollider.Data.(type) {
case *MeleeBullet:
if nil == collision {
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, v)
continue
}
bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon)
offender := currRenderFrame.PlayersArr[v.OffenderJoinIndex-1]
for _, obj := range collision.Objects {
defenderShape := obj.Shape.(*resolv.ConvexPolygon)
switch t := obj.Data.(type) {
case *PlayerDownsync:
if v.OffenderJoinIndex == t.JoinIndex {
continue
addToNextRenderFrame := true
if nil != collision {
switch v := bulletCollider.Data.(type) {
case *MeleeBullet:
bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon)
offender := currRenderFrame.PlayersArr[v.BattleAttr.OffenderJoinIndex-1]
for _, obj := range collision.Objects {
defenderShape := obj.Shape.(*resolv.ConvexPolygon)
switch t := obj.Data.(type) {
case *PlayerDownsync:
if v.BattleAttr.OffenderJoinIndex == t.JoinIndex {
continue
}
overlapped, _, _, _ := calcPushbacks(0, 0, bulletShape, defenderShape)
if !overlapped {
continue
}
addToNextRenderFrame = false
if _, existent := invinsibleSet[t.CharacterState]; existent {
continue
}
if 0 < t.FramesInvinsible {
continue
}
xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
if 0 > offender.DirX {
xfac = -xfac
}
pushbackVelX, pushbackVelY := xfac*v.Bullet.PushbackVelX, v.Bullet.PushbackVelY
atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
atkedPlayerInNextFrame.VelX = pushbackVelX
atkedPlayerInNextFrame.VelY = pushbackVelY
if v.Bullet.BlowUp {
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
} else {
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
}
oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover
if v.Bullet.HitStunFrames > oldFramesToRecover {
atkedPlayerInNextFrame.FramesToRecover = v.Bullet.HitStunFrames
}
default:
addToNextRenderFrame = false
}
if _, existent := invinsibleSet[t.CharacterState]; existent {
continue
}
if 0 < t.FramesInvinsible {
continue
}
overlapped, _, _, _ := CalcPushbacks(0, 0, bulletShape, defenderShape)
if !overlapped {
continue
}
xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
if 0 > offender.DirX {
xfac = -xfac
}
pushbackVelX, pushbackVelY := xfac*v.PushbackVelX, v.PushbackVelY
atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
atkedPlayerInNextFrame.VelX = pushbackVelX
atkedPlayerInNextFrame.VelY = pushbackVelY
if v.BlowUp {
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
} else {
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
}
oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover
if v.HitStunFrames > oldFramesToRecover {
atkedPlayerInNextFrame.FramesToRecover = v.HitStunFrames
}
default:
}
case *FireballBullet:
bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon)
offender := currRenderFrame.PlayersArr[v.BattleAttr.OffenderJoinIndex-1]
for _, obj := range collision.Objects {
defenderShape := obj.Shape.(*resolv.ConvexPolygon)
switch t := obj.Data.(type) {
case *PlayerDownsync:
if v.BattleAttr.OffenderJoinIndex == t.JoinIndex {
continue
}
overlapped, _, _, _ := calcPushbacks(0, 0, bulletShape, defenderShape)
if !overlapped {
continue
}
addToNextRenderFrame = false
if _, existent := invinsibleSet[t.CharacterState]; existent {
continue
}
if 0 < t.FramesInvinsible {
continue
}
xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
if 0 > offender.DirX {
xfac = -xfac
}
pushbackVelX, pushbackVelY := xfac*v.Bullet.PushbackVelX, v.Bullet.PushbackVelY
atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
atkedPlayerInNextFrame.VelX = pushbackVelX
atkedPlayerInNextFrame.VelY = pushbackVelY
if v.Bullet.BlowUp {
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
} else {
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
}
oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover
if v.Bullet.HitStunFrames > oldFramesToRecover {
atkedPlayerInNextFrame.FramesToRecover = v.Bullet.HitStunFrames
}
default:
addToNextRenderFrame = false
}
}
}
}
if addToNextRenderFrame {
switch v := bulletCollider.Data.(type) {
case *MeleeBullet:
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, v)
case *FireballBullet:
v.VirtualGridX, v.VirtualGridY = v.VirtualGridX+v.VelX, v.VirtualGridY+v.VelY
nextRenderFrameFireballBullets = append(nextRenderFrameFireballBullets, v)
}
}
}
@@ -747,7 +958,9 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
oldNextCharacterState := thatPlayerInNextFrame.CharacterState
switch oldNextCharacterState {
case ATK_CHARACTER_STATE_IDLE1, ATK_CHARACTER_STATE_WALKING:
if jumpedOrNotList[i] || ATK_CHARACTER_STATE_INAIR_IDLE1_BY_JUMP == currPlayerDownsync.CharacterState {
if thatPlayerInNextFrame.OnWall {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ONWALL
} else if jumpedOrNotList[i] || ATK_CHARACTER_STATE_INAIR_IDLE1_BY_JUMP == currPlayerDownsync.CharacterState {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_IDLE1_BY_JUMP
} else {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_IDLE1_NO_JUMP
@@ -777,9 +990,11 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
}
return &RoomDownsyncFrame{
Id: currRenderFrame.Id + 1,
PlayersArr: nextRenderFramePlayers,
MeleeBullets: nextRenderFrameMeleeBullets,
Id: currRenderFrame.Id + 1,
PlayersArr: nextRenderFramePlayers,
BulletLocalIdCounter: bulletLocalId,
MeleeBullets: nextRenderFrameMeleeBullets,
FireballBullets: nextRenderFrameFireballBullets,
}
}
@@ -860,3 +1075,77 @@ func AlignPolygon2DToBoundingBox(input *Polygon2D) *Polygon2D {
return output
}
func NewMeleeBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32) *MeleeBullet {
return &MeleeBullet{
BattleAttr: &BulletBattleAttr{
BulletLocalId: bulletLocalId,
OriginatedRenderFrameId: originatedRenderFrameId,
OffenderJoinIndex: offenderJoinIndex,
TeamId: teamId,
},
Bullet: &BulletConfig{
StartupFrames: startupFrames,
CancellableStFrame: cancellableStFrame,
CancellableEdFrame: cancellableEdFrame,
ActiveFrames: activeFrames,
HitStunFrames: hitStunFrames,
BlockStunFrames: blockStunFrames,
PushbackVelX: pushbackVelX,
PushbackVelY: pushbackVelY,
Damage: damage,
SelfLockVelX: selfLockVelX,
SelfLockVelY: selfLockVelY,
HitboxOffsetX: hitboxOffsetX,
HitboxOffsetY: hitboxOffsetY,
HitboxSizeX: hitboxSizeX,
HitboxSizeY: hitboxSizeY,
BlowUp: blowUp,
},
}
}
func NewFireballBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, speciesId int32) *FireballBullet {
return &FireballBullet{
VirtualGridX: virtualGridX,
VirtualGridY: virtualGridY,
DirX: dirX,
DirY: dirY,
VelX: velX,
VelY: velY,
Speed: speed,
SpeciesId: speciesId,
BattleAttr: &BulletBattleAttr{
BulletLocalId: bulletLocalId,
OriginatedRenderFrameId: originatedRenderFrameId,
OffenderJoinIndex: offenderJoinIndex,
TeamId: teamId,
},
Bullet: &BulletConfig{
StartupFrames: startupFrames,
CancellableStFrame: cancellableStFrame,
CancellableEdFrame: cancellableEdFrame,
ActiveFrames: activeFrames,
HitStunFrames: hitStunFrames,
BlockStunFrames: blockStunFrames,
PushbackVelX: pushbackVelX,
PushbackVelY: pushbackVelY,
Damage: damage,
SelfLockVelX: selfLockVelX,
SelfLockVelY: selfLockVelY,
HitboxOffsetX: hitboxOffsetX,
HitboxOffsetY: hitboxOffsetY,
HitboxSizeX: hitboxSizeX,
HitboxSizeY: hitboxSizeY,
BlowUp: blowUp,
},
}
}

View File

@@ -18,6 +18,13 @@ type CharacterConfig struct {
Speed int32
JumpingInitVelY int32
DashingEnabled bool
OnWallEnabled bool
WallJumpingFramesToRecover int32
WallJumpingInitVelX int32
WallJumpingInitVelY int32
WallSlidingVelY int32
SkillMapper SkillMapperType
}
@@ -35,9 +42,12 @@ var Characters = map[int]*CharacterConfig{
GetUpInvinsibleFrames: int32(10),
GetUpFramesToRecover: int32(27),
Speed: int32(float64(1.2) * WORLD_TO_VIRTUAL_GRID_RATIO),
Speed: int32(float64(3.0) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
DashingEnabled: false,
OnWallEnabled: false,
SkillMapper: func(patternId int, currPlayerDownsync *PlayerDownsync) int {
if 1 == patternId {
if 0 == currPlayerDownsync.FramesToRecover {
@@ -51,8 +61,8 @@ var Characters = map[int]*CharacterConfig{
if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
case *MeleeBullet:
if v.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.CancellableEdFrame {
if nextSkillId, existent2 := v.CancelTransit[patternId]; existent2 {
if v.Bullet.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.Bullet.CancellableEdFrame {
if nextSkillId, existent2 := v.Bullet.CancelTransit[patternId]; existent2 {
return nextSkillId
}
}
@@ -78,9 +88,16 @@ var Characters = map[int]*CharacterConfig{
GetUpInvinsibleFrames: int32(10),
GetUpFramesToRecover: int32(27),
Speed: int32(float64(1.4) * WORLD_TO_VIRTUAL_GRID_RATIO),
Speed: int32(float64(4.0) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(7.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
DashingEnabled: true,
OnWallEnabled: true,
WallJumpingFramesToRecover: int32(9), // 8 would be the minimum for an avg human
WallJumpingInitVelX: int32(float64(2.5) * WORLD_TO_VIRTUAL_GRID_RATIO), // Default is "appeared facing right", but actually holding ctrl against left
WallJumpingInitVelY: int32(float64(7) * WORLD_TO_VIRTUAL_GRID_RATIO),
WallSlidingVelY: int32(float64(-1) * WORLD_TO_VIRTUAL_GRID_RATIO),
SkillMapper: func(patternId int, currPlayerDownsync *PlayerDownsync) int {
if 1 == patternId {
if 0 == currPlayerDownsync.FramesToRecover {
@@ -94,8 +111,8 @@ var Characters = map[int]*CharacterConfig{
if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
case *MeleeBullet:
if v.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.CancellableEdFrame {
if nextSkillId, existent2 := v.CancelTransit[patternId]; existent2 {
if v.Bullet.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.Bullet.CancellableEdFrame {
if nextSkillId, existent2 := v.Bullet.CancelTransit[patternId]; existent2 {
return nextSkillId
}
}
@@ -104,6 +121,60 @@ var Characters = map[int]*CharacterConfig{
}
}
// By default no skill can be fired
return NO_SKILL
},
},
4096: &CharacterConfig{
SpeciesId: 4096,
SpeciesName: "Monk",
InAirIdleFrameIdxTurningPoint: 42,
InAirIdleFrameIdxTurnedCycle: 2,
LayDownFrames: int32(14),
LayDownFramesToRecover: int32(14),
GetUpInvinsibleFrames: int32(8),
GetUpFramesToRecover: int32(30),
Speed: int32(float64(3.0) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(7.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
DashingEnabled: false,
OnWallEnabled: false,
SkillMapper: func(patternId int, currPlayerDownsync *PlayerDownsync) int {
if 1 == patternId {
if 0 == currPlayerDownsync.FramesToRecover {
if currPlayerDownsync.InAir {
return 257
} else {
return 7
}
} else {
// Now that "0 < FramesToRecover", we're only able to fire any skill if it's a cancellation
if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
case *MeleeBullet:
if v.Bullet.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.Bullet.CancellableEdFrame {
if nextSkillId, existent2 := v.Bullet.CancelTransit[patternId]; existent2 {
return nextSkillId
}
}
}
}
}
} else if 2 == patternId {
if !currPlayerDownsync.InAir {
return 11
}
} else if 3 == patternId {
if !currPlayerDownsync.InAir {
return 10
}
}
// By default no skill can be fired
return NO_SKILL
},
@@ -119,7 +190,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK1,
Hits: []interface{}{
&MeleeBullet{
Bullet: Bullet{
Bullet: &BulletConfig{
StartupFrames: int32(7),
ActiveFrames: int32(22),
HitStunFrames: int32(13),
@@ -152,7 +223,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK2,
Hits: []interface{}{
&MeleeBullet{
Bullet: Bullet{
Bullet: &BulletConfig{
StartupFrames: int32(18),
ActiveFrames: int32(18),
HitStunFrames: int32(18),
@@ -183,8 +254,8 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK3,
Hits: []interface{}{
&MeleeBullet{
Bullet: Bullet{
StartupFrames: int32(15),
Bullet: &BulletConfig{
StartupFrames: int32(8),
ActiveFrames: int32(30),
HitStunFrames: MAX_INT32,
BlockStunFrames: int32(9),
@@ -193,9 +264,9 @@ var skills = map[int]*Skill{
SelfLockVelY: int32(float64(5) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelX: int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(float64(7) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(48) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetX: int32(float64(16) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
BlowUp: true,
},
@@ -210,7 +281,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK1,
Hits: []interface{}{
&MeleeBullet{
Bullet: Bullet{
Bullet: &BulletConfig{
StartupFrames: int32(7),
ActiveFrames: int32(22),
HitStunFrames: int32(13),
@@ -243,7 +314,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK2,
Hits: []interface{}{
&MeleeBullet{
Bullet: Bullet{
Bullet: &BulletConfig{
StartupFrames: int32(18),
ActiveFrames: int32(18),
HitStunFrames: int32(18),
@@ -274,16 +345,16 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK3,
Hits: []interface{}{
&MeleeBullet{
Bullet: Bullet{
StartupFrames: int32(15),
Bullet: &BulletConfig{
StartupFrames: int32(8),
ActiveFrames: int32(28),
HitStunFrames: MAX_INT32,
BlockStunFrames: int32(9),
Damage: int32(10),
SelfLockVelX: int32(float64(-0.1) * WORLD_TO_VIRTUAL_GRID_RATIO),
SelfLockVelX: NO_LOCK_VEL,
SelfLockVelY: NO_LOCK_VEL,
PushbackVelX: int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(float64(7) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(float64(3) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
@@ -293,6 +364,152 @@ var skills = map[int]*Skill{
},
},
},
7: &Skill{
RecoveryFrames: int32(30),
RecoveryFramesOnBlock: int32(30),
RecoveryFramesOnHit: int32(30),
ReleaseTriggerType: int32(1),
BoundChState: ATK_CHARACTER_STATE_ATK1,
Hits: []interface{}{
&MeleeBullet{
Bullet: &BulletConfig{
StartupFrames: int32(7),
ActiveFrames: int32(22),
HitStunFrames: int32(13),
BlockStunFrames: int32(9),
Damage: int32(5),
SelfLockVelX: NO_LOCK_VEL,
SelfLockVelY: NO_LOCK_VEL,
PushbackVelX: int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(0),
HitboxOffsetX: int32(float64(12) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
CancellableStFrame: int32(13),
CancellableEdFrame: int32(30),
CancelTransit: map[int]int{
1: 8,
},
// TODO: Use non-zero "selfLockVel"
},
},
},
},
8: &Skill{
RecoveryFrames: int32(36),
RecoveryFramesOnBlock: int32(36),
RecoveryFramesOnHit: int32(36),
ReleaseTriggerType: int32(1),
BoundChState: ATK_CHARACTER_STATE_ATK2,
Hits: []interface{}{
&MeleeBullet{
Bullet: &BulletConfig{
StartupFrames: int32(18),
ActiveFrames: int32(18),
HitStunFrames: int32(18),
BlockStunFrames: int32(9),
Damage: int32(5),
SelfLockVelX: int32(float64(0.1) * WORLD_TO_VIRTUAL_GRID_RATIO),
SelfLockVelY: NO_LOCK_VEL,
PushbackVelX: int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(0),
HitboxOffsetX: int32(float64(18) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
CancellableStFrame: int32(22),
CancellableEdFrame: int32(36),
CancelTransit: map[int]int{
1: 9,
},
},
},
},
},
9: &Skill{
RecoveryFrames: int32(40),
RecoveryFramesOnBlock: int32(40),
RecoveryFramesOnHit: int32(40),
ReleaseTriggerType: int32(1),
BoundChState: ATK_CHARACTER_STATE_ATK3,
Hits: []interface{}{
&MeleeBullet{
Bullet: &BulletConfig{
StartupFrames: int32(7),
ActiveFrames: int32(30),
HitStunFrames: MAX_INT32,
BlockStunFrames: int32(9),
Damage: int32(10),
SelfLockVelX: int32(float64(1) * WORLD_TO_VIRTUAL_GRID_RATIO),
SelfLockVelY: NO_LOCK_VEL,
PushbackVelX: int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(float64(4) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetX: int32(float64(10) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
BlowUp: true,
},
},
},
},
10: &Skill{
RecoveryFrames: int32(40),
RecoveryFramesOnBlock: int32(40),
RecoveryFramesOnHit: int32(40),
ReleaseTriggerType: int32(1),
BoundChState: ATK_CHARACTER_STATE_ATK4,
Hits: []interface{}{
&FireballBullet{
SpeciesId: int32(1),
Speed: int32(float64(5) * WORLD_TO_VIRTUAL_GRID_RATIO),
Bullet: &BulletConfig{
StartupFrames: int32(15),
ActiveFrames: MAX_INT32,
HitStunFrames: int32(15),
BlockStunFrames: int32(9),
Damage: int32(20),
SelfLockVelX: NO_LOCK_VEL,
SelfLockVelY: NO_LOCK_VEL,
PushbackVelX: int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(0),
HitboxOffsetX: int32(float64(18) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(float64(5) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeX: int32(float64(48) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
},
},
},
},
11: &Skill{
RecoveryFrames: int32(60),
RecoveryFramesOnBlock: int32(60),
RecoveryFramesOnHit: int32(60),
ReleaseTriggerType: int32(1),
BoundChState: ATK_CHARACTER_STATE_ATK5,
Hits: []interface{}{
&MeleeBullet{
Bullet: &BulletConfig{
StartupFrames: int32(3),
ActiveFrames: int32(25),
HitStunFrames: MAX_INT32,
BlockStunFrames: int32(9),
Damage: int32(30),
SelfLockVelX: int32(float64(1) * WORLD_TO_VIRTUAL_GRID_RATIO),
SelfLockVelY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelX: int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(float64(7) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetX: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(40) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(64) * WORLD_TO_VIRTUAL_GRID_RATIO),
BlowUp: true,
},
},
},
},
255: &Skill{
RecoveryFrames: int32(30),
RecoveryFramesOnBlock: int32(30),
@@ -301,7 +518,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_INAIR_ATK1,
Hits: []interface{}{
&MeleeBullet{
Bullet: Bullet{
Bullet: &BulletConfig{
StartupFrames: int32(3),
ActiveFrames: int32(20),
HitStunFrames: int32(18),
@@ -327,7 +544,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_INAIR_ATK1,
Hits: []interface{}{
&MeleeBullet{
Bullet: Bullet{
Bullet: &BulletConfig{
StartupFrames: int32(3),
ActiveFrames: int32(10),
HitStunFrames: int32(15),
@@ -345,4 +562,30 @@ var skills = map[int]*Skill{
},
},
},
257: &Skill{
RecoveryFrames: int32(30),
RecoveryFramesOnBlock: int32(30),
RecoveryFramesOnHit: int32(30),
ReleaseTriggerType: int32(1),
BoundChState: ATK_CHARACTER_STATE_INAIR_ATK1,
Hits: []interface{}{
&MeleeBullet{
Bullet: &BulletConfig{
StartupFrames: int32(3),
ActiveFrames: int32(20),
HitStunFrames: int32(18),
BlockStunFrames: int32(9),
Damage: int32(5),
SelfLockVelX: NO_LOCK_VEL,
SelfLockVelY: NO_LOCK_VEL,
PushbackVelX: int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(0),
HitboxOffsetX: int32(float64(12) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
},
},
},
},
}

View File

@@ -33,11 +33,17 @@ type PlayerDownsync struct {
MaxHp int32
CharacterState int32
InAir bool
OnWall bool
OnWallNormX int32
OnWallNormY int32
ActiveSkillId int32
ActiveSkillHit int32
FramesInvinsible int32
BulletTeamId int32
ChCollisionTeamId int32 // not the same as "BulletTeamId", because even in the same team, we should allow inter-character collisions
}
type InputFrameDecoded struct {
@@ -56,14 +62,11 @@ type Barrier struct {
Boundary *Polygon2D
}
type Bullet struct {
// for offender
OriginatedRenderFrameId int32 // Copied from the first bullet for all subsequent bullets
OffenderJoinIndex int32 // Copied to favor collision handling of the dispatched bullet
StartupFrames int32 // from "OriginatedRenderFrameId"
CancellableStFrame int32 // from "OriginatedRenderFrameId"
CancellableEdFrame int32 // from "OriginatedRenderFrameId"
ActiveFrames int32
type BulletConfig struct {
StartupFrames int32 // from "OriginatedRenderFrameId"
CancellableStFrame int32 // from "OriginatedRenderFrameId"
CancellableEdFrame int32 // from "OriginatedRenderFrameId"
ActiveFrames int32
// for defender
HitStunFrames int32
@@ -85,8 +88,18 @@ type Bullet struct {
CancelTransit map[int]int
}
type BulletBattleAttr struct {
BulletLocalId int32 // for referencing cached nodes in frontend rendering
// for offender
OriginatedRenderFrameId int32 // Copied from the first bullet for all subsequent bullets
OffenderJoinIndex int32 // Copied to favor collision handling of the dispatched bullet
TeamId int32
}
type MeleeBullet struct {
Bullet
BattleAttr *BulletBattleAttr
Bullet *BulletConfig
}
type FireballBullet struct {
@@ -97,7 +110,9 @@ type FireballBullet struct {
VelX int32
VelY int32
Speed int32
Bullet
SpeciesId int32
BattleAttr *BulletBattleAttr
Bullet *BulletConfig
}
type Skill struct {
@@ -111,14 +126,15 @@ type Skill struct {
}
type RoomDownsyncFrame struct {
Id int32
PlayersArr []*PlayerDownsync
CountdownNanos int64
MeleeBullets []*MeleeBullet
FireballBullets []*FireballBullet
BackendUnconfirmedMask uint64
ShouldForceResync bool
PlayerOpPatternToSkillId map[int]int
Id int32
PlayersArr []*PlayerDownsync
CountdownNanos int64
MeleeBullets []*MeleeBullet
FireballBullets []*FireballBullet
BackendUnconfirmedMask uint64
ShouldForceResync bool
BulletLocalIdCounter int32
}
type InputFrameDownsync struct {
@@ -126,3 +142,10 @@ type InputFrameDownsync struct {
InputList []uint64
ConfirmedList uint64
}
type NpcPatrolCue struct {
FlAct uint64 // Encoded input when collided with this cue & facing left
FrAct uint64 // Encoded input when collided with this cue & facing right
X float64
Y float64
}

View File

@@ -42,67 +42,61 @@ func NewBarrierJs(boundary *Polygon2D) *js.Object {
})
}
func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, activeSkillId, activeSkillHit, framesInvinsible, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius int32, inAir bool) *js.Object {
func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, activeSkillId, activeSkillHit, framesInvinsible, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius int32, inAir, onWall bool, onWallNormX, onWallNormY, bulletTeamId, chCollisionTeamId int32) *js.Object {
return js.MakeWrapper(&PlayerDownsync{
Id: id,
VirtualGridX: virtualGridX,
VirtualGridY: virtualGridY,
DirX: dirX,
DirY: dirY,
VelX: velX,
VelY: velY,
FramesToRecover: framesToRecover,
FramesInChState: framesInChState,
ActiveSkillId: activeSkillId,
ActiveSkillHit: activeSkillHit,
FramesInvinsible: framesInvinsible,
Speed: speed,
BattleState: battleState,
CharacterState: characterState,
JoinIndex: joinIndex,
Hp: hp,
MaxHp: maxHp,
ColliderRadius: colliderRadius,
InAir: inAir,
Id: id,
VirtualGridX: virtualGridX,
VirtualGridY: virtualGridY,
DirX: dirX,
DirY: dirY,
VelX: velX,
VelY: velY,
FramesToRecover: framesToRecover,
FramesInChState: framesInChState,
ActiveSkillId: activeSkillId,
ActiveSkillHit: activeSkillHit,
FramesInvinsible: framesInvinsible,
Speed: speed,
BattleState: battleState,
CharacterState: characterState,
JoinIndex: joinIndex,
Hp: hp,
MaxHp: maxHp,
ColliderRadius: colliderRadius,
InAir: inAir,
OnWall: onWall,
OnWallNormX: onWallNormX,
OnWallNormY: onWallNormY,
BulletTeamId: bulletTeamId,
ChCollisionTeamId: chCollisionTeamId,
})
}
func NewMeleeBulletJs(originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool) *js.Object {
return js.MakeWrapper(&MeleeBullet{
Bullet: Bullet{
OriginatedRenderFrameId: originatedRenderFrameId,
OffenderJoinIndex: offenderJoinIndex,
func NewMeleeBulletJs(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32) *js.Object {
return js.MakeWrapper(NewMeleeBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY, blowUp, teamId))
}
StartupFrames: startupFrames,
CancellableStFrame: cancellableStFrame,
CancellableEdFrame: cancellableEdFrame,
ActiveFrames: activeFrames,
func NewFireballBulletJs(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, speciesId int32) *js.Object {
return js.MakeWrapper(NewFireballBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY, blowUp, teamId, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, speciesId))
}
HitStunFrames: hitStunFrames,
BlockStunFrames: blockStunFrames,
PushbackVelX: pushbackVelX,
PushbackVelY: pushbackVelY,
Damage: damage,
SelfLockVelX: selfLockVelX,
SelfLockVelY: selfLockVelY,
HitboxOffsetX: hitboxOffsetX,
HitboxOffsetY: hitboxOffsetY,
HitboxSizeX: hitboxSizeX,
HitboxSizeY: hitboxSizeY,
BlowUp: blowUp,
},
func NewNpcPatrolCue(flAct, frAct uint64, x, y float64) *js.Object {
return js.MakeFullWrapper(&NpcPatrolCue{
FlAct: flAct,
FrAct: frAct,
X: x,
Y: y,
})
}
func NewRoomDownsyncFrameJs(id int32, playersArr []*PlayerDownsync, meleeBullets []*MeleeBullet) *js.Object {
func NewRoomDownsyncFrameJs(id int32, playersArr []*PlayerDownsync, bulletLocalIdCounter int32, meleeBullets []*MeleeBullet, fireballBullets []*FireballBullet) *js.Object {
// [WARNING] Avoid using "pb.RoomDownsyncFrame" here, in practive "MakeFullWrapper" doesn't expose the public fields for a "protobuf struct" as expected and requires helper functions like "GetCollisionSpaceObjsJs".
return js.MakeFullWrapper(&RoomDownsyncFrame{
Id: id,
PlayersArr: playersArr,
MeleeBullets: meleeBullets,
Id: id,
PlayersArr: playersArr,
BulletLocalIdCounter: bulletLocalIdCounter,
MeleeBullets: meleeBullets,
FireballBullets: fireballBullets,
})
}
@@ -157,6 +151,8 @@ func main() {
"NewBarrierJs": NewBarrierJs,
"NewPlayerDownsyncJs": NewPlayerDownsyncJs,
"NewMeleeBulletJs": NewMeleeBulletJs,
"NewFireballBulletJs": NewFireballBulletJs,
"NewNpcPatrolCue": NewNpcPatrolCue,
"NewRoomDownsyncFrameJs": NewRoomDownsyncFrameJs,
"NewCollisionSpaceJs": NewCollisionSpaceJs,
"NewInputFrameDownsync": NewInputFrameDownsync,