diff --git a/battle_srv/models/pb_type_convert.go b/battle_srv/models/pb_type_convert.go
index cacfe48..b7ce3f0 100644
--- a/battle_srv/models/pb_type_convert.go
+++ b/battle_srv/models/pb_type_convert.go
@@ -10,12 +10,12 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
return nil
}
ret := &pb.RoomDownsyncFrame{
- Id: rdf.Id,
- PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)),
- MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)),
- CountdownNanos: rdf.CountdownNanos,
- BackendUnconfirmedMask: rdf.BackendUnconfirmedMask,
- ShouldForceResync: rdf.ShouldForceResync,
+ Id: rdf.Id,
+ PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)),
+ MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)),
+ CountdownNanos: rdf.CountdownNanos,
+ BackendUnconfirmedMask: rdf.BackendUnconfirmedMask,
+ ShouldForceResync: rdf.ShouldForceResync,
}
for i, last := range rdf.PlayersArr {
@@ -29,8 +29,8 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
- ActiveSkillId: last.ActiveSkillId,
- ActiveSkillHit: last.ActiveSkillHit,
+ ActiveSkillId: last.ActiveSkillId,
+ ActiveSkillHit: last.ActiveSkillHit,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
@@ -47,29 +47,29 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
for i, last := range rdf.MeleeBullets {
pbBullet := &pb.MeleeBullet{
- OriginatedRenderFrameId: last.OriginatedRenderFrameId,
- OffenderJoinIndex: last.OffenderJoinIndex,
+ OriginatedRenderFrameId: last.OriginatedRenderFrameId,
+ OffenderJoinIndex: last.OffenderJoinIndex,
- StartupFrames: last.StartupFrames,
- CancellableStFrame: last.CancellableStFrame,
- CancellableEdFrame: last.CancellableEdFrame,
- ActiveFrames: last.ActiveFrames,
+ StartupFrames: last.StartupFrames,
+ CancellableStFrame: last.CancellableStFrame,
+ CancellableEdFrame: last.CancellableEdFrame,
+ ActiveFrames: last.ActiveFrames,
- HitStunFrames: last.HitStunFrames,
- BlockStunFrames: last.BlockStunFrames,
- PushbackVelX: last.PushbackVelX,
- PushbackVelY: last.PushbackVelY,
- Damage: last.Damage,
+ HitStunFrames: last.HitStunFrames,
+ BlockStunFrames: last.BlockStunFrames,
+ PushbackVelX: last.PushbackVelX,
+ PushbackVelY: last.PushbackVelY,
+ Damage: last.Damage,
SelfLockVelX: last.SelfLockVelX,
SelfLockVelY: last.SelfLockVelY,
- HitboxOffsetX: last.HitboxOffsetX,
- HitboxOffsetY: last.HitboxOffsetY,
- HitboxSizeX: last.HitboxSizeX,
- HitboxSizeY: last.HitboxSizeY,
+ HitboxOffsetX: last.HitboxOffsetX,
+ HitboxOffsetY: last.HitboxOffsetY,
+ HitboxSizeX: last.HitboxSizeX,
+ HitboxSizeY: last.HitboxSizeY,
- BlowUp: last.BlowUp,
+ BlowUp: last.BlowUp,
}
ret.MeleeBullets[i] = pbBullet
}
@@ -77,7 +77,6 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
return ret
}
-/*
func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.PlayerDownsync {
toRet := make([]*pb.PlayerDownsync, len(modelInstances), len(modelInstances))
if nil == modelInstances {
@@ -93,6 +92,10 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
+ FramesToRecover: last.FramesToRecover,
+ FramesInChState: last.FramesInChState,
+ ActiveSkillId: last.ActiveSkillId,
+ ActiveSkillHit: last.ActiveSkillHit,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
@@ -101,8 +104,6 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
- FramesToRecover: last.FramesToRecover,
- FramesInChState: last.FramesInChState,
}
if withMetaInfo {
pbPlayer.Name = last.Name
@@ -114,7 +115,6 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
return toRet
}
-*/
func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
toRet := make([]*battle.PlayerDownsync, len(modelInstances), len(modelInstances))
@@ -124,27 +124,27 @@ func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
for _, last := range modelInstances {
toRet[last.JoinIndex-1] = &battle.PlayerDownsync{
- Id: last.Id,
- VirtualGridX: last.VirtualGridX,
- VirtualGridY: last.VirtualGridY,
- DirX: last.DirX,
- DirY: last.DirY,
- VelX: last.VelX,
- VelY: last.VelY,
- FramesToRecover: last.FramesToRecover,
- FramesInChState: last.FramesInChState,
- ActiveSkillId: last.ActiveSkillId,
- ActiveSkillHit: last.ActiveSkillHit,
- Speed: last.Speed,
- BattleState: last.BattleState,
- CharacterState: last.CharacterState,
- JoinIndex: last.JoinIndex,
- Hp: last.Hp,
- MaxHp: last.MaxHp,
- ColliderRadius: last.ColliderRadius,
- InAir: last.InAir,
- Score: last.Score,
- Removed: last.Removed,
+ Id: last.Id,
+ VirtualGridX: last.VirtualGridX,
+ VirtualGridY: last.VirtualGridY,
+ DirX: last.DirX,
+ DirY: last.DirY,
+ VelX: last.VelX,
+ VelY: last.VelY,
+ FramesToRecover: last.FramesToRecover,
+ FramesInChState: last.FramesInChState,
+ ActiveSkillId: last.ActiveSkillId,
+ ActiveSkillHit: last.ActiveSkillHit,
+ Speed: last.Speed,
+ BattleState: last.BattleState,
+ CharacterState: last.CharacterState,
+ JoinIndex: last.JoinIndex,
+ Hp: last.Hp,
+ MaxHp: last.MaxHp,
+ ColliderRadius: last.ColliderRadius,
+ InAir: last.InAir,
+ Score: last.Score,
+ Removed: last.Removed,
}
}
diff --git a/battle_srv/models/room.go b/battle_srv/models/room.go
index ec362cd..0cc7ac3 100644
--- a/battle_srv/models/room.go
+++ b/battle_srv/models/room.go
@@ -88,12 +88,16 @@ func calRoomScore(inRoomPlayerCount int32, roomPlayerCnt int, currentRoomBattleS
}
type Room struct {
- Id int32
- Capacity int
- Players map[int32]*Player
- PlayersArr []*Player // ordered by joinIndex
- Space *resolv.Space
- CollisionSysMap map[int32]*resolv.Object
+ Id int32
+ Capacity int
+ BattleDurationFrames int32
+ NstDelayFrames int32
+ Players map[int32]*Player
+ PlayersArr []*Player // ordered by joinIndex
+ SpeciesIdList []int32 // ordered by joinIndex
+ CharacterConfigsArr []*battle.CharacterConfig // ordered by joinIndex
+ Space *resolv.Space
+ CollisionSysMap map[int32]*resolv.Object
/**
* The following `PlayerDownsyncSessionDict` is NOT individually put
* under `type Player struct` for a reason.
@@ -135,7 +139,6 @@ type Room struct {
BackendDynamicsEnabled bool
ForceAllResyncOnAnyActiveSlowTicker bool
LastRenderFrameIdTriggeredAt int64
- PlayerDefaultSpeed int32
BulletBattleLocalIdCounter int32
dilutedRollbackEstimatedDtNanos int64
@@ -165,11 +168,12 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
}
defer pR.onPlayerAdded(playerId)
+
pPlayerFromDbInit.AckingFrameId = -1
pPlayerFromDbInit.AckingInputFrameId = -1
pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
- pPlayerFromDbInit.Speed = pR.PlayerDefaultSpeed // Hardcoded
+
pPlayerFromDbInit.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
pPlayerFromDbInit.InAir = true // Hardcoded
@@ -207,7 +211,7 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
pEffectiveInRoomPlayerInstance.AckingInputFrameId = -1
pEffectiveInRoomPlayerInstance.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED
pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
- pEffectiveInRoomPlayerInstance.Speed = pR.PlayerDefaultSpeed // Hardcoded
+
pEffectiveInRoomPlayerInstance.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
pEffectiveInRoomPlayerInstance.InAir = true // Hardcoded
@@ -286,8 +290,8 @@ func (pR *Room) ChooseStage() error {
//Logger.Info("parsed tmx:", zap.Any("stageDiscreteW", stageDiscreteW), zap.Any("strToVec2DListMap", strToVec2DListMap), zap.Any("strToPolygon2DListMap", strToPolygon2DListMap))
- pR.SpaceOffsetX = float64((stageDiscreteW*stageTileW) >> 1)
- pR.SpaceOffsetY = float64((stageDiscreteH*stageTileH) >> 1)
+ pR.SpaceOffsetX = float64((stageDiscreteW * stageTileW) >> 1)
+ pR.SpaceOffsetY = float64((stageDiscreteH * stageTileH) >> 1)
pR.TmxPointsMap = strToVec2DListMap
pR.TmxPolygonsMap = strToPolygon2DListMap
@@ -373,12 +377,20 @@ func (pR *Room) StartBattle() {
pR.RenderFrameId = 0
+ for _, player := range pR.Players {
+ speciesId := int(player.JoinIndex - 1) // FIXME: Hardcoded the values for now
+ chosenCh := battle.Characters[speciesId]
+ pR.CharacterConfigsArr[player.JoinIndex-1] = chosenCh
+ pR.SpeciesIdList[player.JoinIndex-1] = int32(speciesId)
+ }
+ Logger.Info("[StartBattle] ", zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State), zap.Any("SpeciesIdList", pR.SpeciesIdList))
+
// Initialize the "collisionSys" as well as "RenderFrameBuffer"
pR.CurDynamicsRenderFrameId = 0
kickoffFrameJs := &battle.RoomDownsyncFrame{
- Id: pR.RenderFrameId,
- PlayersArr: toJsPlayers(pR.Players),
- CountdownNanos: pR.BattleDurationNanos,
+ Id: pR.RenderFrameId,
+ PlayersArr: toJsPlayers(pR.Players),
+ CountdownNanos: pR.BattleDurationNanos,
}
pR.RenderFrameBuffer.Put(kickoffFrameJs)
@@ -446,7 +458,9 @@ func (pR *Room) StartBattle() {
continue
}
kickoffFrameJs := pR.RenderFrameBuffer.GetByFrameId(0).(*battle.RoomDownsyncFrame)
- pR.sendSafely(toPbRoomDownsyncFrame(kickoffFrameJs), nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true)
+ pbKickOffRenderFrame := toPbRoomDownsyncFrame(kickoffFrameJs)
+ pbKickOffRenderFrame.SpeciesIdList = pR.SpeciesIdList
+ pR.sendSafely(pbKickOffRenderFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true)
}
Logger.Info(fmt.Sprintf("In `battleMainLoop` for roomId=%v sent out kickoffFrame", pR.Id))
}
@@ -515,10 +529,6 @@ func (pR *Room) StartBattle() {
})
}
-func (pR *Room) toDiscreteInputsBufferIndex(inputFrameId int32, joinIndex int32) int32 {
- return (inputFrameId << 2) + joinIndex // allowing joinIndex upto 15
-}
-
func (pR *Room) OnBattleCmdReceived(pReq *pb.WsReq) {
/*
[WARNING] This function "OnBattleCmdReceived" could be called by different ws sessions and thus from different threads!
@@ -709,14 +719,11 @@ func (pR *Room) OnDismissed() {
// Always instantiates new HeapRAM blocks and let the old blocks die out due to not being retained by any root reference.
pR.BulletBattleLocalIdCounter = 0
- pR.WorldToVirtualGridRatio = battle.WORLD_TO_VIRTUAL_GRID_RATIO
- pR.VirtualGridToWorldRatio = float64(1.0) / pR.WorldToVirtualGridRatio // this is a one-off computation, should avoid division in iterations
- pR.SpAtkLookupFrames = 5
- pR.PlayerDefaultSpeed = int32(float64(1) * pR.WorldToVirtualGridRatio) // in virtual grids per frame
- pR.CollisionMinStep = (int32(float64(pR.PlayerDefaultSpeed)*pR.VirtualGridToWorldRatio) << 3) // the approx minimum distance a player can move per frame in world coordinate
- pR.playerOpPatternToSkillId = make(map[int]int)
+ pR.CollisionMinStep = 8 // the approx minimum distance a player can move per frame in world coordinate
pR.Players = make(map[int32]*Player)
pR.PlayersArr = make([]*Player, pR.Capacity)
+ pR.SpeciesIdList = make([]int32, pR.Capacity)
+ pR.CharacterConfigsArr = make([]*battle.CharacterConfig, pR.Capacity)
pR.CollisionSysMap = make(map[int32]*resolv.Object)
pR.PlayerDownsyncSessionDict = make(map[int32]*websocket.Conn)
for _, oldWatchdog := range pR.PlayerActiveWatchdogDict {
@@ -741,18 +748,17 @@ func (pR *Room) OnDismissed() {
pR.RenderFrameId = 0
pR.CurDynamicsRenderFrameId = 0
- pR.InputDelayFrames = 8
pR.NstDelayFrames = 16
- pR.InputScaleFrames = uint32(2)
- pR.ServerFps = 60
+
+ serverFps := 60
pR.RollbackEstimatedDtMillis = 16.667 // Use fixed-and-low-precision to mitigate the inconsistent floating-point-number issue between Golang and JavaScript
pR.RollbackEstimatedDtNanos = 16666666 // A little smaller than the actual per frame time, just for logging FAST FRAME
dilutedServerFps := float64(58.0) // Don't set this value too small, otherwise we might miss force confirmation needs for slow tickers!
- pR.dilutedRollbackEstimatedDtNanos = int64(float64(pR.RollbackEstimatedDtNanos) * float64(pR.ServerFps) / dilutedServerFps)
- pR.BattleDurationFrames = 60 * pR.ServerFps
+ pR.dilutedRollbackEstimatedDtNanos = int64(float64(pR.RollbackEstimatedDtNanos) * float64(serverFps) / dilutedServerFps)
+ pR.BattleDurationFrames = int32(60 * serverFps)
pR.BattleDurationNanos = int64(pR.BattleDurationFrames) * (pR.RollbackEstimatedDtNanos + 1)
- pR.InputFrameUpsyncDelayTolerance = (pR.NstDelayFrames >> pR.InputScaleFrames) - 1 // this value should be strictly smaller than (NstDelayFrames >> InputScaleFrames), otherwise "type#1 forceConfirmation" might become a lag avalanche
- pR.MaxChasingRenderFramesPerUpdate = 12 // Don't set this value too high to avoid exhausting frontend CPU within a single frame
+ pR.InputFrameUpsyncDelayTolerance = battle.ConvertToNoDelayInputFrameId(pR.NstDelayFrames) - 1 // this value should be strictly smaller than (NstDelayFrames >> InputScaleFrames), otherwise "type#1 forceConfirmation" might become a lag avalanche
+ pR.MaxChasingRenderFramesPerUpdate = 12 // Don't set this value too high to avoid exhausting frontend CPU within a single frame
pR.BackendDynamicsEnabled = true // [WARNING] When "false", recovery upon reconnection wouldn't work!
pR.ForceAllResyncOnAnyActiveSlowTicker = true // See tradeoff discussion in "downsyncToAllPlayers"
@@ -874,6 +880,10 @@ func (pR *Room) onPlayerAdded(playerId int32) {
pR.Players[playerId].JoinIndex = int32(index) + 1
pR.JoinIndexBooleanArr[index] = true
+ speciesId := index // FIXME
+ chosenCh := battle.Characters[speciesId]
+ pR.Players[playerId].Speed = chosenCh.Speed
+
// Lazily assign the initial position of "Player" for "RoomDownsyncFrame".
playerPosList := *pR.TmxPointsMap["PlayerStartingPos"]
if index > len(playerPosList) {
@@ -884,7 +894,7 @@ func (pR *Room) onPlayerAdded(playerId int32) {
if nil == playerPos {
panic(fmt.Sprintf("onPlayerAdded error, nil == playerPos, roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
}
- pR.Players[playerId].VirtualGridX, pR.Players[playerId].VirtualGridY = battle.WorldToVirtualGridPos(playerPos.X, playerPos.Y, pR.WorldToVirtualGridRatio)
+ pR.Players[playerId].VirtualGridX, pR.Players[playerId].VirtualGridY = battle.WorldToVirtualGridPos(playerPos.X, playerPos.Y)
// Hardcoded initial character orientation/facing
if 0 == (pR.Players[playerId].JoinIndex % 2) {
pR.Players[playerId].DirX = -2
@@ -1121,7 +1131,7 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
*/
snapshotStFrameId := (pR.LastAllConfirmedInputFrameId - newAllConfirmedCount)
refRenderFrameIdIfNeeded := pR.CurDynamicsRenderFrameId - 1
- refSnapshotStFrameId := battle.ConvertToInputFrameId(refRenderFrameIdIfNeeded, battle.INPUT_DELAY_FRAMES, battle.INPUT_SCALE_FRAMES)
+ refSnapshotStFrameId := battle.ConvertToDelayedInputFrameId(refRenderFrameIdIfNeeded)
if refSnapshotStFrameId < snapshotStFrameId {
snapshotStFrameId = refSnapshotStFrameId
}
@@ -1137,7 +1147,7 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) uint64 {
totPlayerCnt := uint32(pR.Capacity)
allConfirmedMask := uint64((1 << totPlayerCnt) - 1)
unconfirmedMask := uint64(0)
- if pR.LatestPlayerUpsyncedInputFrameId > (pR.LastAllConfirmedInputFrameId + (pR.NstDelayFrames >> pR.InputScaleFrames)) {
+ if pR.LatestPlayerUpsyncedInputFrameId > (pR.LastAllConfirmedInputFrameId + pR.InputFrameUpsyncDelayTolerance + 1) {
// Type#1 check whether there's a significantly slow ticker among players
oldLastAllConfirmedInputFrameId := pR.LastAllConfirmedInputFrameId
for j := pR.LastAllConfirmedInputFrameId + 1; j <= pR.LatestPlayerUpsyncedInputFrameId; j++ {
@@ -1151,7 +1161,7 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) uint64 {
pR.onInputFrameDownsyncAllConfirmed(inputFrameDownsync, -1)
}
if 0 < unconfirmedMask {
- Logger.Info(fmt.Sprintf("[type#1 forceConfirmation] For roomId=%d@renderFrameId=%d, curDynamicsRenderFrameId=%d, LatestPlayerUpsyncedInputFrameId:%d, oldLastAllConfirmedInputFrameId:%d, newLastAllConfirmedInputFrameId:%d, (pR.NstDelayFrames >> pR.InputScaleFrames):%d, InputFrameUpsyncDelayTolerance:%d, unconfirmedMask=%d; there's a slow ticker suspect, forcing all-confirmation", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LatestPlayerUpsyncedInputFrameId, oldLastAllConfirmedInputFrameId, pR.LastAllConfirmedInputFrameId, (pR.NstDelayFrames >> pR.InputScaleFrames), pR.InputFrameUpsyncDelayTolerance, unconfirmedMask))
+ Logger.Info(fmt.Sprintf("[type#1 forceConfirmation] For roomId=%d@renderFrameId=%d, curDynamicsRenderFrameId=%d, LatestPlayerUpsyncedInputFrameId:%d, oldLastAllConfirmedInputFrameId:%d, newLastAllConfirmedInputFrameId:%d, InputFrameUpsyncDelayTolerance:%d, unconfirmedMask=%d; there's a slow ticker suspect, forcing all-confirmation", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LatestPlayerUpsyncedInputFrameId, oldLastAllConfirmedInputFrameId, pR.LastAllConfirmedInputFrameId, pR.InputFrameUpsyncDelayTolerance, unconfirmedMask))
}
} else {
// Type#2 helps resolve the edge case when all players are disconnected temporarily
@@ -1226,7 +1236,7 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
}
}
- nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(pR.InputsBuffer, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.SpaceOffsetX, pR.SpaceOffsetY)
+ nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(pR.InputsBuffer, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.SpaceOffsetX, pR.SpaceOffsetY, pR.CharacterConfigsArr)
pR.RenderFrameBuffer.Put(nextRenderFrame)
pR.CurDynamicsRenderFrameId++
}
@@ -1248,7 +1258,7 @@ func (pR *Room) refreshColliders() {
// For debug-printing only.
Logger.Info("ChooseStage printing polygon2D for barrierPolygon2DList", zap.Any("barrierLocalIdInBattle", barrierLocalIdInBattle), zap.Any("polygon2D.Anchor", polygon2D.Anchor), zap.Any("polygon2D.Points", polygon2D.Points))
*/
- barrierCollider := battle.GenerateConvexPolygonCollider(polygon2DUnaligned, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, nil, "Barrier")
+ barrierCollider := battle.GenerateConvexPolygonCollider(polygon2DUnaligned, pR.SpaceOffsetX, pR.SpaceOffsetY, nil, "Barrier")
pR.Space.Add(barrierCollider)
}
}
@@ -1280,7 +1290,7 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
dynamicsStartedAt := utils.UnixtimeNano()
// Apply "all-confirmed inputFrames" to move forward "pR.CurDynamicsRenderFrameId"
nextDynamicsRenderFrameId := battle.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId) + 1
- Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, LastAllConfirmedInputFrameId=%v, InputDelayFrames=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames, nextDynamicsRenderFrameId))
+ Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, LastAllConfirmedInputFrameId=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, nextDynamicsRenderFrameId))
pR.applyInputFrameDownsyncDynamics(pR.CurDynamicsRenderFrameId, nextDynamicsRenderFrameId)
*pDynamicsDuration = utils.UnixtimeNano() - dynamicsStartedAt
}
@@ -1298,7 +1308,7 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
if 0 < unconfirmedMask {
// [WARNING] As "pR.CurDynamicsRenderFrameId" was just incremented above, "refSnapshotStFrameId" is most possibly larger than "oldLastAllConfirmedInputFrameId + 1", therefore this initial assignment is critical for `ACTIVE NORMAL TICKER`s to receive consecutive ids of inputFrameDownsync.
snapshotStFrameId := oldLastAllConfirmedInputFrameId + 1
- refSnapshotStFrameId := battle.ConvertToDelayedInputFrameId(pR.CurDynamicsRenderFrameId-1)
+ refSnapshotStFrameId := battle.ConvertToDelayedInputFrameId(pR.CurDynamicsRenderFrameId - 1)
if refSnapshotStFrameId < snapshotStFrameId {
snapshotStFrameId = refSnapshotStFrameId
}
@@ -1410,14 +1420,13 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
}
refRenderFrame := tmp.(*battle.RoomDownsyncFrame)
- for i, player := range pR.PlayersArr {
- refRenderFrame.PlayersArr[i].ColliderRadius = player.ColliderRadius // hardcoded for now
- }
if shouldResync3 {
refRenderFrame.ShouldForceResync = true
}
refRenderFrame.BackendUnconfirmedMask = unconfirmedMask
- pR.sendSafely(toPbRoomDownsyncFrame(refRenderFrame), toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false)
+ pbRefRenderFrame := toPbRoomDownsyncFrame(refRenderFrame)
+ pbRefRenderFrame.SpeciesIdList = pR.SpeciesIdList
+ pR.sendSafely(pbRefRenderFrame, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false)
//Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: InputsBuffer=%v", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, pR.InputsBufferString(false)))
if shouldResync1 {
Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: shouldResync1=%v, shouldResync2=%v, shouldResync3=%v, playerBattleState=%d", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, shouldResync1, shouldResync2, shouldResync3, playerBattleState))
diff --git a/battle_srv/protos/room_downsync_frame.pb.go b/battle_srv/protos/room_downsync_frame.pb.go
index 9f5f3f5..a93f289 100644
--- a/battle_srv/protos/room_downsync_frame.pb.go
+++ b/battle_srv/protos/room_downsync_frame.pb.go
@@ -1103,6 +1103,7 @@ type RoomDownsyncFrame struct {
MeleeBullets []*MeleeBullet `protobuf:"bytes,4,rep,name=meleeBullets,proto3" json:"meleeBullets,omitempty"` // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise
BackendUnconfirmedMask uint64 `protobuf:"varint,5,opt,name=backendUnconfirmedMask,proto3" json:"backendUnconfirmedMask,omitempty"` // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
ShouldForceResync bool `protobuf:"varint,6,opt,name=shouldForceResync,proto3" json:"shouldForceResync,omitempty"`
+ SpeciesIdList []int32 `protobuf:"varint,7,rep,packed,name=speciesIdList,proto3" json:"speciesIdList,omitempty"`
}
func (x *RoomDownsyncFrame) Reset() {
@@ -1179,6 +1180,13 @@ func (x *RoomDownsyncFrame) GetShouldForceResync() bool {
return false
}
+func (x *RoomDownsyncFrame) GetSpeciesIdList() []int32 {
+ if x != nil {
+ return x.SpeciesIdList
+ }
+ return nil
+}
+
var File_room_downsync_frame_proto protoreflect.FileDescriptor
var file_room_downsync_frame_proto_rawDesc = []byte{
@@ -1396,7 +1404,7 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
0x12, 0x39, 0x0a, 0x17, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67,
0x67, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0xe7, 0x07, 0x20, 0x01,
0x28, 0x08, 0x52, 0x17, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x6f, 0x67,
- 0x67, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xa2, 0x02, 0x0a, 0x11,
+ 0x67, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xc8, 0x02, 0x0a, 0x11,
0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69,
0x64, 0x12, 0x36, 0x0a, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 0x18,
@@ -1415,8 +1423,11 @@ var file_room_downsync_frame_proto_rawDesc = []byte{
0x73, 0x6b, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63,
0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73,
0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63,
- 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,
+ 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73, 0x49, 0x64, 0x4c, 0x69, 0x73,
+ 0x74, 0x18, 0x07, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x70, 0x65, 0x63, 0x69, 0x65, 0x73,
+ 0x49, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65,
+ 0x5f, 0x73, 0x72, 0x76, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x33,
}
var (
diff --git a/battle_srv/ws/serve.go b/battle_srv/ws/serve.go
index 1c5c03f..f1db6d8 100644
--- a/battle_srv/ws/serve.go
+++ b/battle_srv/ws/serve.go
@@ -240,24 +240,23 @@ func Serve(c *gin.Context) {
// Construct "battleColliderInfo" to downsync
bciFrame := &pb.BattleColliderInfo{
- BoundRoomId: pRoom.Id,
- StageName: pRoom.StageName,
+ BoundRoomId: pRoom.Id,
+ StageName: pRoom.StageName,
- IntervalToPing: int32(Constants.Ws.IntervalToPing),
- WillKickIfInactiveFor: int32(Constants.Ws.WillKickIfInactiveFor),
- BattleDurationNanos: pRoom.BattleDurationNanos,
+ IntervalToPing: int32(Constants.Ws.IntervalToPing),
+ WillKickIfInactiveFor: int32(Constants.Ws.WillKickIfInactiveFor),
+ BattleDurationNanos: pRoom.BattleDurationNanos,
InputFrameUpsyncDelayTolerance: pRoom.InputFrameUpsyncDelayTolerance,
MaxChasingRenderFramesPerUpdate: pRoom.MaxChasingRenderFramesPerUpdate,
- PlayerBattleState: pThePlayer.BattleState, // For frontend to know whether it's rejoining
RollbackEstimatedDtMillis: pRoom.RollbackEstimatedDtMillis,
RollbackEstimatedDtNanos: pRoom.RollbackEstimatedDtNanos,
- InputDelayFrames: pRoom.InputDelayFrames,
- InputScaleFrames: pRoom.InputScaleFrames,
+ SpaceOffsetX: pRoom.SpaceOffsetX,
+ SpaceOffsetY: pRoom.SpaceOffsetY,
- RenderCacheSize: pRoom.RenderCacheSize,
- CollisionMinStep: pRoom.CollisionMinStep,
+ RenderCacheSize: pRoom.RenderCacheSize,
+ CollisionMinStep: pRoom.CollisionMinStep,
FrameDataLoggingEnabled: pRoom.FrameDataLoggingEnabled,
}
diff --git a/frontend/assets/plugin_scripts/jsexport.js b/frontend/assets/plugin_scripts/jsexport.js
index c0aab2b..2c5ffa7 100644
--- a/frontend/assets/plugin_scripts/jsexport.js
+++ b/frontend/assets/plugin_scripts/jsexport.js
@@ -4968,7 +4968,7 @@ $packages["jsexport/battle"] = (function() {
this.Eles = Eles_;
});
SkillMapperType = $pkg.SkillMapperType = $newType(4, $kindFunc, "battle.SkillMapperType", true, "jsexport/battle", true, null);
- CharacterConfig = $pkg.CharacterConfig = $newType(0, $kindStruct, "battle.CharacterConfig", true, "jsexport/battle", true, function(SpeciesId_, SpeciesName_, InAirIdleFrameIdxTurningPoint_, InAirIdleFrameIdxTurnedCycle_, LayDownFrames_, LayDownFramesToRecover_, GetUpFrames_, GetUpFramesToRecover_, JumpingInitVelY_, SkillMapper_) {
+ CharacterConfig = $pkg.CharacterConfig = $newType(0, $kindStruct, "battle.CharacterConfig", true, "jsexport/battle", true, function(SpeciesId_, SpeciesName_, InAirIdleFrameIdxTurningPoint_, InAirIdleFrameIdxTurnedCycle_, LayDownFrames_, LayDownFramesToRecover_, GetUpFrames_, GetUpFramesToRecover_, Speed_, JumpingInitVelY_, SkillMapper_) {
this.$val = this;
if (arguments.length === 0) {
this.SpeciesId = 0;
@@ -4979,6 +4979,7 @@ $packages["jsexport/battle"] = (function() {
this.LayDownFramesToRecover = 0;
this.GetUpFrames = 0;
this.GetUpFramesToRecover = 0;
+ this.Speed = 0;
this.JumpingInitVelY = 0;
this.SkillMapper = $throwNilPointerError;
return;
@@ -4991,6 +4992,7 @@ $packages["jsexport/battle"] = (function() {
this.LayDownFramesToRecover = LayDownFramesToRecover_;
this.GetUpFrames = GetUpFrames_;
this.GetUpFramesToRecover = GetUpFramesToRecover_;
+ this.Speed = Speed_;
this.JumpingInitVelY = JumpingInitVelY_;
this.SkillMapper = SkillMapper_;
});
@@ -6006,7 +6008,7 @@ $packages["jsexport/battle"] = (function() {
InputFrameDownsync.init("", [{prop: "InputFrameId", name: "InputFrameId", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "InputList", name: "InputList", embedded: false, exported: true, typ: sliceType$5, tag: ""}, {prop: "ConfirmedList", name: "ConfirmedList", embedded: false, exported: true, typ: $Uint64, tag: ""}]);
RingBuffer.init("", [{prop: "Ed", name: "Ed", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "St", name: "St", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "EdFrameId", name: "EdFrameId", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "StFrameId", name: "StFrameId", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "N", name: "N", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "Cnt", name: "Cnt", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "Eles", name: "Eles", embedded: false, exported: true, typ: sliceType$2, tag: ""}]);
SkillMapperType.init([$Int, ptrType$5], [$Int], false);
- CharacterConfig.init("", [{prop: "SpeciesId", name: "SpeciesId", embedded: false, exported: true, typ: $Int, tag: ""}, {prop: "SpeciesName", name: "SpeciesName", embedded: false, exported: true, typ: $String, tag: ""}, {prop: "InAirIdleFrameIdxTurningPoint", name: "InAirIdleFrameIdxTurningPoint", embedded: false, exported: true, typ: $Int, tag: ""}, {prop: "InAirIdleFrameIdxTurnedCycle", name: "InAirIdleFrameIdxTurnedCycle", embedded: false, exported: true, typ: $Int, tag: ""}, {prop: "LayDownFrames", name: "LayDownFrames", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "LayDownFramesToRecover", name: "LayDownFramesToRecover", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "GetUpFrames", name: "GetUpFrames", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "GetUpFramesToRecover", name: "GetUpFramesToRecover", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "JumpingInitVelY", name: "JumpingInitVelY", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "SkillMapper", name: "SkillMapper", embedded: false, exported: true, typ: SkillMapperType, tag: ""}]);
+ CharacterConfig.init("", [{prop: "SpeciesId", name: "SpeciesId", embedded: false, exported: true, typ: $Int, tag: ""}, {prop: "SpeciesName", name: "SpeciesName", embedded: false, exported: true, typ: $String, tag: ""}, {prop: "InAirIdleFrameIdxTurningPoint", name: "InAirIdleFrameIdxTurningPoint", embedded: false, exported: true, typ: $Int, tag: ""}, {prop: "InAirIdleFrameIdxTurnedCycle", name: "InAirIdleFrameIdxTurnedCycle", embedded: false, exported: true, typ: $Int, tag: ""}, {prop: "LayDownFrames", name: "LayDownFrames", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "LayDownFramesToRecover", name: "LayDownFramesToRecover", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "GetUpFrames", name: "GetUpFrames", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "GetUpFramesToRecover", name: "GetUpFramesToRecover", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "Speed", name: "Speed", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "JumpingInitVelY", name: "JumpingInitVelY", embedded: false, exported: true, typ: $Int32, tag: ""}, {prop: "SkillMapper", name: "SkillMapper", embedded: false, exported: true, typ: SkillMapperType, tag: ""}]);
SatResult.init("", [{prop: "Overlap", name: "Overlap", embedded: false, exported: true, typ: $Float64, tag: ""}, {prop: "OverlapX", name: "OverlapX", embedded: false, exported: true, typ: $Float64, tag: ""}, {prop: "OverlapY", name: "OverlapY", embedded: false, exported: true, typ: $Float64, tag: ""}, {prop: "AContainedInB", name: "AContainedInB", embedded: false, exported: true, typ: $Bool, tag: ""}, {prop: "BContainedInA", name: "BContainedInA", embedded: false, exported: true, typ: $Bool, tag: ""}, {prop: "Axis", name: "Axis", embedded: false, exported: true, typ: resolv.Vector, tag: ""}]);
$init = function() {
$pkg.$init = function() {};
@@ -6015,7 +6017,7 @@ $packages["jsexport/battle"] = (function() {
$r = resolv.$init(); /* */ $s = 2; case 2: if($c) { $c = false; $r = $r.$blk(); } if ($r && $r.$blk !== undefined) { break s; }
$pkg.DIRECTION_DECODER = new sliceType$1([new sliceType([0, 0]), new sliceType([0, 2]), new sliceType([0, -2]), new sliceType([2, 0]), new sliceType([-2, 0]), new sliceType([1, 1]), new sliceType([-1, -1]), new sliceType([1, -1]), new sliceType([-1, 1])]);
skills = $makeMap($Int.keyFor, [{ k: 1, v: new Skill.ptr(0, 30, 30, 30, 1, 2, new sliceType$2([new MeleeBullet.ptr(new Bullet.ptr(0, 0, 7, 13, 30, 22, 13, 9, 50, 0, 5, 0, 0, 1200, 0, 2400, 3200, false, $makeMap($Int.keyFor, [{ k: 1, v: 2 }])))])) }, { k: 2, v: new Skill.ptr(0, 36, 36, 36, 1, 11, new sliceType$2([new MeleeBullet.ptr(new Bullet.ptr(0, 0, 18, 22, 36, 18, 18, 9, 50, 0, 5, 0, 0, 1800, 0, 2400, 3200, false, $makeMap($Int.keyFor, [{ k: 1, v: 3 }])))])) }, { k: 3, v: new Skill.ptr(0, 60, 60, 60, 1, 12, new sliceType$2([new MeleeBullet.ptr(new Bullet.ptr(0, 0, 15, 0, 0, 40, 999999999, 9, 200, 700, 10, 0, 0, 2400, 0, 3200, 3200, true, false))])) }, { k: 4, v: new Skill.ptr(0, 30, 30, 30, 1, 2, new sliceType$2([new MeleeBullet.ptr(new Bullet.ptr(0, 0, 7, 13, 30, 22, 13, 9, 50, 0, 5, 0, 0, 1200, 0, 2400, 3200, false, $makeMap($Int.keyFor, [{ k: 1, v: 5 }])))])) }, { k: 5, v: new Skill.ptr(0, 36, 36, 36, 1, 11, new sliceType$2([new MeleeBullet.ptr(new Bullet.ptr(0, 0, 18, 22, 36, 18, 18, 9, 50, 0, 5, 0, 0, 1800, 0, 2400, 3200, false, $makeMap($Int.keyFor, [{ k: 1, v: 6 }])))])) }, { k: 6, v: new Skill.ptr(0, 60, 60, 60, 1, 12, new sliceType$2([new MeleeBullet.ptr(new Bullet.ptr(0, 0, 15, 0, 0, 40, 999999999, 9, 200, 700, 10, 0, 0, 2400, 0, 3200, 3200, true, false))])) }, { k: 255, v: new Skill.ptr(0, 34, 34, 34, 1, 6, new sliceType$2([new MeleeBullet.ptr(new Bullet.ptr(0, 0, 3, 0, 0, 20, 18, 9, 50, 0, 5, 0, 0, 1200, 0, 3200, 2400, false, false))])) }, { k: 256, v: new Skill.ptr(0, 34, 34, 34, 1, 6, new sliceType$2([new MeleeBullet.ptr(new Bullet.ptr(0, 0, 3, 0, 0, 20, 18, 9, 50, 0, 5, 0, 0, 1200, 0, 3200, 2400, false, false))])) }]);
- $pkg.Characters = $makeMap($Int.keyFor, [{ k: 0, v: new CharacterConfig.ptr(0, "MonkGirl", 11, 1, 16, 16, 33, 30, 800, (function(patternId, currPlayerDownsync) {
+ $pkg.Characters = $makeMap($Int.keyFor, [{ k: 0, v: new CharacterConfig.ptr(0, "MonkGirl", 11, 1, 16, 16, 33, 30, 120, 800, (function(patternId, currPlayerDownsync) {
var _entry, _entry$1, _ref, _tuple, _tuple$1, currPlayerDownsync, existent1, existent2, nextSkillId, patternId, skillConfig, v, x, x$1;
if (1 === patternId) {
if (0 === currPlayerDownsync.FramesToRecover) {
@@ -6045,7 +6047,7 @@ $packages["jsexport/battle"] = (function() {
}
}
return -1;
- })) }, { k: 1, v: new CharacterConfig.ptr(1, "KnifeGirl", 9, 1, 16, 16, 30, 27, 750, (function(patternId, currPlayerDownsync) {
+ })) }, { k: 1, v: new CharacterConfig.ptr(1, "KnifeGirl", 9, 1, 16, 16, 30, 27, 140, 750, (function(patternId, currPlayerDownsync) {
var _entry, _entry$1, _ref, _tuple, _tuple$1, currPlayerDownsync, existent1, existent2, nextSkillId, patternId, skillConfig, v, x, x$1;
if (1 === patternId) {
if (0 === currPlayerDownsync.FramesToRecover) {
diff --git a/frontend/assets/resources/map/dungeon/map.tmx b/frontend/assets/resources/map/dungeon/map.tmx
index 6e24f2a..3639788 100644
--- a/frontend/assets/resources/map/dungeon/map.tmx
+++ b/frontend/assets/resources/map/dungeon/map.tmx
@@ -9,10 +9,10 @@
-
diff --git a/frontend/assets/resources/pbfiles/room_downsync_frame.proto b/frontend/assets/resources/pbfiles/room_downsync_frame.proto
index b22bc48..7551b66 100644
--- a/frontend/assets/resources/pbfiles/room_downsync_frame.proto
+++ b/frontend/assets/resources/pbfiles/room_downsync_frame.proto
@@ -139,4 +139,5 @@ message RoomDownsyncFrame {
repeated MeleeBullet meleeBullets = 4; // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise
uint64 backendUnconfirmedMask = 5; // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync
bool shouldForceResync = 6;
+ repeated int32 speciesIdList = 7;
}
diff --git a/frontend/assets/scenes/login.fire b/frontend/assets/scenes/login.fire
index d408e2a..903c81d 100644
--- a/frontend/assets/scenes/login.fire
+++ b/frontend/assets/scenes/login.fire
@@ -440,7 +440,7 @@
"array": [
0,
0,
- 216.50135522089343,
+ 216.79917701871616,
0,
0,
0,
diff --git a/frontend/assets/scenes/offline_map.fire b/frontend/assets/scenes/offline_map.fire
index de9f2b1..33d98c7 100644
--- a/frontend/assets/scenes/offline_map.fire
+++ b/frontend/assets/scenes/offline_map.fire
@@ -461,7 +461,7 @@
"array": [
0,
0,
- 210.4441731196186,
+ 209.83528025849938,
0,
0,
0,
diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js
index 3d29d8f..63a8d52 100644
--- a/frontend/assets/scripts/Map.js
+++ b/frontend/assets/scripts/Map.js
@@ -279,7 +279,7 @@ cc.Class({
self.collisionPlayerIndexPrefix = (1 << 17); // For tracking the movements of players
if (null != self.playerRichInfoDict) {
self.playerRichInfoDict.forEach((playerRichInfo, playerId) => {
- if (playerRichInfo.node.parent) {
+ if (playerRichInfo.node && playerRichInfo.node.parent) {
playerRichInfo.node.parent.removeChild(playerRichInfo.node);
}
});
diff --git a/frontend/assets/scripts/modules/room_downsync_frame_proto_bundle.forcemsg.js b/frontend/assets/scripts/modules/room_downsync_frame_proto_bundle.forcemsg.js
index ee15c16..3546a90 100644
--- a/frontend/assets/scripts/modules/room_downsync_frame_proto_bundle.forcemsg.js
+++ b/frontend/assets/scripts/modules/room_downsync_frame_proto_bundle.forcemsg.js
@@ -5161,6 +5161,7 @@ $root.protos = (function() {
* @property {Array.|null} [meleeBullets] RoomDownsyncFrame meleeBullets
* @property {number|Long|null} [backendUnconfirmedMask] RoomDownsyncFrame backendUnconfirmedMask
* @property {boolean|null} [shouldForceResync] RoomDownsyncFrame shouldForceResync
+ * @property {Array.|null} [speciesIdList] RoomDownsyncFrame speciesIdList
*/
/**
@@ -5174,6 +5175,7 @@ $root.protos = (function() {
function RoomDownsyncFrame(properties) {
this.playersArr = [];
this.meleeBullets = [];
+ this.speciesIdList = [];
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
@@ -5228,6 +5230,14 @@ $root.protos = (function() {
*/
RoomDownsyncFrame.prototype.shouldForceResync = false;
+ /**
+ * RoomDownsyncFrame speciesIdList.
+ * @member {Array.} speciesIdList
+ * @memberof protos.RoomDownsyncFrame
+ * @instance
+ */
+ RoomDownsyncFrame.prototype.speciesIdList = $util.emptyArray;
+
/**
* Creates a new RoomDownsyncFrame instance using the specified properties.
* @function create
@@ -5266,6 +5276,12 @@ $root.protos = (function() {
writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.backendUnconfirmedMask);
if (message.shouldForceResync != null && Object.hasOwnProperty.call(message, "shouldForceResync"))
writer.uint32(/* id 6, wireType 0 =*/48).bool(message.shouldForceResync);
+ if (message.speciesIdList != null && message.speciesIdList.length) {
+ writer.uint32(/* id 7, wireType 2 =*/58).fork();
+ for (var i = 0; i < message.speciesIdList.length; ++i)
+ writer.int32(message.speciesIdList[i]);
+ writer.ldelim();
+ }
return writer;
};
@@ -5328,6 +5344,17 @@ $root.protos = (function() {
message.shouldForceResync = reader.bool();
break;
}
+ case 7: {
+ if (!(message.speciesIdList && message.speciesIdList.length))
+ message.speciesIdList = [];
+ if ((tag & 7) === 2) {
+ var end2 = reader.uint32() + reader.pos;
+ while (reader.pos < end2)
+ message.speciesIdList.push(reader.int32());
+ } else
+ message.speciesIdList.push(reader.int32());
+ break;
+ }
default:
reader.skipType(tag & 7);
break;
@@ -5393,6 +5420,13 @@ $root.protos = (function() {
if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync"))
if (typeof message.shouldForceResync !== "boolean")
return "shouldForceResync: boolean expected";
+ if (message.speciesIdList != null && message.hasOwnProperty("speciesIdList")) {
+ if (!Array.isArray(message.speciesIdList))
+ return "speciesIdList: array expected";
+ for (var i = 0; i < message.speciesIdList.length; ++i)
+ if (!$util.isInteger(message.speciesIdList[i]))
+ return "speciesIdList: integer[] expected";
+ }
return null;
};
@@ -5450,6 +5484,13 @@ $root.protos = (function() {
message.backendUnconfirmedMask = new $util.LongBits(object.backendUnconfirmedMask.low >>> 0, object.backendUnconfirmedMask.high >>> 0).toNumber(true);
if (object.shouldForceResync != null)
message.shouldForceResync = Boolean(object.shouldForceResync);
+ if (object.speciesIdList) {
+ if (!Array.isArray(object.speciesIdList))
+ throw TypeError(".protos.RoomDownsyncFrame.speciesIdList: array expected");
+ message.speciesIdList = [];
+ for (var i = 0; i < object.speciesIdList.length; ++i)
+ message.speciesIdList[i] = object.speciesIdList[i] | 0;
+ }
return message;
};
@@ -5469,6 +5510,7 @@ $root.protos = (function() {
if (options.arrays || options.defaults) {
object.playersArr = [];
object.meleeBullets = [];
+ object.speciesIdList = [];
}
if (options.defaults) {
object.id = 0;
@@ -5508,6 +5550,11 @@ $root.protos = (function() {
object.backendUnconfirmedMask = options.longs === String ? $util.Long.prototype.toString.call(message.backendUnconfirmedMask) : options.longs === Number ? new $util.LongBits(message.backendUnconfirmedMask.low >>> 0, message.backendUnconfirmedMask.high >>> 0).toNumber(true) : message.backendUnconfirmedMask;
if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync"))
object.shouldForceResync = message.shouldForceResync;
+ if (message.speciesIdList && message.speciesIdList.length) {
+ object.speciesIdList = [];
+ for (var j = 0; j < message.speciesIdList.length; ++j)
+ object.speciesIdList[j] = message.speciesIdList[j];
+ }
return object;
};
diff --git a/jsexport/battle/battle.go b/jsexport/battle/battle.go
index 0385853..34e2ad0 100644
--- a/jsexport/battle/battle.go
+++ b/jsexport/battle/battle.go
@@ -25,6 +25,8 @@ const (
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"
+ SP_ATK_LOOKUP_FRAMES = int32(5)
+
SNAP_INTO_PLATFORM_OVERLAP = float64(0.1)
SNAP_INTO_PLATFORM_THRESHOLD = float64(0.5)
@@ -96,7 +98,7 @@ func ShouldPrefabInputFrameDownsync(prevRenderFrameId int32, renderFrameId int32
}
func ShouldGenerateInputFrameUpsync(renderFrameId int32) bool {
- return ((renderFrameId & ((1 << INPUT_SCALE_FRAMES) - 1)) == 0)
+ return ((renderFrameId & ((1 << INPUT_SCALE_FRAMES) - 1)) == 0)
}
func ConvertToDelayedInputFrameId(renderFrameId int32) int32 {
@@ -371,7 +373,7 @@ func calcHardPushbacksNorms(joinIndex int32, playerCollider *resolv.Object, play
func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync, currRenderFrame *RoomDownsyncFrame, inputsBuffer *RingBuffer) (int, bool, int32, int32) {
// returns (patternId, jumpedOrNot, effectiveDx, effectiveDy)
delayedInputFrameId := ConvertToDelayedInputFrameId(currRenderFrame.Id)
- delayedInputFrameIdForPrevRdf := ConvertToDelayedInputFrameId(currRenderFrame.Id-1)
+ delayedInputFrameIdForPrevRdf := ConvertToDelayedInputFrameId(currRenderFrame.Id - 1)
if 0 >= delayedInputFrameId {
return PATTERN_ID_UNABLE_TO_OP, false, 0, 0
diff --git a/jsexport/battle/characterConfig.go b/jsexport/battle/characterConfig.go
index 165882a..8e8feaa 100644
--- a/jsexport/battle/characterConfig.go
+++ b/jsexport/battle/characterConfig.go
@@ -15,6 +15,7 @@ type CharacterConfig struct {
GetUpFrames int32
GetUpFramesToRecover int32
+ Speed int32
JumpingInitVelY int32
SkillMapper SkillMapperType
@@ -34,6 +35,7 @@ var Characters = map[int]*CharacterConfig{
GetUpFrames: int32(33),
GetUpFramesToRecover: int32(30), // 3 invinsible frames for just-blown-up character to make a comeback
+ Speed: int32(float64(1.2) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
SkillMapper: func(patternId int, currPlayerDownsync *PlayerDownsync) int {
@@ -76,6 +78,7 @@ var Characters = map[int]*CharacterConfig{
GetUpFrames: int32(30),
GetUpFramesToRecover: int32(27), // 3 invinsible frames for just-blown-up character to make a comeback
+ Speed: int32(float64(1.4) * WORLD_TO_VIRTUAL_GRID_RATIO),
JumpingInitVelY: int32(float64(7.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
SkillMapper: func(patternId int, currPlayerDownsync *PlayerDownsync) int {
diff --git a/jsexport/main.go b/jsexport/main.go
index 6286ea6..275f902 100644
--- a/jsexport/main.go
+++ b/jsexport/main.go
@@ -53,8 +53,8 @@ func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY,
VelY: velY,
FramesToRecover: framesToRecover,
FramesInChState: framesInChState,
- ActiveSkillId: activeSkillId,
- ActiveSkillHit: activeSkillHit,
+ ActiveSkillId: activeSkillId,
+ ActiveSkillHit: activeSkillHit,
Speed: speed,
BattleState: battleState,
CharacterState: characterState,
@@ -169,10 +169,10 @@ func main() {
"VirtualGridToWorldPos": VirtualGridToWorldPos,
"GetCharacterConfigsOrderedByJoinIndex": GetCharacterConfigsOrderedByJoinIndex,
"ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs": ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs,
- "ConvertToDelayedInputFrameId": ConvertToDelayedInputFrameId,
- "ConvertToNoDelayInputFrameId": ConvertToNoDelayInputFrameId,
- "ConvertToFirstUsedRenderFrameId": ConvertToFirstUsedRenderFrameId,
- "ConvertToLastUsedRenderFrameId": ConvertToLastUsedRenderFrameId,
- "ShouldGenerateInputFrameUpsync": ShouldGenerateInputFrameUpsync,
+ "ConvertToDelayedInputFrameId": ConvertToDelayedInputFrameId,
+ "ConvertToNoDelayInputFrameId": ConvertToNoDelayInputFrameId,
+ "ConvertToFirstUsedRenderFrameId": ConvertToFirstUsedRenderFrameId,
+ "ConvertToLastUsedRenderFrameId": ConvertToLastUsedRenderFrameId,
+ "ShouldGenerateInputFrameUpsync": ShouldGenerateInputFrameUpsync,
})
}