Compare commits

..

14 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
79 changed files with 13354 additions and 1274 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). 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) ![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 video mainly shows the following features.
- The backend receives inputs from frontend peers and broadcasts back for synchronization. - 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 ## 1.1 Tools to install
### Backend ### 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) - [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) - [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) - [Redis 3.0.503 or above](https://redis.io/download/) (mandatory)
- [skeema](https://www.skeema.io/) (optional, only for convenient MySQL schema provisioning) - [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{ ret := &pb.RoomDownsyncFrame{
Id: rdf.Id, Id: rdf.Id,
PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)), PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)),
BulletLocalIdCounter: rdf.BulletLocalIdCounter,
MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)), MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)),
FireballBullets: make([]*pb.FireballBullet, len(rdf.FireballBullets), len(rdf.FireballBullets)),
CountdownNanos: rdf.CountdownNanos, CountdownNanos: rdf.CountdownNanos,
BackendUnconfirmedMask: rdf.BackendUnconfirmedMask, BackendUnconfirmedMask: rdf.BackendUnconfirmedMask,
ShouldForceResync: rdf.ShouldForceResync, ShouldForceResync: rdf.ShouldForceResync,
@@ -36,7 +38,12 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
BattleState: last.BattleState, BattleState: last.BattleState,
CharacterState: last.CharacterState, CharacterState: last.CharacterState,
InAir: last.InAir, InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
JoinIndex: last.JoinIndex, JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
Hp: last.Hp, Hp: last.Hp,
MaxHp: last.MaxHp, MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius, ColliderRadius: last.ColliderRadius,
@@ -48,33 +55,75 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
for i, last := range rdf.MeleeBullets { for i, last := range rdf.MeleeBullets {
pbBullet := &pb.MeleeBullet{ pbBullet := &pb.MeleeBullet{
OriginatedRenderFrameId: last.OriginatedRenderFrameId, BulletLocalId: last.BattleAttr.BulletLocalId,
OffenderJoinIndex: last.OffenderJoinIndex, OriginatedRenderFrameId: last.BattleAttr.OriginatedRenderFrameId,
OffenderJoinIndex: last.BattleAttr.OffenderJoinIndex,
TeamId: last.BattleAttr.TeamId,
StartupFrames: last.StartupFrames, StartupFrames: last.Bullet.StartupFrames,
CancellableStFrame: last.CancellableStFrame, CancellableStFrame: last.Bullet.CancellableStFrame,
CancellableEdFrame: last.CancellableEdFrame, CancellableEdFrame: last.Bullet.CancellableEdFrame,
ActiveFrames: last.ActiveFrames, ActiveFrames: last.Bullet.ActiveFrames,
HitStunFrames: last.HitStunFrames, HitStunFrames: last.Bullet.HitStunFrames,
BlockStunFrames: last.BlockStunFrames, BlockStunFrames: last.Bullet.BlockStunFrames,
PushbackVelX: last.PushbackVelX, PushbackVelX: last.Bullet.PushbackVelX,
PushbackVelY: last.PushbackVelY, PushbackVelY: last.Bullet.PushbackVelY,
Damage: last.Damage, Damage: last.Bullet.Damage,
SelfLockVelX: last.SelfLockVelX, SelfLockVelX: last.Bullet.SelfLockVelX,
SelfLockVelY: last.SelfLockVelY, SelfLockVelY: last.Bullet.SelfLockVelY,
HitboxOffsetX: last.HitboxOffsetX, HitboxOffsetX: last.Bullet.HitboxOffsetX,
HitboxOffsetY: last.HitboxOffsetY, HitboxOffsetY: last.Bullet.HitboxOffsetY,
HitboxSizeX: last.HitboxSizeX, HitboxSizeX: last.Bullet.HitboxSizeX,
HitboxSizeY: last.HitboxSizeY, HitboxSizeY: last.Bullet.HitboxSizeY,
BlowUp: last.BlowUp, BlowUp: last.Bullet.BlowUp,
} }
ret.MeleeBullets[i] = pbBullet 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 return ret
} }
@@ -102,7 +151,12 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
BattleState: last.BattleState, BattleState: last.BattleState,
CharacterState: last.CharacterState, CharacterState: last.CharacterState,
InAir: last.InAir, InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
JoinIndex: last.JoinIndex, JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
ColliderRadius: last.ColliderRadius, ColliderRadius: last.ColliderRadius,
Score: last.Score, Score: last.Score,
Removed: last.Removed, Removed: last.Removed,
@@ -142,10 +196,15 @@ func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
BattleState: last.BattleState, BattleState: last.BattleState,
CharacterState: last.CharacterState, CharacterState: last.CharacterState,
JoinIndex: last.JoinIndex, JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
Hp: last.Hp, Hp: last.Hp,
MaxHp: last.MaxHp, MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius, ColliderRadius: last.ColliderRadius,
InAir: last.InAir, InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
Score: last.Score, Score: last.Score,
Removed: last.Removed, Removed: last.Removed,
} }

View File

@@ -128,7 +128,7 @@ type Room struct {
EffectivePlayerCount int32 EffectivePlayerCount int32
DismissalWaitGroup sync.WaitGroup DismissalWaitGroup sync.WaitGroup
InputsBuffer *battle.RingBuffer // Indices are STRICTLY consecutive 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 RenderFrameBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
LatestPlayerUpsyncedInputFrameId int32 LatestPlayerUpsyncedInputFrameId int32
LastAllConfirmedInputFrameId int32 LastAllConfirmedInputFrameId int32
@@ -149,6 +149,7 @@ type Room struct {
TmxPolygonsMap StrToPolygon2DListMap TmxPolygonsMap StrToPolygon2DListMap
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
LastIndividuallyConfirmedInputList []uint64
} }
func (pR *Room) updateScore() { func (pR *Room) updateScore() {
@@ -334,7 +335,20 @@ func (pR *Room) playerDownsyncStr(player *battle.PlayerDownsync) string {
if player.InAir { if player.InAir {
inAirInt = 1 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 return s
} }
@@ -364,7 +378,11 @@ func (pR *Room) rdfIdToActuallyUsedInputString() string {
for _, player := range rdf.PlayersArr { for _, player := range rdf.PlayersArr {
playersStrBldr = append(playersStrBldr, pR.playerDownsyncStr(player)) 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") return strings.Join(s, "\n")
@@ -380,6 +398,9 @@ func (pR *Room) StartBattle() {
for _, player := range pR.Players { for _, player := range pR.Players {
speciesId := int(player.JoinIndex - 1) // FIXME: Hardcoded the values for now speciesId := int(player.JoinIndex - 1) // FIXME: Hardcoded the values for now
if player.JoinIndex == 1 {
speciesId = 4096
}
chosenCh := battle.Characters[speciesId] chosenCh := battle.Characters[speciesId]
pR.CharacterConfigsArr[player.JoinIndex-1] = chosenCh pR.CharacterConfigsArr[player.JoinIndex-1] = chosenCh
pR.SpeciesIdList[player.JoinIndex-1] = int32(speciesId) pR.SpeciesIdList[player.JoinIndex-1] = int32(speciesId)
@@ -741,6 +762,7 @@ func (pR *Room) OnDismissed() {
pR.RenderFrameBuffer = battle.NewRingBuffer(pR.RenderCacheSize) pR.RenderFrameBuffer = battle.NewRingBuffer(pR.RenderCacheSize)
pR.InputsBuffer = battle.NewRingBuffer((pR.RenderCacheSize >> 1) + 1) pR.InputsBuffer = battle.NewRingBuffer((pR.RenderCacheSize >> 1) + 1)
pR.rdfIdToActuallyUsedInput = make(map[int32]*pb.InputFrameDownsync) pR.rdfIdToActuallyUsedInput = make(map[int32]*pb.InputFrameDownsync)
pR.LastIndividuallyConfirmedInputList = make([]uint64, pR.Capacity)
pR.LatestPlayerUpsyncedInputFrameId = -1 pR.LatestPlayerUpsyncedInputFrameId = -1
pR.LastAllConfirmedInputFrameId = -1 pR.LastAllConfirmedInputFrameId = -1
@@ -1017,12 +1039,7 @@ func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputF
func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputFrameDownsync { func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputFrameDownsync {
/* /*
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked. [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 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)" 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 { if nil == tmp1 {
@@ -1034,18 +1051,26 @@ func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputF
ConfirmedList: uint64(0), ConfirmedList: uint64(0),
} }
/*
[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 { for i, _ := range currInputFrameDownsync.InputList {
j2 := pR.PlayersArr[i].LastReceivedInputFrameId // [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.
if j2 < pR.InputsBuffer.StFrameId {
j2 = pR.InputsBuffer.StFrameId
}
tmp2 := pR.InputsBuffer.GetByFrameId(j2)
if nil != tmp2 {
prevInputFrameDownsync := tmp2.(*battle.InputFrameDownsync)
currInputFrameDownsync.InputList[i] = prevInputFrameDownsync.InputList[i]
}
// Don't predict "btnA & btnB"! // 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) pR.InputsBuffer.Put(currInputFrameDownsync)
@@ -1081,6 +1106,7 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
targetInputFrameDownsync.ConfirmedList |= uint64(1 << uint32(player.JoinIndex-1)) targetInputFrameDownsync.ConfirmedList |= uint64(1 << uint32(player.JoinIndex-1))
player.LastReceivedInputFrameId = clientInputFrameId player.LastReceivedInputFrameId = clientInputFrameId
pR.LastIndividuallyConfirmedInputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
if clientInputFrameId > pR.LatestPlayerUpsyncedInputFrameId { if clientInputFrameId > pR.LatestPlayerUpsyncedInputFrameId {
pR.LatestPlayerUpsyncedInputFrameId = clientInputFrameId pR.LatestPlayerUpsyncedInputFrameId = clientInputFrameId

View File

@@ -49,6 +49,11 @@ type PlayerDownsync struct {
ActiveSkillId int32 `protobuf:"varint,21,opt,name=activeSkillId,proto3" json:"activeSkillId,omitempty"` ActiveSkillId int32 `protobuf:"varint,21,opt,name=activeSkillId,proto3" json:"activeSkillId,omitempty"`
ActiveSkillHit int32 `protobuf:"varint,22,opt,name=activeSkillHit,proto3" json:"activeSkillHit,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"` 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"` Name string `protobuf:"bytes,997,opt,name=name,proto3" json:"name,omitempty"`
DisplayName string `protobuf:"bytes,998,opt,name=displayName,proto3" json:"displayName,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"` Avatar string `protobuf:"bytes,999,opt,name=avatar,proto3" json:"avatar,omitempty"`
@@ -247,6 +252,41 @@ func (x *PlayerDownsync) GetFramesInvinsible() int32 {
return 0 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 { func (x *PlayerDownsync) GetName() string {
if x != nil { if x != nil {
return x.Name return x.Name
@@ -789,6 +829,8 @@ type MeleeBullet struct {
HitboxSizeX int32 `protobuf:"varint,16,opt,name=hitboxSizeX,proto3" json:"hitboxSizeX,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"` HitboxSizeY int32 `protobuf:"varint,17,opt,name=hitboxSizeY,proto3" json:"hitboxSizeY,omitempty"`
BlowUp bool `protobuf:"varint,18,opt,name=blowUp,proto3" json:"blowUp,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() { func (x *MeleeBullet) Reset() {
@@ -949,6 +991,283 @@ func (x *MeleeBullet) GetBlowUp() bool {
return false 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 { type BattleColliderInfo struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@@ -967,13 +1286,13 @@ type BattleColliderInfo struct {
SpaceOffsetX float64 `protobuf:"fixed64,11,opt,name=spaceOffsetX,proto3" json:"spaceOffsetX,omitempty"` SpaceOffsetX float64 `protobuf:"fixed64,11,opt,name=spaceOffsetX,proto3" json:"spaceOffsetX,omitempty"`
SpaceOffsetY float64 `protobuf:"fixed64,12,opt,name=spaceOffsetY,proto3" json:"spaceOffsetY,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"` 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() { func (x *BattleColliderInfo) Reset() {
*x = BattleColliderInfo{} *x = BattleColliderInfo{}
if protoimpl.UnsafeEnabled { 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 := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -986,7 +1305,7 @@ func (x *BattleColliderInfo) String() string {
func (*BattleColliderInfo) ProtoMessage() {} func (*BattleColliderInfo) ProtoMessage() {}
func (x *BattleColliderInfo) ProtoReflect() protoreflect.Message { 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 { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -999,7 +1318,7 @@ func (x *BattleColliderInfo) ProtoReflect() protoreflect.Message {
// Deprecated: Use BattleColliderInfo.ProtoReflect.Descriptor instead. // Deprecated: Use BattleColliderInfo.ProtoReflect.Descriptor instead.
func (*BattleColliderInfo) Descriptor() ([]byte, []int) { 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 { func (x *BattleColliderInfo) GetStageName() string {
@@ -1109,15 +1428,17 @@ type RoomDownsyncFrame struct {
PlayersArr []*PlayerDownsync `protobuf:"bytes,2,rep,name=playersArr,proto3" json:"playersArr,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"` 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 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 FireballBullets []*FireballBullet `protobuf:"bytes,5,rep,name=fireballBullets,proto3" json:"fireballBullets,omitempty"`
ShouldForceResync bool `protobuf:"varint,6,opt,name=shouldForceResync,proto3" json:"shouldForceResync,omitempty"` BackendUnconfirmedMask uint64 `protobuf:"varint,1024,opt,name=backendUnconfirmedMask,proto3" json:"backendUnconfirmedMask,omitempty"` // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
SpeciesIdList []int32 `protobuf:"varint,7,rep,packed,name=speciesIdList,proto3" json:"speciesIdList,omitempty"` 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() { func (x *RoomDownsyncFrame) Reset() {
*x = RoomDownsyncFrame{} *x = RoomDownsyncFrame{}
if protoimpl.UnsafeEnabled { 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 := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -1130,7 +1451,7 @@ func (x *RoomDownsyncFrame) String() string {
func (*RoomDownsyncFrame) ProtoMessage() {} func (*RoomDownsyncFrame) ProtoMessage() {}
func (x *RoomDownsyncFrame) ProtoReflect() protoreflect.Message { 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 { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -1143,7 +1464,7 @@ func (x *RoomDownsyncFrame) ProtoReflect() protoreflect.Message {
// Deprecated: Use RoomDownsyncFrame.ProtoReflect.Descriptor instead. // Deprecated: Use RoomDownsyncFrame.ProtoReflect.Descriptor instead.
func (*RoomDownsyncFrame) Descriptor() ([]byte, []int) { 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 { func (x *RoomDownsyncFrame) GetId() int32 {
@@ -1174,6 +1495,13 @@ func (x *RoomDownsyncFrame) GetMeleeBullets() []*MeleeBullet {
return nil return nil
} }
func (x *RoomDownsyncFrame) GetFireballBullets() []*FireballBullet {
if x != nil {
return x.FireballBullets
}
return nil
}
func (x *RoomDownsyncFrame) GetBackendUnconfirmedMask() uint64 { func (x *RoomDownsyncFrame) GetBackendUnconfirmedMask() uint64 {
if x != nil { if x != nil {
return x.BackendUnconfirmedMask return x.BackendUnconfirmedMask
@@ -1195,13 +1523,20 @@ func (x *RoomDownsyncFrame) GetSpeciesIdList() []int32 {
return nil 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 protoreflect.FileDescriptor
var file_room_downsync_frame_proto_rawDesc = []byte{ var file_room_downsync_frame_proto_rawDesc = []byte{
0x0a, 0x19, 0x72, 0x6f, 0x6f, 0x6d, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x65, 0x73, 0x49, 0x6e, 0x76, 0x69, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0xe5, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x18, 0x18, 0x20, 0x01,
0x65, 0x12, 0x21, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x28, 0x05, 0x52, 0x0c, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64,
0x18, 0xe6, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x2c, 0x0a, 0x11, 0x63, 0x68, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54,
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0xe7, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x18, 0x19, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x68, 0x43,
0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x6f, 0x0a, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x16,
0x11, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x0a, 0x06, 0x6f, 0x6e, 0x57, 0x61, 0x6c, 0x6c, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06,
0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x6f, 0x6e, 0x57, 0x61, 0x6c, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x6e, 0x57, 0x61, 0x6c, 0x6c,
0x64, 0x78, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x4e, 0x6f, 0x72, 0x6d, 0x58, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f, 0x6e, 0x57,
0x64, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x58, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x6e, 0x57, 0x61,
0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x59, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6f,
0x12, 0x1c, 0x0a, 0x09, 0x62, 0x74, 0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x6e, 0x57, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x72, 0x6d, 0x59, 0x12, 0x13, 0x0a, 0x04, 0x6e, 0x61,
0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x74, 0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x50, 0x6d, 0x65, 0x18, 0xe5, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x0a, 0x10, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x21, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0xe6,
0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61,
0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0xe7, 0x07, 0x20,
0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x6f, 0x0a, 0x11, 0x49,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64,
0x22, 0x7c, 0x0a, 0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x78,
0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x79,
0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20,
0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x01, 0x28, 0x05, 0x52, 0x09, 0x62, 0x74, 0x6e, 0x41, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1c,
0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x69, 0x0a, 0x09, 0x62, 0x74, 0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28,
0x6e, 0x70, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x05, 0x52, 0x09, 0x62, 0x74, 0x6e, 0x42, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x50, 0x0a, 0x10,
0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63,
0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x3b, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64,
0x0a, 0x0f, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
0x63, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x18,
0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x22, 0x7c,
0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xb8, 0x02, 0x0a, 0x05, 0x0a, 0x12, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e,
0x57, 0x73, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x01, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61,
0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75,
0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x70, 0x75,
0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6e, 0x70,
0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x75, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72,
0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63,
0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0f,
0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x12,
0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x28, 0x0a, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x65, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xb8, 0x02, 0x0a, 0x05, 0x57, 0x73,
0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x4e, 0x0a, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61,
0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x79, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6c, 0x61,
0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01,
0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x49,
0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x27, 0x0a, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6a, 0x6f, 0x69, 0x6e,
0x02, 0x68, 0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x46,
0x6f, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x63,
0x6e, 0x63, 0x52, 0x02, 0x68, 0x62, 0x22, 0x89, 0x02, 0x0a, 0x06, 0x57, 0x73, 0x52, 0x65, 0x73, 0x6b, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x61,
0x70, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49,
0x72, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x49,
0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x4e, 0x0a, 0x15, 0x69,
0x4d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x42,
0x28, 0x05, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x61, 0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70,
0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x15, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x03, 0x72, 0x64, 0x66, 0x12, 0x54, 0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x27, 0x0a, 0x02, 0x68,
0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73,
0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63,
0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x52, 0x02, 0x68, 0x62, 0x22, 0x89, 0x02, 0x0a, 0x06, 0x57, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12,
0x63, 0x52, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x65,
0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x63, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x49, 0x64,
0x69, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x64, 0x4d, 0x73,
0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x67, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x52, 0x03, 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x03, 0x72, 0x64, 0x66, 0x18, 0x04, 0x20, 0x01,
0x6d, 0x65, 0x22, 0xf4, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x42, 0x75, 0x66, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, 0x6d,
0x66, 0x65, 0x72, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x03, 0x72,
0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x64, 0x66, 0x12, 0x54, 0x0a, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70,
0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52,
0x52, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x17, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73,
0x6b, 0x12, 0x58, 0x0a, 0x19, 0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x79, 0x6e, 0x63, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x63, 0x69, 0x46,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x6f, 0x73, 0x2e, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64,
0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x62, 0x63, 0x69, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x52, 0x19, 0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x22, 0xf4, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65,
0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x72, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, 0x66,
0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20,
0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x01, 0x28, 0x05, 0x52, 0x10, 0x72, 0x65, 0x66, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72,
0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x22, 0xbf, 0x05, 0x0a, 0x0b, 0x4d, 0x65, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f,
0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12,
0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x58, 0x0a, 0x19, 0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72,
0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03,
0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x70, 0x75,
0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x19,
0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x74, 0x6f, 0x53, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x78, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x68, 0x6f,
0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x04,
0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63,
0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x22, 0xfd, 0x05, 0x0a, 0x0b, 0x4d, 0x65, 0x6c, 0x65,
0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69,
0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x17, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e,
0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49,
0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69,
0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6f, 0x66,
0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73,
0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46,
0x73, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c,
0x61, 0x6d, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74,
0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x09, 0x20, 0x01, 0x28, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c,
0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64,
0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46,
0x65, 0x6c, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x61, 0x63, 0x74,
0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74,
0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05,
0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12,
0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d,
0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53,
0x65, 0x6c, 0x59, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73,
0x73, 0x65, 0x74, 0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52,
0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x12, 0x22, 0x0a,
0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59, 0x18, 0x0a, 0x20,
0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x12, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c,
0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x18, 0x10, 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, 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, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x18, 0x12, 0x20, 0x01, 0x28,
0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x61,
0x7a, 0x65, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x18, 0x12, 0x20, 0x6d, 0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49,
0x01, 0x28, 0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x22, 0xc9, 0x05, 0x0a, 0x12, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74,
0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x22, 0xd3, 0x07, 0x0a, 0x0e, 0x46, 0x69, 0x72, 0x65,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x62, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x17, 0x6f, 0x72,
0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x54, 0x6f, 0x50, 0x69, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72,
0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x17, 0x6f, 0x72, 0x69,
0x61, 0x6c, 0x54, 0x6f, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x15, 0x77, 0x69, 0x6c, 0x6c, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61,
0x4b, 0x69, 0x63, 0x6b, 0x49, 0x66, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x6f, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72,
0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x77, 0x69, 0x6c, 0x6c, 0x4b, 0x69, 0x63, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
0x6b, 0x49, 0x66, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x6f, 0x72, 0x12, 0x20, 0x11, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64,
0x0a, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x04, 0x20, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x46, 0x72, 0x61,
0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74,
0x12, 0x30, 0x0a, 0x13, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x75, 0x70, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63,
0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x62, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x04,
0x61, 0x74, 0x74, 0x6c, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c,
0x6f, 0x73, 0x12, 0x46, 0x0a, 0x1e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x65, 0x53, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x63,
0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x05,
0x61, 0x6e, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x1e, 0x69, 0x6e, 0x70, 0x75, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x61, 0x62, 0x6c,
0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x55, 0x70, 0x73, 0x79, 0x6e, 0x63, 0x44, 0x65, 0x6c, 0x61, 0x65, 0x45, 0x64, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69,
0x79, 0x54, 0x6f, 0x6c, 0x65, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x1f, 0x6d, 0x61, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c,
0x78, 0x43, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d,
0x61, 0x6d, 0x65, 0x73, 0x50, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x07, 0x20,
0x01, 0x28, 0x05, 0x52, 0x1f, 0x6d, 0x61, 0x78, 0x43, 0x68, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50, 0x65, 0x72, 0x55, 0x70, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46,
0x64, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x19, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x62, 0x6c, 0x6f,
0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x53, 0x74, 0x75, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c,
0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x19, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x09, 0x20, 0x01,
0x6b, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58,
0x69, 0x73, 0x12, 0x3a, 0x0a, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59,
0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x09, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x75, 0x73, 0x68, 0x62, 0x61, 0x63, 0x6b,
0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x45, 0x73, 0x56, 0x65, 0x6c, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0b,
0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x44, 0x74, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x28, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c,
0x0a, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58, 0x18, 0x0c, 0x20, 0x01,
0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x58,
0x61, 0x63, 0x68, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x6c, 0x59,
0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x66, 0x4c, 0x6f, 0x63, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x22, 0x0a, 0x0c, 0x56, 0x65, 0x6c, 0x59, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66,
0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0c, 0x20, 0x01, 0x66, 0x73, 0x65, 0x74, 0x58, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74,
0x28, 0x01, 0x52, 0x0c, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x58, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x69,
0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59, 0x18, 0x0f, 0x20, 0x01, 0x28,
0x53, 0x74, 0x65, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x05, 0x52, 0x0d, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x59,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x12, 0x39, 0x0a, 0x17, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x58, 0x18,
0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0xe7, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x65, 0x58, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53, 0x69, 0x7a, 0x65,
0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x59, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x69, 0x74, 0x62, 0x6f, 0x78, 0x53,
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xc8, 0x02, 0x0a, 0x11, 0x52, 0x6f, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x59, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x18, 0x12,
0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x12, 0x16, 0x0a, 0x06,
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x74, 0x65,
0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x4c, 0x6f,
0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x62, 0x75, 0x6c,
0x72, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x6c, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x70,
0x72, 0x73, 0x41, 0x72, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73,
0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74,
0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x37, 0x0a, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x18, 0xe7, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52,
0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x58, 0x12, 0x23, 0x0a,
0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69, 0x64, 0x59, 0x18, 0xe8, 0x07,
0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x47, 0x72, 0x69,
0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x59, 0x12, 0x13, 0x0a, 0x04, 0x64, 0x69, 0x72, 0x58, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28,
0x64, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x05, 0x52, 0x04, 0x64, 0x69, 0x72, 0x58, 0x12, 0x13, 0x0a, 0x04, 0x64, 0x69, 0x72, 0x59, 0x18,
0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55, 0xea, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x69, 0x72, 0x59, 0x12, 0x13, 0x0a, 0x04,
0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x2c, 0x76, 0x65, 0x6c, 0x58, 0x18, 0xeb, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x76, 0x65, 0x6c,
0x0a, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x58, 0x12, 0x13, 0x0a, 0x04, 0x76, 0x65, 0x6c, 0x59, 0x18, 0xec, 0x07, 0x20, 0x01, 0x28, 0x05,
0x79, 0x6e, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x52, 0x04, 0x76, 0x65, 0x6c, 0x59, 0x12, 0x15, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18,
0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x12, 0x24, 0x0a, 0x0d, 0xed, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x22, 0xc9, 0x05,
0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x07, 0x20, 0x0a, 0x12, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72,
0x03, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c, 0x69, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d,
0x73, 0x74, 0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x5f, 0x73, 0x72, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 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 ( var (
@@ -1452,7 +1871,7 @@ func file_room_downsync_frame_proto_rawDescGZIP() []byte {
return file_room_downsync_frame_proto_rawDescData 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{}{ var file_room_downsync_frame_proto_goTypes = []interface{}{
(*PlayerDownsync)(nil), // 0: protos.PlayerDownsync (*PlayerDownsync)(nil), // 0: protos.PlayerDownsync
(*InputFrameDecoded)(nil), // 1: protos.InputFrameDecoded (*InputFrameDecoded)(nil), // 1: protos.InputFrameDecoded
@@ -1463,23 +1882,25 @@ var file_room_downsync_frame_proto_goTypes = []interface{}{
(*WsResp)(nil), // 6: protos.WsResp (*WsResp)(nil), // 6: protos.WsResp
(*InputsBufferSnapshot)(nil), // 7: protos.InputsBufferSnapshot (*InputsBufferSnapshot)(nil), // 7: protos.InputsBufferSnapshot
(*MeleeBullet)(nil), // 8: protos.MeleeBullet (*MeleeBullet)(nil), // 8: protos.MeleeBullet
(*BattleColliderInfo)(nil), // 9: protos.BattleColliderInfo (*FireballBullet)(nil), // 9: protos.FireballBullet
(*RoomDownsyncFrame)(nil), // 10: protos.RoomDownsyncFrame (*BattleColliderInfo)(nil), // 10: protos.BattleColliderInfo
(*RoomDownsyncFrame)(nil), // 11: protos.RoomDownsyncFrame
} }
var file_room_downsync_frame_proto_depIdxs = []int32{ var file_room_downsync_frame_proto_depIdxs = []int32{
2, // 0: protos.WsReq.inputFrameUpsyncBatch:type_name -> protos.InputFrameUpsync 2, // 0: protos.WsReq.inputFrameUpsyncBatch:type_name -> protos.InputFrameUpsync
4, // 1: protos.WsReq.hb:type_name -> protos.HeartbeatUpsync 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 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 3, // 5: protos.InputsBufferSnapshot.toSendInputFrameDownsyncs:type_name -> protos.InputFrameDownsync
0, // 6: protos.RoomDownsyncFrame.playersArr:type_name -> protos.PlayerDownsync 0, // 6: protos.RoomDownsyncFrame.playersArr:type_name -> protos.PlayerDownsync
8, // 7: protos.RoomDownsyncFrame.meleeBullets:type_name -> protos.MeleeBullet 8, // 7: protos.RoomDownsyncFrame.meleeBullets:type_name -> protos.MeleeBullet
8, // [8:8] is the sub-list for method output_type 9, // 8: protos.RoomDownsyncFrame.fireballBullets:type_name -> protos.FireballBullet
8, // [8:8] is the sub-list for method input_type 9, // [9:9] is the sub-list for method output_type
8, // [8:8] is the sub-list for extension type_name 9, // [9:9] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension extendee 9, // [9:9] is the sub-list for extension type_name
0, // [0:8] is the sub-list for field 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() } 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{} { 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: case 0:
return &v.state return &v.state
case 1: 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{} { 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 { switch v := v.(*RoomDownsyncFrame); i {
case 0: case 0:
return &v.state return &v.state
@@ -1627,7 +2060,7 @@ func file_room_downsync_frame_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_room_downsync_frame_proto_rawDesc, RawDescriptor: file_room_downsync_frame_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 11, NumMessages: 12,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

View File

@@ -4,8 +4,10 @@ go 1.18
require ( require (
resolv v0.0.0 resolv v0.0.0
jsexport v0.0.0
) )
replace ( replace (
resolv => ../resolv_tailored 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> <key>spriteSourceSize</key>
<string>{112,128}</string> <string>{112,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{824,544},{112,128}}</string> <string>{{806,750},{112,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>Atk1_1.png</key> <key>Atk1_1.png</key>
<dict> <dict>
@@ -30,9 +30,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{112,128}</string> <string>{112,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{0,1200},{112,128}}</string> <string>{{0,1076},{112,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>Atk1_10.png</key> <key>Atk1_10.png</key>
<dict> <dict>
@@ -60,7 +60,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,128}</string> <string>{80,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{940,0},{80,128}}</string> <string>{{528,515},{80,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -75,7 +75,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,128}</string> <string>{80,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{940,128},{80,128}}</string> <string>{{934,640},{80,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -90,9 +90,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{112,128}</string> <string>{112,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{0,964},{112,128}}</string> <string>{{128,1076},{112,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>Atk1_4.png</key> <key>Atk1_4.png</key>
<dict> <dict>
@@ -105,9 +105,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{112,128}</string> <string>{112,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{112,964},{112,128}}</string> <string>{{678,862},{112,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>Atk1_5.png</key> <key>Atk1_5.png</key>
<dict> <dict>
@@ -120,7 +120,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,128}</string> <string>{96,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{840,288},{96,128}}</string> <string>{{512,643},{96,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -135,7 +135,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,128}</string> <string>{96,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{840,416},{96,128}}</string> <string>{{512,771},{96,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -150,7 +150,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,128}</string> <string>{80,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{940,256},{80,128}}</string> <string>{{934,768},{80,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -165,7 +165,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,128}</string> <string>{80,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{936,384},{80,128}}</string> <string>{{934,896},{80,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -180,9 +180,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,128}</string> <string>{80,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{936,512},{80,128}}</string> <string>{{806,958},{80,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>Atk2_0.png</key> <key>Atk2_0.png</key>
<dict> <dict>
@@ -195,7 +195,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,128}</string> <string>{80,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{936,640},{80,128}}</string> <string>{{934,1024},{80,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -210,7 +210,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,128}</string> <string>{96,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{582,531},{96,128}}</string> <string>{{512,899},{96,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -225,7 +225,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,112}</string> <string>{128,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{326,871},{128,112}}</string> <string>{{128,964},{128,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -240,7 +240,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,96}</string> <string>{96,96}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{696,1200},{96,96}}</string> <string>{{912,1152},{96,96}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -255,7 +255,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,112}</string> <string>{96,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{416,983},{96,112}}</string> <string>{{340,1197},{96,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -270,7 +270,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,112}</string> <string>{96,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{656,1092},{96,112}}</string> <string>{{452,1196},{96,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -285,9 +285,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,112}</string> <string>{96,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{528,1113},{96,112}}</string> <string>{{564,1155},{96,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <false/>
</dict> </dict>
<key>Atk2_5.png</key> <key>Atk2_5.png</key>
<dict> <dict>
@@ -300,9 +300,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,112}</string> <string>{96,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{392,1207},{96,112}}</string> <string>{{608,1043},{96,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <false/>
</dict> </dict>
<key>Atk2_6.png</key> <key>Atk2_6.png</key>
<dict> <dict>
@@ -330,7 +330,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,112}</string> <string>{128,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{454,871},{128,112}}</string> <string>{{678,750},{128,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -525,7 +525,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,128}</string> <string>{96,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{582,659},{96,128}}</string> <string>{{512,1027},{96,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -540,7 +540,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{112,112}</string> <string>{112,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{240,1081},{112,112}}</string> <string>{{448,1293},{112,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -555,7 +555,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,112}</string> <string>{96,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{504,1209},{96,112}}</string> <string>{{660,1155},{96,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -570,7 +570,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,112}</string> <string>{128,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{678,980},{128,112}}</string> <string>{{384,988},{128,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -634,6 +634,111 @@
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </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> <key>GetUp1_1.png</key>
<dict> <dict>
<key>aliases</key> <key>aliases</key>
@@ -645,7 +750,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,118}</string> <string>{128,118}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{806,791},{128,118}}</string> <string>{{384,634},{128,118}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -660,7 +765,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,118}</string> <string>{128,118}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{0,846},{128,118}}</string> <string>{{384,752},{128,118}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -675,7 +780,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,118}</string> <string>{128,118}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{128,846},{128,118}}</string> <string>{{256,753},{128,118}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -690,7 +795,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,118}</string> <string>{128,118}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{326,753},{128,118}}</string> <string>{{128,846},{128,118}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -705,7 +810,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,118}</string> <string>{128,118}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{454,753},{128,118}}</string> <string>{{0,958},{128,118}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -720,7 +825,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,118}</string> <string>{128,118}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{678,862},{128,118}}</string> <string>{{384,870},{128,118}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -735,7 +840,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,118}</string> <string>{128,118}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{806,909},{128,118}}</string> <string>{{256,871},{128,118}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -750,7 +855,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{256,489},{70,128}}</string> <string>{{940,0},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -765,7 +870,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{256,617},{70,128}}</string> <string>{{940,128},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -780,7 +885,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{256,745},{70,128}}</string> <string>{{940,256},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -795,7 +900,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{256,873},{70,128}}</string> <string>{{937,384},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -810,7 +915,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{112,1200},{70,128}}</string> <string>{{936,512},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -825,7 +930,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{182,1200},{70,128}}</string> <string>{{608,531},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -840,7 +945,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{252,1200},{70,128}}</string> <string>{{608,659},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -855,7 +960,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{252,1200},{70,128}}</string> <string>{{608,659},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -870,7 +975,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{182,1200},{70,128}}</string> <string>{{608,531},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -885,7 +990,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{112,1200},{70,128}}</string> <string>{{936,512},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -900,7 +1005,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{256,873},{70,128}}</string> <string>{{937,384},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -915,7 +1020,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{256,745},{70,128}}</string> <string>{{940,256},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -930,7 +1035,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{256,617},{70,128}}</string> <string>{{940,128},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -945,7 +1050,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{322,1200},{70,128}}</string> <string>{{608,787},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -960,9 +1065,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{70,128}</string> <string>{70,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{528,1043},{70,128}}</string> <string>{{608,915},{70,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <false/>
</dict> </dict>
<key>InAirAtk1_0.png</key> <key>InAirAtk1_0.png</key>
<dict> <dict>
@@ -975,7 +1080,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{112,96}</string> <string>{112,96}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{128,1092},{112,96}}</string> <string>{{228,1197},{112,96}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -1005,7 +1110,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{144,112}</string> <string>{144,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{680,512},{144,112}}</string> <string>{{0,489},{144,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -1020,7 +1125,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,112}</string> <string>{128,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{806,1027},{128,112}}</string> <string>{{256,989},{128,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -1035,7 +1140,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,96}</string> <string>{96,96}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{792,1139},{96,96}}</string> <string>{{672,1363},{96,96}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -1050,7 +1155,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,96}</string> <string>{80,96}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{934,1104},{80,96}}</string> <string>{{672,1267},{80,96}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -1065,7 +1170,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{112,112}</string> <string>{112,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{352,1081},{112,112}}</string> <string>{{560,1292},{112,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -1080,7 +1185,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{128,96}</string> <string>{128,96}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{0,1092},{128,96}}</string> <string>{{384,1100},{128,96}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -1095,9 +1200,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,112}</string> <string>{80,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{934,768},{80,112}}</string> <string>{{800,1038},{80,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>InAirIdle1_1.png</key> <key>InAirIdle1_1.png</key>
<dict> <dict>
@@ -1110,9 +1215,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,112}</string> <string>{80,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{934,880},{80,112}}</string> <string>{{800,1118},{80,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>InAirIdle1_2.png</key> <key>InAirIdle1_2.png</key>
<dict> <dict>
@@ -1125,9 +1230,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{64,128}</string> <string>{64,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{464,1079},{64,128}}</string> <string>{{678,974},{64,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>InAirIdle1_3.png</key> <key>InAirIdle1_3.png</key>
<dict> <dict>
@@ -1140,9 +1245,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,112}</string> <string>{80,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{934,992},{80,112}}</string> <string>{{756,1198},{80,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>InAirIdle1_4.png</key> <key>InAirIdle1_4.png</key>
<dict> <dict>
@@ -1155,7 +1260,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,96}</string> <string>{80,96}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{224,1001},{80,96}}</string> <string>{{752,1278},{80,96}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1170,9 +1275,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,96}</string> <string>{80,96}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{320,1001},{80,96}}</string> <string>{{768,1358},{80,96}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <false/>
</dict> </dict>
<key>InAirIdle1_6.png</key> <key>InAirIdle1_6.png</key>
<dict> <dict>
@@ -1185,9 +1290,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{80,96}</string> <string>{80,96}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{792,1235},{80,96}}</string> <string>{{868,1248},{80,96}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>InAirIdle1_7.png</key> <key>InAirIdle1_7.png</key>
<dict> <dict>
@@ -1200,7 +1305,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,112}</string> <string>{96,112}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{600,1209},{96,112}}</string> <string>{{704,1038},{96,112}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </dict>
@@ -1215,9 +1320,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,128}</string> <string>{96,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{582,787},{96,128}}</string> <string>{{256,1101},{96,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>InAirIdle1_9.png</key> <key>InAirIdle1_9.png</key>
<dict> <dict>
@@ -1230,9 +1335,9 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{96,128}</string> <string>{96,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{582,915},{96,128}}</string> <string>{{806,862},{96,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<false/> <true/>
</dict> </dict>
<key>LayDown1_1.png</key> <key>LayDown1_1.png</key>
<dict> <dict>
@@ -1264,6 +1369,51 @@
<key>textureRotated</key> <key>textureRotated</key>
<false/> <false/>
</dict> </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> <key>Walking_1.png</key>
<dict> <dict>
<key>aliases</key> <key>aliases</key>
@@ -1275,7 +1425,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{0,489},{119,128}}</string> <string>{{144,489},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1290,7 +1440,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{128,489},{119,128}}</string> <string>{{0,601},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1305,7 +1455,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{0,608},{119,128}}</string> <string>{{680,512},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1320,7 +1470,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{128,608},{119,128}}</string> <string>{{808,512},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1335,7 +1485,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{326,515},{119,128}}</string> <string>{{272,515},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1350,7 +1500,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{454,515},{119,128}}</string> <string>{{128,608},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1365,7 +1515,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{678,624},{119,128}}</string> <string>{{0,720},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1380,7 +1530,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{806,672},{119,128}}</string> <string>{{400,515},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1395,7 +1545,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{0,727},{119,128}}</string> <string>{{678,631},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1410,7 +1560,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{128,727},{119,128}}</string> <string>{{806,631},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1425,7 +1575,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{326,634},{119,128}}</string> <string>{{256,634},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1440,7 +1590,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{454,634},{119,128}}</string> <string>{{128,727},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1455,7 +1605,7 @@
<key>spriteSourceSize</key> <key>spriteSourceSize</key>
<string>{119,128}</string> <string>{119,128}</string>
<key>textureRect</key> <key>textureRect</key>
<string>{{678,743},{119,128}}</string> <string>{{0,839},{119,128}}</string>
<key>textureRotated</key> <key>textureRotated</key>
<true/> <true/>
</dict> </dict>
@@ -1471,9 +1621,9 @@
<key>realTextureFileName</key> <key>realTextureFileName</key>
<string>KnifeGirl.png</string> <string>KnifeGirl.png</string>
<key>size</key> <key>size</key>
<string>{1020,1331}</string> <string>{1014,1459}</string>
<key>smartupdate</key> <key>smartupdate</key>
<string>$TexturePacker:SmartUpdate:9514b6b35473e14baf98f68515bcb817:1aae9dd4a8024ce783fdab093a39672a:1ae107e0c6667a1ecb5ed98687517e0e$</string> <string>$TexturePacker:SmartUpdate:4ca72309f7dc04bba6be361462471d91:9a48d10caa37a76ff8c43fb72bce6103:1ae107e0c6667a1ecb5ed98687517e0e$</string>
<key>textureFileName</key> <key>textureFileName</key>
<string>KnifeGirl.png</string> <string>KnifeGirl.png</string>
</dict> </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"?> <?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="1" source="tiles0.tsx"/>
<tileset firstgid="65" source="tiles1.tsx"/> <tileset firstgid="65" source="tiles1.tsx"/>
<tileset firstgid="129" source="tiles2.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"> <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> </data>
</layer> </layer>
<objectgroup id="1" name="PlayerStartingPos"> <objectgroup id="1" name="PlayerStartingPos">
<object id="135" x="1040.33" y="1081"> <object id="135" x="1140" y="488">
<point/> <point/>
</object> </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/> <point/>
</object> </object>
</objectgroup> </objectgroup>
@@ -20,197 +59,147 @@
<properties> <properties>
<property name="type" value="barrier_and_shelter"/> <property name="type" value="barrier_and_shelter"/>
</properties> </properties>
<object id="54" x="656" y="1504" width="80" height="16"> <object id="57" x="768" y="560" width="32" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="55" x="736" y="1552" width="112" height="16"> <object id="60" x="1232" y="432" width="208" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="57" x="768" y="1472" width="32" height="16"> <object id="65" x="1040" y="576" width="32" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="58" x="1040" y="1536" width="80" height="16"> <object id="66" x="1040" y="560" width="16" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="59" x="1040" y="1568" width="224" height="48"> <object id="67" x="784" y="544" width="256" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="60" x="1216" y="1344" width="224" height="16"> <object id="84" x="640" y="224" width="16" height="800">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="62" x="1040" y="1552" width="208" height="16"> <object id="85" x="1680" y="224" width="16" height="800">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="63" x="1040" y="1504" width="48" height="16"> <object id="86" x="1104" y="496" width="96" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="64" x="1040" y="1520" width="64" height="16"> <object id="90" x="1232" y="496" width="320" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="65" x="1040" y="1488" width="32" height="16"> <object id="97" x="1248" y="416" width="158" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="66" x="1040" y="1472" width="16" height="16"> <object id="98" x="1280" y="400" width="96" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="67" x="784" y="1456" width="256" height="16"> <object id="100" x="1552" y="576" width="128" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="73" x="784" y="1568" width="96" height="16"> <object id="101" x="1568" y="560" width="112" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="74" x="816" y="1584" width="96" height="16"> <object id="102" x="1584" y="544" width="96" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="79" x="640" y="1616" width="1056" height="16"> <object id="103" x="1600" y="528" width="80" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="83" x="640" y="480" width="1056" height="16"> <object id="104" x="768" y="382" width="304" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="84" x="640" y="480" width="16" height="1152"> <object id="105" x="768" y="302" width="16" height="96">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="85" x="1680" y="480" width="16" height="1152"> <object id="106" x="1056" y="302" width="16" height="96">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="86" x="1104" y="1408" width="96" height="16"> <object id="113" x="640" y="1008" width="1056" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="87" x="1456" y="1568" width="224" height="48"> <object id="114" x="640" y="224" width="1056" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="88" x="1264" y="1584" width="16" height="32"> <object id="119" x="656" y="592" width="1024" height="416">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="89" x="1280" y="1600" width="16" height="16"> <object id="120" x="736" y="512" width="16" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="90" x="1232" y="1408" width="304" height="16"> <object id="121" x="736" y="336" width="16" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="91" x="1440" y="1584" width="16" height="32"> <object id="125" x="688" y="448" width="16" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="92" x="1424" y="1600" width="16" height="16"> <object id="127" x="1088" y="320" width="16" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="93" x="1488" y="1552" width="192" height="16"> <object id="128" x="1120" y="336" width="16" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="94" x="1504" y="1536" width="176" height="16"> <object id="129" x="1136" y="368" width="16" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="95" x="1520" y="1520" width="160" height="16"> <object id="130" x="1168" y="384" width="16" height="16">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>
</object> </object>
<object id="96" x="1568" y="1408" width="16" height="16"> <object id="132" x="1184" y="416" 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">
<properties> <properties>
<property name="boundary_type" value="barrier"/> <property name="boundary_type" value="barrier"/>
</properties> </properties>

View File

@@ -29,6 +29,13 @@ message PlayerDownsync {
int32 activeSkillHit = 22; int32 activeSkillHit = 22;
int32 framesInvinsible = 23; 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 name = 997;
string displayName = 998; string displayName = 998;
string avatar = 999; string avatar = 999;
@@ -111,6 +118,47 @@ message MeleeBullet {
int32 hitboxSizeY = 17; int32 hitboxSizeY = 17;
bool blowUp = 18; 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 { message BattleColliderInfo {
@@ -130,7 +178,7 @@ message BattleColliderInfo {
double spaceOffsetY = 12; double spaceOffsetY = 12;
int32 collisionMinStep = 13; int32 collisionMinStep = 13;
bool frameDataLoggingEnabled = 999; bool frameDataLoggingEnabled = 1024;
} }
message RoomDownsyncFrame { message RoomDownsyncFrame {
@@ -138,7 +186,11 @@ message RoomDownsyncFrame {
repeated PlayerDownsync playersArr = 2; repeated PlayerDownsync playersArr = 2;
int64 countdownNanos = 3; 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 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 repeated FireballBullet fireballBullets = 5;
bool shouldForceResync = 6;
repeated int32 speciesIdList = 7; 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__": 8
},
{
"__id__": 11
} }
], ],
"_active": true, "_active": true,
"_components": [ "_components": [
{
"__id__": 21
},
{ {
"__id__": 22 "__id__": 22
} }
@@ -194,180 +188,6 @@
"fileId": "5apzDmIE9IuaMOyF3z06sc", "fileId": "5apzDmIE9IuaMOyF3z06sc",
"sync": false "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", "__type__": "cc.Node",
"_name": "arrowTip", "_name": "arrowTip",
@@ -379,11 +199,11 @@
"_active": true, "_active": true,
"_components": [ "_components": [
{ {
"__id__": 9 "__id__": 6
} }
], ],
"_prefab": { "_prefab": {
"__id__": 10 "__id__": 7
}, },
"_opacity": 255, "_opacity": 255,
"_color": { "_color": {
@@ -437,7 +257,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 8 "__id__": 5
}, },
"_enabled": true, "_enabled": true,
"_materials": [ "_materials": [
@@ -486,16 +306,19 @@
}, },
"_children": [ "_children": [
{ {
"__id__": 12 "__id__": 9
}, },
{ {
"__id__": 16 "__id__": 13
},
{
"__id__": 17
} }
], ],
"_active": true, "_active": true,
"_components": [], "_components": [],
"_prefab": { "_prefab": {
"__id__": 20 "__id__": 21
}, },
"_opacity": 255, "_opacity": 255,
"_color": { "_color": {
@@ -549,20 +372,20 @@
"_name": "MonkGirl", "_name": "MonkGirl",
"_objFlags": 0, "_objFlags": 0,
"_parent": { "_parent": {
"__id__": 11 "__id__": 8
}, },
"_children": [], "_children": [],
"_active": false, "_active": false,
"_components": [ "_components": [
{ {
"__id__": 13 "__id__": 10
}, },
{ {
"__id__": 14 "__id__": 11
} }
], ],
"_prefab": { "_prefab": {
"__id__": 15 "__id__": 12
}, },
"_opacity": 255, "_opacity": 255,
"_color": { "_color": {
@@ -616,7 +439,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 12 "__id__": 9
}, },
"_enabled": true, "_enabled": true,
"_defaultClip": null, "_defaultClip": null,
@@ -669,7 +492,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 12 "__id__": 9
}, },
"_enabled": true, "_enabled": true,
"_materials": [ "_materials": [
@@ -712,20 +535,20 @@
"_name": "KnifeGirl", "_name": "KnifeGirl",
"_objFlags": 0, "_objFlags": 0,
"_parent": { "_parent": {
"__id__": 11 "__id__": 8
}, },
"_children": [], "_children": [],
"_active": false, "_active": false,
"_components": [ "_components": [
{ {
"__id__": 17 "__id__": 14
}, },
{ {
"__id__": 18 "__id__": 15
} }
], ],
"_prefab": { "_prefab": {
"__id__": 19 "__id__": 16
}, },
"_opacity": 255, "_opacity": 255,
"_color": { "_color": {
@@ -779,7 +602,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 16 "__id__": 13
}, },
"_enabled": true, "_enabled": true,
"_defaultClip": null, "_defaultClip": null,
@@ -822,6 +645,14 @@
}, },
{ {
"__uuid__": "9b500cb0-8048-4715-81db-cc975c914225" "__uuid__": "9b500cb0-8048-4715-81db-cc975c914225"
},
null,
null,
{
"__uuid__": "38b2c892-347b-4009-93f8-65b2ab1614f0"
},
{
"__uuid__": "411f964a-4dd8-424c-b2e2-d92b10474ce2"
} }
], ],
"playOnLoad": false, "playOnLoad": false,
@@ -832,7 +663,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 16 "__id__": 13
}, },
"_enabled": true, "_enabled": true,
"_materials": [ "_materials": [
@@ -870,6 +701,171 @@
"fileId": "bdCx1wrTtJ1KaGHUmgL7iA", "fileId": "bdCx1wrTtJ1KaGHUmgL7iA",
"sync": false "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", "__type__": "cc.PrefabInfo",
"root": { "root": {
@@ -881,32 +877,6 @@
"fileId": "7aN7Gcc/tBw5EGlTJVBj2+", "fileId": "7aN7Gcc/tBw5EGlTJVBj2+",
"sync": false "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", "__type__": "b74b05YDqZFRo4OkZRFZX8k",
"_name": "", "_name": "",
@@ -917,10 +887,10 @@
"_enabled": true, "_enabled": true,
"lastMovedAt": 0, "lastMovedAt": 0,
"animNode": { "animNode": {
"__id__": 11 "__id__": 8
}, },
"arrowTipNode": { "arrowTipNode": {
"__id__": 8 "__id__": 5
}, },
"coordLabel": { "coordLabel": {
"__id__": 3 "__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,
0, 0,
1, 1,
1.5, 1.2,
1.5, 1.2,
1 1
] ]
}, },
@@ -234,6 +234,9 @@
"controlledCharacterPrefab": { "controlledCharacterPrefab": {
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a" "__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
}, },
"fireballPrefab": {
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
},
"joystickInputControllerNode": { "joystickInputControllerNode": {
"__id__": 6 "__id__": 6
}, },
@@ -268,6 +271,7 @@
"renderFrameIdLagTolerance": 4, "renderFrameIdLagTolerance": 4,
"jigglingEps1D": 0.001, "jigglingEps1D": 0.001,
"bulletTriggerEnabled": true, "bulletTriggerEnabled": true,
"closeOnForcedtoResyncNotSelf": true,
"_id": "d12gkAmppNlIzqcRDELa91" "_id": "d12gkAmppNlIzqcRDELa91"
}, },
{ {
@@ -453,7 +457,7 @@
"array": [ "array": [
0, 0,
0, 0,
215.81269742929726, 209.57814771583418,
0, 0,
0, 0,
0, 0,

View File

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

View File

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

View File

@@ -14,6 +14,10 @@ window.ATK_CHARACTER_STATE = {
GetUp1: [10, "GetUp1"], GetUp1: [10, "GetUp1"],
Atk2: [11, "Atk2"], Atk2: [11, "Atk2"],
Atk3: [12, "Atk3"], Atk3: [12, "Atk3"],
Atk4: [13, "Atk4"],
Atk5: [14, "Atk5"],
Dashing: [15, "Dashing"],
OnWall: [16, "OnWall"],
}; };
window.ATK_CHARACTER_STATE_ARR = []; 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.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.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.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 = new Set();
window.ATK_CHARACTER_STATE_IN_AIR_SET.add(window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0]); 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.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.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.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. 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) { 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. // 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 // Update directions
if (this.animComp && this.animComp.node) { if (this.animComp && this.animComp.node) {
if (0 > rdfPlayer.DirX) { if (0 > rdfPlayer.DirX) {
this.animNode.scaleX = (-1.0); this.animNode.scaleX = (-1.0);
} else if (0 < rdfPlayer.DirX) { } 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 newAnimName = window.ATK_CHARACTER_STATE_ARR[newCharacterState][1];
let playingAnimName = null; let playingAnimName = null;
let underlyingAnimationCtrl = null; let underlyingAnimationCtrl = null;

View File

@@ -12,7 +12,7 @@ cc.Class({
}, },
}, },
onLoad () { onLoad() {
this.mainCamera = this.mapNode.parent.getChildByName("Main Camera").getComponent(cc.Camera); this.mainCamera = this.mapNode.parent.getChildByName("Main Camera").getComponent(cc.Camera);
this.mapScriptIns = this.mapNode.getComponent("Map"); this.mapScriptIns = this.mapNode.getComponent("Map");
}, },
@@ -29,9 +29,6 @@ cc.Class({
if (!selfPlayerRichInfo) return; if (!selfPlayerRichInfo) return;
const selfPlayerNode = selfPlayerRichInfo.node; const selfPlayerNode = selfPlayerRichInfo.node;
if (!selfPlayerNode) return; if (!selfPlayerNode) return;
const pDiff = selfPlayerNode.position.sub(self.mainCamera.node.position); self.mapNode.setPosition(cc.v2().sub(selfPlayerNode.position));
pDiff.normalizeSelf();
const newCamPos = self.mainCamera.node.position.add(pDiff.mul(dt*self.speed));
self.mainCamera.node.setPosition(newCamPos);
} }
}); });

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", "ver": "1.0.5",
"uuid": "247b7613-6c6e-4f01-b1d6-5f8f041b5688", "uuid": "e66a2a91-9916-469e-a4b2-54cc0bcba3f0",
"isPlugin": false, "isPlugin": false,
"loadPluginInWeb": true, "loadPluginInWeb": true,
"loadPluginInNative": 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 i18n.init(window.language); // languageID should be equal to the one we input in New Language ID input field
const RingBuffer = require('./RingBuffer'); const RingBuffer = require('./RingBuffer');
const PriorityQueue = require("./PriorityQueue");
window.ALL_MAP_STATES = { window.ALL_MAP_STATES = {
VISUAL: 0, // For free dragging & zooming. VISUAL: 0, // For free dragging & zooming.
@@ -44,6 +45,10 @@ cc.Class({
type: cc.Prefab, type: cc.Prefab,
default: null, default: null,
}, },
fireballPrefab: {
type: cc.Prefab,
default: null,
},
joystickInputControllerNode: { joystickInputControllerNode: {
type: cc.Node, type: cc.Node,
default: null default: null
@@ -287,6 +292,30 @@ cc.Class({
self.playerRichInfoDict = new Map(); self.playerRichInfoDict = new Map();
// Clearing previous info of all players. [ENDS] // 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.renderFrameId = 0; // After battle started
self.bulletBattleLocalIdCounter = 0; self.bulletBattleLocalIdCounter = 0;
self.lastAllConfirmedInputFrameId = -1; self.lastAllConfirmedInputFrameId = -1;
@@ -575,21 +604,27 @@ cc.Class({
}, },
onRoomDownsyncFrame(pbRdf /* pb.RoomDownsyncFrame */ , accompaniedInputFrameDownsyncBatch /* pb.InputFrameDownsyncBatch */ ) { onRoomDownsyncFrame(pbRdf /* pb.RoomDownsyncFrame */ , accompaniedInputFrameDownsyncBatch /* pb.InputFrameDownsyncBatch */ ) {
const jsPlayersArr = new Array().fill(null); const jsPlayersArr = new Array(pbRdf.playersArr.length).fill(null);
for (let k in pbRdf.playersArr) { for (let k = 0; k < pbRdf.playersArr.length; ++k) {
const pbPlayer = pbRdf.playersArr[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; jsPlayersArr[k] = jsPlayer;
} }
const jsMeleeBulletsArr = []; const jsMeleeBulletsArr = new Array(pbRdf.meleeBullets.length).fill(null);
for (let k in pbRdf.meleeBullets) { for (let k = 0; k < pbRdf.meleeBullets.length; ++k) {
const pbBullet = pbRdf.meleeBullets[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); 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.push(jsBullet); 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". // 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; const self = window.mapIns;
self.onInputFrameDownsyncBatch(accompaniedInputFrameDownsyncBatch); // Important to do this step before setting IN_BATTLE self.onInputFrameDownsyncBatch(accompaniedInputFrameDownsyncBatch); // Important to do this step before setting IN_BATTLE
if (!self.recentRenderCache) { if (!self.recentRenderCache) {
@@ -685,6 +720,8 @@ cc.Class({
equalPlayers(lhs, rhs) { 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 (null != lhs && null == rhs) return false;
if (lhs.VirtualGridX != rhs.VirtualGridX) return false; if (lhs.VirtualGridX != rhs.VirtualGridX) return false;
if (lhs.VirtualGridY != rhs.VirtualGridY) return false; if (lhs.VirtualGridY != rhs.VirtualGridY) return false;
if (lhs.DirX != rhs.DirX) return false; if (lhs.DirX != rhs.DirX) return false;
@@ -703,20 +740,44 @@ cc.Class({
equalMeleeBullets(lhs, rhs) { equalMeleeBullets(lhs, rhs) {
if (null == lhs || null == rhs) return false; if (null == lhs || null == rhs) return false;
if (lhs.battleLocalId != rhs.battleLocalId) return false; if (null == lhs && null != rhs) return false;
if (lhs.offenderPlayerId != rhs.offenderPlayerId) return false; if (null != lhs && null == rhs) return false;
if (lhs.offenderJoinIndex != rhs.offenderJoinIndex) return false; if (lhs.BattleAttr.BulletLocalId != rhs.BattleAttr.BulletLocalId) return false;
if (lhs.originatedRenderFrameId != rhs.originatedRenderFrameId) 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; return true;
}, },
equalRoomDownsyncFrames(lhs, rhs) { equalRoomDownsyncFrames(lhs, rhs) {
if (null == lhs || null == rhs) return false; if (null == lhs || null == rhs) return false;
for (let k in lhs.players) { for (let k in lhs.PlayersArr) {
if (!this.equalPlayers(lhs.players[k], rhs.players[k])) return false; if (!this.equalPlayers(lhs.PlayersArr[k], rhs.PlayersArr[k])) return false;
} }
for (let k in lhs.meleeBullets) { for (let k in lhs.MeleeBullets) {
if (!this.equalMeleeBullets(lhs.meleeBullets[k], rhs.meleeBullets[k])) return false; 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; 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! // [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)) { if (self.othersForcedDownsyncRenderFrameDict.has(rdf.Id)) {
const delayedInputFrameId = gopkgs.ConvertToDelayedInputFrameId(rdf.id); const delayedInputFrameId = gopkgs.ConvertToDelayedInputFrameId(rdf.Id);
const othersForcedDownsyncRenderFrame = self.othersForcedDownsyncRenderFrameDict.get(rdf.id); const othersForcedDownsyncRenderFrame = self.othersForcedDownsyncRenderFrameDict.get(rdf.Id);
if (self.lastAllConfirmedInputFrameId >= delayedInputFrameId && !self.equalRoomDownsyncFrames(othersForcedDownsyncRenderFrame, rdf)) { 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)} rdf=${JSON.stringify(rdf)}
othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame)}`); othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame)}`);
// closeWSConnection(constants.RET_CODE.CLIENT_MISMATCHED_RENDER_FRAME, ""); // closeWSConnection(constants.RET_CODE.CLIENT_MISMATCHED_RENDER_FRAME, "");
// self.onManualRejoinRequired("[DEBUG] CLIENT_MISMATCHED_RENDER_FRAME"); // self.onManualRejoinRequired("[DEBUG] CLIENT_MISMATCHED_RENDER_FRAME");
rdf = othersForcedDownsyncRenderFrame; rdf = othersForcedDownsyncRenderFrame;
self.othersForcedDownsyncRenderFrameDict.delete(rdf.id); self.othersForcedDownsyncRenderFrameDict.delete(rdf.Id);
} }
} }
self.applyRoomDownsyncFrameDynamics(rdf, prevRdf); self.applyRoomDownsyncFrameDynamics(rdf, prevRdf);
@@ -1047,6 +1108,41 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
playerRichInfo.scriptIns.updateCharacterAnim(currPlayerDownsync, prevRdfPlayer, false, chConfig); 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 // Update countdown
self.countdownNanos = self.battleDurationNanos - self.renderFrameId * self.rollbackEstimatedDtNanos; self.countdownNanos = self.battleDurationNanos - self.renderFrameId * self.rollbackEstimatedDtNanos;
if (self.countdownNanos <= 0) { if (self.countdownNanos <= 0) {
@@ -1168,7 +1264,12 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
playerDownsyncStr(playerDownsync) { playerDownsyncStr(playerDownsync) {
if (null == playerDownsync) return ""; 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) { inputFrameDownsyncStr(inputFrameDownsync) {
@@ -1197,8 +1298,13 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
for (let k in rdf.PlayersArr) { for (let k in rdf.PlayersArr) {
playersStrBldr.push(self.playerDownsyncStr(rdf.PlayersArr[k])); 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} s.push(`rdfId:${i}
players:[${playersStrBldr.join(',')}] players:[${playersStrBldr.join(',')}]
fireballs:[${fireballsStrBldr.join(',')}]
actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`); actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
} }
@@ -1236,6 +1342,7 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
case ATK_CHARACTER_STATE.BlownUp1[0]: case ATK_CHARACTER_STATE.BlownUp1[0]:
case ATK_CHARACTER_STATE.InAirIdle1NoJump[0]: case ATK_CHARACTER_STATE.InAirIdle1NoJump[0]:
case ATK_CHARACTER_STATE.InAirIdle1ByJump[0]: case ATK_CHARACTER_STATE.InAirIdle1ByJump[0]:
case ATK_CHARACTER_STATE.OnWall[0]:
[colliderWidth, colliderHeight] = [player.ColliderRadius * 2, player.ColliderRadius * 2]; [colliderWidth, colliderHeight] = [player.ColliderRadius * 2, player.ColliderRadius * 2];
break; break;
} }
@@ -1257,11 +1364,11 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
for (let k in rdf.MeleeBullets) { for (let k in rdf.MeleeBullets) {
const meleeBullet = rdf.MeleeBullets[k]; const meleeBullet = rdf.MeleeBullets[k];
if ( 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) { if (1 == offender.JoinIndex) {
g2.strokeColor = cc.Color.BLUE; g2.strokeColor = cc.Color.BLUE;
} else { } else {
@@ -1285,6 +1392,34 @@ actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
g2.stroke(); 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() { onLoad() {
const self = this; const self = this;
window.mapIns = self; window.mapIns = self;
self.showCriticalCoordinateLabels = false; self.showCriticalCoordinateLabels = true;
const mapNode = self.node; const mapNode = self.node;
const canvasNode = mapNode.parent; const canvasNode = mapNode.parent;
@@ -29,7 +29,7 @@ cc.Class({
/** Init required prefab ended. */ /** Init required prefab ended. */
self.inputFrameUpsyncDelayTolerance = 2; self.inputFrameUpsyncDelayTolerance = 2;
self.collisionMinStep = 8; self.collisionMinStep = 2;
self.renderCacheSize = 1024; self.renderCacheSize = 1024;
self.serverFps = 60; self.serverFps = 60;
@@ -92,9 +92,11 @@ cc.Class({
const p1Vpos = gopkgs.WorldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y); 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 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 colliderRadiusV = gopkgs.WorldToVirtualGridPos(12.0, 0);
const speciesIdList = [4096, 1];
const chConfigsOrderedByJoinIndex = gopkgs.GetCharacterConfigsOrderedByJoinIndex(speciesIdList);
const startRdf = window.pb.protos.RoomDownsyncFrame.create({ const startRdf = window.pb.protos.RoomDownsyncFrame.create({
id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START, id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START,
playersArr: [ playersArr: [
@@ -103,7 +105,7 @@ cc.Class({
joinIndex: 1, joinIndex: 1,
virtualGridX: p1Vpos[0], virtualGridX: p1Vpos[0],
virtualGridY: p1Vpos[1], virtualGridY: p1Vpos[1],
speed: speedV[0], speed: chConfigsOrderedByJoinIndex[0].Speed,
colliderRadius: colliderRadiusV[0], colliderRadius: colliderRadiusV[0],
characterState: window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0], characterState: window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0],
framesToRecover: 0, framesToRecover: 0,
@@ -112,13 +114,14 @@ cc.Class({
velX: 0, velX: 0,
velY: 0, velY: 0,
inAir: true, inAir: true,
onWall: false,
}), }),
window.pb.protos.PlayerDownsync.create({ window.pb.protos.PlayerDownsync.create({
id: 11, id: 11,
joinIndex: 2, joinIndex: 2,
virtualGridX: p2Vpos[0], virtualGridX: p2Vpos[0],
virtualGridY: p2Vpos[1], virtualGridY: p2Vpos[1],
speed: speedV[0], speed: chConfigsOrderedByJoinIndex[1].Speed,
colliderRadius: colliderRadiusV[0], colliderRadius: colliderRadiusV[0],
characterState: window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0], characterState: window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0],
framesToRecover: 0, framesToRecover: 0,
@@ -127,9 +130,10 @@ cc.Class({
velX: 0, velX: 0,
velY: 0, velY: 0,
inAir: true, inAir: true,
onWall: false,
}), }),
], ],
speciesIdList: [1, 0], speciesIdList: speciesIdList,
}); });
self.selfPlayerInfo = { self.selfPlayerInfo = {

View File

@@ -12,32 +12,15 @@ var BinaryHeap = function (customCompare) {
* @private * @private
*/ */
this.list = []; this.list = [];
this.lookupKeyToIndex = {};
if (customCompare) { if (customCompare) {
this.compare = customCompare; this.compare = customCompare;
} }
}; };
/** BinaryHeap.prototype.contains = function (lookupKey) {
* Builds a heap with the provided keys and values, this will discard the return null != this.lookupKeyToIndex[lookupKey];
* 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);
}; };
/** /**
@@ -45,6 +28,7 @@ BinaryHeap.prototype.buildHeap = function (keys, values) {
*/ */
BinaryHeap.prototype.clear = function () { BinaryHeap.prototype.clear = function () {
this.list.length = 0; 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 * @return {Node} node The heap's minimum node or undefined if the heap is
* empty. * empty.
*/ */
BinaryHeap.prototype.extractMinimum = function () { BinaryHeap.prototype.pop = function () {
if (!this.list.length) { if (0 == this.list.length) {
return undefined; return null;
} }
if (this.list.length === 1) { if (1 == this.list.length) {
delete this.lookupKeyToIndex[Object.keys(this.lookupKeyToIndex)[0]];
return this.list.shift(); return this.list.shift();
} }
var min = this.list[0]; var min = this.list[0];
delete this.lookupKeyToIndex[min.lookupKey];
this.list[0] = this.list.pop(); this.list[0] = this.list.pop();
this.lookupKeyToIndex[this.list[0].lookupKey] = 0;
heapify(this, 0); heapify(this, 0);
return min; return min;
}; };
@@ -72,8 +61,8 @@ BinaryHeap.prototype.extractMinimum = function () {
* @return {Node} node The heap's minimum node or undefined if the heap is * @return {Node} node The heap's minimum node or undefined if the heap is
* empty. * empty.
*/ */
BinaryHeap.prototype.findMinimum = function () { BinaryHeap.prototype.top = function () {
return this.isEmpty() ? undefined : this.list[0]; return this.isEmpty() ? null : this.list[0];
}; };
/** /**
@@ -83,25 +72,79 @@ BinaryHeap.prototype.findMinimum = function () {
* @param {Object} value The value to insert. * @param {Object} value The value to insert.
* @return {Node} node The inserted node. * @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 i = this.list.length;
var node = new Node(key, value); var node = new Node(key, value, lookupKey);
this.list.push(node); this.list.push(node);
var parent = getParent(i); this.lookupKeyToIndex[lookupKey] = i;
while (typeof parent !== 'undefined' && let u = getParent(i);
this.compare(this.list[i], this.list[parent]) < 0) { while (null != u && this.compare(this.list[i], this.list[u]) < 0) {
swap(this.list, i, parent); swap(this.list, i, u, this.lookupKeyToIndex);
i = parent; i = u;
parent = getParent(i); u = getParent(i);
} }
return node; 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. * @return {boolean} Whether the heap is empty.
*/ */
BinaryHeap.prototype.isEmpty = function () { 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; 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. * 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. * @param {number} i The index of the node to heapify.
*/ */
function heapify(heap, i) { function heapify(heap, i) {
var l = getLeft(i); let cur = i;
var r = getRight(i); let smallest = -1;
var smallest = i; while (cur != smallest) {
const l = getLeft(cur);
const r = getRight(cur);
smallest = cur;
if (l < heap.list.length && if (l < heap.list.length &&
heap.compare(heap.list[l], heap.list[i]) < 0) { heap.compare(heap.list[l], heap.list[smallest]) < 0) {
smallest = l; smallest = l;
} }
if (r < heap.list.length && if (r < heap.list.length &&
heap.compare(heap.list[r], heap.list[smallest]) < 0) { heap.compare(heap.list[r], heap.list[smallest]) < 0) {
smallest = r; smallest = r;
} }
if (smallest !== i) {
swap(heap.list, i, smallest);
heapify(heap, smallest);
}
}
/** if (smallest !== cur) {
* Builds a heap from a node array, this will discard the heap's current data. swap(heap.list, cur, smallest, heap.lookupKeyToIndex);
* cur = smallest;
* @private smallest = -1;
* @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);
} }
} }
@@ -186,10 +212,16 @@ function buildHeapFromNodeArray(heap, nodeArray) {
* @param {number} a The index of the first element. * @param {number} a The index of the first element.
* @param {number} b The index of the second 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]; var temp = array[a];
array[a] = array[b]; array[a] = array[b];
array[b] = temp; 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. * @return {number} The index of the node's parent.
*/ */
function getParent(i) { function getParent(i) {
if (i === 0) { if (0 == i) {
return undefined; return null;
} }
return Math.floor((i - 1) / 2); return Math.floor((i - 1) / 2);
} }
@@ -235,9 +267,10 @@ function getRight(i) {
* @param {Object} key The key of the new node. * @param {Object} key The key of the new node.
* @param {Object} value The value 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.key = key;
this.value = value; this.value = value;
this.lookupKey = lookupKey;
} }
module.exports = BinaryHeap; 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 = { let toRet = {
playerStartingPositions: [], playerStartingPositions: [],
barriers: [], barriers: [],
npcStartingPositions: [],
npcPatrolCues: [],
}; };
const tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap); // This is a magic name. const tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap); // This is a magic name.
@@ -128,6 +130,38 @@ TileCollisionManager.prototype.extractBoundaryObjects = function(withTiledMapNod
toRet.playerStartingPositions.push(wpos); toRet.playerStartingPositions.push(wpos);
} }
break; 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": case "Barrier":
for (let j = 0; j < allObjects.length; ++j) { for (let j = 0; j < allObjects.length; ++j) {
let object = allObjects[j]; let object = allObjects[j];
@@ -205,30 +239,6 @@ TileCollisionManager.prototype.initMapNodeByTiledBoundaries = function(mapScript
mapScriptIns.barrierColliders.push(newBarrierColliderIns); mapScriptIns.barrierColliders.push(newBarrierColliderIns);
mapScriptIns.node.addChild(newBarrier); 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(); window.tileCollisionManager = new TileCollisionManager();

View File

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

View File

@@ -68,7 +68,7 @@
"shelter_z_reducer", "shelter_z_reducer",
"shelter" "shelter"
], ],
"last-module-event-record-time": 1672287736326, "last-module-event-record-time": 1673325961305,
"simulator-orientation": false, "simulator-orientation": false,
"simulator-resolution": { "simulator-resolution": {
"height": 640, "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. 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 ( import (
"math" "math"
"resolv" "resolv"
//"fmt"
) )
const ( const (
@@ -21,7 +22,7 @@ const (
GRAVITY_X = int32(0) 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 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) 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" 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_OVERLAP = float64(0.1)
SNAP_INTO_PLATFORM_THRESHOLD = float64(0.5) SNAP_INTO_PLATFORM_THRESHOLD = float64(0.5)
VERTICAL_PLATFORM_THRESHOLD = float64(0.9)
NO_SKILL = -1 NO_SKILL = -1
NO_SKILL_HIT = -1 NO_SKILL_HIT = -1
@@ -64,6 +66,11 @@ const (
ATK_CHARACTER_STATE_ATK2 = int32(11) ATK_CHARACTER_STATE_ATK2 = int32(11)
ATK_CHARACTER_STATE_ATK3 = int32(12) 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{ var inAirSet = map[int32]bool{
@@ -72,6 +79,7 @@ var inAirSet = map[int32]bool{
ATK_CHARACTER_STATE_INAIR_ATK1: true, ATK_CHARACTER_STATE_INAIR_ATK1: true,
ATK_CHARACTER_STATE_INAIR_ATKED1: true, ATK_CHARACTER_STATE_INAIR_ATKED1: true,
ATK_CHARACTER_STATE_BLOWN_UP1: true, ATK_CHARACTER_STATE_BLOWN_UP1: true,
ATK_CHARACTER_STATE_ONWALL: true,
} }
var noOpSet = map[int32]bool{ var noOpSet = map[int32]bool{
@@ -100,6 +108,13 @@ var nonAttackingSet = map[int32]bool{
ATK_CHARACTER_STATE_GET_UP1: true, 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) { func ShouldPrefabInputFrameDownsync(prevRenderFrameId int32, renderFrameId int32) (bool, int32) {
for i := prevRenderFrameId + 1; i <= renderFrameId; i++ { for i := prevRenderFrameId + 1; i <= renderFrameId; i++ {
if (0 <= i) && (0 == (i & ((1 << INPUT_SCALE_FRAMES) - 1))) { if (0 <= i) && (0 == (i & ((1 << INPUT_SCALE_FRAMES) - 1))) {
@@ -153,7 +168,7 @@ type SatResult struct {
Axis resolv.Vector 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() origX, origY := playerShape.Position()
defer func() { defer func() {
playerShape.SetPosition(origX, origY) 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) { func WorldToVirtualGridPos(wx, wy float64) (int32, int32) {
// [WARNING] Introduces loss of precision! // [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. // 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 virtualGridX int32 = int32(math.Round(wx * WORLD_TO_VIRTUAL_GRID_RATIO))
var virtualGridY int32 = int32(math.Floor(wy * WORLD_TO_VIRTUAL_GRID_RATIO)) var virtualGridY int32 = int32(math.Round(wy * WORLD_TO_VIRTUAL_GRID_RATIO))
return virtualGridX, virtualGridY 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) 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 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 { if nil == collision {
return &ret return &ret
} }
@@ -356,10 +387,9 @@ func calcHardPushbacksNorms(joinIndex int32, playerCollider *resolv.Object, play
for _, obj := range collision.Objects { for _, obj := range collision.Objects {
isBarrier := false isBarrier := false
switch obj.Data.(type) { switch obj.Data.(type) {
case *PlayerDownsync: case *PlayerDownsync, *MeleeBullet, *FireballBullet:
case *MeleeBullet:
default: 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 isBarrier = true
} }
@@ -367,7 +397,7 @@ func calcHardPushbacksNorms(joinIndex int32, playerCollider *resolv.Object, play
continue continue
} }
barrierShape := obj.Shape.(*resolv.ConvexPolygon) 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 { if !overlapped {
continue continue
} }
@@ -418,14 +448,22 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
if decodedInput.BtnBLevel > prevBtnBLevel { if decodedInput.BtnBLevel > prevBtnBLevel {
if _, existent := inAirSet[currPlayerDownsync.CharacterState]; !existent { if _, existent := inAirSet[currPlayerDownsync.CharacterState]; !existent {
jumpedOrNot = true jumpedOrNot = true
} else if ATK_CHARACTER_STATE_ONWALL == currPlayerDownsync.CharacterState {
jumpedOrNot = true
} }
} }
} }
patternId := PATTERN_ID_NO_OP patternId := PATTERN_ID_NO_OP
if decodedInput.BtnALevel > prevBtnALevel { if decodedInput.BtnALevel > prevBtnALevel {
if 0 > effDy {
patternId = 3
} else if 0 < effDy {
patternId = 2
} else {
patternId = 1 patternId = 1
} }
}
return patternId, jumpedOrNot, effDx, effDy return patternId, jumpedOrNot, effDx, effDy
} }
@@ -447,6 +485,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
VelY: currPlayerDownsync.VelY, VelY: currPlayerDownsync.VelY,
CharacterState: currPlayerDownsync.CharacterState, CharacterState: currPlayerDownsync.CharacterState,
InAir: true, InAir: true,
OnWall: false,
Speed: currPlayerDownsync.Speed, Speed: currPlayerDownsync.Speed,
BattleState: currPlayerDownsync.BattleState, BattleState: currPlayerDownsync.BattleState,
Score: currPlayerDownsync.Score, Score: currPlayerDownsync.Score,
@@ -460,6 +499,8 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
ActiveSkillHit: currPlayerDownsync.ActiveSkillHit, ActiveSkillHit: currPlayerDownsync.ActiveSkillHit,
FramesInvinsible: currPlayerDownsync.FramesInvinsible - 1, FramesInvinsible: currPlayerDownsync.FramesInvinsible - 1,
ColliderRadius: currPlayerDownsync.ColliderRadius, ColliderRadius: currPlayerDownsync.ColliderRadius,
OnWallNormX: currPlayerDownsync.OnWallNormX,
OnWallNormY: currPlayerDownsync.OnWallNormY,
} }
if nextRenderFramePlayers[i].FramesToRecover < 0 { if nextRenderFramePlayers[i].FramesToRecover < 0 {
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? 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) effPushbacks := make([]Vec2D, roomCapacity)
hardPushbackNorms := make([]*[]Vec2D, roomCapacity) hardPushbackNorms := make([]*[]Vec2D, roomCapacity)
jumpedOrNotList := make([]bool, roomCapacity) jumpedOrNotList := make([]bool, roomCapacity)
bulletLocalId := currRenderFrame.BulletLocalIdCounter
// 1. Process player inputs // 1. Process player inputs
for i, currPlayerDownsync := range currRenderFrame.PlayersArr { for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
jumpedOrNotList[i] = false
chConfig := chConfigsOrderedByJoinIndex[i] chConfig := chConfigsOrderedByJoinIndex[i]
thatPlayerInNextFrame := nextRenderFramePlayers[i] thatPlayerInNextFrame := nextRenderFramePlayers[i]
patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, inputsBuffer) patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, inputsBuffer)
if jumpedOrNot { jumpedOrNotList[i] = jumpedOrNot
thatPlayerInNextFrame.VelY = int32(chConfig.JumpingInitVelY)
jumpedOrNotList[i] = true
}
joinIndex := currPlayerDownsync.JoinIndex joinIndex := currPlayerDownsync.JoinIndex
skillId := chConfig.SkillMapper(patternId, currPlayerDownsync) skillId := chConfig.SkillMapper(patternId, currPlayerDownsync)
if skillConfig, existent := skills[skillId]; existent { if skillConfig, existent := skills[skillId]; existent {
thatPlayerInNextFrame.ActiveSkillId = int32(skillId) thatPlayerInNextFrame.ActiveSkillId = int32(skillId)
thatPlayerInNextFrame.ActiveSkillHit = 0 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 // Hardcoded to use only the first hit for now
switch v := skillConfig.Hits[thatPlayerInNextFrame.ActiveSkillHit].(type) { switch v := skillConfig.Hits[thatPlayerInNextFrame.ActiveSkillHit].(type) {
case *MeleeBullet: case *MeleeBullet:
var newBullet MeleeBullet = *v // Copied primitive fields into an onstack variable var newBullet MeleeBullet = *v // Copied primitive fields into an onstack variable
newBullet.OriginatedRenderFrameId = currRenderFrame.Id newBullet.BattleAttr = &BulletBattleAttr{
newBullet.OffenderJoinIndex = joinIndex BulletLocalId: bulletLocalId,
OriginatedRenderFrameId: currRenderFrame.Id,
OffenderJoinIndex: joinIndex,
TeamId: currPlayerDownsync.BulletTeamId,
}
bulletLocalId++
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, &newBullet) nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, &newBullet)
thatPlayerInNextFrame.FramesToRecover = skillConfig.RecoveryFrames 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
}
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
}
}
hasLockVel := false if false == hasLockVel && false == currPlayerDownsync.InAir {
if NO_LOCK_VEL != v.SelfLockVelX {
hasLockVel = true
xfac := int32(1)
if 0 > thatPlayerInNextFrame.DirX {
xfac = -xfac
}
thatPlayerInNextFrame.VelX = xfac * v.SelfLockVelX
}
if NO_LOCK_VEL != v.SelfLockVelY {
hasLockVel = true
thatPlayerInNextFrame.VelY = v.SelfLockVelY
}
if false == hasLockVel {
if false == currPlayerDownsync.InAir {
thatPlayerInNextFrame.VelX = 0 thatPlayerInNextFrame.VelX = 0
} }
}
}
thatPlayerInNextFrame.CharacterState = skillConfig.BoundChState thatPlayerInNextFrame.CharacterState = skillConfig.BoundChState
continue // Don't allow movement if skill is used continue // Don't allow movement if skill is used
} }
if 0 == currPlayerDownsync.FramesToRecover { if 0 == currPlayerDownsync.FramesToRecover {
if 0 != effDx || 0 != effDy { if 0 != effDx {
thatPlayerInNextFrame.DirX, thatPlayerInNextFrame.DirY = effDx, effDy xfac := int32(1)
thatPlayerInNextFrame.VelX = effDx * currPlayerDownsync.Speed 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 thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_WALKING
} else { } else {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1 thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
@@ -541,20 +617,39 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
for i, currPlayerDownsync := range currRenderFrame.PlayersArr { for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
joinIndex := currPlayerDownsync.JoinIndex joinIndex := currPlayerDownsync.JoinIndex
effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y = float64(0), float64(0) effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y = float64(0), float64(0)
thatPlayerInNextFrame := nextRenderFramePlayers[i]
chConfig := chConfigsOrderedByJoinIndex[i] chConfig := chConfigsOrderedByJoinIndex[i]
// Reset playerCollider position from the "virtual grid position" // Reset playerCollider position from the "virtual grid position"
newVx, newVy := currPlayerDownsync.VirtualGridX+currPlayerDownsync.VelX, currPlayerDownsync.VirtualGridY+currPlayerDownsync.VelY newVx, newVy := currPlayerDownsync.VirtualGridX+currPlayerDownsync.VelX, currPlayerDownsync.VirtualGridY+currPlayerDownsync.VelY
if jumpedOrNotList[i] { if jumpedOrNotList[i] {
// 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 newVy += chConfig.JumpingInitVelY // Immediately gets out of any snapping
} }
}
wx, wy := VirtualGridToWorldPos(newVx, newVy) wx, wy := VirtualGridToWorldPos(newVx, newVy)
colliderWidth, colliderHeight := currPlayerDownsync.ColliderRadius*2, currPlayerDownsync.ColliderRadius*4 colliderWidth, colliderHeight := currPlayerDownsync.ColliderRadius*2, currPlayerDownsync.ColliderRadius*4
switch currPlayerDownsync.CharacterState { switch currPlayerDownsync.CharacterState {
case ATK_CHARACTER_STATE_LAY_DOWN1: case ATK_CHARACTER_STATE_LAY_DOWN1:
colliderWidth, colliderHeight = currPlayerDownsync.ColliderRadius*4, currPlayerDownsync.ColliderRadius*2 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 colliderWidth, colliderHeight = currPlayerDownsync.ColliderRadius*2, currPlayerDownsync.ColliderRadius*2
} }
@@ -566,40 +661,69 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
// Add to collision system // Add to collision system
collisionSys.Add(playerCollider) collisionSys.Add(playerCollider)
thatPlayerInNextFrame := nextRenderFramePlayers[i]
if currPlayerDownsync.InAir { if currPlayerDownsync.InAir {
if ATK_CHARACTER_STATE_ONWALL == currPlayerDownsync.CharacterState && !jumpedOrNotList[i] {
thatPlayerInNextFrame.VelX += GRAVITY_X
thatPlayerInNextFrame.VelY = chConfig.WallSlidingVelY
} else {
thatPlayerInNextFrame.VelX += GRAVITY_X thatPlayerInNextFrame.VelX += GRAVITY_X
thatPlayerInNextFrame.VelY += GRAVITY_Y thatPlayerInNextFrame.VelY += GRAVITY_Y
} }
} }
}
// 3. Add bullet colliders into collision system // 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 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 { for _, meleeBullet := range currRenderFrame.MeleeBullets {
if (meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames <= currRenderFrame.Id) && (meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames+meleeBullet.ActiveFrames > currRenderFrame.Id) { if (meleeBullet.BattleAttr.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames <= currRenderFrame.Id) && (meleeBullet.BattleAttr.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames+meleeBullet.Bullet.ActiveFrames > currRenderFrame.Id) {
offender := currRenderFrame.PlayersArr[meleeBullet.OffenderJoinIndex-1] offender := currRenderFrame.PlayersArr[meleeBullet.BattleAttr.OffenderJoinIndex-1]
xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis" xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
if 0 > offender.DirX { if 0 > offender.DirX {
xfac = -xfac xfac = -xfac
} }
bulletWx, bulletWy := VirtualGridToWorldPos(offender.VirtualGridX+xfac*meleeBullet.HitboxOffsetX, offender.VirtualGridY) bulletWx, bulletWy := VirtualGridToWorldPos(offender.VirtualGridX+xfac*meleeBullet.Bullet.HitboxOffsetX, offender.VirtualGridY)
hitboxSizeWx, hitboxSizeWy := VirtualGridToWorldPos(meleeBullet.HitboxSizeX, meleeBullet.HitboxSizeY) 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") 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) collisionSys.Add(newBulletCollider)
bulletColliders = append(bulletColliders, newBulletCollider) bulletColliders = append(bulletColliders, newBulletCollider)
} else { } else if meleeBullet.BattleAttr.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames+meleeBullet.Bullet.ActiveFrames > currRenderFrame.Id {
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, meleeBullet) 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 // 4. Calc pushbacks for each player (after its movement) w/o bullets
for i, currPlayerDownsync := range currRenderFrame.PlayersArr { for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
joinIndex := currPlayerDownsync.JoinIndex joinIndex := currPlayerDownsync.JoinIndex
playerCollider := playerColliders[i] playerCollider := playerColliders[i]
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon) playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
hardPushbackNorms[joinIndex-1] = calcHardPushbacksNorms(joinIndex, playerCollider, playerShape, SNAP_INTO_PLATFORM_OVERLAP, &(effPushbacks[joinIndex-1]))
thatPlayerInNextFrame := nextRenderFramePlayers[i] thatPlayerInNextFrame := nextRenderFramePlayers[i]
hardPushbackNorms[joinIndex-1] = calcHardPushbacksNorms(joinIndex, currPlayerDownsync, thatPlayerInNextFrame, playerCollider, playerShape, SNAP_INTO_PLATFORM_OVERLAP, &(effPushbacks[joinIndex-1]))
chConfig := chConfigsOrderedByJoinIndex[i] chConfig := chConfigsOrderedByJoinIndex[i]
landedOnGravityPushback := false landedOnGravityPushback := false
@@ -609,7 +733,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
switch obj.Data.(type) { switch obj.Data.(type) {
case *PlayerDownsync: case *PlayerDownsync:
isAnotherPlayer = true isAnotherPlayer = true
case *MeleeBullet: case *MeleeBullet, *FireballBullet:
isBullet = true isBullet = true
default: default:
// By default it's a regular barrier, even if data is nil // By default it's a regular barrier, even if data is nil
@@ -620,7 +744,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
continue continue
} }
bShape := obj.Shape.(*resolv.ConvexPolygon) 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 { if !overlapped {
continue continue
} }
@@ -648,24 +772,27 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
} }
if landedOnGravityPushback { if landedOnGravityPushback {
thatPlayerInNextFrame.InAir = false thatPlayerInNextFrame.InAir = false
if currPlayerDownsync.InAir && 0 >= currPlayerDownsync.VelY { fallStopping := (currPlayerDownsync.InAir && 0 >= currPlayerDownsync.VelY)
// fallStopping if fallStopping {
thatPlayerInNextFrame.VelY = 0 thatPlayerInNextFrame.VelY = 0
thatPlayerInNextFrame.VelX = 0 thatPlayerInNextFrame.VelX = 0
if _, existent := nonAttackingSet[thatPlayerInNextFrame.CharacterState]; existent {
if ATK_CHARACTER_STATE_BLOWN_UP1 == thatPlayerInNextFrame.CharacterState { if ATK_CHARACTER_STATE_BLOWN_UP1 == thatPlayerInNextFrame.CharacterState {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_LAY_DOWN1 thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_LAY_DOWN1
thatPlayerInNextFrame.FramesToRecover = chConfig.LayDownFramesToRecover thatPlayerInNextFrame.FramesToRecover = chConfig.LayDownFramesToRecover
} else { } 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 halfColliderWidthDiff, halfColliderHeightDiff := int32(0), currPlayerDownsync.ColliderRadius
_, halfColliderWorldHeightDiff := VirtualGridToWorldPos(halfColliderWidthDiff, halfColliderHeightDiff) _, halfColliderWorldHeightDiff := VirtualGridToWorldPos(halfColliderWidthDiff, halfColliderHeightDiff)
effPushbacks[joinIndex-1].Y -= halfColliderWorldHeightDiff // To prevent bouncing due to abrupt change of collider shape effPushbacks[joinIndex-1].Y -= halfColliderWorldHeightDiff
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
} }
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_IDLE1
thatPlayerInNextFrame.FramesToRecover = 0
} }
} else { } else {
// landedOnGravityPushback not fallStopping, could be in LayDown or GetUp
if _, existent := nonAttackingSet[thatPlayerInNextFrame.CharacterState]; existent { if _, existent := nonAttackingSet[thatPlayerInNextFrame.CharacterState]; existent {
// not fallStopping, could be in LayDown or GetUp
if ATK_CHARACTER_STATE_LAY_DOWN1 == thatPlayerInNextFrame.CharacterState { if ATK_CHARACTER_STATE_LAY_DOWN1 == thatPlayerInNextFrame.CharacterState {
if 0 == thatPlayerInNextFrame.FramesToRecover { if 0 == thatPlayerInNextFrame.FramesToRecover {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_GET_UP1 thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_GET_UP1
@@ -680,59 +807,143 @@ 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 // 5. Check bullet-anything collisions
for _, bulletCollider := range bulletColliders { for _, bulletCollider := range bulletColliders {
collision := bulletCollider.Check(0, 0) collision := bulletCollider.Check(0, 0)
bulletCollider.Space.Remove(bulletCollider) // Make sure that the bulletCollider is always removed for each renderFrame bulletCollider.Space.Remove(bulletCollider) // Make sure that the bulletCollider is always removed for each renderFrame
addToNextRenderFrame := true
if nil != collision {
switch v := bulletCollider.Data.(type) { switch v := bulletCollider.Data.(type) {
case *MeleeBullet: case *MeleeBullet:
if nil == collision {
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, v)
continue
}
bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon) bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon)
offender := currRenderFrame.PlayersArr[v.OffenderJoinIndex-1] offender := currRenderFrame.PlayersArr[v.BattleAttr.OffenderJoinIndex-1]
for _, obj := range collision.Objects { for _, obj := range collision.Objects {
defenderShape := obj.Shape.(*resolv.ConvexPolygon) defenderShape := obj.Shape.(*resolv.ConvexPolygon)
switch t := obj.Data.(type) { switch t := obj.Data.(type) {
case *PlayerDownsync: case *PlayerDownsync:
if v.OffenderJoinIndex == t.JoinIndex { if v.BattleAttr.OffenderJoinIndex == t.JoinIndex {
continue continue
} }
overlapped, _, _, _ := calcPushbacks(0, 0, bulletShape, defenderShape)
if !overlapped {
continue
}
addToNextRenderFrame = false
if _, existent := invinsibleSet[t.CharacterState]; existent { if _, existent := invinsibleSet[t.CharacterState]; existent {
continue continue
} }
if 0 < t.FramesInvinsible { if 0 < t.FramesInvinsible {
continue continue
} }
overlapped, _, _, _ := CalcPushbacks(0, 0, bulletShape, defenderShape) 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
}
}
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 { if !overlapped {
continue 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" xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
if 0 > offender.DirX { if 0 > offender.DirX {
xfac = -xfac xfac = -xfac
} }
pushbackVelX, pushbackVelY := xfac*v.PushbackVelX, v.PushbackVelY pushbackVelX, pushbackVelY := xfac*v.Bullet.PushbackVelX, v.Bullet.PushbackVelY
atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1] atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
atkedPlayerInNextFrame.VelX = pushbackVelX atkedPlayerInNextFrame.VelX = pushbackVelX
atkedPlayerInNextFrame.VelY = pushbackVelY atkedPlayerInNextFrame.VelY = pushbackVelY
if v.BlowUp { if v.Bullet.BlowUp {
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1 atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
} else { } else {
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1 atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
} }
oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover
if v.HitStunFrames > oldFramesToRecover { if v.Bullet.HitStunFrames > oldFramesToRecover {
atkedPlayerInNextFrame.FramesToRecover = v.HitStunFrames atkedPlayerInNextFrame.FramesToRecover = v.Bullet.HitStunFrames
} }
default: 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)
}
}
}
// 6. Get players out of stuck barriers if there's any // 6. Get players out of stuck barriers if there's any
for i, currPlayerDownsync := range currRenderFrame.PlayersArr { for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
@@ -747,7 +958,9 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
oldNextCharacterState := thatPlayerInNextFrame.CharacterState oldNextCharacterState := thatPlayerInNextFrame.CharacterState
switch oldNextCharacterState { switch oldNextCharacterState {
case ATK_CHARACTER_STATE_IDLE1, ATK_CHARACTER_STATE_WALKING: 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 thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_IDLE1_BY_JUMP
} else { } else {
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_IDLE1_NO_JUMP thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_IDLE1_NO_JUMP
@@ -779,7 +992,9 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
return &RoomDownsyncFrame{ return &RoomDownsyncFrame{
Id: currRenderFrame.Id + 1, Id: currRenderFrame.Id + 1,
PlayersArr: nextRenderFramePlayers, PlayersArr: nextRenderFramePlayers,
BulletLocalIdCounter: bulletLocalId,
MeleeBullets: nextRenderFrameMeleeBullets, MeleeBullets: nextRenderFrameMeleeBullets,
FireballBullets: nextRenderFrameFireballBullets,
} }
} }
@@ -860,3 +1075,77 @@ func AlignPolygon2DToBoundingBox(input *Polygon2D) *Polygon2D {
return output 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 Speed int32
JumpingInitVelY int32 JumpingInitVelY int32
DashingEnabled bool
OnWallEnabled bool
WallJumpingFramesToRecover int32
WallJumpingInitVelX int32
WallJumpingInitVelY int32
WallSlidingVelY int32
SkillMapper SkillMapperType SkillMapper SkillMapperType
} }
@@ -35,9 +42,12 @@ var Characters = map[int]*CharacterConfig{
GetUpInvinsibleFrames: int32(10), GetUpInvinsibleFrames: int32(10),
GetUpFramesToRecover: int32(27), 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), JumpingInitVelY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
DashingEnabled: false,
OnWallEnabled: false,
SkillMapper: func(patternId int, currPlayerDownsync *PlayerDownsync) int { SkillMapper: func(patternId int, currPlayerDownsync *PlayerDownsync) int {
if 1 == patternId { if 1 == patternId {
if 0 == currPlayerDownsync.FramesToRecover { if 0 == currPlayerDownsync.FramesToRecover {
@@ -51,8 +61,8 @@ var Characters = map[int]*CharacterConfig{
if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 { if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) { switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
case *MeleeBullet: case *MeleeBullet:
if v.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.CancellableEdFrame { if v.Bullet.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.Bullet.CancellableEdFrame {
if nextSkillId, existent2 := v.CancelTransit[patternId]; existent2 { if nextSkillId, existent2 := v.Bullet.CancelTransit[patternId]; existent2 {
return nextSkillId return nextSkillId
} }
} }
@@ -78,9 +88,16 @@ var Characters = map[int]*CharacterConfig{
GetUpInvinsibleFrames: int32(10), GetUpInvinsibleFrames: int32(10),
GetUpFramesToRecover: int32(27), 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), 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 { SkillMapper: func(patternId int, currPlayerDownsync *PlayerDownsync) int {
if 1 == patternId { if 1 == patternId {
if 0 == currPlayerDownsync.FramesToRecover { if 0 == currPlayerDownsync.FramesToRecover {
@@ -94,8 +111,8 @@ var Characters = map[int]*CharacterConfig{
if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 { if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) { switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
case *MeleeBullet: case *MeleeBullet:
if v.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.CancellableEdFrame { if v.Bullet.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.Bullet.CancellableEdFrame {
if nextSkillId, existent2 := v.CancelTransit[patternId]; existent2 { if nextSkillId, existent2 := v.Bullet.CancelTransit[patternId]; existent2 {
return nextSkillId 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 // By default no skill can be fired
return NO_SKILL return NO_SKILL
}, },
@@ -119,7 +190,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK1, BoundChState: ATK_CHARACTER_STATE_ATK1,
Hits: []interface{}{ Hits: []interface{}{
&MeleeBullet{ &MeleeBullet{
Bullet: Bullet{ Bullet: &BulletConfig{
StartupFrames: int32(7), StartupFrames: int32(7),
ActiveFrames: int32(22), ActiveFrames: int32(22),
HitStunFrames: int32(13), HitStunFrames: int32(13),
@@ -152,7 +223,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK2, BoundChState: ATK_CHARACTER_STATE_ATK2,
Hits: []interface{}{ Hits: []interface{}{
&MeleeBullet{ &MeleeBullet{
Bullet: Bullet{ Bullet: &BulletConfig{
StartupFrames: int32(18), StartupFrames: int32(18),
ActiveFrames: int32(18), ActiveFrames: int32(18),
HitStunFrames: int32(18), HitStunFrames: int32(18),
@@ -183,8 +254,8 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK3, BoundChState: ATK_CHARACTER_STATE_ATK3,
Hits: []interface{}{ Hits: []interface{}{
&MeleeBullet{ &MeleeBullet{
Bullet: Bullet{ Bullet: &BulletConfig{
StartupFrames: int32(15), StartupFrames: int32(8),
ActiveFrames: int32(30), ActiveFrames: int32(30),
HitStunFrames: MAX_INT32, HitStunFrames: MAX_INT32,
BlockStunFrames: int32(9), BlockStunFrames: int32(9),
@@ -193,9 +264,9 @@ var skills = map[int]*Skill{
SelfLockVelY: int32(float64(5) * WORLD_TO_VIRTUAL_GRID_RATIO), SelfLockVelY: int32(float64(5) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelX: int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO), PushbackVelX: int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO),
PushbackVelY: int32(float64(7) * WORLD_TO_VIRTUAL_GRID_RATIO), PushbackVelY: int32(float64(7) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO), HitboxOffsetX: int32(float64(16) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0), HitboxOffsetY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeX: int32(float64(48) * WORLD_TO_VIRTUAL_GRID_RATIO), HitboxSizeX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO), HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
BlowUp: true, BlowUp: true,
}, },
@@ -210,7 +281,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK1, BoundChState: ATK_CHARACTER_STATE_ATK1,
Hits: []interface{}{ Hits: []interface{}{
&MeleeBullet{ &MeleeBullet{
Bullet: Bullet{ Bullet: &BulletConfig{
StartupFrames: int32(7), StartupFrames: int32(7),
ActiveFrames: int32(22), ActiveFrames: int32(22),
HitStunFrames: int32(13), HitStunFrames: int32(13),
@@ -243,7 +314,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK2, BoundChState: ATK_CHARACTER_STATE_ATK2,
Hits: []interface{}{ Hits: []interface{}{
&MeleeBullet{ &MeleeBullet{
Bullet: Bullet{ Bullet: &BulletConfig{
StartupFrames: int32(18), StartupFrames: int32(18),
ActiveFrames: int32(18), ActiveFrames: int32(18),
HitStunFrames: int32(18), HitStunFrames: int32(18),
@@ -274,16 +345,16 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_ATK3, BoundChState: ATK_CHARACTER_STATE_ATK3,
Hits: []interface{}{ Hits: []interface{}{
&MeleeBullet{ &MeleeBullet{
Bullet: Bullet{ Bullet: &BulletConfig{
StartupFrames: int32(15), StartupFrames: int32(8),
ActiveFrames: int32(28), ActiveFrames: int32(28),
HitStunFrames: MAX_INT32, HitStunFrames: MAX_INT32,
BlockStunFrames: int32(9), BlockStunFrames: int32(9),
Damage: int32(10), Damage: int32(10),
SelfLockVelX: int32(float64(-0.1) * WORLD_TO_VIRTUAL_GRID_RATIO), SelfLockVelX: NO_LOCK_VEL,
SelfLockVelY: NO_LOCK_VEL, SelfLockVelY: NO_LOCK_VEL,
PushbackVelX: int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO), 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), HitboxOffsetX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
HitboxOffsetY: int32(0), HitboxOffsetY: int32(0),
HitboxSizeX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO), 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{ 255: &Skill{
RecoveryFrames: int32(30), RecoveryFrames: int32(30),
RecoveryFramesOnBlock: int32(30), RecoveryFramesOnBlock: int32(30),
@@ -301,7 +518,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_INAIR_ATK1, BoundChState: ATK_CHARACTER_STATE_INAIR_ATK1,
Hits: []interface{}{ Hits: []interface{}{
&MeleeBullet{ &MeleeBullet{
Bullet: Bullet{ Bullet: &BulletConfig{
StartupFrames: int32(3), StartupFrames: int32(3),
ActiveFrames: int32(20), ActiveFrames: int32(20),
HitStunFrames: int32(18), HitStunFrames: int32(18),
@@ -327,7 +544,7 @@ var skills = map[int]*Skill{
BoundChState: ATK_CHARACTER_STATE_INAIR_ATK1, BoundChState: ATK_CHARACTER_STATE_INAIR_ATK1,
Hits: []interface{}{ Hits: []interface{}{
&MeleeBullet{ &MeleeBullet{
Bullet: Bullet{ Bullet: &BulletConfig{
StartupFrames: int32(3), StartupFrames: int32(3),
ActiveFrames: int32(10), ActiveFrames: int32(10),
HitStunFrames: int32(15), 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 MaxHp int32
CharacterState int32 CharacterState int32
InAir bool InAir bool
OnWall bool
OnWallNormX int32
OnWallNormY int32
ActiveSkillId int32 ActiveSkillId int32
ActiveSkillHit int32 ActiveSkillHit int32
FramesInvinsible 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 { type InputFrameDecoded struct {
@@ -56,10 +62,7 @@ type Barrier struct {
Boundary *Polygon2D Boundary *Polygon2D
} }
type Bullet struct { type BulletConfig 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" StartupFrames int32 // from "OriginatedRenderFrameId"
CancellableStFrame int32 // from "OriginatedRenderFrameId" CancellableStFrame int32 // from "OriginatedRenderFrameId"
CancellableEdFrame int32 // from "OriginatedRenderFrameId" CancellableEdFrame int32 // from "OriginatedRenderFrameId"
@@ -85,8 +88,18 @@ type Bullet struct {
CancelTransit map[int]int 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 { type MeleeBullet struct {
Bullet BattleAttr *BulletBattleAttr
Bullet *BulletConfig
} }
type FireballBullet struct { type FireballBullet struct {
@@ -97,7 +110,9 @@ type FireballBullet struct {
VelX int32 VelX int32
VelY int32 VelY int32
Speed int32 Speed int32
Bullet SpeciesId int32
BattleAttr *BulletBattleAttr
Bullet *BulletConfig
} }
type Skill struct { type Skill struct {
@@ -118,7 +133,8 @@ type RoomDownsyncFrame struct {
FireballBullets []*FireballBullet FireballBullets []*FireballBullet
BackendUnconfirmedMask uint64 BackendUnconfirmedMask uint64
ShouldForceResync bool ShouldForceResync bool
PlayerOpPatternToSkillId map[int]int
BulletLocalIdCounter int32
} }
type InputFrameDownsync struct { type InputFrameDownsync struct {
@@ -126,3 +142,10 @@ type InputFrameDownsync struct {
InputList []uint64 InputList []uint64
ConfirmedList 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,7 +42,7 @@ 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{ return js.MakeWrapper(&PlayerDownsync{
Id: id, Id: id,
VirtualGridX: virtualGridX, VirtualGridX: virtualGridX,
@@ -64,45 +64,39 @@ func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY,
MaxHp: maxHp, MaxHp: maxHp,
ColliderRadius: colliderRadius, ColliderRadius: colliderRadius,
InAir: inAir, 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 { 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(&MeleeBullet{ return js.MakeWrapper(NewMeleeBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY, blowUp, teamId))
Bullet: Bullet{ }
OriginatedRenderFrameId: originatedRenderFrameId,
OffenderJoinIndex: offenderJoinIndex,
StartupFrames: startupFrames, 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 {
CancellableStFrame: cancellableStFrame, 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))
CancellableEdFrame: cancellableEdFrame, }
ActiveFrames: activeFrames,
HitStunFrames: hitStunFrames, func NewNpcPatrolCue(flAct, frAct uint64, x, y float64) *js.Object {
BlockStunFrames: blockStunFrames, return js.MakeFullWrapper(&NpcPatrolCue{
PushbackVelX: pushbackVelX, FlAct: flAct,
PushbackVelY: pushbackVelY, FrAct: frAct,
Damage: damage, X: x,
Y: y,
SelfLockVelX: selfLockVelX,
SelfLockVelY: selfLockVelY,
HitboxOffsetX: hitboxOffsetX,
HitboxOffsetY: hitboxOffsetY,
HitboxSizeX: hitboxSizeX,
HitboxSizeY: hitboxSizeY,
BlowUp: blowUp,
},
}) })
} }
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". // [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{ return js.MakeFullWrapper(&RoomDownsyncFrame{
Id: id, Id: id,
PlayersArr: playersArr, PlayersArr: playersArr,
BulletLocalIdCounter: bulletLocalIdCounter,
MeleeBullets: meleeBullets, MeleeBullets: meleeBullets,
FireballBullets: fireballBullets,
}) })
} }
@@ -157,6 +151,8 @@ func main() {
"NewBarrierJs": NewBarrierJs, "NewBarrierJs": NewBarrierJs,
"NewPlayerDownsyncJs": NewPlayerDownsyncJs, "NewPlayerDownsyncJs": NewPlayerDownsyncJs,
"NewMeleeBulletJs": NewMeleeBulletJs, "NewMeleeBulletJs": NewMeleeBulletJs,
"NewFireballBulletJs": NewFireballBulletJs,
"NewNpcPatrolCue": NewNpcPatrolCue,
"NewRoomDownsyncFrameJs": NewRoomDownsyncFrameJs, "NewRoomDownsyncFrameJs": NewRoomDownsyncFrameJs,
"NewCollisionSpaceJs": NewCollisionSpaceJs, "NewCollisionSpaceJs": NewCollisionSpaceJs,
"NewInputFrameDownsync": NewInputFrameDownsync, "NewInputFrameDownsync": NewInputFrameDownsync,