From a85c6f9ad8b4ff1b4226981f9252a1702aed8e03 Mon Sep 17 00:00:00 2001 From: genxium Date: Sun, 25 Dec 2022 20:17:22 +0800 Subject: [PATCH] Refactored backend to use jsexport dynamics. --- battle_srv/go.mod | 3 +- battle_srv/models/pb_type_convert.go | 90 ++- battle_srv/models/room.go | 61 +- battle_srv/protos/room_downsync_frame.pb.go | 114 ++- battle_srv/ws/serve.go | 15 +- dnmshared/go.mod | 8 + dnmshared/resolv_helper.go | 4 +- dnmshared/tmx_parser.go | 40 +- frontend/assets/plugin_scripts/jsexport.js | 4 +- .../pbfiles/room_downsync_frame.proto | 3 +- frontend/assets/scripts/Map.js | 718 ++++-------------- frontend/assets/scripts/OfflineMapBackend.js | 281 +------ ...om_downsync_frame_proto_bundle.forcemsg.js | 95 +-- jsexport/battle/battle.go | 6 +- jsexport/battle/room_downsync_frame.go | 9 +- jsexport/main.go | 29 +- 16 files changed, 445 insertions(+), 1035 deletions(-) diff --git a/battle_srv/go.mod b/battle_srv/go.mod index 454070c..0a19de0 100644 --- a/battle_srv/go.mod +++ b/battle_srv/go.mod @@ -16,13 +16,13 @@ require ( github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0 github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967 - github.com/solarlune/resolv v0.5.1 github.com/thoas/go-funk v0.0.0-20180716193722-1060394a7713 go.uber.org/zap v1.9.1 google.golang.org/protobuf v1.28.1 dnmshared v0.0.0 jsexport v0.0.0 + resolv v0.0.0 ) require ( @@ -50,4 +50,5 @@ require ( replace ( dnmshared => ../dnmshared jsexport => ../jsexport + resolv => ../resolv_tailored ) diff --git a/battle_srv/models/pb_type_convert.go b/battle_srv/models/pb_type_convert.go index d0cec28..d6c9983 100644 --- a/battle_srv/models/pb_type_convert.go +++ b/battle_srv/models/pb_type_convert.go @@ -5,25 +5,74 @@ import ( "jsexport/battle" ) -func toPbRenderFrame(rdf *battle.RoomDownsyncFrame) { - if nil == rdf { - return nil - } - ret := &pb.RoomDownsyncFrame{ - Id: rdf.Id, - PlayersArr: make([]pb.PlayerDownsync, len(rdf.PlayersArr)), - MeleeBullets: make([]pb.MeleeBullet, len(rdf.MeleeBullets)), - } +func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame { + if nil == rdf { + 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)), + } + + for i, last := range rdf.PlayersArr { + pbPlayer := &pb.PlayerDownsync{ + Id: last.Id, + VirtualGridX: last.VirtualGridX, + VirtualGridY: last.VirtualGridY, + DirX: last.DirX, + DirY: last.DirY, + VelX: last.VelX, + VelY: last.VelY, + Speed: last.Speed, + BattleState: last.BattleState, + CharacterState: last.CharacterState, + InAir: last.InAir, + JoinIndex: last.JoinIndex, + ColliderRadius: last.ColliderRadius, + Score: last.Score, + Removed: last.Removed, + } + ret.PlayersArr[i] = pbPlayer + } + + for i, last := range rdf.MeleeBullets { + pbBullet := &pb.MeleeBullet{ + BattleLocalId: last.BattleLocalId, + StartupFrames: last.StartupFrames, + ActiveFrames: last.ActiveFrames, + RecoveryFrames: last.RecoveryFrames, + RecoveryFramesOnBlock: last.RecoveryFramesOnBlock, + RecoveryFramesOnHit: last.RecoveryFramesOnHit, + HitboxOffset: last.HitboxOffset, + HitStunFrames: last.HitStunFrames, + BlockStunFrames: last.BlockStunFrames, + Pushback: last.Pushback, + ReleaseTriggerType: last.ReleaseTriggerType, + Damage: last.Damage, + + SelfMoveforwardX: last.SelfMoveforwardX, + SelfMoveforwardY: last.SelfMoveforwardY, + HitboxSizeX: last.HitboxSizeX, + HitboxSizeY: last.HitboxSizeY, + + OffenderJoinIndex: last.OffenderJoinIndex, + OffenderPlayerId: last.OffenderPlayerId, + } + ret.MeleeBullets[i] = pbBullet + } + + return ret } -func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) map[int32]*pb.PlayerDownsync { - toRet := make(map[int32]*pb.PlayerDownsync, 0) +func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.PlayerDownsync { + toRet := make([]*pb.PlayerDownsync, len(modelInstances), len(modelInstances)) if nil == modelInstances { return toRet } - for k, last := range modelInstances { - toRet[k] = &pb.PlayerDownsync{ + for _, last := range modelInstances { + pbPlayer := &pb.PlayerDownsync{ Id: last.Id, VirtualGridX: last.VirtualGridX, VirtualGridY: last.VirtualGridY, @@ -41,23 +90,24 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) map[int32] Removed: last.Removed, } if withMetaInfo { - toRet[k].Name = last.Name - toRet[k].DisplayName = last.DisplayName - toRet[k].Avatar = last.Avatar + pbPlayer.Name = last.Name + pbPlayer.DisplayName = last.DisplayName + pbPlayer.Avatar = last.Avatar } + toRet[last.JoinIndex-1] = pbPlayer } return toRet } -func toJsPlayers(modelInstances map[int32]*Player) map[int32]*battle.PlayerDownsync { - toRet := make(map[int32]*battle.PlayerDownsync, 0) +func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync { + toRet := make([]*battle.PlayerDownsync, len(modelInstances), len(modelInstances)) if nil == modelInstances { return toRet } - for k, last := range modelInstances { - toRet[k] = &battle.PlayerDownsync{ + for _, last := range modelInstances { + toRet[last.JoinIndex-1] = &battle.PlayerDownsync{ Id: last.Id, VirtualGridX: last.VirtualGridX, VirtualGridY: last.VirtualGridY, diff --git a/battle_srv/models/room.go b/battle_srv/models/room.go index 033b576..1f0ffdb 100644 --- a/battle_srv/models/room.go +++ b/battle_srv/models/room.go @@ -9,13 +9,13 @@ import ( "fmt" "github.com/golang/protobuf/proto" "github.com/gorilla/websocket" - "github.com/solarlune/resolv" "go.uber.org/zap" "io/ioutil" "jsexport/battle" "math/rand" "os" "path/filepath" + "resolv" "strings" "sync" "sync/atomic" @@ -284,6 +284,8 @@ func (pR *Room) ChooseStage() error { panic(err) } + //Logger.Info("parsed tmx:", zap.Any("stageDiscreteW", stageDiscreteW), zap.Any("strToVec2DListMap", strToVec2DListMap), zap.Any("strToPolygon2DListMap", strToPolygon2DListMap)) + pR.StageDiscreteW = stageDiscreteW pR.StageDiscreteH = stageDiscreteH pR.StageTileW = stageTileW @@ -352,7 +354,7 @@ func (pR *Room) StartBattle() { pR.CurDynamicsRenderFrameId = 0 kickoffFrameJs := &battle.RoomDownsyncFrame{ Id: pR.RenderFrameId, - Players: toJsPlayers(pR.Players, false), + PlayersArr: toJsPlayers(pR.Players), CountdownNanos: pR.BattleDurationNanos, } pR.RenderFrameBuffer.Put(kickoffFrameJs) @@ -420,12 +422,8 @@ func (pR *Room) StartBattle() { case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL: continue } - kickoffFrame := &pb.RoomDownsyncFrame{ - Id: pR.RenderFrameId, - Players: toPbPlayers(pR.Players, false), - CountdownNanos: pR.BattleDurationNanos, - } - pR.sendSafely(kickoffFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true) + kickoffFrameJs := pR.RenderFrameBuffer.GetByFrameId(0).(*battle.RoomDownsyncFrame) + pR.sendSafely(toPbRoomDownsyncFrame(kickoffFrameJs), nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true) } Logger.Info(fmt.Sprintf("In `battleMainLoop` for roomId=%v sent out kickoffFrame", pR.Id)) } @@ -594,7 +592,7 @@ func (pR *Room) StopBattleForSettlement() { for playerId, _ := range pR.Players { assembledFrame := pb.RoomDownsyncFrame{ Id: pR.RenderFrameId, - Players: toPbPlayers(pR.Players, false), + PlayersArr: toPbPlayers(pR.Players, false), CountdownNanos: -1, // TODO: Replace this magic constant! } pR.sendSafely(&assembledFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_STOPPED, playerId, true) @@ -620,7 +618,7 @@ func (pR *Room) onBattlePrepare(cb BattleStartCbType) { battleReadyToStartFrame := &pb.RoomDownsyncFrame{ Id: DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START, - Players: toPbPlayers(pR.Players, true), + PlayersArr: toPbPlayers(pR.Players, true), CountdownNanos: pR.BattleDurationNanos, } @@ -691,7 +689,8 @@ func (pR *Room) OnDismissed() { pR.WorldToVirtualGridRatio = float64(1000) 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.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.Players = make(map[int32]*Player) pR.PlayersArr = make([]*Player, pR.Capacity) pR.CollisionSysMap = make(map[int32]*resolv.Object) @@ -878,7 +877,7 @@ func (pR *Room) onPlayerAdded(playerId int32) { pR.JoinIndexBooleanArr[index] = true // Lazily assign the initial position of "Player" for "RoomDownsyncFrame". - playerPosList := pR.TmxPointsMap["PlayerStartingPos"] + playerPosList := *pR.TmxPointsMap["PlayerStartingPos"] if index > len(playerPosList) { panic(fmt.Sprintf("onPlayerAdded error, index >= len(playerPosList), roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount)) } @@ -928,8 +927,8 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool { switch targetPlayerBattleState { case PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK: playerAckedFrame := &pb.RoomDownsyncFrame{ - Id: pR.RenderFrameId, - Players: toPbPlayers(pR.Players, true), + Id: pR.RenderFrameId, + PlayersArr: toPbPlayers(pR.Players, true), } // Broadcast normally added player info to all players in the same room @@ -1205,8 +1204,6 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende } Logger.Debug(fmt.Sprintf("Applying inputFrame dynamics: roomId=%v, room.RenderFrameId=%v, fromRenderFrameId=%v, toRenderFrameId=%v", pR.Id, pR.RenderFrameId, fromRenderFrameId, toRenderFrameId)) - totPlayerCnt := uint32(pR.Capacity) - allConfirmedMask := uint64((1 << totPlayerCnt) - 1) for collisionSysRenderFrameId := fromRenderFrameId; collisionSysRenderFrameId < toRenderFrameId; collisionSysRenderFrameId++ { currRenderFrameTmp := pR.RenderFrameBuffer.GetByFrameId(collisionSysRenderFrameId) @@ -1215,7 +1212,8 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende } currRenderFrame := currRenderFrameTmp.(*battle.RoomDownsyncFrame) delayedInputFrameId := pR.ConvertToInputFrameId(collisionSysRenderFrameId, pR.InputDelayFrames) - var delayedInputFrame *pb.InputFrameDownsync = nil + var delayedInputList []uint64 = nil + var delayedInputListForPrevRenderFrame []uint64 = nil if 0 <= delayedInputFrameId { if delayedInputFrameId > pR.LastAllConfirmedInputFrameId { panic(fmt.Sprintf("delayedInputFrameId=%v is not yet all-confirmed for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false))) @@ -1224,12 +1222,20 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende if nil == tmp { panic(fmt.Sprintf("delayedInputFrameId=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false))) } - delayedInputFrame = tmp.(*pb.InputFrameDownsync) - // [WARNING] It's possible that by now "allConfirmedMask != delayedInputFrame.ConfirmedList && delayedInputFrameId <= pR.LastAllConfirmedInputFrameId", we trust "pR.LastAllConfirmedInputFrameId" as the TOP AUTHORITY. - delayedInputFrame.ConfirmedList = allConfirmedMask + delayedInputFrame := tmp.(*pb.InputFrameDownsync) + delayedInputList = delayedInputFrame.InputList + delayedInputFrameIdForPrevRenderFrame := pR.ConvertToInputFrameId(collisionSysRenderFrameId-1, pR.InputDelayFrames) + if 0 <= delayedInputFrameIdForPrevRenderFrame { + tmp = pR.InputsBuffer.GetByFrameId(delayedInputFrameId) + if nil == tmp { + panic(fmt.Sprintf("delayedInputFrameIdForPrevRenderFrame=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId-1=%v! InputsBuffer=%v", delayedInputFrameIdForPrevRenderFrame, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId-1, pR.InputsBufferString(false))) + } + delayedInputFrameForPrevRenderFrame := tmp.(*pb.InputFrameDownsync) + delayedInputListForPrevRenderFrame = delayedInputFrameForPrevRenderFrame.InputList + } } - nextRenderFrame := pR.applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputFrame, currRenderFrame, pR.CollisionSysMap) + nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputList, delayedInputListForPrevRenderFrame, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.GravityX, pR.GravityY, pR.JumpingInitVelY, pR.InputDelayFrames, pR.InputScaleFrames, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformThreshold, pR.WorldToVirtualGridRatio, pR.VirtualGridToWorldRatio) pR.RenderFrameBuffer.Put(nextRenderFrame) pR.CurDynamicsRenderFrameId++ } @@ -1240,9 +1246,8 @@ func (pR *Room) refreshColliders(spaceW, spaceH int32) { topPadding, bottomPadding, leftPadding, rightPadding := pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap - minStep := (int(float64(pR.PlayerDefaultSpeed)*pR.VirtualGridToWorldRatio) << 3) // the approx minimum distance a player can move per frame in world coordinate - pR.Space = resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep) // allocate a new collision space everytime after a battle is settled - jsPlayers := toJsPlayers(pR.Players, false) + pR.Space = resolv.NewSpace(int(spaceW), int(spaceH), int(pR.CollisionMinStep), int(pR.CollisionMinStep)) // allocate a new collision space everytime after a battle is settled + jsPlayers := toJsPlayers(pR.Players) for _, player := range jsPlayers { wx, wy := battle.VirtualGridToWorldPos(player.VirtualGridX, player.VirtualGridY, pR.VirtualGridToWorldRatio) colliderWidth, colliderHeight := player.ColliderRadius*2, player.ColliderRadius*4 @@ -1259,7 +1264,7 @@ func (pR *Room) refreshColliders(spaceW, spaceH int32) { pR.PlayersArr[joinIndex-1] = player } - barrierPolygon2DList := pR.TmxPolygonsMap["Barrier"] + barrierPolygon2DList := *pR.TmxPolygonsMap["Barrier"] for _, polygon2DUnaligned := range barrierPolygon2DList { /* // For debug-printing only. @@ -1427,14 +1432,14 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender } refRenderFrame := tmp.(*battle.RoomDownsyncFrame) - for _, player := range pR.PlayersArr { - refRenderFrame.Players[player.Id].ColliderRadius = player.ColliderRadius // hardcoded for now + 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(refRenderFrame, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false) + pR.sendSafely(toPbRoomDownsyncFrame(refRenderFrame), toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false) //Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: InputsBuffer=%v", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, pR.InputsBufferString(false))) 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 d180d59..a56abdf 100644 --- a/battle_srv/protos/room_downsync_frame.pb.go +++ b/battle_srv/protos/room_downsync_frame.pb.go @@ -960,6 +960,7 @@ type BattleColliderInfo struct { JumpingInitVelY int32 `protobuf:"varint,27,opt,name=jumpingInitVelY,proto3" json:"jumpingInitVelY,omitempty"` GravityX int32 `protobuf:"varint,28,opt,name=gravityX,proto3" json:"gravityX,omitempty"` GravityY int32 `protobuf:"varint,29,opt,name=gravityY,proto3" json:"gravityY,omitempty"` + CollisionMinStep int32 `protobuf:"varint,30,opt,name=collisionMinStep,proto3" json:"collisionMinStep,omitempty"` } func (x *BattleColliderInfo) Reset() { @@ -1197,18 +1198,24 @@ func (x *BattleColliderInfo) GetGravityY() int32 { return 0 } +func (x *BattleColliderInfo) GetCollisionMinStep() int32 { + if x != nil { + return x.CollisionMinStep + } + return 0 +} + type RoomDownsyncFrame struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - PlayersArr []*PlayerDownsync `protobuf:"bytes,2,rep,name=playersArr,proto3" json:"playersArr,omitempty"` - CountdownNanos int64 `protobuf:"varint,3,opt,name=countdownNanos,proto3" json:"countdownNanos,omitempty"` - MeleeBullets []*MeleeBullet `protobuf:"bytes,4,rep,name=meleeBullets,proto3" json:"meleeBullets,omitempty"` // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise - BackendUnconfirmedMask uint64 `protobuf:"varint,5,opt,name=backendUnconfirmedMask,proto3" json:"backendUnconfirmedMask,omitempty"` // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync - ShouldForceResync bool `protobuf:"varint,6,opt,name=shouldForceResync,proto3" json:"shouldForceResync,omitempty"` - Players map[int32]*PlayerDownsync `protobuf:"bytes,99,rep,name=players,proto3" json:"players,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // TO BE DEPRECATED + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + PlayersArr []*PlayerDownsync `protobuf:"bytes,2,rep,name=playersArr,proto3" json:"playersArr,omitempty"` + CountdownNanos int64 `protobuf:"varint,3,opt,name=countdownNanos,proto3" json:"countdownNanos,omitempty"` + MeleeBullets []*MeleeBullet `protobuf:"bytes,4,rep,name=meleeBullets,proto3" json:"meleeBullets,omitempty"` // I don't know how to mimic inheritance/composition in protobuf by far, thus using an array for each type of bullet as a compromise + BackendUnconfirmedMask uint64 `protobuf:"varint,5,opt,name=backendUnconfirmedMask,proto3" json:"backendUnconfirmedMask,omitempty"` // Indexed by "joinIndex", same compression concern as stated in InputFrameDownsync + ShouldForceResync bool `protobuf:"varint,6,opt,name=shouldForceResync,proto3" json:"shouldForceResync,omitempty"` } func (x *RoomDownsyncFrame) Reset() { @@ -1285,13 +1292,6 @@ func (x *RoomDownsyncFrame) GetShouldForceResync() bool { return false } -func (x *RoomDownsyncFrame) GetPlayers() map[int32]*PlayerDownsync { - if x != nil { - return x.Players - } - return nil -} - var File_room_downsync_frame_proto protoreflect.FileDescriptor var file_room_downsync_frame_proto_rawDesc = []byte{ @@ -1462,7 +1462,7 @@ var file_room_downsync_frame_proto_rawDesc = []byte{ 0x6c, 0x66, 0x4d, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x58, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x65, 0x6c, 0x66, 0x4d, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x59, 0x18, 0x13, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x73, 0x65, 0x6c, 0x66, 0x4d, 0x6f, - 0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x59, 0x22, 0xde, 0x0b, 0x0a, 0x12, 0x42, + 0x76, 0x65, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x59, 0x22, 0x8a, 0x0c, 0x0a, 0x12, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, @@ -1551,42 +1551,35 @@ var file_room_downsync_frame_proto_rawDesc = []byte{ 0x76, 0x69, 0x74, 0x79, 0x58, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x79, 0x58, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x79, 0x59, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x79, - 0x59, 0x1a, 0x58, 0x0a, 0x15, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb8, 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, 0x36, 0x0a, 0x16, 0x62, 0x61, - 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, - 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x62, 0x61, 0x63, 0x6b, - 0x65, 0x6e, 0x64, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, - 0x73, 0x6b, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, - 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, - 0x12, 0x40, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x63, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x52, 0x6f, 0x6f, 0x6d, 0x44, - 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x73, 0x1a, 0x52, 0x0a, 0x0c, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x13, 0x5a, 0x11, 0x62, 0x61, 0x74, 0x74, 0x6c, 0x65, - 0x5f, 0x73, 0x72, 0x76, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x59, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, + 0x6e, 0x53, 0x74, 0x65, 0x70, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x63, 0x6f, 0x6c, + 0x6c, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x1a, 0x58, 0x0a, + 0x15, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x53, 0x6b, 0x69, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, + 0x2e, 0x4d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa2, 0x02, 0x0a, 0x11, 0x52, 0x6f, 0x6f, 0x6d, + 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, + 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x41, 0x72, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x73, 0x41, 0x72, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, + 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x12, 0x37, 0x0a, + 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x4d, 0x65, 0x6c, + 0x65, 0x65, 0x42, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x6d, 0x65, 0x6c, 0x65, 0x65, 0x42, + 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, + 0x64, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x55, + 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x2c, + 0x0a, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x79, 0x6e, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x68, 0x6f, 0x75, 0x6c, + 0x64, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x79, 0x6e, 0x63, 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 ( @@ -1601,7 +1594,7 @@ func file_room_downsync_frame_proto_rawDescGZIP() []byte { return file_room_downsync_frame_proto_rawDescData } -var file_room_downsync_frame_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_room_downsync_frame_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_room_downsync_frame_proto_goTypes = []interface{}{ (*PlayerDownsync)(nil), // 0: protos.PlayerDownsync (*InputFrameDecoded)(nil), // 1: protos.InputFrameDecoded @@ -1615,7 +1608,6 @@ var file_room_downsync_frame_proto_goTypes = []interface{}{ (*BattleColliderInfo)(nil), // 9: protos.BattleColliderInfo (*RoomDownsyncFrame)(nil), // 10: protos.RoomDownsyncFrame nil, // 11: protos.BattleColliderInfo.MeleeSkillConfigEntry - nil, // 12: protos.RoomDownsyncFrame.PlayersEntry } var file_room_downsync_frame_proto_depIdxs = []int32{ 2, // 0: protos.WsReq.inputFrameUpsyncBatch:type_name -> protos.InputFrameUpsync @@ -1627,14 +1619,12 @@ var file_room_downsync_frame_proto_depIdxs = []int32{ 11, // 6: protos.BattleColliderInfo.meleeSkillConfig:type_name -> protos.BattleColliderInfo.MeleeSkillConfigEntry 0, // 7: protos.RoomDownsyncFrame.playersArr:type_name -> protos.PlayerDownsync 8, // 8: protos.RoomDownsyncFrame.meleeBullets:type_name -> protos.MeleeBullet - 12, // 9: protos.RoomDownsyncFrame.players:type_name -> protos.RoomDownsyncFrame.PlayersEntry - 8, // 10: protos.BattleColliderInfo.MeleeSkillConfigEntry.value:type_name -> protos.MeleeBullet - 0, // 11: protos.RoomDownsyncFrame.PlayersEntry.value:type_name -> protos.PlayerDownsync - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 8, // 9: protos.BattleColliderInfo.MeleeSkillConfigEntry.value:type_name -> protos.MeleeBullet + 10, // [10:10] is the sub-list for method output_type + 10, // [10:10] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_room_downsync_frame_proto_init() } @@ -1782,7 +1772,7 @@ func file_room_downsync_frame_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_room_downsync_frame_proto_rawDesc, NumEnums: 0, - NumMessages: 13, + NumMessages: 12, NumExtensions: 0, NumServices: 0, }, diff --git a/battle_srv/ws/serve.go b/battle_srv/ws/serve.go index 8299428..65c9691 100644 --- a/battle_srv/ws/serve.go +++ b/battle_srv/ws/serve.go @@ -240,14 +240,12 @@ func Serve(c *gin.Context) { // Construct "battleColliderInfo" to downsync bciFrame := &pb.BattleColliderInfo{ - BoundRoomId: pRoom.Id, - StageName: pRoom.StageName, - StrToVec2DListMap: pRoom.StrToVec2DListMap, - StrToPolygon2DListMap: pRoom.StrToPolygon2DListMap, - StageDiscreteW: pRoom.StageDiscreteW, - StageDiscreteH: pRoom.StageDiscreteH, - StageTileW: pRoom.StageTileW, - StageTileH: pRoom.StageTileH, + BoundRoomId: pRoom.Id, + StageName: pRoom.StageName, + StageDiscreteW: pRoom.StageDiscreteW, + StageDiscreteH: pRoom.StageDiscreteH, + StageTileW: pRoom.StageTileW, + StageTileH: pRoom.StageTileH, IntervalToPing: int32(Constants.Ws.IntervalToPing), WillKickIfInactiveFor: int32(Constants.Ws.WillKickIfInactiveFor), @@ -273,6 +271,7 @@ func Serve(c *gin.Context) { JumpingInitVelY: pRoom.JumpingInitVelY, GravityX: pRoom.GravityX, GravityY: pRoom.GravityY, + CollisionMinStep: pRoom.CollisionMinStep, } resp := &pb.WsResp{ diff --git a/dnmshared/go.mod b/dnmshared/go.mod index bd7bc58..dac3d35 100644 --- a/dnmshared/go.mod +++ b/dnmshared/go.mod @@ -1,3 +1,11 @@ module dnmshared go 1.18 + +require ( + resolv v0.0.0 +) + +replace ( + resolv => ../resolv_tailored +) diff --git a/dnmshared/resolv_helper.go b/dnmshared/resolv_helper.go index 7faeb7c..0c6a4c3 100644 --- a/dnmshared/resolv_helper.go +++ b/dnmshared/resolv_helper.go @@ -1,9 +1,9 @@ package dnmshared import ( - . "jsexport/battle" "fmt" - "github.com/solarlune/resolv" + . "jsexport/battle" + "resolv" "strings" ) diff --git a/dnmshared/tmx_parser.go b/dnmshared/tmx_parser.go index 516d133..c5d7a48 100644 --- a/dnmshared/tmx_parser.go +++ b/dnmshared/tmx_parser.go @@ -175,8 +175,8 @@ func (l *TmxLayer) decodeBase64() ([]uint32, error) { return gids, nil } -type StrToVec2DListMap map[string]([]*Vec2D) -type StrToPolygon2DListMap map[string]([]*Polygon2D) +type StrToVec2DListMap map[string](*[]*Vec2D) +type StrToPolygon2DListMap map[string](*[]*Polygon2D) func tmxPolylineToPolygon2D(pTmxMapIns *TmxMap, singleObjInTmxFile *TmxOrTsxObject, targetPolyline *TmxOrTsxPolyline) (*Polygon2D, error) { if nil == targetPolyline { @@ -321,19 +321,18 @@ func DeserializeTsxToColliderDict(pTmxMapIns *TmxMap, byteArrOfTsxFile []byte, f theStrToPolygon2DListMap = gidBoundariesMap[globalGid] } - var pThePolygon2DList []*Polygon2D - if _, ok := theStrToPolygon2DListMap[key]; ok { - pThePolygon2DList = theStrToPolygon2DListMap[key] - } else { - pThePolygon2DList = make([]*Polygon2D, 0) - theStrToPolygon2DListMap[key] = pThePolygon2DList + var pThePolygon2DList *[]*Polygon2D = nil + if _, ok := theStrToPolygon2DListMap[key]; !ok { + tmp := make([]*Polygon2D, 0) + theStrToPolygon2DListMap[key] = &tmp } + pThePolygon2DList = theStrToPolygon2DListMap[key] thePolygon2DFromPolyline, err := tsxPolylineToOffsetsWrtTileCenter(pTmxMapIns, singleObj, singleObj.Polyline, pTsxIns) if nil != err { panic(err) } - pThePolygon2DList = append(pThePolygon2DList, thePolygon2DFromPolyline) + *pThePolygon2DList = append(*pThePolygon2DList, thePolygon2DFromPolyline) } } return nil @@ -346,11 +345,10 @@ func ParseTmxLayersAndGroups(pTmxMapIns *TmxMap, gidBoundariesMap map[int]StrToP for _, objGroup := range pTmxMapIns.ObjectGroups { switch objGroup.Name { case "PlayerStartingPos": - var pTheVec2DListToCache []*Vec2D - _, ok := toRetStrToVec2DListMap[objGroup.Name] - if false == ok { - pTheVec2DListToCache = make([]*Vec2D, 0) - toRetStrToVec2DListMap[objGroup.Name] = pTheVec2DListToCache + var pTheVec2DListToCache *[]*Vec2D = nil + if _, ok := toRetStrToVec2DListMap[objGroup.Name]; !ok { + tmp := make([]*Vec2D, 0) + toRetStrToVec2DListMap[objGroup.Name] = &tmp } pTheVec2DListToCache = toRetStrToVec2DListMap[objGroup.Name] for _, singleObjInTmxFile := range objGroup.Objects { @@ -359,16 +357,16 @@ func ParseTmxLayersAndGroups(pTmxMapIns *TmxMap, gidBoundariesMap map[int]StrToP Y: singleObjInTmxFile.Y, } thePosInWorld := pTmxMapIns.continuousObjLayerOffsetToContinuousMapNodePos(theUntransformedPos) - pTheVec2DListToCache = append(pTheVec2DListToCache, &thePosInWorld) + *pTheVec2DListToCache = append(*pTheVec2DListToCache, &thePosInWorld) } case "Barrier": // Note that in this case, the "Polygon2D.Anchor" of each "TmxOrTsxObject" is exactly overlapping with "Polygon2D.Points[0]". - var pThePolygon2DListToCache []*Polygon2D - _, ok := toRetStrToPolygon2DListMap[objGroup.Name] - if false == ok { - pThePolygon2DListToCache = make([]*Polygon2D, 0) - toRetStrToPolygon2DListMap[objGroup.Name] = pThePolygon2DListToCache + var pThePolygon2DListToCache *[]*Polygon2D = nil + if _, ok := toRetStrToPolygon2DListMap[objGroup.Name]; !ok { + tmp := make([]*Polygon2D, 0) + toRetStrToPolygon2DListMap[objGroup.Name] = &tmp } + pThePolygon2DListToCache = toRetStrToPolygon2DListMap[objGroup.Name] for _, singleObjInTmxFile := range objGroup.Objects { if nil == singleObjInTmxFile.Polyline { @@ -402,7 +400,7 @@ func ParseTmxLayersAndGroups(pTmxMapIns *TmxMap, gidBoundariesMap map[int]StrToP if nil != err { panic(err) } - pThePolygon2DListToCache = append(pThePolygon2DListToCache, thePolygon2DInWorld) + *pThePolygon2DListToCache = append(*pThePolygon2DListToCache, thePolygon2DInWorld) } default: } diff --git a/frontend/assets/plugin_scripts/jsexport.js b/frontend/assets/plugin_scripts/jsexport.js index b68e41a..774cf5a 100644 --- a/frontend/assets/plugin_scripts/jsexport.js +++ b/frontend/assets/plugin_scripts/jsexport.js @@ -13,8 +13,8 @@ $packages["internal/unsafeheader"]=(function(){var $pkg={},$init;$init=function( $packages["internal/reflectlite"]=(function(){var $pkg={},$init,D,A,B,C,E,F,I,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AG,AH,AI,AT,AV,BL,BN,BO,BP,CU,CW,DU,DV,DW,DX,DY,DZ,EA,EC,ED,EE,EF,EG,EH,EI,EJ,EK,EL,EM,EN,EO,ES,ET,EU,EV,EW,EX,EY,EZ,AD,AR,BB,BD,BE,BF,BG,BH,BM,BQ,BS,BU,DH,DN,AK,AL,AM,AN,AP,AQ,AU,BA,BC,BI,BJ,BK,BR,BT,BV,BW,BX,BY,BZ,CB,CC,CF,CH,CJ,CM,CQ,CR,CV,CX,CY,CZ,DC,DD,DE,DF,DG,DI,DJ,DK,DL,DM;D=$packages["github.com/gopherjs/gopherjs/js"];A=$packages["internal/goarch"];B=$packages["internal/unsafeheader"];C=$packages["runtime"];E=$pkg.Value=$newType(0,$kindStruct,"reflectlite.Value",true,"internal/reflectlite",true,function(typ_,ptr_,flag_){this.$val=this;if(arguments.length===0){this.typ=DU.nil;this.ptr=0;this.flag=0;return;}this.typ=typ_;this.ptr=ptr_;this.flag=flag_;});F=$pkg.flag=$newType(4,$kindUintptr,"reflectlite.flag",true,"internal/reflectlite",false,null);I=$pkg.ValueError=$newType(0,$kindStruct,"reflectlite.ValueError",true,"internal/reflectlite",true,function(Method_,Kind_){this.$val=this;if(arguments.length===0){this.Method="";this.Kind=0;return;}this.Method=Method_;this.Kind=Kind_;});O=$pkg.Type=$newType(8,$kindInterface,"reflectlite.Type",true,"internal/reflectlite",true,null);P=$pkg.Kind=$newType(4,$kindUint,"reflectlite.Kind",true,"internal/reflectlite",true,null);Q=$pkg.tflag=$newType(1,$kindUint8,"reflectlite.tflag",true,"internal/reflectlite",false,null);R=$pkg.rtype=$newType(0,$kindStruct,"reflectlite.rtype",true,"internal/reflectlite",false,function(size_,ptrdata_,hash_,tflag_,align_,fieldAlign_,kind_,equal_,gcdata_,str_,ptrToThis_){this.$val=this;if(arguments.length===0){this.size=0;this.ptrdata=0;this.hash=0;this.tflag=0;this.align=0;this.fieldAlign=0;this.kind=0;this.equal=$throwNilPointerError;this.gcdata=EG.nil;this.str=0;this.ptrToThis=0;return;}this.size=size_;this.ptrdata=ptrdata_;this.hash=hash_;this.tflag=tflag_;this.align=align_;this.fieldAlign=fieldAlign_;this.kind=kind_;this.equal=equal_;this.gcdata=gcdata_;this.str=str_;this.ptrToThis=ptrToThis_;});S=$pkg.method=$newType(0,$kindStruct,"reflectlite.method",true,"internal/reflectlite",false,function(name_,mtyp_,ifn_,tfn_){this.$val=this;if(arguments.length===0){this.name=0;this.mtyp=0;this.ifn=0;this.tfn=0;return;}this.name=name_;this.mtyp=mtyp_;this.ifn=ifn_;this.tfn=tfn_;});T=$pkg.chanDir=$newType(4,$kindInt,"reflectlite.chanDir",true,"internal/reflectlite",false,null);U=$pkg.arrayType=$newType(0,$kindStruct,"reflectlite.arrayType",true,"internal/reflectlite",false,function(rtype_,elem_,slice_,len_){this.$val=this;if(arguments.length===0){this.rtype=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);this.elem=DU.nil;this.slice=DU.nil;this.len=0;return;}this.rtype=rtype_;this.elem=elem_;this.slice=slice_;this.len=len_;});V=$pkg.chanType=$newType(0,$kindStruct,"reflectlite.chanType",true,"internal/reflectlite",false,function(rtype_,elem_,dir_){this.$val=this;if(arguments.length===0){this.rtype=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);this.elem=DU.nil;this.dir=0;return;}this.rtype=rtype_;this.elem=elem_;this.dir=dir_;});W=$pkg.imethod=$newType(0,$kindStruct,"reflectlite.imethod",true,"internal/reflectlite",false,function(name_,typ_){this.$val=this;if(arguments.length===0){this.name=0;this.typ=0;return;}this.name=name_;this.typ=typ_;});X=$pkg.interfaceType=$newType(0,$kindStruct,"reflectlite.interfaceType",true,"internal/reflectlite",false,function(rtype_,pkgPath_,methods_){this.$val=this;if(arguments.length===0){this.rtype=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);this.pkgPath=new BO.ptr(EG.nil);this.methods=EK.nil;return;}this.rtype=rtype_;this.pkgPath=pkgPath_;this.methods=methods_;});Y=$pkg.mapType=$newType(0,$kindStruct,"reflectlite.mapType",true,"internal/reflectlite",false,function(rtype_,key_,elem_,bucket_,hasher_,keysize_,valuesize_,bucketsize_,flags_){this.$val=this;if(arguments.length===0){this.rtype=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);this.key=DU.nil;this.elem=DU.nil;this.bucket=DU.nil;this.hasher=$throwNilPointerError;this.keysize=0;this.valuesize=0;this.bucketsize=0;this.flags=0;return;}this.rtype=rtype_;this.key=key_;this.elem=elem_;this.bucket=bucket_;this.hasher=hasher_;this.keysize=keysize_;this.valuesize=valuesize_;this.bucketsize=bucketsize_;this.flags=flags_;});Z=$pkg.ptrType=$newType(0,$kindStruct,"reflectlite.ptrType",true,"internal/reflectlite",false,function(rtype_,elem_){this.$val=this;if(arguments.length===0){this.rtype=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);this.elem=DU.nil;return;}this.rtype=rtype_;this.elem=elem_;});AA=$pkg.sliceType=$newType(0,$kindStruct,"reflectlite.sliceType",true,"internal/reflectlite",false,function(rtype_,elem_){this.$val=this;if(arguments.length===0){this.rtype=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);this.elem=DU.nil;return;}this.rtype=rtype_;this.elem=elem_;});AB=$pkg.structField=$newType(0,$kindStruct,"reflectlite.structField",true,"internal/reflectlite",false,function(name_,typ_,offsetEmbed_){this.$val=this;if(arguments.length===0){this.name=new BO.ptr(EG.nil);this.typ=DU.nil;this.offsetEmbed=0;return;}this.name=name_;this.typ=typ_;this.offsetEmbed=offsetEmbed_;});AC=$pkg.structType=$newType(0,$kindStruct,"reflectlite.structType",true,"internal/reflectlite",false,function(rtype_,pkgPath_,fields_){this.$val=this;if(arguments.length===0){this.rtype=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);this.pkgPath=new BO.ptr(EG.nil);this.fields=EL.nil;return;}this.rtype=rtype_;this.pkgPath=pkgPath_;this.fields=fields_;});AG=$pkg.nameOff=$newType(4,$kindInt32,"reflectlite.nameOff",true,"internal/reflectlite",false,null);AH=$pkg.typeOff=$newType(4,$kindInt32,"reflectlite.typeOff",true,"internal/reflectlite",false,null);AI=$pkg.textOff=$newType(4,$kindInt32,"reflectlite.textOff",true,"internal/reflectlite",false,null);AT=$pkg.errorString=$newType(0,$kindStruct,"reflectlite.errorString",true,"internal/reflectlite",false,function(s_){this.$val=this;if(arguments.length===0){this.s="";return;}this.s=s_;});AV=$pkg.Method=$newType(0,$kindStruct,"reflectlite.Method",true,"internal/reflectlite",true,function(Name_,PkgPath_,Type_,Func_,Index_){this.$val=this;if(arguments.length===0){this.Name="";this.PkgPath="";this.Type=$ifaceNil;this.Func=new E.ptr(DU.nil,0,0);this.Index=0;return;}this.Name=Name_;this.PkgPath=PkgPath_;this.Type=Type_;this.Func=Func_;this.Index=Index_;});BL=$pkg.uncommonType=$newType(0,$kindStruct,"reflectlite.uncommonType",true,"internal/reflectlite",false,function(pkgPath_,mcount_,xcount_,moff_,_methods_){this.$val=this;if(arguments.length===0){this.pkgPath=0;this.mcount=0;this.xcount=0;this.moff=0;this._methods=ED.nil;return;}this.pkgPath=pkgPath_;this.mcount=mcount_;this.xcount=xcount_;this.moff=moff_;this._methods=_methods_;});BN=$pkg.funcType=$newType(0,$kindStruct,"reflectlite.funcType",true,"internal/reflectlite",false,function(rtype_,inCount_,outCount_,_in_,_out_){this.$val=this;if(arguments.length===0){this.rtype=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);this.inCount=0;this.outCount=0;this._in=DW.nil;this._out=DW.nil;return;}this.rtype=rtype_;this.inCount=inCount_;this.outCount=outCount_;this._in=_in_;this._out=_out_;});BO=$pkg.name=$newType(0,$kindStruct,"reflectlite.name",true,"internal/reflectlite",false,function(bytes_){this.$val=this;if(arguments.length===0){this.bytes=EG.nil;return;}this.bytes=bytes_;});BP=$pkg.nameData=$newType(0,$kindStruct,"reflectlite.nameData",true,"internal/reflectlite",false,function(name_,tag_,exported_){this.$val=this;if(arguments.length===0){this.name="";this.tag="";this.exported=false;return;}this.name=name_;this.tag=tag_;this.exported=exported_;});CU=$pkg.mapIter=$newType(0,$kindStruct,"reflectlite.mapIter",true,"internal/reflectlite",false,function(t_,m_,keys_,i_,last_){this.$val=this;if(arguments.length===0){this.t=$ifaceNil;this.m=null;this.keys=null;this.i=0;this.last=null;return;}this.t=t_;this.m=m_;this.keys=keys_;this.i=i_;this.last=last_;});CW=$pkg.TypeEx=$newType(8,$kindInterface,"reflectlite.TypeEx",true,"internal/reflectlite",true,null);DU=$ptrType(R);DV=$sliceType(BO);DW=$sliceType(DU);DX=$sliceType($String);DY=$sliceType($emptyInterface);DZ=$ptrType(D.Object);EA=$funcType([DY],[DZ],true);EC=$ptrType(BL);ED=$sliceType(S);EE=$ptrType(BN);EF=$sliceType(E);EG=$ptrType($Uint8);EH=$ptrType($UnsafePointer);EI=$sliceType(O);EJ=$sliceType(DZ);EK=$sliceType(W);EL=$sliceType(AB);EM=$ptrType(BP);EN=$structType("internal/reflectlite",[{prop:"str",name:"str",embedded:false,exported:false,typ:$String,tag:""}]);EO=$ptrType(CU);ES=$arrayType($Uintptr,2);ET=$sliceType($Uint8);EU=$ptrType(I);EV=$funcType([$UnsafePointer,$UnsafePointer],[$Bool],false);EW=$ptrType(X);EX=$funcType([$UnsafePointer,$Uintptr],[$Uintptr],false);EY=$ptrType(AB);EZ=$ptrType(AT);F.prototype.kind=function(){var m;m=this.$val;return((((m&31)>>>0)>>>0));};$ptrType(F).prototype.kind=function(){return new F(this.$get()).kind();};F.prototype.ro=function(){var m;m=this.$val;if(!((((m&96)>>>0)===0))){return 32;}return 0;};$ptrType(F).prototype.ro=function(){return new F(this.$get()).ro();};E.ptr.prototype.pointer=function(){var m;m=this;if(!((m.typ.size===4))||!m.typ.pointers()){$panic(new $String("can't call pointer on a non-pointer Value"));}if(!((((m.flag&128)>>>0)===0))){return(m.ptr).$get();}return m.ptr;};E.prototype.pointer=function(){return this.$val.pointer();};I.ptr.prototype.Error=function(){var m;m=this;if(m.Kind===0){return"reflect: call of "+m.Method+" on zero Value";}return"reflect: call of "+m.Method+" on "+new P(m.Kind).String()+" Value";};I.prototype.Error=function(){return this.$val.Error();};F.prototype.mustBeExported=function(){var m;m=this.$val;if(m===0){$panic(new I.ptr(DF(),0));}if(!((((m&96)>>>0)===0))){$panic(new $String("reflect: "+DF()+" using value obtained using unexported field"));}};$ptrType(F).prototype.mustBeExported=function(){return new F(this.$get()).mustBeExported();};F.prototype.mustBeAssignable=function(){var m;m=this.$val;if(m===0){$panic(new I.ptr(DF(),0));}if(!((((m&96)>>>0)===0))){$panic(new $String("reflect: "+DF()+" using value obtained using unexported field"));}if(((m&256)>>>0)===0){$panic(new $String("reflect: "+DF()+" using unaddressable value"));}};$ptrType(F).prototype.mustBeAssignable=function(){return new F(this.$get()).mustBeAssignable();};E.ptr.prototype.CanSet=function(){var m;m=this;return((m.flag&352)>>>0)===256;};E.prototype.CanSet=function(){return this.$val.CanSet();};E.ptr.prototype.IsValid=function(){var m;m=this;return!((m.flag===0));};E.prototype.IsValid=function(){return this.$val.IsValid();};E.ptr.prototype.Kind=function(){var m;m=this;return new F(m.flag).kind();};E.prototype.Kind=function(){return this.$val.Kind();};E.ptr.prototype.Type=function(){var m,n;m=this;n=m.flag;if(n===0){$panic(new I.ptr("reflectlite.Value.Type",0));}return m.typ;};E.prototype.Type=function(){return this.$val.Type();};AB.ptr.prototype.embedded=function(){var m;m=this;return!((((m.offsetEmbed&1)>>>0)===0));};AB.prototype.embedded=function(){return this.$val.embedded();};P.prototype.String=function(){var m;m=this.$val;if(((m>>0))=AD.$length)?($throwRuntimeError("index out of range"),undefined):AD.$array[AD.$offset+m]);}return(0>=AD.$length?($throwRuntimeError("index out of range"),undefined):AD.$array[AD.$offset+0]);};$ptrType(P).prototype.String=function(){return new P(this.$get()).String();};R.ptr.prototype.String=function(){var m,n;m=this;n=$clone(m.nameOff(m.str),BO).name();if(!((((m.tflag&2)>>>0)===0))){return $substring(n,1);}return n;};R.prototype.String=function(){return this.$val.String();};R.ptr.prototype.Size=function(){var m;m=this;return m.size;};R.prototype.Size=function(){return this.$val.Size();};R.ptr.prototype.Kind=function(){var m;m=this;return((((m.kind&31)>>>0)>>>0));};R.prototype.Kind=function(){return this.$val.Kind();};R.ptr.prototype.pointers=function(){var m;m=this;return!((m.ptrdata===0));};R.prototype.pointers=function(){return this.$val.pointers();};R.ptr.prototype.common=function(){var m;m=this;return m;};R.prototype.common=function(){return this.$val.common();};R.ptr.prototype.exportedMethods=function(){var m,n;m=this;n=m.uncommon();if(n===EC.nil){return ED.nil;}return n.exportedMethods();};R.prototype.exportedMethods=function(){return this.$val.exportedMethods();};R.ptr.prototype.NumMethod=function(){var m,n;m=this;if(m.Kind()===20){n=(m.kindType);return n.NumMethod();}return m.exportedMethods().$length;};R.prototype.NumMethod=function(){return this.$val.NumMethod();};R.ptr.prototype.PkgPath=function(){var m,n;m=this;if(((m.tflag&4)>>>0)===0){return"";}n=m.uncommon();if(n===EC.nil){return"";}return $clone(m.nameOff(n.pkgPath),BO).name();};R.prototype.PkgPath=function(){return this.$val.PkgPath();};R.ptr.prototype.hasName=function(){var m;m=this;return!((((m.tflag&4)>>>0)===0));};R.prototype.hasName=function(){return this.$val.hasName();};R.ptr.prototype.Name=function(){var m,n,o;m=this;if(!m.hasName()){return"";}n=m.String();o=n.length-1>>0;while(true){if(!(o>=0&&!((n.charCodeAt(o)===46)))){break;}o=o-(1)>>0;}return $substring(n,(o+1>>0));};R.prototype.Name=function(){return this.$val.Name();};R.ptr.prototype.chanDir=function(){var m,n;m=this;if(!((m.Kind()===18))){$panic(new $String("reflect: chanDir of non-chan type"));}n=(m.kindType);return((n.dir>>0));};R.prototype.chanDir=function(){return this.$val.chanDir();};R.ptr.prototype.Elem=function(){var m,n,o,p,q,r,s;m=this;n=m.Kind();if(n===(17)){o=(m.kindType);return AP(o.elem);}else if(n===(18)){p=(m.kindType);return AP(p.elem);}else if(n===(21)){q=(m.kindType);return AP(q.elem);}else if(n===(22)){r=(m.kindType);return AP(r.elem);}else if(n===(23)){s=(m.kindType);return AP(s.elem);}$panic(new $String("reflect: Elem of invalid type"));};R.prototype.Elem=function(){return this.$val.Elem();};R.ptr.prototype.In=function(m){var m,n,o,p;n=this;if(!((n.Kind()===19))){$panic(new $String("reflect: In of non-func type"));}o=(n.kindType);return AP((p=o.in$(),((m<0||m>=p.$length)?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+m])));};R.prototype.In=function(m){return this.$val.In(m);};R.ptr.prototype.Len=function(){var m,n;m=this;if(!((m.Kind()===17))){$panic(new $String("reflect: Len of non-array type"));}n=(m.kindType);return((n.len>>0));};R.prototype.Len=function(){return this.$val.Len();};R.ptr.prototype.NumIn=function(){var m,n;m=this;if(!((m.Kind()===19))){$panic(new $String("reflect: NumIn of non-func type"));}n=(m.kindType);return((n.inCount>>0));};R.prototype.NumIn=function(){return this.$val.NumIn();};R.ptr.prototype.NumOut=function(){var m,n;m=this;if(!((m.Kind()===19))){$panic(new $String("reflect: NumOut of non-func type"));}n=(m.kindType);return n.out().$length;};R.prototype.NumOut=function(){return this.$val.NumOut();};R.ptr.prototype.Out=function(m){var m,n,o,p;n=this;if(!((n.Kind()===19))){$panic(new $String("reflect: Out of non-func type"));}o=(n.kindType);return AP((p=o.out(),((m<0||m>=p.$length)?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+m])));};R.prototype.Out=function(m){return this.$val.Out(m);};X.ptr.prototype.NumMethod=function(){var m;m=this;return m.methods.$length;};X.prototype.NumMethod=function(){return this.$val.NumMethod();};R.ptr.prototype.Implements=function(m){var{m,n,o,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=this;if($interfaceIsEqual(m,$ifaceNil)){$panic(new $String("reflect: nil type passed to Type.Implements"));}o=m.Kind();$s=3;case 3:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}if(!((o===20))){$s=1;continue;}$s=2;continue;case 1:$panic(new $String("reflect: non-interface type passed to Type.Implements"));case 2:$s=-1;return AK($assertType(m,DU),n);}return;}var $f={$blk:R.ptr.prototype.Implements,$c:true,$r,m,n,o,$s};return $f;};R.prototype.Implements=function(m){return this.$val.Implements(m);};R.ptr.prototype.AssignableTo=function(m){var{m,n,o,p,q,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=this;if($interfaceIsEqual(m,$ifaceNil)){$panic(new $String("reflect: nil type passed to Type.AssignableTo"));}o=$assertType(m,DU);p=AL(o,n);$s=1;case 1:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=p||AK(o,n);$s=2;case 2:return q;}return;}var $f={$blk:R.ptr.prototype.AssignableTo,$c:true,$r,m,n,o,p,q,$s};return $f;};R.prototype.AssignableTo=function(m){return this.$val.AssignableTo(m);};AK=function(m,n){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,m,n,o,p,q,r,s,t,u,v,w,x,y,z;if(!((m.Kind()===20))){return false;}o=(m.kindType);if(o.methods.$length===0){return true;}if(n.Kind()===20){p=(n.kindType);q=0;r=0;while(true){if(!(r=s.$length)?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+q]));u=$clone(o.rtype.nameOff(t.name),BO);w=(v=p.methods,((r<0||r>=v.$length)?($throwRuntimeError("index out of range"),undefined):v.$array[v.$offset+r]));x=$clone(n.nameOff(w.name),BO);if($clone(x,BO).name()===$clone(u,BO).name()&&n.typeOff(w.typ)===o.rtype.typeOff(t.typ)){if(!$clone(u,BO).isExported()){y=$clone(u,BO).pkgPath();if(y===""){y=$clone(o.pkgPath,BO).name();}z=$clone(x,BO).pkgPath();if(z===""){z=$clone(p.pkgPath,BO).name();}if(!(y===z)){r=r+(1)>>0;continue;}}q=q+(1)>>0;if(q>=o.methods.$length){return true;}}r=r+(1)>>0;}return false;}aa=n.uncommon();if(aa===EC.nil){return false;}ab=0;ac=aa.methods();ad=0;while(true){if(!(ad<((aa.mcount>>0)))){break;}af=(ae=o.methods,((ab<0||ab>=ae.$length)?($throwRuntimeError("index out of range"),undefined):ae.$array[ae.$offset+ab]));ag=$clone(o.rtype.nameOff(af.name),BO);ah=$clone(((ad<0||ad>=ac.$length)?($throwRuntimeError("index out of range"),undefined):ac.$array[ac.$offset+ad]),S);ai=$clone(n.nameOff(ah.name),BO);if($clone(ai,BO).name()===$clone(ag,BO).name()&&n.typeOff(ah.mtyp)===o.rtype.typeOff(af.typ)){if(!$clone(ag,BO).isExported()){aj=$clone(ag,BO).pkgPath();if(aj===""){aj=$clone(o.pkgPath,BO).name();}ak=$clone(ai,BO).pkgPath();if(ak===""){ak=$clone(n.nameOff(aa.pkgPath),BO).name();}if(!(aj===ak)){ad=ad+(1)>>0;continue;}}ab=ab+(1)>>0;if(ab>=o.methods.$length){return true;}}ad=ad+(1)>>0;}return false;};AL=function(m,n){var{m,n,o,p,$s,$r,$c}=$restore(this,{m,n});$s=$s||0;s:while(true){switch($s){case 0:if(m===n){$s=-1;return true;}if(m.hasName()&&n.hasName()||!((m.Kind()===n.Kind()))){$s=-1;return false;}o=AN(m,n,true);$s=1;case 1:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}p=o;$s=2;case 2:return p;}return;}var $f={$blk:AL,$c:true,$r,m,n,o,p,$s};return $f;};AM=function(m,n,o){var{m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{m,n,o});$s=$s||0;s:while(true){switch($s){case 0:if(o){$s=-1;return $interfaceIsEqual(m,n);}q=m.Name();$s=4;case 4:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=n.Name();$s=5;case 5:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}if(!(q===r)){p=true;$s=3;continue s;}s=m.Kind();$s=6;case 6:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}t=n.Kind();$s=7;case 7:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}p=!((s===t));case 3:if(p){$s=1;continue;}$s=2;continue;case 1:$s=-1;return false;case 2:u=m.common();$s=8;case 8:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}v=u;w=n.common();$s=9;case 9:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}x=w;y=AN(v,x,false);$s=10;case 10:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}z=y;$s=11;case 11:return z;}return;}var $f={$blk:AM,$c:true,$r,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};AN=function(m,n,o){var{aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{m,n,o});$s=$s||0;s:while(true){switch($s){case 0:if(m===n){$s=-1;return true;}p=m.Kind();if(!((p===n.Kind()))){$s=-1;return false;}if(1<=p&&p<=16||(p===24)||(p===26)){$s=-1;return true;}q=p;if(q===(17)){$s=2;continue;}if(q===(18)){$s=3;continue;}if(q===(19)){$s=4;continue;}if(q===(20)){$s=5;continue;}if(q===(21)){$s=6;continue;}if((q===(22))||(q===(23))){$s=7;continue;}if(q===(25)){$s=8;continue;}$s=9;continue;case 2:if(!(m.Len()===n.Len())){r=false;$s=10;continue s;}s=AM(m.Elem(),n.Elem(),o);$s=11;case 11:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}r=s;case 10:t=r;$s=12;case 12:return t;case 3:if(!(n.chanDir()===3)){u=false;$s=15;continue s;}v=AM(m.Elem(),n.Elem(),o);$s=16;case 16:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}u=v;case 15:if(u){$s=13;continue;}$s=14;continue;case 13:$s=-1;return true;case 14:if(!(n.chanDir()===m.chanDir())){w=false;$s=17;continue s;}x=AM(m.Elem(),n.Elem(),o);$s=18;case 18:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}w=x;case 17:y=w;$s=19;case 19:return y;case 4:z=(m.kindType);aa=(n.kindType);if(!((z.outCount===aa.outCount))||!((z.inCount===aa.inCount))){$s=-1;return false;}ab=0;case 20:if(!(ab>0;$s=20;continue;case 21:ad=0;case 25:if(!(ad>0;$s=25;continue;case 26:$s=-1;return true;case 5:af=(m.kindType);ag=(n.kindType);if((af.methods.$length===0)&&(ag.methods.$length===0)){$s=-1;return true;}$s=-1;return false;case 6:ai=AM(m.Key(),n.Key(),o);$s=31;case 31:if($c){$c=false;ai=ai.$blk();}if(ai&&ai.$blk!==undefined){break s;}if(!(ai)){ah=false;$s=30;continue s;}aj=AM(m.Elem(),n.Elem(),o);$s=32;case 32:if($c){$c=false;aj=aj.$blk();}if(aj&&aj.$blk!==undefined){break s;}ah=aj;case 30:ak=ah;$s=33;case 33:return ak;case 7:al=AM(m.Elem(),n.Elem(),o);$s=34;case 34:if($c){$c=false;al=al.$blk();}if(al&&al.$blk!==undefined){break s;}am=al;$s=35;case 35:return am;case 8:an=(m.kindType);ao=(n.kindType);if(!((an.fields.$length===ao.fields.$length))){$s=-1;return false;}if(!($clone(an.pkgPath,BO).name()===$clone(ao.pkgPath,BO).name())){$s=-1;return false;}ap=an.fields;aq=0;case 36:if(!(aq=as.$length)?($throwRuntimeError("index out of range"),undefined):as.$array[as.$offset+ar]));av=(au=ao.fields,((ar<0||ar>=au.$length)?($throwRuntimeError("index out of range"),undefined):au.$array[au.$offset+ar]));if(!($clone(at.name,BO).name()===$clone(av.name,BO).name())){$s=-1;return false;}aw=AM(at.typ,av.typ,o);$s=40;case 40:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}if(!aw){$s=38;continue;}$s=39;continue;case 38:$s=-1;return false;case 39:if(o&&!($clone(at.name,BO).tag()===$clone(av.name,BO).tag())){$s=-1;return false;}if(!((at.offsetEmbed===av.offsetEmbed))){$s=-1;return false;}aq++;$s=36;continue;case 37:$s=-1;return true;case 9:case 1:$s=-1;return false;}return;}var $f={$blk:AN,$c:true,$r,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};AP=function(m){var m;if(m===DU.nil){return $ifaceNil;}return m;};AQ=function(m){var m;return((m.kind&32)>>>0)===0;};E.ptr.prototype.object=function(){var m,n,o,p;m=this;if((m.typ.Kind()===17)||(m.typ.Kind()===25)){return m.ptr;}if(!((((m.flag&128)>>>0)===0))){n=m.ptr.$get();if(!(n===$ifaceNil)&&!(n.constructor===BI(m.typ))){switch(0){default:o=m.typ.Kind();if((o===(11))||(o===(6))){n=new(BI(m.typ))(n.$high,n.$low);}else if((o===(15))||(o===(16))){n=new(BI(m.typ))(n.$real,n.$imag);}else if(o===(23)){if(n===n.constructor.nil){n=BI(m.typ).nil;break;}p=new(BI(m.typ))(n.$array);p.$offset=n.$offset;p.$length=n.$length;p.$capacity=n.$capacity;n=p;}}}return n;}return m.ptr;};E.prototype.object=function(){return this.$val.object();};E.ptr.prototype.assignTo=function(m,n,o){var{m,n,o,p,q,r,s,t,u,$s,$r,$c}=$restore(this,{m,n,o});$s=$s||0;s:while(true){switch($s){case 0:p=this;if(!((((p.flag&512)>>>0)===0))){$s=1;continue;}$s=2;continue;case 1:q=DG(m,$clone(p,E));$s=3;case 3:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}E.copy(p,q);case 2:r=AL(n,p.typ);$s=8;case 8:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}if(r){$s=5;continue;}if(AK(n,p.typ)){$s=6;continue;}$s=7;continue;case 5:s=(((p.flag&384)>>>0)|new F(p.flag).ro())>>>0;s=(s|(((n.Kind()>>>0))))>>>0;$s=-1;return new E.ptr(n,p.ptr,s);case 6:if(o===0){o=CJ(n);}t=DD($clone(p,E));$s=9;case 9:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}u=t;if(n.NumMethod()===0){(o).$set(u);}else{DE(n,u,o);}$s=-1;return new E.ptr(n,o,148);case 7:case 4:$panic(new $String(m+": value of type "+p.typ.String()+" is not assignable to type "+n.String()));$s=-1;return new E.ptr(DU.nil,0,0);}return;}var $f={$blk:E.ptr.prototype.assignTo,$c:true,$r,m,n,o,p,q,r,s,t,u,$s};return $f;};E.prototype.assignTo=function(m,n,o){return this.$val.assignTo(m,n,o);};E.ptr.prototype.Cap=function(){var m,n,o;m=this;n=new F(m.flag).kind();o=n;if(o===(17)){return m.typ.Len();}else if((o===(18))||(o===(23))){return $parseInt($clone(m,E).object().$capacity)>>0;}$panic(new I.ptr("reflect.Value.Cap",n));};E.prototype.Cap=function(){return this.$val.Cap();};E.ptr.prototype.Index=function(m){var{aa,ab,ac,ad,ae,af,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:m=[m];n=[n];o=[o];p=[p];q=[q];r=[r];s=this;t=new F(s.flag).kind();u=t;if(u===(17)){$s=2;continue;}if(u===(23)){$s=3;continue;}if(u===(24)){$s=4;continue;}$s=5;continue;case 2:v=(s.typ.kindType);if(m[0]<0||m[0]>((v.len>>0))){$panic(new $String("reflect: array index out of range"));}q[0]=v.elem;w=(((((s.flag&384)>>>0)|new F(s.flag).ro())>>>0)|((q[0].Kind()>>>0)))>>>0;n[0]=s.ptr;if(!((((w&128)>>>0)===0))&&!((q[0].Kind()===17))&&!((q[0].Kind()===25))){$s=7;continue;}$s=8;continue;case 7:$s=-1;return new E.ptr(q[0],(new(BI(DL(q[0])))((function(m,n,o,p,q,r){return function(){return DI(q[0],n[0][m[0]]);};})(m,n,o,p,q,r),(function(m,n,o,p,q,r){return function(x){var x;n[0][m[0]]=DJ(q[0],x);};})(m,n,o,p,q,r))),w);case 8:x=BZ(q[0],DI(q[0],n[0][m[0]]),w);$s=9;case 9:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}y=x;$s=10;case 10:return y;case 3:z=$clone(s,E).object();if(m[0]<0||m[0]>=($parseInt(z.$length)>>0)){$panic(new $String("reflect: slice index out of range"));}aa=(s.typ.kindType);r[0]=aa.elem;ab=(((384|new F(s.flag).ro())>>>0)|((r[0].Kind()>>>0)))>>>0;m[0]=m[0]+(($parseInt(z.$offset)>>0))>>0;o[0]=z.$array;if(!((((ab&128)>>>0)===0))&&!((r[0].Kind()===17))&&!((r[0].Kind()===25))){$s=11;continue;}$s=12;continue;case 11:$s=-1;return new E.ptr(r[0],(new(BI(DL(r[0])))((function(m,n,o,p,q,r){return function(){return DI(r[0],o[0][m[0]]);};})(m,n,o,p,q,r),(function(m,n,o,p,q,r){return function(ac){var ac;o[0][m[0]]=DJ(r[0],ac);};})(m,n,o,p,q,r))),ab);case 12:ac=BZ(r[0],DI(r[0],o[0][m[0]]),ab);$s=13;case 13:if($c){$c=false;ac=ac.$blk();}if(ac&&ac.$blk!==undefined){break s;}ad=ac;$s=14;case 14:return ad;case 4:ae=(s.ptr).$get();if(m[0]<0||m[0]>=ae.length){$panic(new $String("reflect: string index out of range"));}af=(((new F(s.flag).ro()|8)>>>0)|128)>>>0;p[0]=ae.charCodeAt(m[0]);$s=-1;return new E.ptr(BD,((p.$ptr||(p.$ptr=new EG(function(){return this.$target[0];},function($v){this.$target[0]=$v;},p)))),af);case 5:$panic(new I.ptr("reflect.Value.Index",t));case 6:case 1:$s=-1;return new E.ptr(DU.nil,0,0);}return;}var $f={$blk:E.ptr.prototype.Index,$c:true,$r,aa,ab,ac,ad,ae,af,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};E.prototype.Index=function(m){return this.$val.Index(m);};E.ptr.prototype.InterfaceData=function(){var m;m=this;$panic(new $String("InterfaceData is not supported by GopherJS"));};E.prototype.InterfaceData=function(){return this.$val.InterfaceData();};E.ptr.prototype.IsNil=function(){var m,n,o;m=this;n=new F(m.flag).kind();o=n;if((o===(22))||(o===(23))){return $clone(m,E).object()===BI(m.typ).nil;}else if(o===(18)){return $clone(m,E).object()===$chanNil;}else if(o===(19)){return $clone(m,E).object()===$throwNilPointerError;}else if(o===(21)){return $clone(m,E).object()===false;}else if(o===(20)){return $clone(m,E).object()===$ifaceNil;}else if(o===(26)){return $clone(m,E).object()===0;}else{$panic(new I.ptr("reflect.Value.IsNil",n));}};E.prototype.IsNil=function(){return this.$val.IsNil();};E.ptr.prototype.Len=function(){var m,n,o;m=this;n=new F(m.flag).kind();o=n;if((o===(17))||(o===(24))){return $parseInt($clone(m,E).object().length);}else if(o===(23)){return $parseInt($clone(m,E).object().$length)>>0;}else if(o===(18)){return $parseInt($clone(m,E).object().$buffer.length)>>0;}else if(o===(21)){return $parseInt($keys($clone(m,E).object()).length);}else{$panic(new I.ptr("reflect.Value.Len",n));}};E.prototype.Len=function(){return this.$val.Len();};E.ptr.prototype.Pointer=function(){var m,n,o;m=this;n=new F(m.flag).kind();o=n;if((o===(18))||(o===(21))||(o===(22))||(o===(26))){if($clone(m,E).IsNil()){return 0;}return $clone(m,E).object();}else if(o===(19)){if($clone(m,E).IsNil()){return 0;}return 1;}else if(o===(23)){if($clone(m,E).IsNil()){return 0;}return $clone(m,E).object().$array;}else{$panic(new I.ptr("reflect.Value.Pointer",n));}};E.prototype.Pointer=function(){return this.$val.Pointer();};E.ptr.prototype.Set=function(m){var{m,n,o,p,q,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=this;new F(n.flag).mustBeAssignable();new F(m.flag).mustBeExported();o=$clone(m,E).assignTo("reflect.Set",n.typ,0);$s=1;case 1:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}E.copy(m,o);if(!((((n.flag&128)>>>0)===0))){$s=2;continue;}$s=3;continue;case 2:p=n.typ.Kind();if(p===(17)){$s=5;continue;}if(p===(20)){$s=6;continue;}if(p===(25)){$s=7;continue;}$s=8;continue;case 5:BI(n.typ).copy(n.ptr,m.ptr);$s=9;continue;case 6:q=DD($clone(m,E));$s=10;case 10:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}n.ptr.$set(q);$s=9;continue;case 7:BY(n.ptr,m.ptr,n.typ);$s=9;continue;case 8:n.ptr.$set($clone(m,E).object());case 9:case 4:$s=-1;return;case 3:n.ptr=m.ptr;$s=-1;return;}return;}var $f={$blk:E.ptr.prototype.Set,$c:true,$r,m,n,o,p,q,$s};return $f;};E.prototype.Set=function(m){return this.$val.Set(m);};E.ptr.prototype.SetBytes=function(m){var{m,n,o,p,q,r,s,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=this;new F(n.flag).mustBeAssignable();new F(n.flag).mustBe(23);o=n.typ.Elem().Kind();$s=3;case 3:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}if(!((o===8))){$s=1;continue;}$s=2;continue;case 1:$panic(new $String("reflect.Value.SetBytes of non-byte slice"));case 2:p=m;if(!(n.typ.Name()==="")){q=true;$s=6;continue s;}r=n.typ.Elem().Name();$s=7;case 7:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}q=!(r==="");case 6:if(q){$s=4;continue;}$s=5;continue;case 4:s=new(BI(n.typ))(p.$array);s.$offset=p.$offset;s.$length=p.$length;s.$capacity=p.$capacity;p=s;case 5:n.ptr.$set(p);$s=-1;return;}return;}var $f={$blk:E.ptr.prototype.SetBytes,$c:true,$r,m,n,o,p,q,r,s,$s};return $f;};E.prototype.SetBytes=function(m){return this.$val.SetBytes(m);};E.ptr.prototype.SetCap=function(m){var m,n,o,p;n=this;new F(n.flag).mustBeAssignable();new F(n.flag).mustBe(23);o=n.ptr.$get();if(m<($parseInt(o.$length)>>0)||m>($parseInt(o.$capacity)>>0)){$panic(new $String("reflect: slice capacity out of range in SetCap"));}p=new(BI(n.typ))(o.$array);p.$offset=o.$offset;p.$length=o.$length;p.$capacity=m;n.ptr.$set(p);};E.prototype.SetCap=function(m){return this.$val.SetCap(m);};E.ptr.prototype.SetLen=function(m){var m,n,o,p;n=this;new F(n.flag).mustBeAssignable();new F(n.flag).mustBe(23);o=n.ptr.$get();if(m<0||m>($parseInt(o.$capacity)>>0)){$panic(new $String("reflect: slice length out of range in SetLen"));}p=new(BI(n.typ))(o.$array);p.$offset=o.$offset;p.$length=m;p.$capacity=o.$capacity;n.ptr.$set(p);};E.prototype.SetLen=function(m){return this.$val.SetLen(m);};E.ptr.prototype.Slice=function(m,n){var{m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{m,n});$s=$s||0;s:while(true){switch($s){case 0:o=this;p=0;q=$ifaceNil;r=null;s=new F(o.flag).kind();t=s;if(t===(17)){$s=2;continue;}if(t===(23)){$s=3;continue;}if(t===(24)){$s=4;continue;}$s=5;continue;case 2:if(((o.flag&256)>>>0)===0){$panic(new $String("reflect.Value.Slice: slice of unaddressable array"));}u=(o.typ.kindType);p=((u.len>>0));q=CH(u.elem);r=new(BI(q))($clone(o,E).object());$s=6;continue;case 3:q=o.typ;r=$clone(o,E).object();p=$parseInt(r.$capacity)>>0;$s=6;continue;case 4:v=(o.ptr).$get();if(m<0||nv.length){$panic(new $String("reflect.Value.Slice: string slice index out of bounds"));}w=CC(new $String($substring(v,m,n)));$s=7;case 7:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}x=w;$s=8;case 8:return x;case 5:$panic(new I.ptr("reflect.Value.Slice",s));case 6:case 1:if(m<0||np){$panic(new $String("reflect.Value.Slice: slice index out of bounds"));}y=BZ(q,$subslice(r,m,n),new F(o.flag).ro());$s=9;case 9:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}z=y;$s=10;case 10:return z;}return;}var $f={$blk:E.ptr.prototype.Slice,$c:true,$r,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};E.prototype.Slice=function(m,n){return this.$val.Slice(m,n);};E.ptr.prototype.Slice3=function(m,n,o){var{m,n,o,p,q,r,s,t,u,v,w,x,$s,$r,$c}=$restore(this,{m,n,o});$s=$s||0;s:while(true){switch($s){case 0:p=this;q=0;r=$ifaceNil;s=null;t=new F(p.flag).kind();u=t;if(u===(17)){if(((p.flag&256)>>>0)===0){$panic(new $String("reflect.Value.Slice: slice of unaddressable array"));}v=(p.typ.kindType);q=((v.len>>0));r=CH(v.elem);s=new(BI(r))($clone(p,E).object());}else if(u===(23)){r=p.typ;s=$clone(p,E).object();q=$parseInt(s.$capacity)>>0;}else{$panic(new I.ptr("reflect.Value.Slice3",t));}if(m<0||nq){$panic(new $String("reflect.Value.Slice3: slice index out of bounds"));}w=BZ(r,$subslice(s,m,n,o),new F(p.flag).ro());$s=1;case 1:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}x=w;$s=2;case 2:return x;}return;}var $f={$blk:E.ptr.prototype.Slice3,$c:true,$r,m,n,o,p,q,r,s,t,u,v,w,x,$s};return $f;};E.prototype.Slice3=function(m,n,o){return this.$val.Slice3(m,n,o);};E.ptr.prototype.Close=function(){var m;m=this;new F(m.flag).mustBe(18);new F(m.flag).mustBeExported();$close($clone(m,E).object());};E.prototype.Close=function(){return this.$val.Close();};E.ptr.prototype.Elem=function(){var{m,n,o,p,q,r,s,t,u,v,$s,$r,$c}=$restore(this,{});$s=$s||0;s:while(true){switch($s){case 0:m=this;n=new F(m.flag).kind();o=n;if(o===(20)){$s=2;continue;}if(o===(22)){$s=3;continue;}$s=4;continue;case 2:p=$clone(m,E).object();if(p===$ifaceNil){$s=-1;return new E.ptr(DU.nil,0,0);}q=BJ(p.constructor);r=BZ(q,p.$val,new F(m.flag).ro());$s=6;case 6:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}s=r;$s=7;case 7:return s;case 3:if($clone(m,E).IsNil()){$s=-1;return new E.ptr(DU.nil,0,0);}t=$clone(m,E).object();u=(m.typ.kindType);v=(((((m.flag&96)>>>0)|128)>>>0)|256)>>>0;v=(v|(((u.elem.Kind()>>>0))))>>>0;$s=-1;return new E.ptr(u.elem,(DI(u.elem,t)),v);case 4:$panic(new I.ptr("reflect.Value.Elem",n));case 5:case 1:$s=-1;return new E.ptr(DU.nil,0,0);}return;}var $f={$blk:E.ptr.prototype.Elem,$c:true,$r,m,n,o,p,q,r,s,t,u,v,$s};return $f;};E.prototype.Elem=function(){return this.$val.Elem();};E.ptr.prototype.NumField=function(){var m,n;m=this;new F(m.flag).mustBe(25);n=(m.typ.kindType);return n.fields.$length;};E.prototype.NumField=function(){return this.$val.NumField();};E.ptr.prototype.MapKeys=function(){var{m,n,o,p,q,r,s,t,u,v,w,$s,$r,$c}=$restore(this,{});$s=$s||0;s:while(true){switch($s){case 0:m=this;new F(m.flag).mustBe(21);n=(m.typ.kindType);o=n.key;p=(new F(m.flag).ro()|((o.Kind()>>>0)))>>>0;q=$clone(m,E).pointer();r=0;if(!(q===0)){r=CZ(q);}s=CV(m.typ,q);t=$makeSlice(EF,r);u=0;u=0;case 1:if(!(u=t.$length)?($throwRuntimeError("index out of range"),undefined):t.$array[t.$offset+u]),DM(o,p,w));CY(s);u=u+(1)>>0;$s=1;continue;case 2:$s=-1;return $subslice(t,0,u);}return;}var $f={$blk:E.ptr.prototype.MapKeys,$c:true,$r,m,n,o,p,q,r,s,t,u,v,w,$s};return $f;};E.prototype.MapKeys=function(){return this.$val.MapKeys();};E.ptr.prototype.MapIndex=function(m){var{m,n,o,p,q,r,s,t,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=this;new F(n.flag).mustBe(21);o=(n.typ.kindType);p=$clone(m,E).assignTo("reflect.Value.MapIndex",o.key,0);$s=1;case 1:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}E.copy(m,p);q=0;if(!((((m.flag&128)>>>0)===0))){q=m.ptr;}else{q=((m.$ptr_ptr||(m.$ptr_ptr=new EH(function(){return this.$target.ptr;},function($v){this.$target.ptr=$v;},m))));}r=CR(n.typ,$clone(n,E).pointer(),q);if(r===0){$s=-1;return new E.ptr(DU.nil,0,0);}s=o.elem;t=new F((((n.flag|m.flag)>>>0))).ro();t=(t|(((s.Kind()>>>0))))>>>0;$s=-1;return DM(s,t,r);}return;}var $f={$blk:E.ptr.prototype.MapIndex,$c:true,$r,m,n,o,p,q,r,s,t,$s};return $f;};E.prototype.MapIndex=function(m){return this.$val.MapIndex(m);};E.ptr.prototype.Field=function(m){var{aa,ab,ac,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=[n];o=[o];p=[p];q=[q];r=this;if(!((new F(r.flag).kind()===25))){$panic(new I.ptr("reflect.Value.Field",new F(r.flag).kind()));}s=(r.typ.kindType);if(((m>>>0))>=((s.fields.$length>>>0))){$panic(new $String("reflect: Field index out of range"));}o[0]=$internalize(BI(r.typ).fields[m].prop,$String);u=(t=s.fields,((m<0||m>=t.$length)?($throwRuntimeError("index out of range"),undefined):t.$array[t.$offset+m]));q[0]=u.typ;v=(((r.flag&416)>>>0)|((q[0].Kind()>>>0)))>>>0;if(!$clone(u.name,BO).isExported()){if(u.embedded()){v=(v|(64))>>>0;}else{v=(v|(32))>>>0;}}x=$clone((w=s.fields,((m<0||m>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+m])).name,BO).tag();if(!(x==="")&&!((m===0))){$s=1;continue;}$s=2;continue;case 1:n[0]=DK(x);if(!(n[0]==="")){$s=3;continue;}$s=4;continue;case 3:case 5:y=[y];z=$clone(r,E).Field(0);$s=7;case 7:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}E.copy(r,z);if(r.typ===DH){$s=8;continue;}$s=9;continue;case 8:y[0]=$clone(r,E).object().object;$s=-1;return new E.ptr(q[0],(new(BI(DL(q[0])))((function(n,o,p,q,y){return function(){return $internalize(y[0][$externalize(n[0],$String)],BI(q[0]));};})(n,o,p,q,y),(function(n,o,p,q,y){return function(aa){var aa;y[0][$externalize(n[0],$String)]=$externalize(aa,BI(q[0]));};})(n,o,p,q,y))),v);case 9:if(r.typ.Kind()===22){$s=10;continue;}$s=11;continue;case 10:aa=$clone(r,E).Elem();$s=12;case 12:if($c){$c=false;aa=aa.$blk();}if(aa&&aa.$blk!==undefined){break s;}E.copy(r,aa);case 11:$s=5;continue;case 6:case 4:case 2:p[0]=r.ptr;if(!((((v&128)>>>0)===0))&&!((q[0].Kind()===17))&&!((q[0].Kind()===25))){$s=13;continue;}$s=14;continue;case 13:$s=-1;return new E.ptr(q[0],(new(BI(DL(q[0])))((function(n,o,p,q){return function(){return DI(q[0],p[0][$externalize(o[0],$String)]);};})(n,o,p,q),(function(n,o,p,q){return function(ab){var ab;p[0][$externalize(o[0],$String)]=DJ(q[0],ab);};})(n,o,p,q))),v);case 14:ab=BZ(q[0],DI(q[0],p[0][$externalize(o[0],$String)]),v);$s=15;case 15:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}ac=ab;$s=16;case 16:return ac;}return;}var $f={$blk:E.ptr.prototype.Field,$c:true,$r,aa,ab,ac,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};E.prototype.Field=function(m){return this.$val.Field(m);};AT.ptr.prototype.Error=function(){var m;m=this;return m.s;};AT.prototype.Error=function(){return this.$val.Error();};AU=function(m){var m;if(m.length<2){return[m,$ifaceNil];}if((m.charCodeAt(0)===39)||(m.charCodeAt(0)===34)){if(m.charCodeAt((m.length-1>>0))===m.charCodeAt(0)){return[$substring(m,1,(m.length-1>>0)),$ifaceNil];}return["",$pkg.ErrSyntax];}return[m,$ifaceNil];};F.prototype.mustBe=function(m){var m,n;n=this.$val;if(!((((((n&31)>>>0)>>>0))===m))){$panic(new I.ptr(DF(),new F(n).kind()));}};$ptrType(F).prototype.mustBe=function(m){return new F(this.$get()).mustBe(m);};R.ptr.prototype.Comparable=function(){var{m,n,o,p,q,r,s,$s,$r,$c}=$restore(this,{});$s=$s||0;s:while(true){switch($s){case 0:m=this;n=m.Kind();if((n===(19))||(n===(23))||(n===(21))){$s=2;continue;}if(n===(17)){$s=3;continue;}if(n===(25)){$s=4;continue;}$s=5;continue;case 2:$s=-1;return false;case 3:o=m.Elem().Comparable();$s=6;case 6:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}p=o;$s=7;case 7:return p;case 4:q=0;case 8:if(!(q>0;$s=8;continue;case 9:case 5:case 1:$s=-1;return true;}return;}var $f={$blk:R.ptr.prototype.Comparable,$c:true,$r,m,n,o,p,q,r,s,$s};return $f;};R.prototype.Comparable=function(){return this.$val.Comparable();};R.ptr.prototype.IsVariadic=function(){var m,n;m=this;if(!((m.Kind()===19))){$panic(new $String("reflect: IsVariadic of non-func type"));}n=(m.kindType);return!((((n.outCount&32768)>>>0)===0));};R.prototype.IsVariadic=function(){return this.$val.IsVariadic();};R.ptr.prototype.Field=function(m){var m,n,o,p;n=this;if(!((n.Kind()===25))){$panic(new $String("reflect: Field of non-struct type"));}o=(n.kindType);if(m<0||m>=o.fields.$length){$panic(new $String("reflect: Field index out of bounds"));}return(p=o.fields,((m<0||m>=p.$length)?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+m]));};R.prototype.Field=function(m){return this.$val.Field(m);};R.ptr.prototype.Key=function(){var m,n;m=this;if(!((m.Kind()===21))){$panic(new $String("reflect: Key of non-map type"));}n=(m.kindType);return AP(n.key);};R.prototype.Key=function(){return this.$val.Key();};R.ptr.prototype.NumField=function(){var m,n;m=this;if(!((m.Kind()===25))){$panic(new $String("reflect: NumField of non-struct type"));}n=(m.kindType);return n.fields.$length;};R.prototype.NumField=function(){return this.$val.NumField();};R.ptr.prototype.Method=function(m){var{aa,ab,ac,ad,ae,af,ag,ah,ai,aj,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=[n];o=new AV.ptr("","",$ifaceNil,new E.ptr(DU.nil,0,0),0);p=this;if(p.Kind()===20){$s=1;continue;}$s=2;continue;case 1:q=(p.kindType);r=q.rtype.Method(m);$s=3;case 3:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}AV.copy(o,r);s=o;$s=4;case 4:return s;case 2:t=p.exportedMethods();if(m<0||m>=t.$length){$panic(new $String("reflect: Method index out of range"));}u=$clone(((m<0||m>=t.$length)?($throwRuntimeError("index out of range"),undefined):t.$array[t.$offset+m]),S);v=$clone(p.nameOff(u.name),BO);o.Name=$clone(v,BO).name();w=19;x=p.typeOff(u.mtyp);y=(x.kindType);z=$makeSlice(EI,0,(1+y.in$().$length>>0));z=$append(z,p);aa=y.in$();ab=0;while(true){if(!(ab=aa.$length)?($throwRuntimeError("index out of range"),undefined):aa.$array[aa.$offset+ab]);z=$append(z,ac);ab++;}ad=$makeSlice(EI,0,y.out().$length);ae=y.out();af=0;while(true){if(!(af=ae.$length)?($throwRuntimeError("index out of range"),undefined):ae.$array[ae.$offset+af]);ad=$append(ad,ag);af++;}ah=CF(z,ad,y.rtype.IsVariadic());$s=5;case 5:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}ai=ah;o.Type=ai;n[0]=$internalize($methodSet(p[$externalize(BE,$String)])[m].prop,$String);aj=D.MakeFunc((function(n){return function(aj,ak){var aj,ak,al;al=(0>=ak.$length?($throwRuntimeError("index out of range"),undefined):ak.$array[ak.$offset+0]);return new $jsObjectPtr(al[$externalize(n[0],$String)].apply(al,$externalize($subslice(ak,1),EJ)));};})(n));E.copy(o.Func,new E.ptr($assertType(ai,DU),(aj),w));o.Index=m;AV.copy(o,o);$s=-1;return o;}return;}var $f={$blk:R.ptr.prototype.Method,$c:true,$r,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};R.prototype.Method=function(m){return this.$val.Method(m);};BA=function(m){var{m,n,o,p,q,r,s,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=[n];o=[o];p=[p];q=CC(m);$s=1;case 1:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=$clone(q,E);if(!(($clone(r,E).Kind()===23))){$panic(new I.ptr("Swapper",$clone(r,E).Kind()));}p[0]=(($clone(r,E).Len()>>>0));s=p[0];if(s===(0)){$s=-1;return(function(n,o,p){return function(t,u){var t,u;$panic(new $String("reflect: slice index out of range"));};})(n,o,p);}else if(s===(1)){$s=-1;return(function(n,o,p){return function(t,u){var t,u;if(!((t===0))||!((u===0))){$panic(new $String("reflect: slice index out of range"));}};})(n,o,p);}n[0]=m.$array;o[0]=$parseInt(m.$offset)>>0;$s=-1;return(function(n,o,p){return function(t,u){var t,u,v;if(((t>>>0))>=p[0]||((u>>>0))>=p[0]){$panic(new $String("reflect: slice index out of range"));}t=t+(o[0])>>0;u=u+(o[0])>>0;v=n[0][t];n[0][t]=n[0][u];n[0][u]=v;};})(n,o,p);}return;}var $f={$blk:BA,$c:true,$r,m,n,o,p,q,r,s,$s};return $f;};$pkg.Swapper=BA;BC=function(){var{m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{});$s=$s||0;s:while(true){switch($s){case 0:m=(function(m){var m;});$r=m((n=new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),new n.constructor.elem(n)));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((o=new BL.ptr(0,0,0,0,ED.nil),new o.constructor.elem(o)));$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((p=new S.ptr(0,0,0,0),new p.constructor.elem(p)));$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((q=new U.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),DU.nil,DU.nil,0),new q.constructor.elem(q)));$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((r=new V.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),DU.nil,0),new r.constructor.elem(r)));$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((s=new BN.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),0,0,DW.nil,DW.nil),new s.constructor.elem(s)));$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((t=new X.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),new BO.ptr(EG.nil),EK.nil),new t.constructor.elem(t)));$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((u=new Y.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),DU.nil,DU.nil,DU.nil,$throwNilPointerError,0,0,0,0),new u.constructor.elem(u)));$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((v=new Z.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),DU.nil),new v.constructor.elem(v)));$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((w=new AA.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),DU.nil),new w.constructor.elem(w)));$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((x=new AC.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),new BO.ptr(EG.nil),EL.nil),new x.constructor.elem(x)));$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((y=new W.ptr(0,0),new y.constructor.elem(y)));$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=m((z=new AB.ptr(new BO.ptr(EG.nil),DU.nil,0),new z.constructor.elem(z)));$s=13;case 13:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}BB=true;BD=$assertType(CB(new $Uint8(0)),DU);$s=-1;return;}return;}var $f={$blk:BC,$c:true,$r,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};BI=function(m){var m;return m[$externalize(BE,$String)];};BJ=function(m){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,m,n,o,p,q,r,s,t,u,v,w,x,y,z;if(m[$externalize(BF,$String)]===undefined){n=new R.ptr(((($parseInt(m.size)>>0)>>>0)),0,0,0,0,0,((($parseInt(m.kind)>>0)<<24>>>24)),$throwNilPointerError,EG.nil,BT($clone(BR(BW(m.string),"",!!(m.exported)),BO)),0);n[$externalize(BE,$String)]=m;m[$externalize(BF,$String)]=n;o=$methodSet(m);if(!(($parseInt(o.length)===0))||!!(m.named)){n.tflag=(n.tflag|(1))>>>0;if(!!(m.named)){n.tflag=(n.tflag|(4))>>>0;}p=ED.nil;q=0;while(true){if(!(q<$parseInt(o.length))){break;}r=o[q];s=BW(r.pkg)==="";if(!s){q=q+(1)>>0;continue;}p=$append(p,new S.ptr(BT($clone(BR(BW(r.name),"",s),BO)),BV(BJ(r.typ)),0,0));q=q+(1)>>0;}t=((p.$length<<16>>>16));u=0;while(true){if(!(u<$parseInt(o.length))){break;}v=o[u];w=BW(v.pkg)==="";if(w){u=u+(1)>>0;continue;}p=$append(p,new S.ptr(BT($clone(BR(BW(v.name),"",w),BO)),BV(BJ(v.typ)),0,0));u=u+(1)>>0;}x=new BL.ptr(BT($clone(BR(BW(m.pkg),"",false),BO)),(($parseInt(o.length)<<16>>>16)),t,0,p);y=n;(BM||$throwRuntimeError("assignment to entry in nil map"))[DU.keyFor(y)]={k:y,v:x};x[$externalize(BE,$String)]=m;}z=n.Kind();if(z===(17)){BK(n,new U.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),BJ(m.elem),DU.nil,((($parseInt(m.len)>>0)>>>0))));}else if(z===(18)){aa=3;if(!!(m.sendOnly)){aa=2;}if(!!(m.recvOnly)){aa=1;}BK(n,new V.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),BJ(m.elem),((aa>>>0))));}else if(z===(19)){ab=m.params;ac=$makeSlice(DW,$parseInt(ab.length));ad=ac;ae=0;while(true){if(!(ae=ac.$length)?($throwRuntimeError("index out of range"),undefined):ac.$array[ac.$offset+af]=BJ(ab[af]));ae++;}ag=m.results;ah=$makeSlice(DW,$parseInt(ag.length));ai=ah;aj=0;while(true){if(!(aj=ah.$length)?($throwRuntimeError("index out of range"),undefined):ah.$array[ah.$offset+ak]=BJ(ag[ak]));aj++;}al=(($parseInt(ag.length)<<16>>>16));if(!!(m.variadic)){al=(al|(32768))>>>0;}BK(n,new BN.ptr($clone(n,R),(($parseInt(ab.length)<<16>>>16)),al,ac,ah));}else if(z===(20)){am=m.methods;an=$makeSlice(EK,$parseInt(am.length));ao=an;ap=0;while(true){if(!(ap=an.$length)?($throwRuntimeError("index out of range"),undefined):an.$array[an.$offset+aq]),new W.ptr(BT($clone(BR(BW(ar.name),"",BW(ar.pkg)===""),BO)),BV(BJ(ar.typ))));ap++;}BK(n,new X.ptr($clone(n,R),$clone(BR(BW(m.pkg),"",false),BO),an));}else if(z===(21)){BK(n,new Y.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),BJ(m.key),BJ(m.elem),DU.nil,$throwNilPointerError,0,0,0,0));}else if(z===(22)){BK(n,new Z.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),BJ(m.elem)));}else if(z===(23)){BK(n,new AA.ptr(new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0),BJ(m.elem)));}else if(z===(25)){as=m.fields;at=$makeSlice(EL,$parseInt(as.length));au=at;av=0;while(true){if(!(av>>0))<<1>>>0;if(!!(ax.embedded)){ay=(ay|(1))>>>0;}AB.copy(((aw<0||aw>=at.$length)?($throwRuntimeError("index out of range"),undefined):at.$array[at.$offset+aw]),new AB.ptr($clone(BR(BW(ax.name),BW(ax.tag),!!(ax.exported)),BO),BJ(ax.typ),ay));av++;}BK(n,new AC.ptr($clone(n,R),$clone(BR(BW(m.pkgPath),"",false),BO),at));}}return((m[$externalize(BF,$String)]));};BK=function(m,n){var m,n;m[$externalize(BG,$String)]=n;n[$externalize(BH,$String)]=m;};BL.ptr.prototype.methods=function(){var m;m=this;return m._methods;};BL.prototype.methods=function(){return this.$val.methods();};BL.ptr.prototype.exportedMethods=function(){var m;m=this;return $subslice(m._methods,0,m.xcount,m.xcount);};BL.prototype.exportedMethods=function(){return this.$val.exportedMethods();};R.ptr.prototype.uncommon=function(){var m,n;m=this;return(n=BM[DU.keyFor(m)],n!==undefined?n.v:EC.nil);};R.prototype.uncommon=function(){return this.$val.uncommon();};BN.ptr.prototype.in$=function(){var m;m=this;return m._in;};BN.prototype.in$=function(){return this.$val.in$();};BN.ptr.prototype.out=function(){var m;m=this;return m._out;};BN.prototype.out=function(){return this.$val.out();};BO.ptr.prototype.name=function(){var m,n,o;m="";n=this;m=(o=BQ[EG.keyFor(n.bytes)],o!==undefined?o.v:EM.nil).name;return m;};BO.prototype.name=function(){return this.$val.name();};BO.ptr.prototype.tag=function(){var m,n,o;m="";n=this;m=(o=BQ[EG.keyFor(n.bytes)],o!==undefined?o.v:EM.nil).tag;return m;};BO.prototype.tag=function(){return this.$val.tag();};BO.ptr.prototype.pkgPath=function(){var m;m=this;return"";};BO.prototype.pkgPath=function(){return this.$val.pkgPath();};BO.ptr.prototype.isExported=function(){var m,n;m=this;return(n=BQ[EG.keyFor(m.bytes)],n!==undefined?n.v:EM.nil).exported;};BO.prototype.isExported=function(){return this.$val.isExported();};BR=function(m,n,o){var m,n,o,p,q;p=$newDataPointer(0,EG);q=p;(BQ||$throwRuntimeError("assignment to entry in nil map"))[EG.keyFor(q)]={k:q,v:new BP.ptr(m,n,o)};return new BO.ptr(p);};R.ptr.prototype.nameOff=function(m){var m,n,o;n=this;return(o=((m>>0)),((o<0||o>=BS.$length)?($throwRuntimeError("index out of range"),undefined):BS.$array[BS.$offset+o]));};R.prototype.nameOff=function(m){return this.$val.nameOff(m);};BT=function(m){var m,n;n=BS.$length;BS=$append(BS,m);return((n>>0));};R.ptr.prototype.typeOff=function(m){var m,n,o;n=this;return(o=((m>>0)),((o<0||o>=BU.$length)?($throwRuntimeError("index out of range"),undefined):BU.$array[BU.$offset+o]));};R.prototype.typeOff=function(m){return this.$val.typeOff(m);};BV=function(m){var m,n;n=BU.$length;BU=$append(BU,m);return((n>>0));};BW=function(m){var m,n;n=new EN.ptr("");n.str=m;return n.str;};BX=function(m){var m;return!!(BI(m).wrapped);};BY=function(m,n,o){var m,n,o,p,q,r;p=BI(o).fields;q=0;while(true){if(!(q<$parseInt(p.length))){break;}r=$internalize(p[q].prop,$String);m[$externalize(r,$String)]=n[$externalize(r,$String)];q=q+(1)>>0;}};BZ=function(m,n,o){var{m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{m,n,o});$s=$s||0;s:while(true){switch($s){case 0:p=m.common();$s=1;case 1:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=p;t=m.Kind();$s=6;case 6:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}if(t===17){s=true;$s=5;continue s;}u=m.Kind();$s=7;case 7:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}s=u===25;case 5:if(s){r=true;$s=4;continue s;}v=m.Kind();$s=8;case 8:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}r=v===22;case 4:if(r){$s=2;continue;}$s=3;continue;case 2:w=m.Kind();$s=9;case 9:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}x=new E.ptr(q,(n),(o|((w>>>0)))>>>0);$s=10;case 10:return x;case 3:y=m.Kind();$s=11;case 11:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}z=new E.ptr(q,($newDataPointer(n,BI(q.ptrTo()))),(((o|((y>>>0)))>>>0)|128)>>>0);$s=12;case 12:return z;}return;}var $f={$blk:BZ,$c:true,$r,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};CB=function(m){var m;if(!BB){return new R.ptr(0,0,0,0,0,0,0,$throwNilPointerError,EG.nil,0,0);}if($interfaceIsEqual(m,$ifaceNil)){return $ifaceNil;}return BJ(m.constructor);};$pkg.TypeOf=CB;CC=function(m){var{m,n,o,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:if($interfaceIsEqual(m,$ifaceNil)){$s=-1;return new E.ptr(DU.nil,0,0);}n=BZ(BJ(m.constructor),m.$val,0);$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}o=n;$s=2;case 2:return o;}return;}var $f={$blk:CC,$c:true,$r,m,n,o,$s};return $f;};$pkg.ValueOf=CC;CF=function(m,n,o){var{aa,ab,ac,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{m,n,o});$s=$s||0;s:while(true){switch($s){case 0:if(!(o)){p=false;$s=3;continue s;}if(m.$length===0){q=true;$s=4;continue s;}s=(r=m.$length-1>>0,((r<0||r>=m.$length)?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+r])).Kind();$s=5;case 5:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}q=!((s===23));case 4:p=q;case 3:if(p){$s=1;continue;}$s=2;continue;case 1:$panic(new $String("reflect.FuncOf: last arg of variadic func must be slice"));case 2:t=$makeSlice(EJ,m.$length);u=m;v=0;while(true){if(!(v=u.$length)?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+v]);((w<0||w>=t.$length)?($throwRuntimeError("index out of range"),undefined):t.$array[t.$offset+w]=BI(x));v++;}y=$makeSlice(EJ,n.$length);z=n;aa=0;while(true){if(!(aa=z.$length)?($throwRuntimeError("index out of range"),undefined):z.$array[z.$offset+aa]);((ab<0||ab>=y.$length)?($throwRuntimeError("index out of range"),undefined):y.$array[y.$offset+ab]=BI(ac));aa++;}$s=-1;return BJ($funcType($externalize(t,EJ),$externalize(y,EJ),$externalize(o,$Bool)));}return;}var $f={$blk:CF,$c:true,$r,aa,ab,ac,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};$pkg.FuncOf=CF;R.ptr.prototype.ptrTo=function(){var m;m=this;return BJ($ptrType(BI(m)));};R.prototype.ptrTo=function(){return this.$val.ptrTo();};CH=function(m){var m;return BJ($sliceType(BI(m)));};$pkg.SliceOf=CH;CJ=function(m){var m,n;n=m.Kind();if(n===(25)){return(new(BI(m).ptr)());}else if(n===(17)){return(BI(m).zero());}else{return($newDataPointer(BI(m).zero(),BI(m.ptrTo())));}};CM=function(m,n,o){var m,n,o;n.$set(o.$get());};CQ=function(m,n){var m,n,o,p;o=n;if(!(o.$get===undefined)){o=o.$get();}p=$internalize(BI(m.Key()).keyFor(o),$String);return[o,p];};CR=function(m,n,o){var m,n,o,p,q,r;p=CQ(m,o);q=p[1];r=n[$externalize(q,$String)];if(r===undefined){return 0;}return($newDataPointer(r.v,BI(DL(m.Elem()))));};CU.ptr.prototype.skipUntilValidKey=function(){var m,n;m=this;while(true){if(!(m.i<$parseInt(m.keys.length))){break;}n=m.keys[m.i];if(!(m.m[$externalize($internalize(n,$String),$String)]===undefined)){break;}m.i=m.i+(1)>>0;}};CU.prototype.skipUntilValidKey=function(){return this.$val.skipUntilValidKey();};CV=function(m,n){var m,n;return(new CU.ptr(m,n,$keys(n),0,null));};CX=function(m){var{m,n,o,p,q,r,s,t,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:n=($pointerOfStructConversion(m,EO));o=null;if(!(n.last===null)){o=n.last;}else{n.skipUntilValidKey();if(n.i===$parseInt(n.keys.length)){$s=-1;return 0;}p=n.keys[n.i];o=n.m[$externalize($internalize(p,$String),$String)];n.last=o;}q=$assertType(n.t,CW).Key();$s=1;case 1:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=DL(q);$s=2;case 2:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}s=BI(r);$s=3;case 3:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}t=($newDataPointer(o.k,s));$s=4;case 4:return t;}return;}var $f={$blk:CX,$c:true,$r,m,n,o,p,q,r,s,t,$s};return $f;};CY=function(m){var m,n;n=($pointerOfStructConversion(m,EO));n.last=null;n.i=n.i+(1)>>0;};CZ=function(m){var m;return $parseInt($keys(m).length);};DC=function(m,n,o){var m,n,o,p,q,r,s,t,u,v,w,x,y;p=DU.nil;q=EE.nil;r=0;s="";if(n.typ.Kind()===20){t=(n.typ.kindType);if(o<0||o>=t.methods.$length){$panic(new $String("reflect: internal error: invalid method index"));}v=(u=t.methods,((o<0||o>=u.$length)?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+o]));if(!$clone(t.rtype.nameOff(v.name),BO).isExported()){$panic(new $String("reflect: "+m+" of unexported method"));}q=(t.rtype.typeOff(v.typ).kindType);s=$clone(t.rtype.nameOff(v.name),BO).name();}else{w=n.typ.exportedMethods();if(((o>>>0))>=((w.$length>>>0))){$panic(new $String("reflect: internal error: invalid method index"));}x=$clone(((o<0||o>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+o]),S);if(!$clone(n.typ.nameOff(x.name),BO).isExported()){$panic(new $String("reflect: "+m+" of unexported method"));}q=(n.typ.typeOff(x.mtyp).kindType);s=$internalize($methodSet(BI(n.typ))[o].prop,$String);}y=$clone(n,E).object();if(BX(n.typ)){y=new(BI(n.typ))(y);}r=(y[$externalize(s,$String)]);return[p,q,r];};DD=function(m){var{m,n,$s,$r,$c}=$restore(this,{m});$s=$s||0;s:while(true){switch($s){case 0:if(m.flag===0){$panic(new I.ptr("reflect.Value.Interface",0));}if(!((((m.flag&512)>>>0)===0))){$s=1;continue;}$s=2;continue;case 1:n=DG("Interface",$clone(m,E));$s=3;case 3:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}E.copy(m,n);case 2:if(BX(m.typ)){$s=-1;return((new(BI(m.typ))($clone(m,E).object())));}$s=-1;return(($clone(m,E).object()));}return;}var $f={$blk:DD,$c:true,$r,m,n,$s};return $f;};DE=function(m,n,o){var m,n,o;o.$set(n);};DF=function(){return"?FIXME?";};DG=function(m,n){var{m,n,o,p,q,r,s,t,$s,$r,$c}=$restore(this,{m,n});$s=$s||0;s:while(true){switch($s){case 0:o=[o];p=[p];if(((n.flag&512)>>>0)===0){$panic(new $String("reflect: internal error: invalid use of makePartialFunc"));}q=DC(m,$clone(n,E),((n.flag>>0))>>10>>0);o[0]=q[2];p[0]=$clone(n,E).object();if(BX(n.typ)){p[0]=new(BI(n.typ))(p[0]);}r=D.MakeFunc((function(o,p){return function(r,s){var r,s;return new $jsObjectPtr(o[0].apply(p[0],$externalize(s,EJ)));};})(o,p));s=$clone(n,E).Type().common();$s=1;case 1:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}t=new E.ptr(s,(r),(new F(n.flag).ro()|19)>>>0);$s=2;case 2:return t;}return;}var $f={$blk:DG,$c:true,$r,m,n,o,p,q,r,s,t,$s};return $f;};DI=function(m,n){var m,n;if($interfaceIsEqual(m,DH)){return new(BI(DH))(n);}return n;};DJ=function(m,n){var m,n;if($interfaceIsEqual(m,DH)){return n.object;}return n;};DK=function(m){var m,n,o,p,q,r;while(true){if(!(!(m===""))){break;}n=0;while(true){if(!(n>0;}m=$substring(m,n);if(m===""){break;}n=0;while(true){if(!(n>0;}if((n+1>>0)>=m.length||!((m.charCodeAt(n)===58))||!((m.charCodeAt((n+1>>0))===34))){break;}o=($substring(m,0,n));m=$substring(m,(n+1>>0));n=1;while(true){if(!(n>0;}n=n+(1)>>0;}if(n>=m.length){break;}p=($substring(m,0,(n+1>>0)));m=$substring(m,(n+1>>0));if(o==="js"){q=AU(p);r=q[0];return r;}}return"";};DL=function(m){var m;return $assertType(m,DU).ptrTo();};$pkg.PtrTo=DL;DM=function(m,n,o){var m,n,o,p;if(AQ(m)){p=CJ(m);CM(m,p,o);return new E.ptr(m,p,(n|128)>>>0);}return new E.ptr(m,(o).$get(),n);};E.methods=[{prop:"pointer",name:"pointer",pkg:"internal/reflectlite",typ:$funcType([],[$UnsafePointer],false)},{prop:"CanSet",name:"CanSet",pkg:"",typ:$funcType([],[$Bool],false)},{prop:"IsValid",name:"IsValid",pkg:"",typ:$funcType([],[$Bool],false)},{prop:"Kind",name:"Kind",pkg:"",typ:$funcType([],[P],false)},{prop:"numMethod",name:"numMethod",pkg:"internal/reflectlite",typ:$funcType([],[$Int],false)},{prop:"Type",name:"Type",pkg:"",typ:$funcType([],[O],false)},{prop:"object",name:"object",pkg:"internal/reflectlite",typ:$funcType([],[DZ],false)},{prop:"assignTo",name:"assignTo",pkg:"internal/reflectlite",typ:$funcType([$String,DU,$UnsafePointer],[E],false)},{prop:"call",name:"call",pkg:"internal/reflectlite",typ:$funcType([$String,EF],[EF],false)},{prop:"Cap",name:"Cap",pkg:"",typ:$funcType([],[$Int],false)},{prop:"Index",name:"Index",pkg:"",typ:$funcType([$Int],[E],false)},{prop:"InterfaceData",name:"InterfaceData",pkg:"",typ:$funcType([],[ES],false)},{prop:"IsNil",name:"IsNil",pkg:"",typ:$funcType([],[$Bool],false)},{prop:"Len",name:"Len",pkg:"",typ:$funcType([],[$Int],false)},{prop:"Pointer",name:"Pointer",pkg:"",typ:$funcType([],[$Uintptr],false)},{prop:"Set",name:"Set",pkg:"",typ:$funcType([E],[],false)},{prop:"SetBytes",name:"SetBytes",pkg:"",typ:$funcType([ET],[],false)},{prop:"SetCap",name:"SetCap",pkg:"",typ:$funcType([$Int],[],false)},{prop:"SetLen",name:"SetLen",pkg:"",typ:$funcType([$Int],[],false)},{prop:"Slice",name:"Slice",pkg:"",typ:$funcType([$Int,$Int],[E],false)},{prop:"Slice3",name:"Slice3",pkg:"",typ:$funcType([$Int,$Int,$Int],[E],false)},{prop:"Close",name:"Close",pkg:"",typ:$funcType([],[],false)},{prop:"Elem",name:"Elem",pkg:"",typ:$funcType([],[E],false)},{prop:"NumField",name:"NumField",pkg:"",typ:$funcType([],[$Int],false)},{prop:"MapKeys",name:"MapKeys",pkg:"",typ:$funcType([],[EF],false)},{prop:"MapIndex",name:"MapIndex",pkg:"",typ:$funcType([E],[E],false)},{prop:"Field",name:"Field",pkg:"",typ:$funcType([$Int],[E],false)}];F.methods=[{prop:"kind",name:"kind",pkg:"internal/reflectlite",typ:$funcType([],[P],false)},{prop:"ro",name:"ro",pkg:"internal/reflectlite",typ:$funcType([],[F],false)},{prop:"mustBeExported",name:"mustBeExported",pkg:"internal/reflectlite",typ:$funcType([],[],false)},{prop:"mustBeAssignable",name:"mustBeAssignable",pkg:"internal/reflectlite",typ:$funcType([],[],false)},{prop:"mustBe",name:"mustBe",pkg:"internal/reflectlite",typ:$funcType([P],[],false)}];EU.methods=[{prop:"Error",name:"Error",pkg:"",typ:$funcType([],[$String],false)}];P.methods=[{prop:"String",name:"String",pkg:"",typ:$funcType([],[$String],false)}];DU.methods=[{prop:"String",name:"String",pkg:"",typ:$funcType([],[$String],false)},{prop:"Size",name:"Size",pkg:"",typ:$funcType([],[$Uintptr],false)},{prop:"Kind",name:"Kind",pkg:"",typ:$funcType([],[P],false)},{prop:"pointers",name:"pointers",pkg:"internal/reflectlite",typ:$funcType([],[$Bool],false)},{prop:"common",name:"common",pkg:"internal/reflectlite",typ:$funcType([],[DU],false)},{prop:"exportedMethods",name:"exportedMethods",pkg:"internal/reflectlite",typ:$funcType([],[ED],false)},{prop:"NumMethod",name:"NumMethod",pkg:"",typ:$funcType([],[$Int],false)},{prop:"PkgPath",name:"PkgPath",pkg:"",typ:$funcType([],[$String],false)},{prop:"hasName",name:"hasName",pkg:"internal/reflectlite",typ:$funcType([],[$Bool],false)},{prop:"Name",name:"Name",pkg:"",typ:$funcType([],[$String],false)},{prop:"chanDir",name:"chanDir",pkg:"internal/reflectlite",typ:$funcType([],[T],false)},{prop:"Elem",name:"Elem",pkg:"",typ:$funcType([],[O],false)},{prop:"In",name:"In",pkg:"",typ:$funcType([$Int],[O],false)},{prop:"Len",name:"Len",pkg:"",typ:$funcType([],[$Int],false)},{prop:"NumIn",name:"NumIn",pkg:"",typ:$funcType([],[$Int],false)},{prop:"NumOut",name:"NumOut",pkg:"",typ:$funcType([],[$Int],false)},{prop:"Out",name:"Out",pkg:"",typ:$funcType([$Int],[O],false)},{prop:"Implements",name:"Implements",pkg:"",typ:$funcType([O],[$Bool],false)},{prop:"AssignableTo",name:"AssignableTo",pkg:"",typ:$funcType([O],[$Bool],false)},{prop:"Comparable",name:"Comparable",pkg:"",typ:$funcType([],[$Bool],false)},{prop:"IsVariadic",name:"IsVariadic",pkg:"",typ:$funcType([],[$Bool],false)},{prop:"kindType",name:"kindType",pkg:"internal/reflectlite",typ:$funcType([],[DU],false)},{prop:"Field",name:"Field",pkg:"",typ:$funcType([$Int],[AB],false)},{prop:"Key",name:"Key",pkg:"",typ:$funcType([],[O],false)},{prop:"NumField",name:"NumField",pkg:"",typ:$funcType([],[$Int],false)},{prop:"Method",name:"Method",pkg:"",typ:$funcType([$Int],[AV],false)},{prop:"uncommon",name:"uncommon",pkg:"internal/reflectlite",typ:$funcType([],[EC],false)},{prop:"nameOff",name:"nameOff",pkg:"internal/reflectlite",typ:$funcType([AG],[BO],false)},{prop:"typeOff",name:"typeOff",pkg:"internal/reflectlite",typ:$funcType([AH],[DU],false)},{prop:"ptrTo",name:"ptrTo",pkg:"internal/reflectlite",typ:$funcType([],[DU],false)}];EW.methods=[{prop:"NumMethod",name:"NumMethod",pkg:"",typ:$funcType([],[$Int],false)}];EY.methods=[{prop:"offset",name:"offset",pkg:"internal/reflectlite",typ:$funcType([],[$Uintptr],false)},{prop:"embedded",name:"embedded",pkg:"internal/reflectlite",typ:$funcType([],[$Bool],false)}];EZ.methods=[{prop:"Error",name:"Error",pkg:"",typ:$funcType([],[$String],false)}];EC.methods=[{prop:"methods",name:"methods",pkg:"internal/reflectlite",typ:$funcType([],[ED],false)},{prop:"exportedMethods",name:"exportedMethods",pkg:"internal/reflectlite",typ:$funcType([],[ED],false)}];EE.methods=[{prop:"in$",name:"in",pkg:"internal/reflectlite",typ:$funcType([],[DW],false)},{prop:"out",name:"out",pkg:"internal/reflectlite",typ:$funcType([],[DW],false)}];BO.methods=[{prop:"data",name:"data",pkg:"internal/reflectlite",typ:$funcType([$Int,$String],[EG],false)},{prop:"hasTag",name:"hasTag",pkg:"internal/reflectlite",typ:$funcType([],[$Bool],false)},{prop:"readVarint",name:"readVarint",pkg:"internal/reflectlite",typ:$funcType([$Int],[$Int,$Int],false)},{prop:"name",name:"name",pkg:"internal/reflectlite",typ:$funcType([],[$String],false)},{prop:"tag",name:"tag",pkg:"internal/reflectlite",typ:$funcType([],[$String],false)},{prop:"pkgPath",name:"pkgPath",pkg:"internal/reflectlite",typ:$funcType([],[$String],false)},{prop:"isExported",name:"isExported",pkg:"internal/reflectlite",typ:$funcType([],[$Bool],false)}];EO.methods=[{prop:"skipUntilValidKey",name:"skipUntilValidKey",pkg:"internal/reflectlite",typ:$funcType([],[],false)}];E.init("internal/reflectlite",[{prop:"typ",name:"typ",embedded:false,exported:false,typ:DU,tag:""},{prop:"ptr",name:"ptr",embedded:false,exported:false,typ:$UnsafePointer,tag:""},{prop:"flag",name:"flag",embedded:true,exported:false,typ:F,tag:""}]);I.init("",[{prop:"Method",name:"Method",embedded:false,exported:true,typ:$String,tag:""},{prop:"Kind",name:"Kind",embedded:false,exported:true,typ:P,tag:""}]);O.init([{prop:"AssignableTo",name:"AssignableTo",pkg:"",typ:$funcType([O],[$Bool],false)},{prop:"Comparable",name:"Comparable",pkg:"",typ:$funcType([],[$Bool],false)},{prop:"Elem",name:"Elem",pkg:"",typ:$funcType([],[O],false)},{prop:"Implements",name:"Implements",pkg:"",typ:$funcType([O],[$Bool],false)},{prop:"Kind",name:"Kind",pkg:"",typ:$funcType([],[P],false)},{prop:"Name",name:"Name",pkg:"",typ:$funcType([],[$String],false)},{prop:"PkgPath",name:"PkgPath",pkg:"",typ:$funcType([],[$String],false)},{prop:"Size",name:"Size",pkg:"",typ:$funcType([],[$Uintptr],false)},{prop:"String",name:"String",pkg:"",typ:$funcType([],[$String],false)},{prop:"common",name:"common",pkg:"internal/reflectlite",typ:$funcType([],[DU],false)},{prop:"uncommon",name:"uncommon",pkg:"internal/reflectlite",typ:$funcType([],[EC],false)}]);R.init("internal/reflectlite",[{prop:"size",name:"size",embedded:false,exported:false,typ:$Uintptr,tag:""},{prop:"ptrdata",name:"ptrdata",embedded:false,exported:false,typ:$Uintptr,tag:""},{prop:"hash",name:"hash",embedded:false,exported:false,typ:$Uint32,tag:""},{prop:"tflag",name:"tflag",embedded:false,exported:false,typ:Q,tag:""},{prop:"align",name:"align",embedded:false,exported:false,typ:$Uint8,tag:""},{prop:"fieldAlign",name:"fieldAlign",embedded:false,exported:false,typ:$Uint8,tag:""},{prop:"kind",name:"kind",embedded:false,exported:false,typ:$Uint8,tag:""},{prop:"equal",name:"equal",embedded:false,exported:false,typ:EV,tag:""},{prop:"gcdata",name:"gcdata",embedded:false,exported:false,typ:EG,tag:""},{prop:"str",name:"str",embedded:false,exported:false,typ:AG,tag:""},{prop:"ptrToThis",name:"ptrToThis",embedded:false,exported:false,typ:AH,tag:""}]);S.init("internal/reflectlite",[{prop:"name",name:"name",embedded:false,exported:false,typ:AG,tag:""},{prop:"mtyp",name:"mtyp",embedded:false,exported:false,typ:AH,tag:""},{prop:"ifn",name:"ifn",embedded:false,exported:false,typ:AI,tag:""},{prop:"tfn",name:"tfn",embedded:false,exported:false,typ:AI,tag:""}]);U.init("internal/reflectlite",[{prop:"rtype",name:"rtype",embedded:true,exported:false,typ:R,tag:""},{prop:"elem",name:"elem",embedded:false,exported:false,typ:DU,tag:""},{prop:"slice",name:"slice",embedded:false,exported:false,typ:DU,tag:""},{prop:"len",name:"len",embedded:false,exported:false,typ:$Uintptr,tag:""}]);V.init("internal/reflectlite",[{prop:"rtype",name:"rtype",embedded:true,exported:false,typ:R,tag:""},{prop:"elem",name:"elem",embedded:false,exported:false,typ:DU,tag:""},{prop:"dir",name:"dir",embedded:false,exported:false,typ:$Uintptr,tag:""}]);W.init("internal/reflectlite",[{prop:"name",name:"name",embedded:false,exported:false,typ:AG,tag:""},{prop:"typ",name:"typ",embedded:false,exported:false,typ:AH,tag:""}]);X.init("internal/reflectlite",[{prop:"rtype",name:"rtype",embedded:true,exported:false,typ:R,tag:""},{prop:"pkgPath",name:"pkgPath",embedded:false,exported:false,typ:BO,tag:""},{prop:"methods",name:"methods",embedded:false,exported:false,typ:EK,tag:""}]);Y.init("internal/reflectlite",[{prop:"rtype",name:"rtype",embedded:true,exported:false,typ:R,tag:""},{prop:"key",name:"key",embedded:false,exported:false,typ:DU,tag:""},{prop:"elem",name:"elem",embedded:false,exported:false,typ:DU,tag:""},{prop:"bucket",name:"bucket",embedded:false,exported:false,typ:DU,tag:""},{prop:"hasher",name:"hasher",embedded:false,exported:false,typ:EX,tag:""},{prop:"keysize",name:"keysize",embedded:false,exported:false,typ:$Uint8,tag:""},{prop:"valuesize",name:"valuesize",embedded:false,exported:false,typ:$Uint8,tag:""},{prop:"bucketsize",name:"bucketsize",embedded:false,exported:false,typ:$Uint16,tag:""},{prop:"flags",name:"flags",embedded:false,exported:false,typ:$Uint32,tag:""}]);Z.init("internal/reflectlite",[{prop:"rtype",name:"rtype",embedded:true,exported:false,typ:R,tag:""},{prop:"elem",name:"elem",embedded:false,exported:false,typ:DU,tag:""}]);AA.init("internal/reflectlite",[{prop:"rtype",name:"rtype",embedded:true,exported:false,typ:R,tag:""},{prop:"elem",name:"elem",embedded:false,exported:false,typ:DU,tag:""}]);AB.init("internal/reflectlite",[{prop:"name",name:"name",embedded:false,exported:false,typ:BO,tag:""},{prop:"typ",name:"typ",embedded:false,exported:false,typ:DU,tag:""},{prop:"offsetEmbed",name:"offsetEmbed",embedded:false,exported:false,typ:$Uintptr,tag:""}]);AC.init("internal/reflectlite",[{prop:"rtype",name:"rtype",embedded:true,exported:false,typ:R,tag:""},{prop:"pkgPath",name:"pkgPath",embedded:false,exported:false,typ:BO,tag:""},{prop:"fields",name:"fields",embedded:false,exported:false,typ:EL,tag:""}]);AT.init("internal/reflectlite",[{prop:"s",name:"s",embedded:false,exported:false,typ:$String,tag:""}]);AV.init("",[{prop:"Name",name:"Name",embedded:false,exported:true,typ:$String,tag:""},{prop:"PkgPath",name:"PkgPath",embedded:false,exported:true,typ:$String,tag:""},{prop:"Type",name:"Type",embedded:false,exported:true,typ:O,tag:""},{prop:"Func",name:"Func",embedded:false,exported:true,typ:E,tag:""},{prop:"Index",name:"Index",embedded:false,exported:true,typ:$Int,tag:""}]);BL.init("internal/reflectlite",[{prop:"pkgPath",name:"pkgPath",embedded:false,exported:false,typ:AG,tag:""},{prop:"mcount",name:"mcount",embedded:false,exported:false,typ:$Uint16,tag:""},{prop:"xcount",name:"xcount",embedded:false,exported:false,typ:$Uint16,tag:""},{prop:"moff",name:"moff",embedded:false,exported:false,typ:$Uint32,tag:""},{prop:"_methods",name:"_methods",embedded:false,exported:false,typ:ED,tag:""}]);BN.init("internal/reflectlite",[{prop:"rtype",name:"rtype",embedded:true,exported:false,typ:R,tag:"reflect:\"func\""},{prop:"inCount",name:"inCount",embedded:false,exported:false,typ:$Uint16,tag:""},{prop:"outCount",name:"outCount",embedded:false,exported:false,typ:$Uint16,tag:""},{prop:"_in",name:"_in",embedded:false,exported:false,typ:DW,tag:""},{prop:"_out",name:"_out",embedded:false,exported:false,typ:DW,tag:""}]);BO.init("internal/reflectlite",[{prop:"bytes",name:"bytes",embedded:false,exported:false,typ:EG,tag:""}]);BP.init("internal/reflectlite",[{prop:"name",name:"name",embedded:false,exported:false,typ:$String,tag:""},{prop:"tag",name:"tag",embedded:false,exported:false,typ:$String,tag:""},{prop:"exported",name:"exported",embedded:false,exported:false,typ:$Bool,tag:""}]);CU.init("internal/reflectlite",[{prop:"t",name:"t",embedded:false,exported:false,typ:O,tag:""},{prop:"m",name:"m",embedded:false,exported:false,typ:DZ,tag:""},{prop:"keys",name:"keys",embedded:false,exported:false,typ:DZ,tag:""},{prop:"i",name:"i",embedded:false,exported:false,typ:$Int,tag:""},{prop:"last",name:"last",embedded:false,exported:false,typ:DZ,tag:""}]);CW.init([{prop:"AssignableTo",name:"AssignableTo",pkg:"",typ:$funcType([O],[$Bool],false)},{prop:"Comparable",name:"Comparable",pkg:"",typ:$funcType([],[$Bool],false)},{prop:"Elem",name:"Elem",pkg:"",typ:$funcType([],[O],false)},{prop:"Implements",name:"Implements",pkg:"",typ:$funcType([O],[$Bool],false)},{prop:"Key",name:"Key",pkg:"",typ:$funcType([],[O],false)},{prop:"Kind",name:"Kind",pkg:"",typ:$funcType([],[P],false)},{prop:"Name",name:"Name",pkg:"",typ:$funcType([],[$String],false)},{prop:"PkgPath",name:"PkgPath",pkg:"",typ:$funcType([],[$String],false)},{prop:"Size",name:"Size",pkg:"",typ:$funcType([],[$Uintptr],false)},{prop:"String",name:"String",pkg:"",typ:$funcType([],[$String],false)},{prop:"common",name:"common",pkg:"internal/reflectlite",typ:$funcType([],[DU],false)},{prop:"uncommon",name:"uncommon",pkg:"internal/reflectlite",typ:$funcType([],[EC],false)}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=D.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}BD=DU.nil;BS=DV.nil;BU=DW.nil;AD=new DX(["invalid","bool","int","int8","int16","int32","int64","uint","uint8","uint16","uint32","uint64","uintptr","float32","float64","complex64","complex128","array","chan","func","interface","map","ptr","slice","string","struct","unsafe.Pointer"]);AR=$assertType($internalize($call,$emptyInterface),EA);$pkg.ErrSyntax=new AT.ptr("invalid syntax");BB=false;BE="_jsType";BF="_reflectType";BG="kindType";BH="_rtype";BM={};BQ={};DH=BJ($jsObjectPtr);DN=$assertType($internalize($select,$emptyInterface),EA);$r=BC();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})(); $packages["sort"]=(function(){var $pkg={},$init,A,V,AZ,BA,AN,AO,B,C,D,E,G,H,U,AP;A=$packages["internal/reflectlite"];V=$pkg.lessSwap=$newType(0,$kindStruct,"sort.lessSwap",true,"sort",false,function(Less_,Swap_){this.$val=this;if(arguments.length===0){this.Less=$throwNilPointerError;this.Swap=$throwNilPointerError;return;}this.Less=Less_;this.Swap=Swap_;});AZ=$funcType([$Int,$Int],[$Bool],false);BA=$funcType([$Int,$Int],[],false);B=function(a,b,c){var{a,b,c,d,e,f,g,$s,$r,$c}=$restore(this,{a,b,c});$s=$s||0;s:while(true){switch($s){case 0:d=b+1>>0;case 1:if(!(db)){f=false;$s=5;continue s;}g=a.Less(e,e-1>>0);$s=6;case 6:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;case 5:if(!(f)){$s=4;continue;}$r=a.Swap(e,e-1>>0);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e-(1)>>0;$s=3;continue;case 4:d=d+(1)>>0;$s=1;continue;case 2:$s=-1;return;}return;}var $f={$blk:B,$c:true,$r,a,b,c,d,e,f,g,$s};return $f;};C=function(a,b,c,d){var{a,b,c,d,e,f,g,h,i,$s,$r,$c}=$restore(this,{a,b,c,d});$s=$s||0;s:while(true){switch($s){case 0:e=b;case 1:f=($imul(2,e))+1>>0;if(f>=c){$s=2;continue;}if(!((f+1>>0)>0,(d+f>>0)+1>>0);$s=6;case 6:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;case 5:if(g){$s=3;continue;}$s=4;continue;case 3:f=f+(1)>>0;case 4:i=a.Less(d+e>>0,d+f>>0);$s=9;case 9:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}if(!i){$s=7;continue;}$s=8;continue;case 7:$s=-1;return;case 8:$r=a.Swap(d+e>>0,d+f>>0);$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=f;$s=1;continue;case 2:$s=-1;return;}return;}var $f={$blk:C,$c:true,$r,a,b,c,d,e,f,g,h,i,$s};return $f;};D=function(a,b,c){var{a,b,c,d,e,f,g,h,i,$s,$r,$c}=$restore(this,{a,b,c});$s=$s||0;s:while(true){switch($s){case 0:d=b;e=0;f=c-b>>0;h=(g=((f-1>>0))/2,(g===g&&g!==1/0&&g!==-1/0)?g>>0:$throwRuntimeError("integer divide by zero"));case 1:if(!(h>=0)){$s=2;continue;}$r=C($clone(a,V),h,f,d);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}h=h-(1)>>0;$s=1;continue;case 2:i=f-1>>0;case 4:if(!(i>=0)){$s=5;continue;}$r=a.Swap(d,d+i>>0);$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C($clone(a,V),e,i,d);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=i-(1)>>0;$s=4;continue;case 5:$s=-1;return;}return;}var $f={$blk:D,$c:true,$r,a,b,c,d,e,f,g,h,i,$s};return $f;};E=function(a,b,c,d){var{a,b,c,d,e,f,g,$s,$r,$c}=$restore(this,{a,b,c,d});$s=$s||0;s:while(true){switch($s){case 0:e=a.Less(b,c);$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}if(e){$s=1;continue;}$s=2;continue;case 1:$r=a.Swap(b,c);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:f=a.Less(d,b);$s=7;case 7:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}if(f){$s=5;continue;}$s=6;continue;case 5:$r=a.Swap(d,b);$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}g=a.Less(b,c);$s=11;case 11:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}if(g){$s=9;continue;}$s=10;continue;case 9:$r=a.Swap(b,c);$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 10:case 6:$s=-1;return;}return;}var $f={$blk:E,$c:true,$r,a,b,c,d,e,f,g,$s};return $f;};G=function(a,b,c){var{a,aa,ab,ac,ad,ae,af,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{a,b,c});$s=$s||0;s:while(true){switch($s){case 0:d=0;e=0;f=((((((b+c>>0)>>>0))>>>1>>>0)>>0));if((c-b>>0)>40){$s=1;continue;}$s=2;continue;case 1:h=(g=((c-b>>0))/8,(g===g&&g!==1/0&&g!==-1/0)?g>>0:$throwRuntimeError("integer divide by zero"));$r=E($clone(a,V),b,b+h>>0,b+($imul(2,h))>>0);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E($clone(a,V),f,f-h>>0,f+h>>0);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E($clone(a,V),c-1>>0,(c-1>>0)-h>>0,(c-1>>0)-($imul(2,h))>>0);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:$r=E($clone(a,V),b,f,c-1>>0);$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=b;j=b+1>>0;k=c-1>>0;l=j;m=k;case 7:if(!(l>0;$s=7;continue;case 8:p=l;case 11:case 13:if(!(p>0;$s=13;continue;case 14:case 17:if(!(p>0);$s=20;case 20:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}s=t;case 19:if(!(s)){$s=18;continue;}m=m-(1)>>0;$s=17;continue;case 18:if(p>=m){$s=12;continue;}$r=a.Swap(p,m-1>>0);$s=21;case 21:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}p=p+(1)>>0;m=m-(1)>>0;$s=11;continue;case 12:u=(c-m>>0)<5;if(!u&&(c-m>>0)<(v=((c-b>>0))/4,(v===v&&v!==1/0&&v!==-1/0)?v>>0:$throwRuntimeError("integer divide by zero"))){$s=22;continue;}$s=23;continue;case 22:w=0;x=a.Less(i,c-1>>0);$s=26;case 26:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}if(!x){$s=24;continue;}$s=25;continue;case 24:$r=a.Swap(m,c-1>>0);$s=27;case 27:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}m=m+(1)>>0;w=w+(1)>>0;case 25:y=a.Less(p-1>>0,i);$s=30;case 30:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}if(!y){$s=28;continue;}$s=29;continue;case 28:p=p-(1)>>0;w=w+(1)>>0;case 29:z=a.Less(f,i);$s=33;case 33:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}if(!z){$s=31;continue;}$s=32;continue;case 31:$r=a.Swap(f,p-1>>0);$s=34;case 34:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}p=p-(1)>>0;w=w+(1)>>0;case 32:u=w>1;case 23:if(u){$s=35;continue;}$s=36;continue;case 35:case 37:case 39:if(!(l>0,i);$s=42;case 42:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}aa=!ab;case 41:if(!(aa)){$s=40;continue;}p=p-(1)>>0;$s=39;continue;case 40:case 43:if(!(l>0;$s=43;continue;case 44:if(l>=p){$s=38;continue;}$r=a.Swap(l,p-1>>0);$s=47;case 47:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}l=l+(1)>>0;p=p-(1)>>0;$s=37;continue;case 38:case 36:$r=a.Swap(i,p-1>>0);$s=48;case 48:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}ae=p-1>>0;af=m;d=ae;e=af;$s=-1;return[d,e];}return;}var $f={$blk:G,$c:true,$r,a,aa,ab,ac,ad,ae,af,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};H=function(a,b,c,d){var{a,b,c,d,e,f,g,h,i,j,$s,$r,$c}=$restore(this,{a,b,c,d});$s=$s||0;s:while(true){switch($s){case 0:case 1:if(!((c-b>>0)>12)){$s=2;continue;}if(d===0){$s=3;continue;}$s=4;continue;case 3:$r=D($clone(a,V),b,c);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 4:d=d-(1)>>0;f=G($clone(a,V),b,c);$s=6;case 6:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;g=e[0];h=e[1];if((g-b>>0)<(c-h>>0)){$s=7;continue;}$s=8;continue;case 7:$r=H($clone(a,V),b,g,d);$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b=h;$s=9;continue;case 8:$r=H($clone(a,V),h,c,d);$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}c=g;case 9:$s=1;continue;case 2:if((c-b>>0)>1){$s=12;continue;}$s=13;continue;case 12:i=b+6>>0;case 14:if(!(i>0);$s=18;case 18:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}if(j){$s=16;continue;}$s=17;continue;case 16:$r=a.Swap(i,i-6>>0);$s=19;case 19:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 17:i=i+(1)>>0;$s=14;continue;case 15:$r=B($clone(a,V),b,c);$s=20;case 20:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 13:$s=-1;return;}return;}var $f={$blk:H,$c:true,$r,a,b,c,d,e,f,g,h,i,j,$s};return $f;};U=function(a){var a,b,c;b=0;c=a;while(true){if(!(c>0)){break;}b=b+(1)>>0;c=(c>>$min((1),31))>>0;}return $imul(b,2);};AP=function(a,b){var{a,b,c,d,e,f,g,$s,$r,$c}=$restore(this,{a,b});$s=$s||0;s:while(true){switch($s){case 0:c=AN(a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=$clone(c,A.Value);e=AO(a);$s=2;case 2:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;g=$clone(d,A.Value).Len();$r=H(new V.ptr(b,f),0,g,U(g));$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}var $f={$blk:AP,$c:true,$r,a,b,c,d,e,f,g,$s};return $f;};$pkg.Slice=AP;V.init("",[{prop:"Less",name:"Less",embedded:false,exported:true,typ:AZ,tag:""},{prop:"Swap",name:"Swap",embedded:false,exported:true,typ:BA,tag:""}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}AN=A.ValueOf;AO=A.Swapper;}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})(); $packages["resolv"]=(function(){var $pkg={},$init,A,B,C,D,O,Q,R,T,V,Y,AA,AB,AF,AH,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,L,P,S,U,W,X,Z,AC,AD,AE,AG,AI;A=$packages["math"];B=$packages["sort"];C=$pkg.Vector=$newType(12,$kindSlice,"resolv.Vector",true,"resolv",true,null);D=$pkg.Axis=$newType(4,$kindInt,"resolv.Axis",true,"resolv",true,null);O=$pkg.Space=$newType(0,$kindStruct,"resolv.Space",true,"resolv",true,function(Cells_,CellWidth_,CellHeight_){this.$val=this;if(arguments.length===0){this.Cells=AM.nil;this.CellWidth=0;this.CellHeight=0;return;}this.Cells=Cells_;this.CellWidth=CellWidth_;this.CellHeight=CellHeight_;});Q=$pkg.Shape=$newType(8,$kindInterface,"resolv.Shape",true,"resolv",true,null);R=$pkg.Line=$newType(0,$kindStruct,"resolv.Line",true,"resolv",true,function(Start_,End_){this.$val=this;if(arguments.length===0){this.Start=C.nil;this.End=C.nil;return;}this.Start=Start_;this.End=End_;});T=$pkg.ConvexPolygon=$newType(0,$kindStruct,"resolv.ConvexPolygon",true,"resolv",true,function(Points_,X_,Y_,Closed_){this.$val=this;if(arguments.length===0){this.Points=AQ.nil;this.X=0;this.Y=0;this.Closed=false;return;}this.Points=Points_;this.X=X_;this.Y=Y_;this.Closed=Closed_;});V=$pkg.ContactSet=$newType(0,$kindStruct,"resolv.ContactSet",true,"resolv",true,function(Points_,MTV_,Center_){this.$val=this;if(arguments.length===0){this.Points=AQ.nil;this.MTV=C.nil;this.Center=C.nil;return;}this.Points=Points_;this.MTV=MTV_;this.Center=Center_;});Y=$pkg.Circle=$newType(0,$kindStruct,"resolv.Circle",true,"resolv",true,function(X_,Y_,Radius_){this.$val=this;if(arguments.length===0){this.X=0;this.Y=0;this.Radius=0;return;}this.X=X_;this.Y=Y_;this.Radius=Radius_;});AA=$pkg.Projection=$newType(0,$kindStruct,"resolv.Projection",true,"resolv",true,function(Min_,Max_){this.$val=this;if(arguments.length===0){this.Min=0;this.Max=0;return;}this.Min=Min_;this.Max=Max_;});AB=$pkg.Object=$newType(0,$kindStruct,"resolv.Object",true,"resolv",true,function(Shape_,Space_,X_,Y_,W_,H_,TouchingCells_,Data_,ignoreList_,tags_){this.$val=this;if(arguments.length===0){this.Shape=$ifaceNil;this.Space=AN.nil;this.X=0;this.Y=0;this.W=0;this.H=0;this.TouchingCells=AL.nil;this.Data=$ifaceNil;this.ignoreList=false;this.tags=AW.nil;return;}this.Shape=Shape_;this.Space=Space_;this.X=X_;this.Y=Y_;this.W=W_;this.H=H_;this.TouchingCells=TouchingCells_;this.Data=Data_;this.ignoreList=ignoreList_;this.tags=tags_;});AF=$pkg.Collision=$newType(0,$kindStruct,"resolv.Collision",true,"resolv",true,function(checkingObject_,dx_,dy_,Objects_,Cells_){this.$val=this;if(arguments.length===0){this.checkingObject=AO.nil;this.dx=0;this.dy=0;this.Objects=AP.nil;this.Cells=AL.nil;return;}this.checkingObject=checkingObject_;this.dx=dx_;this.dy=dy_;this.Objects=Objects_;this.Cells=Cells_;});AH=$pkg.Cell=$newType(0,$kindStruct,"resolv.Cell",true,"resolv",true,function(X_,Y_,Objects_){this.$val=this;if(arguments.length===0){this.X=0;this.Y=0;this.Objects=AP.nil;return;}this.X=X_;this.Y=Y_;this.Objects=Objects_;});AJ=$sliceType($Float64);AK=$ptrType(AH);AL=$sliceType(AK);AM=$sliceType(AL);AN=$ptrType(O);AO=$ptrType(AB);AP=$sliceType(AO);AQ=$sliceType(C);AR=$ptrType(R);AS=$sliceType(AR);AT=$ptrType(Y);AU=$ptrType(T);AV=$ptrType(V);AW=$sliceType($String);AX=$ptrType(AF);AY=$sliceType(D);AZ=$mapType(AO,$Bool);C.prototype.Clone=function(){var a,b;a=this;b=$makeSlice(C,a.$length);$copySlice(b,a);return b;};$ptrType(C).prototype.Clone=function(){return this.$get().Clone();};C.prototype.Add=function(a){var a,b,c,d,e,f;b=this;c=b.$length;d=a;e=0;while(true){if(!(e=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+f]).$length>c){AD($convertSliceType(b,AJ),1,$convertSliceType(b,AJ),$convertSliceType($subslice(((f<0||f>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+f]),0,c),AJ));}else{AD($convertSliceType(b,AJ),1,$convertSliceType(b,AJ),$convertSliceType(((f<0||f>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+f]),AJ));}e++;}return b;};$ptrType(C).prototype.Add=function(a){return this.$get().Add(a);};C.prototype.Sub=function(a){var a,b,c,d,e,f;b=this;c=b.$length;d=a;e=0;while(true){if(!(e=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+f]).$length>c){AD($convertSliceType(b,AJ),-1,$convertSliceType($subslice(((f<0||f>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+f]),0,c),AJ),$convertSliceType(b,AJ));}else{AD($convertSliceType(b,AJ),-1,$convertSliceType(((f<0||f>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+f]),AJ),$convertSliceType(b,AJ));}e++;}return b;};$ptrType(C).prototype.Sub=function(a){return this.$get().Sub(a);};C.prototype.Scale=function(a){var a,b;b=this;AE($convertSliceType(b,AJ),a,$convertSliceType(b,AJ));return b;};$ptrType(C).prototype.Scale=function(a){return this.$get().Scale(a);};C.prototype.Equal=function(a){var a,b,c,d,e;b=this;if(!((b.$length===a.$length))){return false;}c=b;d=0;while(true){if(!(d=b.$length)?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+e])-((e<0||e>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+e]))>1e-08){return false;}d++;}return true;};$ptrType(C).prototype.Equal=function(a){return this.$get().Equal(a);};C.prototype.Magnitude=function(){var a;a=this;return A.Sqrt(a.Magnitude2());};$ptrType(C).prototype.Magnitude=function(){return this.$get().Magnitude();};C.prototype.Magnitude2=function(){var a,b,c,d,e;a=this;b=0;c=a;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);b=b+(e*e);d++;}return b;};$ptrType(C).prototype.Magnitude2=function(){return this.$get().Magnitude2();};C.prototype.Unit=function(){var a,b,c,d,e;a=this;b=a.Magnitude();if(b<1e-08){return a;}c=a;d=0;while(true){if(!(d=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+e]=((e<0||e>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+e])/b);d++;}return a;};$ptrType(C).prototype.Unit=function(){return this.$get().Unit();};L=function(a,b){var a,b,c,d,e,f,g,h,i,j,k;c=0;d=a.$length;e=b.$length;f=c;g=d;h=e;if(g>h){b=$appendSlice(b,$convertSliceType($makeSlice(C,(g-h>>0)),AJ));}if(g>0)),AJ));}i=a;j=0;while(true){if(!(j=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+k])*((k<0||k>=b.$length)?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+k]));j++;}return f;};$pkg.Dot=L;C.prototype.Dot=function(a){var a,b;b=this;return L(b,a);};$ptrType(C).prototype.Dot=function(a){return this.$get().Dot(a);};C.prototype.Cross=function(a){var a,b;b=this;if(!((b.$length===3))||!((a.$length===3))){return C.nil;}return new C([(1>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+1])*(2>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+2])-(2>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+2])*(1>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+1]),(2>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+2])*(0>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+0])-(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0])*(2>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+2]),(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0])*(2>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+2])-(2>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+2])*(0>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+0])]);};$ptrType(C).prototype.Cross=function(a){return this.$get().Cross(a);};C.prototype.Rotate=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;c=this;d=2;e=c.$length;f=d;g=e;if(g===0){return c;}if(b.$length>0){f=(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0]);}if((g===1)&&!((f===2))){c=$append(c,0,0);}if((g<2&&(f===2))||((g===2)&&!((f===2)))){c=$append(c,0);}h=(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]);i=(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]);j=h;k=i;l=A.Cos(a);m=A.Sin(a);n=l;o=m;p=f;if(p===(0)){q=(2>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+2]);(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]=k*n-q*o);(2>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+2]=k*o+q*n);}else if(p===(1)){r=(2>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+2]);(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]=j*n+r*o);(2>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+2]=-j*o+r*n);}else if(p===(2)){(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]=j*n-k*o);(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]=j*o+k*n);}if(g>3){return $subslice(c,0,3);}return c;};$ptrType(C).prototype.Rotate=function(a,b){return this.$get().Rotate(a,b);};C.prototype.X=function(){var a;a=this;if(a.$length<1){return 0;}return(0>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+0]);};$ptrType(C).prototype.X=function(){return this.$get().X();};C.prototype.Y=function(){var a;a=this;if(a.$length<2){return 0;}return(1>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+1]);};$ptrType(C).prototype.Y=function(){return this.$get().Y();};C.prototype.Z=function(){var a;a=this;if(a.$length<3){return 0;}return(2>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+2]);};$ptrType(C).prototype.Z=function(){return this.$get().Z();};P=function(a,b,c,d){var a,b,c,d,e,f,g;e=new O.ptr(AM.nil,c,d);e.Resize((f=a/c,(f===f&&f!==1/0&&f!==-1/0)?f>>0:$throwRuntimeError("integer divide by zero")),(g=b/d,(g===g&&g!==1/0&&g!==-1/0)?g>>0:$throwRuntimeError("integer divide by zero")));return e;};$pkg.NewSpace=P;O.ptr.prototype.Add=function(a){var{a,b,c,d,e,$s,$r,$c}=$restore(this,{a});$s=$s||0;s:while(true){switch($s){case 0:b=this;if(b===AN.nil){$panic(new $String("ERROR: space is nil"));}c=a;d=0;case 1:if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);e.Space=b;$r=e.Update();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d++;$s=1;continue;case 2:$s=-1;return;}return;}var $f={$blk:O.ptr.prototype.Add,$c:true,$r,a,b,c,d,e,$s};return $f;};O.prototype.Add=function(a){return this.$val.Add(a);};O.ptr.prototype.Remove=function(a){var a,b,c,d,e,f,g,h;b=this;if(b===AN.nil){$panic(new $String("ERROR: space is nil"));}c=a;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);f=e.TouchingCells;g=0;while(true){if(!(g=f.$length)?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+g]);h.unregister(e);g++;}e.TouchingCells=new AL([]);e.Space=AN.nil;d++;}};O.prototype.Remove=function(a){return this.$val.Remove(a);};O.ptr.prototype.Objects=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;a=this;b=$makeMap(AO.keyFor,[]);c=new AP([]);d=a.Cells;e=0;while(true){if(!(e=h.$length)?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+f]));i=0;while(true){if(!(i=m.$length)?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+f])),((j<0||j>=l.$length)?($throwRuntimeError("index out of range"),undefined):l.$array[l.$offset+j])).Objects;n=0;while(true){if(!(n=k.$length)?($throwRuntimeError("index out of range"),undefined):k.$array[k.$offset+n]);p=(q=b[AO.keyFor(o)],q!==undefined?[q.v,true]:[false,false]);r=p[1];if(!r){c=$append(c,o);s=o;(b||$throwRuntimeError("assignment to entry in nil map"))[AO.keyFor(s)]={k:s,v:true};}n++;}i++;}e++;}return c;};O.prototype.Objects=function(){return this.$val.Objects();};O.ptr.prototype.Resize=function(a,b){var a,b,c,d,e,f,g;c=this;c.Cells=new AM([]);d=0;while(true){if(!(d=g.$length)?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+d]=$append((f=c.Cells,((d<0||d>=f.$length)?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+d])),AI(e,d))));e=e+(1)>>0;}d=d+(1)>>0;}};O.prototype.Resize=function(a,b){return this.$val.Resize(a,b);};O.ptr.prototype.Cell=function(a,b){var a,b,c,d,e,f;c=this;if(b>=0&&b=0&&a<(d=c.Cells,((b<0||b>=d.$length)?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+b])).$length){return(e=(f=c.Cells,((b<0||b>=f.$length)?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+b])),((a<0||a>=e.$length)?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+a]));}return AK.nil;};O.prototype.Cell=function(a,b){return this.$val.Cell(a,b);};O.ptr.prototype.CheckCells=function(a,b,c,d,e){var a,b,c,d,e,f,g,h,i,j,k,l,m;f=this;g=a;while(true){if(!(g<(a+c>>0))){break;}h=b;while(true){if(!(h<(b+d>>0))){break;}i=f.Cell(g,h);if(!(i===AK.nil)){if(e.$length>0){if(i.ContainsTags(e)){j=i.Objects;k=0;while(true){if(!(k=j.$length)?($throwRuntimeError("index out of range"),undefined):j.$array[j.$offset+k]);if(l.HasTags(e)){return l;}k++;}}}else if(i.Occupied()){return(m=i.Objects,(0>=m.$length?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+0]));}}h=h+(1)>>0;}g=g+(1)>>0;}return AO.nil;};O.prototype.CheckCells=function(a,b,c,d,e){return this.$val.CheckCells(a,b,c,d,e);};O.ptr.prototype.CheckCellsWorld=function(a,b,c,d,e){var a,b,c,d,e,f,g,h,i,j,k,l;f=this;g=f.WorldToSpace(a,b);h=g[0];i=g[1];j=f.WorldToSpace(c,d);k=j[0];l=j[1];return f.CheckCells(h,i,k,l,e);};O.prototype.CheckCellsWorld=function(a,b,c,d,e){return this.$val.CheckCellsWorld(a,b,c,d,e);};O.ptr.prototype.UnregisterAllObjects=function(){var a,b,c,d,e,f,g;a=this;b=0;while(true){if(!(b=d.$length)?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+b])).$length)){break;}g=(e=(f=a.Cells,((b<0||b>=f.$length)?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+b])),((c<0||c>=e.$length)?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+c]));a.Remove(g.Objects);c=c+(1)>>0;}b=b+(1)>>0;}};O.prototype.UnregisterAllObjects=function(){return this.$val.UnregisterAllObjects();};O.ptr.prototype.WorldToSpace=function(a,b){var a,b,c,d,e;c=this;d=((A.Floor(a/(c.CellWidth))>>0));e=((A.Floor(b/(c.CellHeight))>>0));return[d,e];};O.prototype.WorldToSpace=function(a,b){return this.$val.WorldToSpace(a,b);};O.ptr.prototype.SpaceToWorld=function(a,b){var a,b,c,d,e;c=this;d=(($imul(a,c.CellWidth)));e=(($imul(b,c.CellHeight)));return[d,e];};O.prototype.SpaceToWorld=function(a,b){return this.$val.SpaceToWorld(a,b);};O.ptr.prototype.Height=function(){var a;a=this;return a.Cells.$length;};O.prototype.Height=function(){return this.$val.Height();};O.ptr.prototype.Width=function(){var a,b;a=this;if(a.Cells.$length>0){return(b=a.Cells,(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0])).$length;}return 0;};O.prototype.Width=function(){return this.$val.Width();};O.ptr.prototype.CellsInLine=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;e=this;f=new AL([]);g=e.Cell(a,b);h=e.Cell(c,d);if(!(g===AK.nil)&&!(h===AK.nil)){i=new C([((c-a>>0)),((d-b>>0))]).Unit();(0>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+0]=(0>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+0])*(((j=e.CellWidth/2,(j===j&&j!==1/0&&j!==-1/0)?j>>0:$throwRuntimeError("integer divide by zero")))));(1>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+1]=(1>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+1])*(((k=e.CellHeight/2,(k===k&&k!==1/0&&k!==-1/0)?k>>0:$throwRuntimeError("integer divide by zero")))));l=e.SpaceToWorld(a,b);m=l[0];n=l[1];q=new C([m+((o=e.CellWidth/2,(o===o&&o!==1/0&&o!==-1/0)?o>>0:$throwRuntimeError("integer divide by zero"))),n+((p=e.CellHeight/2,(p===p&&p!==1/0&&p!==-1/0)?p>>0:$throwRuntimeError("integer divide by zero")))]);r=false;while(true){if(!(!(g===AK.nil))){break;}if(g===h){f=$append(f,g);break;}f=$append(f,g);if(r){(1>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+1]=(1>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+1])+((1>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+1])));}else{(0>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+0]=(0>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+0])+((0>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+0])));}s=e.WorldToSpace((0>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+0]),(1>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+1]));t=s[0];u=s[1];v=e.Cell(t,u);if(!(v===g)){g=v;}r=!r;}}return f;};O.prototype.CellsInLine=function(a,b,c,d){return this.$val.CellsInLine(a,b,c,d);};S=function(a,b,c,d){var a,b,c,d;return new R.ptr(new C([a,b]),new C([c,d]));};$pkg.NewLine=S;R.ptr.prototype.Project=function(a){var a,b;b=this;return b.Vector().Scale(a.Dot(b.Start.Sub(new AQ([b.End]))));};R.prototype.Project=function(a){return this.$val.Project(a);};R.ptr.prototype.Normal=function(){var a,b;a=this;b=a.Vector();return new C([(1>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+1]),-(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0])]).Unit();};R.prototype.Normal=function(){return this.$val.Normal();};R.ptr.prototype.Vector=function(){var a;a=this;return a.End.Clone().Sub(new AQ([a.Start])).Unit();};R.prototype.Vector=function(){return this.$val.Vector();};R.ptr.prototype.IntersectionPointsLine=function(a){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;b=this;k=((c=b.End,(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]))-(d=b.Start,(0>=d.$length?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+0])))*((e=a.End,(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1]))-(f=a.Start,(1>=f.$length?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+1])))-((g=a.End,(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0]))-(h=a.Start,(0>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+0])))*((i=b.End,(1>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+1]))-(j=b.Start,(1>=j.$length?($throwRuntimeError("index out of range"),undefined):j.$array[j.$offset+1])));if(!((k===0))){t=((((l=b.Start,(1>=l.$length?($throwRuntimeError("index out of range"),undefined):l.$array[l.$offset+1]))-(m=a.Start,(1>=m.$length?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+1])))*((n=a.End,(0>=n.$length?($throwRuntimeError("index out of range"),undefined):n.$array[n.$offset+0]))-(o=a.Start,(0>=o.$length?($throwRuntimeError("index out of range"),undefined):o.$array[o.$offset+0]))))-(((p=b.Start,(0>=p.$length?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+0]))-(q=a.Start,(0>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+0])))*((r=a.End,(1>=r.$length?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+1]))-(s=a.Start,(1>=s.$length?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+1]))))+1)/k;ac=((((u=b.Start,(1>=u.$length?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+1]))-(v=a.Start,(1>=v.$length?($throwRuntimeError("index out of range"),undefined):v.$array[v.$offset+1])))*((w=b.End,(0>=w.$length?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+0]))-(x=b.Start,(0>=x.$length?($throwRuntimeError("index out of range"),undefined):x.$array[x.$offset+0]))))-(((y=b.Start,(0>=y.$length?($throwRuntimeError("index out of range"),undefined):y.$array[y.$offset+0]))-(z=a.Start,(0>=z.$length?($throwRuntimeError("index out of range"),undefined):z.$array[z.$offset+0])))*((aa=b.End,(1>=aa.$length?($throwRuntimeError("index out of range"),undefined):aa.$array[aa.$offset+1]))-(ab=b.Start,(1>=ab.$length?($throwRuntimeError("index out of range"),undefined):ab.$array[ab.$offset+1]))))+1)/k;if((0=ad.$length?($throwRuntimeError("index out of range"),undefined):ad.$array[ad.$offset+0]))-(ae=b.Start,(0>=ae.$length?($throwRuntimeError("index out of range"),undefined):ae.$array[ae.$offset+0]));ai=(ag=b.End,(1>=ag.$length?($throwRuntimeError("index out of range"),undefined):ag.$array[ag.$offset+1]))-(ah=b.Start,(1>=ah.$length?($throwRuntimeError("index out of range"),undefined):ah.$array[ah.$offset+1]));return new C([(aj=b.Start,(0>=aj.$length?($throwRuntimeError("index out of range"),undefined):aj.$array[aj.$offset+0]))+(t*af),(ak=b.Start,(1>=ak.$length?($throwRuntimeError("index out of range"),undefined):ak.$array[ak.$offset+1]))+(t*ai)]);}}return C.nil;};R.prototype.IntersectionPointsLine=function(a){return this.$val.IntersectionPointsLine(a);};R.ptr.prototype.IntersectionPointsCircle=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;b=this;c=new AQ([]);d=new C([a.X,a.Y]);e=b.Start.Sub(new AQ([d]));f=b.End.Sub(new AQ([d]));g=f.Sub(new AQ([e]));h=(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0])*(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0])+(1>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+1])*(1>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+1]);i=2*(((0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0])*(0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0]))+((1>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+1])*(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1])));j=((0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0])*(0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0]))+((1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1])*(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1]))-(a.Radius*a.Radius);k=i*i-(4*h*j);if(k<0){}else if(k===0){l=-i/(2*h);if(l>=0&&l<=1){c=$append(c,new C([(m=b.Start,(0>=m.$length?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+0]))+l*(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0]),(n=b.Start,(1>=n.$length?($throwRuntimeError("index out of range"),undefined):n.$array[n.$offset+1]))+l*(1>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+1])]));}}else{o=(-i+A.Sqrt(k))/(2*h);if(o>=0&&o<=1){c=$append(c,new C([(p=b.Start,(0>=p.$length?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+0]))+o*(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0]),(q=b.Start,(1>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+1]))+o*(1>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+1])]));}o=(-i-A.Sqrt(k))/(2*h);if(o>=0&&o<=1){c=$append(c,new C([(r=b.Start,(0>=r.$length?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+0]))+o*(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0]),(s=b.Start,(1>=s.$length?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+1]))+o*(1>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+1])]));}}return c;};R.prototype.IntersectionPointsCircle=function(a){return this.$val.IntersectionPointsCircle(a);};U=function(a){var a,b;b=new T.ptr(new AQ([]),0,0,true);b.AddPoints(a);return b;};$pkg.NewConvexPolygon=U;T.ptr.prototype.Clone=function(){var a,b,c,d,e,f;a=this;b=new AQ([]);c=a.Points;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);b=$append(b,e.Clone());d++;}f=U(AJ.nil);f.X=a.X;f.Y=a.Y;f.AddPointsVec(b);f.Closed=a.Closed;return f;};T.prototype.Clone=function(){return this.$val.Clone();};T.ptr.prototype.AddPointsVec=function(a){var a,b;b=this;b.Points=$appendSlice(b.Points,a);};T.prototype.AddPointsVec=function(a){return this.$val.AddPointsVec(a);};T.ptr.prototype.AddPoints=function(a){var a,b,c,d;b=this;c=0;while(true){if(!(c=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+c]),(d=c+1>>0,((d<0||d>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+d]))]));c=c+(2)>>0;}};T.prototype.AddPoints=function(a){return this.$val.AddPoints(a);};T.ptr.prototype.Lines=function(){var a,b,c,d,e,f,g,h,i,j;a=this;b=new AS([]);c=a.Transformed();d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);f=(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]);g=e;h=f;if(d<(c.$length-1>>0)){h=(i=d+1>>0,((i<0||i>=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+i]));}else if(!a.Closed){break;}j=S((0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0]),(1>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+1]),(0>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+0]),(1>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+1]));b=$append(b,j);d=d+(1)>>0;}return b;};T.prototype.Lines=function(){return this.$val.Lines();};T.ptr.prototype.Transformed=function(){var a,b,c,d,e;a=this;b=new AQ([]);c=a.Points;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);b=$append(b,new C([(0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0])+a.X,(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1])+a.Y]));d++;}return b;};T.prototype.Transformed=function(){return this.$val.Transformed();};T.ptr.prototype.Bounds=function(){var a,b,c,d,e,f,g,h;a=this;b=a.Transformed();e=new C([(c=(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0]),(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0])),(d=(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0]),(1>=d.$length?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+1]))]);f=e.Clone();g=0;while(true){if(!(g=b.$length)?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+g]);if((0>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+0])<(0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0])){(0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0]=(0>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+0]));}else if((0>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+0])>(0>=f.$length?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+0])){(0>=f.$length?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+0]=(0>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+0]));}if((1>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+1])<(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1])){(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1]=(1>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+1]));}else if((1>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+1])>(1>=f.$length?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+1])){(1>=f.$length?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+1]=(1>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+1]));}g=g+(1)>>0;}return[e,f];};T.prototype.Bounds=function(){return this.$val.Bounds();};T.ptr.prototype.Position=function(){var a;a=this;return[a.X,a.Y];};T.prototype.Position=function(){return this.$val.Position();};T.ptr.prototype.SetPosition=function(a,b){var a,b,c;c=this;c.X=a;c.Y=b;};T.prototype.SetPosition=function(a,b){return this.$val.SetPosition(a,b);};T.ptr.prototype.SetPositionVec=function(a){var a,b;b=this;b.X=a.X();b.Y=a.Y();};T.prototype.SetPositionVec=function(a){return this.$val.SetPositionVec(a);};T.ptr.prototype.Move=function(a,b){var a,b,c;c=this;c.X=c.X+(a);c.Y=c.Y+(b);};T.prototype.Move=function(a,b){return this.$val.Move(a,b);};T.ptr.prototype.MoveVec=function(a){var a,b;b=this;b.X=b.X+(a.X());b.Y=b.Y+(a.Y());};T.prototype.MoveVec=function(a){return this.$val.MoveVec(a);};T.ptr.prototype.Center=function(){var a,b,c,d,e;a=this;b=new C([0,0]);c=a.Transformed();d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);b.Add(new AQ([e]));d++;}(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0]=(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0])/((a.Transformed().$length)));(1>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+1]=(1>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+1])/((a.Transformed().$length)));return b;};T.prototype.Center=function(){return this.$val.Center();};T.ptr.prototype.Project=function(a){var a,b,c,d,e,f,g,h,i,j,k;b=this;a=a.Unit();c=b.Transformed();f=a.Dot(new C([(d=(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]),(0>=d.$length?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+0])),(e=(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]),(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1]))]));g=f;h=1;while(true){if(!(h=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+h]),(0>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+0])),(j=((h<0||h>=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+h]),(1>=j.$length?($throwRuntimeError("index out of range"),undefined):j.$array[j.$offset+1]))]));if(kg){g=k;}h=h+(1)>>0;}return new AA.ptr(f,g);};T.prototype.Project=function(a){return this.$val.Project(a);};T.ptr.prototype.SATAxes=function(){var a,b,c,d,e;a=this;b=new AQ([]);c=a.Lines();d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);b=$append(b,e.Normal());d++;}return b;};T.prototype.SATAxes=function(){return this.$val.SATAxes();};T.ptr.prototype.PointInside=function(a){var a,b,c,d,e,f,g;b=this;c=S((0>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+0]),(1>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+1]),(0>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+0])+9.99999999999e+11,(1>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+1]));d=0;e=b.Lines();f=0;while(true){if(!(f=e.$length)?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+f]);if(!(g.IntersectionPointsLine(c)===C.nil)){d=d+(1)>>0;}f++;}return d===1;};T.prototype.PointInside=function(a){return this.$val.PointInside(a);};W=function(){return new V.ptr(new AQ([]),new C([0,0]),new C([0,0]));};$pkg.NewContactSet=W;V.ptr.prototype.LeftmostPoint=function(){var a,b,c,d,e;a=this;b=C.nil;c=a.Points;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(b===C.nil||(0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0])<(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0])){b=e;}d++;}return b;};V.prototype.LeftmostPoint=function(){return this.$val.LeftmostPoint();};V.ptr.prototype.RightmostPoint=function(){var a,b,c,d,e;a=this;b=C.nil;c=a.Points;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(b===C.nil||(0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0])>(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0])){b=e;}d++;}return b;};V.prototype.RightmostPoint=function(){return this.$val.RightmostPoint();};V.ptr.prototype.TopmostPoint=function(){var a,b,c,d,e;a=this;b=C.nil;c=a.Points;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(b===C.nil||(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1])<(1>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+1])){b=e;}d++;}return b;};V.prototype.TopmostPoint=function(){return this.$val.TopmostPoint();};V.ptr.prototype.BottommostPoint=function(){var a,b,c,d,e;a=this;b=C.nil;c=a.Points;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(b===C.nil||(1>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+1])>(1>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+1])){b=e;}d++;}return b;};V.prototype.BottommostPoint=function(){return this.$val.BottommostPoint();};T.ptr.prototype.Intersection=function(a,b,c){var{a,aa,ab,ac,ad,ae,af,ag,ah,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{a,b,c});$s=$s||0;s:while(true){switch($s){case 0:d=this;e=W();f=d.X;g=d.Y;d.X=d.X+(a);d.Y=d.Y+(b);h=$assertType(c,AT,true);i=h[0];j=h[1];if(j){k=d.Lines();l=0;while(true){if(!(l=k.$length)?($throwRuntimeError("index out of range"),undefined):k.$array[k.$offset+l]);e.Points=$appendSlice(e.Points,m.IntersectionPointsCircle(i));l++;}}else{n=$assertType(c,AU,true);o=n[0];p=n[1];if(p){q=d.Lines();r=0;while(true){if(!(r=q.$length)?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+r]);t=o.Lines();u=0;while(true){if(!(u=t.$length)?($throwRuntimeError("index out of range"),undefined):t.$array[t.$offset+u]);w=s.IntersectionPointsLine(v);if(!(w===C.nil)){e.Points=$append(e.Points,w);}u++;}r++;}}}if(e.Points.$length>0){$s=1;continue;}$s=2;continue;case 1:x=e.Points;y=0;while(true){if(!(y=x.$length)?($throwRuntimeError("index out of range"),undefined):x.$array[x.$offset+y]);e.Center=e.Center.Add(new AQ([z]));y++;}(ab=e.Center,(0>=ab.$length?($throwRuntimeError("index out of range"),undefined):ab.$array[ab.$offset+0]=(aa=e.Center,(0>=aa.$length?($throwRuntimeError("index out of range"),undefined):aa.$array[aa.$offset+0]))/((e.Points.$length))));(ad=e.Center,(1>=ad.$length?($throwRuntimeError("index out of range"),undefined):ad.$array[ad.$offset+1]=(ac=e.Center,(1>=ac.$length?($throwRuntimeError("index out of range"),undefined):ac.$array[ac.$offset+1]))/((e.Points.$length))));ae=d.calculateMTV(e,c);$s=4;case 4:if($c){$c=false;ae=ae.$blk();}if(ae&&ae.$blk!==undefined){break s;}af=ae;if(!(af===C.nil)){e.MTV=af;}$s=3;continue;case 2:e=AV.nil;case 3:if(!(e===AV.nil)&&(!((a===0))||!((b===0)))){ag=new C([a,b]).Magnitude();ah=e.MTV.Magnitude();e.MTV=e.MTV.Unit().Scale(ah-ag);}d.X=f;d.Y=g;$s=-1;return e;}return;}var $f={$blk:T.ptr.prototype.Intersection,$c:true,$r,a,aa,ab,ac,ad,ae,af,ag,ah,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};T.prototype.Intersection=function(a,b,c){return this.$val.Intersection(a,b,c);};T.ptr.prototype.calculateMTV=function(a,b){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,$s,$r,$c}=$restore(this,{a,b});$s=$s||0;s:while(true){switch($s){case 0:c=[c];d=[d];e=this;f=new C([0,0]);g=new C([1.7976931348623157e+308,0]);h=b;if($assertType(h,AU,true)[1]){$s=1;continue;}if($assertType(h,AT,true)[1]){$s=2;continue;}$s=3;continue;case 1:i=h.$val;k=e.SATAxes();l=0;while(true){if(!(l=k.$length)?($throwRuntimeError("index out of range"),undefined):k.$array[k.$offset+l]);if(!$clone(e.Project(m),AA).Overlapping($clone(i.Project(m),AA))){$s=-1;return C.nil;}n=$clone(e.Project(m),AA).Overlap($clone(i.Project(m),AA));if(g.Magnitude()>n){g=m.Scale(n);}l++;}o=i.SATAxes();p=0;while(true){if(!(p=o.$length)?($throwRuntimeError("index out of range"),undefined):o.$array[o.$offset+p]);if(!$clone(e.Project(q),AA).Overlapping($clone(i.Project(q),AA))){$s=-1;return C.nil;}r=$clone(e.Project(q),AA).Overlap($clone(i.Project(q),AA));if(g.Magnitude()>r){g=q.Scale(r);}p++;}$s=3;continue;case 2:j=h.$val;d[0]=$appendSlice(new AQ([]),e.Transformed());d[0]=$append(d[0],a.Center);c[0]=new C([j.X,j.Y]);$r=B.Slice(d[0],(function(c,d){return function(s,t){var s,t;return((s<0||s>=d[0].$length)?($throwRuntimeError("index out of range"),undefined):d[0].$array[d[0].$offset+s]).Sub(new AQ([c[0]])).Magnitude()<((t<0||t>=d[0].$length)?($throwRuntimeError("index out of range"),undefined):d[0].$array[d[0].$offset+t]).Sub(new AQ([c[0]])).Magnitude();};})(c,d));$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}g=new C([(0>=c[0].$length?($throwRuntimeError("index out of range"),undefined):c[0].$array[c[0].$offset+0])-(s=(0>=d[0].$length?($throwRuntimeError("index out of range"),undefined):d[0].$array[d[0].$offset+0]),(0>=s.$length?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+0])),(1>=c[0].$length?($throwRuntimeError("index out of range"),undefined):c[0].$array[c[0].$offset+1])-(t=(0>=d[0].$length?($throwRuntimeError("index out of range"),undefined):d[0].$array[d[0].$offset+0]),(1>=t.$length?($throwRuntimeError("index out of range"),undefined):t.$array[t.$offset+1]))]);g=g.Unit().Scale(g.Magnitude()-j.Radius);case 3:(0>=f.$length?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+0]=(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0]));(1>=f.$length?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+1]=(1>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+1]));$s=-1;return f;}return;}var $f={$blk:T.ptr.prototype.calculateMTV,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,$s};return $f;};T.prototype.calculateMTV=function(a,b){return this.$val.calculateMTV(a,b);};T.ptr.prototype.ContainedBy=function(a){var a,b,c,d,e,f,g,h,i,j;b=this;c=a;if($assertType(c,AU,true)[1]){d=c.$val;e=b.SATAxes();f=0;while(true){if(!(f=e.$length)?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+f]);if(!$clone(b.Project(g),AA).IsInside($clone(d.Project(g),AA))){return false;}f++;}h=d.SATAxes();i=0;while(true){if(!(i=h.$length)?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+i]);if(!$clone(b.Project(j),AA).IsInside($clone(d.Project(j),AA))){return false;}i++;}}return true;};T.prototype.ContainedBy=function(a){return this.$val.ContainedBy(a);};T.ptr.prototype.FlipH=function(){var a,b,c,d;a=this;b=a.Points;c=0;while(true){if(!(c=b.$length)?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+c]);(0>=d.$length?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+0]=-(0>=d.$length?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+0]));c++;}a.ReverseVertexOrder();};T.prototype.FlipH=function(){return this.$val.FlipH();};T.ptr.prototype.FlipV=function(){var a,b,c,d;a=this;b=a.Points;c=0;while(true){if(!(c=b.$length)?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+c]);(1>=d.$length?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+1]=-(1>=d.$length?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+1]));c++;}a.ReverseVertexOrder();};T.prototype.FlipV=function(){return this.$val.FlipV();};T.ptr.prototype.ReverseVertexOrder=function(){var a,b,c,d,e;a=this;c=new AQ([(b=a.Points,(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0]))]);d=a.Points.$length-1>>0;while(true){if(!(d>=1)){break;}c=$append(c,(e=a.Points,((d<0||d>=e.$length)?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+d])));d=d-(1)>>0;}a.Points=c;};T.prototype.ReverseVertexOrder=function(){return this.$val.ReverseVertexOrder();};X=function(a,b,c,d){var a,b,c,d;return U(new AJ([a,b,a+c,b,a+c,b+d,a,b+d]));};$pkg.NewRectangle=X;Z=function(a,b,c){var a,b,c,d;d=new Y.ptr(a,b,c);return d;};$pkg.NewCircle=Z;Y.ptr.prototype.Clone=function(){var a;a=this;return Z(a.X,a.Y,a.Radius);};Y.prototype.Clone=function(){return this.$val.Clone();};Y.ptr.prototype.Bounds=function(){var a;a=this;return[new C([a.X-a.Radius,a.Y-a.Radius]),new C([a.X+a.Radius,a.Y+a.Radius])];};Y.prototype.Bounds=function(){return this.$val.Bounds();};Y.ptr.prototype.Intersection=function(a,b,c){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$r,$c}=$restore(this,{a,b,c});$s=$s||0;s:while(true){switch($s){case 0:d=this;e=AV.nil;f=d.X;g=d.Y;d.X=d.X+(a);d.Y=d.Y+(b);h=c;if($assertType(h,AU,true)[1]){$s=1;continue;}if($assertType(h,AT,true)[1]){$s=2;continue;}$s=3;continue;case 1:i=h.$val;k=i.Intersection(-a,-b,d);$s=4;case 4:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}e=k;if(!(e===AV.nil)){e.MTV=e.MTV.Scale(-1);}$s=3;continue;case 2:j=h.$val;e=W();e.Points=d.IntersectionPointsCircle(j);if(e.Points.$length===0){$s=-1;return AV.nil;}e.MTV=new C([d.X-j.X,d.Y-j.Y]);l=e.MTV.Magnitude();e.MTV=e.MTV.Unit().Scale(d.Radius+j.Radius-l);m=e.Points;n=0;while(true){if(!(n=m.$length)?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+n]);e.Center=e.Center.Add(new AQ([o]));n++;}(q=e.Center,(0>=q.$length?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+0]=(p=e.Center,(0>=p.$length?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+0]))/((e.Points.$length))));(s=e.Center,(1>=s.$length?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+1]=(r=e.Center,(1>=r.$length?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+1]))/((e.Points.$length))));case 3:d.X=f;d.Y=g;$s=-1;return e;}return;}var $f={$blk:Y.ptr.prototype.Intersection,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s};return $f;};Y.prototype.Intersection=function(a,b,c){return this.$val.Intersection(a,b,c);};Y.ptr.prototype.Move=function(a,b){var a,b,c;c=this;c.X=c.X+(a);c.Y=c.Y+(b);};Y.prototype.Move=function(a,b){return this.$val.Move(a,b);};Y.ptr.prototype.MoveVec=function(a){var a,b;b=this;b.X=b.X+(a.X());b.Y=b.Y+(a.Y());};Y.prototype.MoveVec=function(a){return this.$val.MoveVec(a);};Y.ptr.prototype.SetPosition=function(a,b){var a,b,c;c=this;c.X=a;c.Y=b;};Y.prototype.SetPosition=function(a,b){return this.$val.SetPosition(a,b);};Y.ptr.prototype.SetPositionVec=function(a){var a,b;b=this;b.X=a.X();b.Y=a.Y();};Y.prototype.SetPositionVec=function(a){return this.$val.SetPositionVec(a);};Y.ptr.prototype.Position=function(){var a;a=this;return[a.X,a.Y];};Y.prototype.Position=function(){return this.$val.Position();};Y.ptr.prototype.PointInside=function(a){var a,b;b=this;return a.Sub(new AQ([new C([b.X,b.Y])])).Magnitude()<=b.Radius;};Y.prototype.PointInside=function(a){return this.$val.PointInside(a);};Y.ptr.prototype.IntersectionPointsCircle=function(a){var a,b,c,d,e,f,g;b=this;c=A.Sqrt(A.Pow(a.X-b.X,2)+A.Pow(a.Y-b.Y,2));if(c>b.Radius+a.Radius||c0;};AA.prototype.Overlapping=function(a){return this.$val.Overlapping(a);};AA.ptr.prototype.Overlap=function(a){var a,b;b=this;return A.Min(b.Max,a.Max)-A.Max(b.Min,a.Min);};AA.prototype.Overlap=function(a){return this.$val.Overlap(a);};AA.ptr.prototype.IsInside=function(a){var a,b;b=this;return b.Min>=a.Min&&b.Max<=a.Max;};AA.prototype.IsInside=function(a){return this.$val.IsInside(a);};AC=function(a,b,c,d,e){var a,b,c,d,e,f;f=new AB.ptr($ifaceNil,AN.nil,a,b,c,d,AL.nil,$ifaceNil,$makeMap(AO.keyFor,[]),new AW([]));if(e.$length>0){f.AddTags(e);}return f;};$pkg.NewObject=AC;AB.ptr.prototype.Clone=function(){var{a,b,c,d,e,f,g,h,$s,$r,$c}=$restore(this,{});$s=$s||0;s:while(true){switch($s){case 0:a=this;b=AC(a.X,a.Y,a.W,a.H,a.Tags());b.Data=a.Data;if(!($interfaceIsEqual(a.Shape,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:c=a.Shape.Clone();$s=3;case 3:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$r=b.SetShape(c);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:d=a.ignoreList;e=0;f=$keys(d);while(true){if(!(e>0;}h=h+(1)>>0;}}if(!($interfaceIsEqual(a.Shape,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:$r=a.Shape.SetPosition(a.X,a.Y);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:$s=-1;return;}return;}var $f={$blk:AB.ptr.prototype.Update,$c:true,$r,a,b,c,d,e,f,g,h,i,j,$s};return $f;};AB.prototype.Update=function(){return this.$val.Update();};AB.ptr.prototype.AddTags=function(a){var a,b;b=this;b.tags=$appendSlice(b.tags,a);};AB.prototype.AddTags=function(a){return this.$val.AddTags(a);};AB.ptr.prototype.RemoveTags=function(a){var a,b,c,d,e,f,g,h,i;b=this;c=a;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);f=b.tags;g=0;while(true){if(!(g=f.$length)?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+g]);if(i===e){b.tags=$appendSlice($subslice(b.tags,0,h),$subslice(b.tags,(h+1>>0)));break;}g++;}d++;}};AB.prototype.RemoveTags=function(a){return this.$val.RemoveTags(a);};AB.ptr.prototype.HasTags=function(a){var a,b,c,d,e,f,g,h;b=this;c=a;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);f=b.tags;g=0;while(true){if(!(g=f.$length)?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+g]);if(h===e){return true;}g++;}d++;}return false;};AB.prototype.HasTags=function(a){return this.$val.HasTags(a);};AB.ptr.prototype.Tags=function(){var a;a=this;return $appendSlice(new AW([]),a.tags);};AB.prototype.Tags=function(){return this.$val.Tags();};AB.ptr.prototype.SetShape=function(a){var{a,b,$s,$r,$c}=$restore(this,{a});$s=$s||0;s:while(true){switch($s){case 0:b=this;if(!($interfaceIsEqual(b.Shape,a))){$s=1;continue;}$s=2;continue;case 1:b.Shape=a;$r=b.Update();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:$s=-1;return;}return;}var $f={$blk:AB.ptr.prototype.SetShape,$c:true,$r,a,b,$s};return $f;};AB.prototype.SetShape=function(a){return this.$val.SetShape(a);};AB.ptr.prototype.BoundsToSpace=function(a,b){var a,b,c,d,e,f,g,h,i;c=this;d=c.Space.WorldToSpace(c.X+a,c.Y+b);e=d[0];f=d[1];g=c.Space.WorldToSpace(c.X+c.W+a-1,c.Y+c.H+b-1);h=g[0];i=g[1];return[e,f,h,i];};AB.prototype.BoundsToSpace=function(a,b){return this.$val.BoundsToSpace(a,b);};AB.ptr.prototype.SharesCells=function(a){var a,b,c,d,e;b=this;c=b.TouchingCells;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(e.Contains(a)){return true;}d++;}return false;};AB.prototype.SharesCells=function(a){return this.$val.SharesCells(a);};AB.ptr.prototype.SharesCellsTags=function(a){var a,b,c,d,e;b=this;c=b.TouchingCells;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(e.ContainsTags(a)){return true;}d++;}return false;};AB.prototype.SharesCellsTags=function(a){return this.$val.SharesCellsTags(a);};AB.ptr.prototype.Center=function(){var a;a=this;return[a.X+(a.W/2),a.Y+(a.H/2)];};AB.prototype.Center=function(){return this.$val.Center();};AB.ptr.prototype.SetCenter=function(a,b){var a,b,c;c=this;c.X=a-(c.W/2);c.Y=b-(c.H/2);};AB.prototype.SetCenter=function(a,b){return this.$val.SetCenter(a,b);};AB.ptr.prototype.CellPosition=function(){var a,b;a=this;b=a.Center();return a.Space.WorldToSpace(b[0],b[1]);};AB.prototype.CellPosition=function(){return this.$val.CellPosition();};AB.ptr.prototype.SetRight=function(a){var a,b;b=this;b.X=a-b.W;};AB.prototype.SetRight=function(a){return this.$val.SetRight(a);};AB.ptr.prototype.SetBottom=function(a){var a,b;b=this;b.Y=a-b.H;};AB.prototype.SetBottom=function(a){return this.$val.SetBottom(a);};AB.ptr.prototype.Bottom=function(){var a;a=this;return a.Y+a.H;};AB.prototype.Bottom=function(){return this.$val.Bottom();};AB.ptr.prototype.Right=function(){var a;a=this;return a.X+a.W;};AB.prototype.Right=function(){return this.$val.Right();};AB.ptr.prototype.SetBounds=function(a,b){var a,b,c;c=this;c.X=(0>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+0]);c.Y=(1>=a.$length?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+1]);c.W=(0>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+0])-c.X;c.H=(1>=b.$length?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+1])-c.Y;};AB.prototype.SetBounds=function(a,b){return this.$val.SetBounds(a,b);};AB.ptr.prototype.Check=function(a,b,c){var{a,aa,ab,ac,ad,ae,af,ag,ah,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{a,b,c});$s=$s||0;s:while(true){switch($s){case 0:d=[d];e=[e];f=[f];g=[g];h=this;if(h.Space===AN.nil){$s=-1;return AX.nil;}d[0]=AG();d[0].checkingObject=h;if(a<0){a=A.Min(a,-1);}else if(a>0){a=A.Max(a,1);}if(b<0){b=A.Min(b,-1);}else if(b>0){b=A.Max(b,1);}d[0].dx=a;d[0].dy=b;i=h.BoundsToSpace(a,b);j=i[0];k=i[1];l=i[2];m=i[3];n=$makeMap(AO.keyFor,[]);o=$makeMap(AK.keyFor,[]);p=k;while(true){if(!(p<=m)){break;}q=j;while(true){if(!(q<=l)){break;}r=h.Space.Cell(q,p);if(!(r===AK.nil)){s=r.Objects;t=0;while(true){if(!(t=s.$length)?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+t]);w=(v=h.ignoreList[AO.keyFor(u)],v!==undefined?v.v:false);if(u===h||w){t++;continue;}x=(y=n[AO.keyFor(u)],y!==undefined?[y.v,true]:[false,false]);z=x[1];if(((c.$length===0)||u.HasTags(c))&&!z){d[0].Objects=$append(d[0].Objects,u);aa=u;(n||$throwRuntimeError("assignment to entry in nil map"))[AO.keyFor(aa)]={k:aa,v:true};ab=(ac=o[AK.keyFor(r)],ac!==undefined?[ac.v,true]:[false,false]);ad=ab[1];if(!ad){d[0].Cells=$append(d[0].Cells,r);ae=r;(o||$throwRuntimeError("assignment to entry in nil map"))[AK.keyFor(ae)]={k:ae,v:true};}t++;continue;}t++;}}q=q+(1)>>0;}p=p+(1)>>0;}if(d[0].Objects.$length===0){$s=-1;return AX.nil;}af=d[0].checkingObject.Center();ag=af[0];ah=af[1];g[0]=new C([ag,ah]);$r=B.Slice(d[0].Objects,(function(d,e,f,g){return function(ai,aj){var ai,aj,ak,al,am,an,ao,ap,aq,ar;ak=(al=d[0].Objects,((ai<0||ai>=al.$length)?($throwRuntimeError("index out of range"),undefined):al.$array[al.$offset+ai])).Center();am=ak[0];an=ak[1];ao=(ap=d[0].Objects,((aj<0||aj>=ap.$length)?($throwRuntimeError("index out of range"),undefined):ap.$array[ap.$offset+aj])).Center();aq=ao[0];ar=ao[1];return new C([am,an]).Sub(new AQ([g[0]])).Magnitude2()=ak.$length)?($throwRuntimeError("index out of range"),undefined):ak.$array[ak.$offset+ai])).X,f[0]))+((al=f[0]/2,(al===al&&al!==1/0&&al!==-1/0)?al>>0:$throwRuntimeError("integer divide by zero")))>>0)),((($imul((am=d[0].Cells,((ai<0||ai>=am.$length)?($throwRuntimeError("index out of range"),undefined):am.$array[am.$offset+ai])).Y,e[0]))+((an=e[0]/2,(an===an&&an!==1/0&&an!==-1/0)?an>>0:$throwRuntimeError("integer divide by zero")))>>0))]).Sub(new AQ([g[0]])).Magnitude2()=ao.$length)?($throwRuntimeError("index out of range"),undefined):ao.$array[ao.$offset+aj])).X,f[0]))+((ap=f[0]/2,(ap===ap&&ap!==1/0&&ap!==-1/0)?ap>>0:$throwRuntimeError("integer divide by zero")))>>0)),((($imul((aq=d[0].Cells,((aj<0||aj>=aq.$length)?($throwRuntimeError("index out of range"),undefined):aq.$array[aq.$offset+aj])).Y,e[0]))+((ar=e[0]/2,(ar===ar&&ar!==1/0&&ar!==-1/0)?ar>>0:$throwRuntimeError("integer divide by zero")))>>0))]).Sub(new AQ([g[0]])).Magnitude2();};})(d,e,f,g));$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return d[0];}return;}var $f={$blk:AB.ptr.prototype.Check,$c:true,$r,a,aa,ab,ac,ad,ae,af,ag,ah,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};AB.prototype.Check=function(a,b,c){return this.$val.Check(a,b,c);};AB.ptr.prototype.Overlaps=function(a){var a,b;b=this;return a.X<=b.X+b.W&&a.X+a.W>=b.X&&a.Y<=b.Y+b.H&&a.Y+a.H>=b.Y;};AB.prototype.Overlaps=function(a){return this.$val.Overlaps(a);};AB.ptr.prototype.AddToIgnoreList=function(a){var a,b,c;b=this;c=a;(b.ignoreList||$throwRuntimeError("assignment to entry in nil map"))[AO.keyFor(c)]={k:c,v:true};};AB.prototype.AddToIgnoreList=function(a){return this.$val.AddToIgnoreList(a);};AB.ptr.prototype.RemoveFromIgnoreList=function(a){var a,b;b=this;delete b.ignoreList[AO.keyFor(a)];};AB.prototype.RemoveFromIgnoreList=function(a){return this.$val.RemoveFromIgnoreList(a);};AD=function(a,b,c,d){var a,b,c,d,e,f,g,h,i;e=d.$length;f=c;g=0;while(true){if(!(g=f.$length)?($throwRuntimeError("index out of range"),undefined):f.$array[f.$offset+g]);if(h===e){return;}((h<0||h>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+h]=b*i+((h<0||h>=d.$length)?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+h]));g++;}};AE=function(a,b,c){var a,b,c,d,e,f;d=c;e=0;while(true){if(!(e=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+f]=((f<0||f>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+f])*(b));e++;}};AG=function(){return new AF.ptr(AO.nil,0,0,new AP([]),AL.nil);};$pkg.NewCollision=AG;AF.ptr.prototype.HasTags=function(a){var a,b,c,d,e;b=this;c=b.Objects;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(e===b.checkingObject){d++;continue;}if(e.HasTags(a)){return true;}d++;}return false;};AF.prototype.HasTags=function(a){return this.$val.HasTags(a);};AF.ptr.prototype.ObjectsByTags=function(a){var a,b,c,d,e,f;b=this;c=new AP([]);d=b.Objects;e=0;while(true){if(!(e=d.$length)?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+e]);if(f===b.checkingObject){e++;continue;}if(f.HasTags(a)){c=$append(c,f);}e++;}return c;};AF.prototype.ObjectsByTags=function(a){return this.$val.ObjectsByTags(a);};AF.ptr.prototype.ContactWithObject=function(a){var a,b,c;b=this;c=new C([0,0]);if(b.dx<0){(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]=a.X+a.W-b.checkingObject.X);}else if(b.dx>0){(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]=a.X-b.checkingObject.W-b.checkingObject.X);}if(b.dy<0){(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]=a.Y+a.H-b.checkingObject.Y);}else if(b.dy>0){(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]=a.Y-b.checkingObject.H-b.checkingObject.Y);}return c;};AF.prototype.ContactWithObject=function(a){return this.$val.ContactWithObject(a);};AF.ptr.prototype.ContactWithCell=function(a){var a,b,c,d,e;b=this;c=new C([0,0]);d=(($imul(a.X,b.checkingObject.Space.CellWidth)));e=(($imul(a.Y,b.checkingObject.Space.CellHeight)));if(b.dx<0){(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]=d+(b.checkingObject.Space.CellWidth)-b.checkingObject.X);}else if(b.dx>0){(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0]=d-b.checkingObject.W-b.checkingObject.X);}if(b.dy<0){(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]=e+(b.checkingObject.Space.CellHeight)-b.checkingObject.Y);}else if(b.dy>0){(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]=e-b.checkingObject.H-b.checkingObject.Y);}return c;};AF.prototype.ContactWithCell=function(a){return this.$val.ContactWithCell(a);};AF.ptr.prototype.SlideAgainstCell=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;c=this;d=c.checkingObject.Space;f=(e=c.Cells,(0>=e.$length?($throwRuntimeError("index out of range"),undefined):e.$array[e.$offset+0]));g=d.SpaceToWorld(f.X,f.Y);h=g[0];i=g[1];j=(d.CellWidth)/2;k=(d.CellHeight)/2;h=h+(j);i=i+(k);l=c.checkingObject.Center();m=l[0];n=l[1];o=m-h;p=n-i;q=d.Cell(f.X-1>>0,f.Y);r=d.Cell(f.X+1>>0,f.Y);s=d.Cell(f.X,f.Y-1>>0);t=d.Cell(f.X,f.Y+1>>0);u=new C([0,0]);if(!((c.dy===0))){if(o>0&&(r===AK.nil||!r.ContainsTags(b))){(0>=u.$length?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+0]=h+j-c.checkingObject.X);}else if(o<0&&(q===AK.nil||!q.ContainsTags(b))){(0>=u.$length?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+0]=h-j-(c.checkingObject.X+c.checkingObject.W));}else{return C.nil;}}if(!((c.dx===0))){if(p>0&&(t===AK.nil||!t.ContainsTags(b))){(1>=u.$length?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+1]=i+k-c.checkingObject.Y);}else if(p<0&&(s===AK.nil||!s.ContainsTags(b))){(1>=u.$length?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+1]=i-k-(c.checkingObject.Y+c.checkingObject.H));}else{return C.nil;}}return u;};AF.prototype.SlideAgainstCell=function(a,b){return this.$val.SlideAgainstCell(a,b);};AI=function(a,b){var a,b;return new AH.ptr(a,b,new AP([]));};AH.ptr.prototype.register=function(a){var a,b;b=this;if(!b.Contains(a)){b.Objects=$append(b.Objects,a);}};AH.prototype.register=function(a){return this.$val.register(a);};AH.ptr.prototype.unregister=function(a){var a,b,c,d,e,f,g,h,i;b=this;c=b.Objects;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(f===a){(i=b.Objects,((e<0||e>=i.$length)?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+e]=(g=b.Objects,h=b.Objects.$length-1>>0,((h<0||h>=g.$length)?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+h]))));b.Objects=$subslice(b.Objects,0,(b.Objects.$length-1>>0));break;}d++;}};AH.prototype.unregister=function(a){return this.$val.unregister(a);};AH.ptr.prototype.Contains=function(a){var a,b,c,d,e;b=this;c=b.Objects;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(e===a){return true;}d++;}return false;};AH.prototype.Contains=function(a){return this.$val.Contains(a);};AH.ptr.prototype.ContainsTags=function(a){var a,b,c,d,e;b=this;c=b.Objects;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(e.HasTags(a)){return true;}d++;}return false;};AH.prototype.ContainsTags=function(a){return this.$val.ContainsTags(a);};AH.ptr.prototype.Occupied=function(){var a;a=this;return a.Objects.$length>0;};AH.prototype.Occupied=function(){return this.$val.Occupied();};C.methods=[{prop:"Clone",name:"Clone",pkg:"",typ:$funcType([],[C],false)},{prop:"Add",name:"Add",pkg:"",typ:$funcType([AQ],[C],true)},{prop:"Sub",name:"Sub",pkg:"",typ:$funcType([AQ],[C],true)},{prop:"Scale",name:"Scale",pkg:"",typ:$funcType([$Float64],[C],false)},{prop:"Equal",name:"Equal",pkg:"",typ:$funcType([C],[$Bool],false)},{prop:"Magnitude",name:"Magnitude",pkg:"",typ:$funcType([],[$Float64],false)},{prop:"Magnitude2",name:"Magnitude2",pkg:"",typ:$funcType([],[$Float64],false)},{prop:"Unit",name:"Unit",pkg:"",typ:$funcType([],[C],false)},{prop:"Dot",name:"Dot",pkg:"",typ:$funcType([C],[$Float64],false)},{prop:"Cross",name:"Cross",pkg:"",typ:$funcType([C],[C],false)},{prop:"Rotate",name:"Rotate",pkg:"",typ:$funcType([$Float64,AY],[C],true)},{prop:"X",name:"X",pkg:"",typ:$funcType([],[$Float64],false)},{prop:"Y",name:"Y",pkg:"",typ:$funcType([],[$Float64],false)},{prop:"Z",name:"Z",pkg:"",typ:$funcType([],[$Float64],false)}];AN.methods=[{prop:"Add",name:"Add",pkg:"",typ:$funcType([AP],[],true)},{prop:"Remove",name:"Remove",pkg:"",typ:$funcType([AP],[],true)},{prop:"Objects",name:"Objects",pkg:"",typ:$funcType([],[AP],false)},{prop:"Resize",name:"Resize",pkg:"",typ:$funcType([$Int,$Int],[],false)},{prop:"Cell",name:"Cell",pkg:"",typ:$funcType([$Int,$Int],[AK],false)},{prop:"CheckCells",name:"CheckCells",pkg:"",typ:$funcType([$Int,$Int,$Int,$Int,AW],[AO],true)},{prop:"CheckCellsWorld",name:"CheckCellsWorld",pkg:"",typ:$funcType([$Float64,$Float64,$Float64,$Float64,AW],[AO],true)},{prop:"UnregisterAllObjects",name:"UnregisterAllObjects",pkg:"",typ:$funcType([],[],false)},{prop:"WorldToSpace",name:"WorldToSpace",pkg:"",typ:$funcType([$Float64,$Float64],[$Int,$Int],false)},{prop:"SpaceToWorld",name:"SpaceToWorld",pkg:"",typ:$funcType([$Int,$Int],[$Float64,$Float64],false)},{prop:"Height",name:"Height",pkg:"",typ:$funcType([],[$Int],false)},{prop:"Width",name:"Width",pkg:"",typ:$funcType([],[$Int],false)},{prop:"CellsInLine",name:"CellsInLine",pkg:"",typ:$funcType([$Int,$Int,$Int,$Int],[AL],false)}];AR.methods=[{prop:"Project",name:"Project",pkg:"",typ:$funcType([C],[C],false)},{prop:"Normal",name:"Normal",pkg:"",typ:$funcType([],[C],false)},{prop:"Vector",name:"Vector",pkg:"",typ:$funcType([],[C],false)},{prop:"IntersectionPointsLine",name:"IntersectionPointsLine",pkg:"",typ:$funcType([AR],[C],false)},{prop:"IntersectionPointsCircle",name:"IntersectionPointsCircle",pkg:"",typ:$funcType([AT],[AQ],false)}];AU.methods=[{prop:"Clone",name:"Clone",pkg:"",typ:$funcType([],[Q],false)},{prop:"AddPointsVec",name:"AddPointsVec",pkg:"",typ:$funcType([AQ],[],true)},{prop:"AddPoints",name:"AddPoints",pkg:"",typ:$funcType([AJ],[],true)},{prop:"Lines",name:"Lines",pkg:"",typ:$funcType([],[AS],false)},{prop:"Transformed",name:"Transformed",pkg:"",typ:$funcType([],[AQ],false)},{prop:"Bounds",name:"Bounds",pkg:"",typ:$funcType([],[C,C],false)},{prop:"Position",name:"Position",pkg:"",typ:$funcType([],[$Float64,$Float64],false)},{prop:"SetPosition",name:"SetPosition",pkg:"",typ:$funcType([$Float64,$Float64],[],false)},{prop:"SetPositionVec",name:"SetPositionVec",pkg:"",typ:$funcType([C],[],false)},{prop:"Move",name:"Move",pkg:"",typ:$funcType([$Float64,$Float64],[],false)},{prop:"MoveVec",name:"MoveVec",pkg:"",typ:$funcType([C],[],false)},{prop:"Center",name:"Center",pkg:"",typ:$funcType([],[C],false)},{prop:"Project",name:"Project",pkg:"",typ:$funcType([C],[AA],false)},{prop:"SATAxes",name:"SATAxes",pkg:"",typ:$funcType([],[AQ],false)},{prop:"PointInside",name:"PointInside",pkg:"",typ:$funcType([C],[$Bool],false)},{prop:"Intersection",name:"Intersection",pkg:"",typ:$funcType([$Float64,$Float64,Q],[AV],false)},{prop:"calculateMTV",name:"calculateMTV",pkg:"resolv",typ:$funcType([AV,Q],[C],false)},{prop:"ContainedBy",name:"ContainedBy",pkg:"",typ:$funcType([Q],[$Bool],false)},{prop:"FlipH",name:"FlipH",pkg:"",typ:$funcType([],[],false)},{prop:"FlipV",name:"FlipV",pkg:"",typ:$funcType([],[],false)},{prop:"ReverseVertexOrder",name:"ReverseVertexOrder",pkg:"",typ:$funcType([],[],false)}];AV.methods=[{prop:"LeftmostPoint",name:"LeftmostPoint",pkg:"",typ:$funcType([],[C],false)},{prop:"RightmostPoint",name:"RightmostPoint",pkg:"",typ:$funcType([],[C],false)},{prop:"TopmostPoint",name:"TopmostPoint",pkg:"",typ:$funcType([],[C],false)},{prop:"BottommostPoint",name:"BottommostPoint",pkg:"",typ:$funcType([],[C],false)}];AT.methods=[{prop:"Clone",name:"Clone",pkg:"",typ:$funcType([],[Q],false)},{prop:"Bounds",name:"Bounds",pkg:"",typ:$funcType([],[C,C],false)},{prop:"Intersection",name:"Intersection",pkg:"",typ:$funcType([$Float64,$Float64,Q],[AV],false)},{prop:"Move",name:"Move",pkg:"",typ:$funcType([$Float64,$Float64],[],false)},{prop:"MoveVec",name:"MoveVec",pkg:"",typ:$funcType([C],[],false)},{prop:"SetPosition",name:"SetPosition",pkg:"",typ:$funcType([$Float64,$Float64],[],false)},{prop:"SetPositionVec",name:"SetPositionVec",pkg:"",typ:$funcType([C],[],false)},{prop:"Position",name:"Position",pkg:"",typ:$funcType([],[$Float64,$Float64],false)},{prop:"PointInside",name:"PointInside",pkg:"",typ:$funcType([C],[$Bool],false)},{prop:"IntersectionPointsCircle",name:"IntersectionPointsCircle",pkg:"",typ:$funcType([AT],[AQ],false)}];AA.methods=[{prop:"Overlapping",name:"Overlapping",pkg:"",typ:$funcType([AA],[$Bool],false)},{prop:"Overlap",name:"Overlap",pkg:"",typ:$funcType([AA],[$Float64],false)},{prop:"IsInside",name:"IsInside",pkg:"",typ:$funcType([AA],[$Bool],false)}];AO.methods=[{prop:"Clone",name:"Clone",pkg:"",typ:$funcType([],[AO],false)},{prop:"Update",name:"Update",pkg:"",typ:$funcType([],[],false)},{prop:"AddTags",name:"AddTags",pkg:"",typ:$funcType([AW],[],true)},{prop:"RemoveTags",name:"RemoveTags",pkg:"",typ:$funcType([AW],[],true)},{prop:"HasTags",name:"HasTags",pkg:"",typ:$funcType([AW],[$Bool],true)},{prop:"Tags",name:"Tags",pkg:"",typ:$funcType([],[AW],false)},{prop:"SetShape",name:"SetShape",pkg:"",typ:$funcType([Q],[],false)},{prop:"BoundsToSpace",name:"BoundsToSpace",pkg:"",typ:$funcType([$Float64,$Float64],[$Int,$Int,$Int,$Int],false)},{prop:"SharesCells",name:"SharesCells",pkg:"",typ:$funcType([AO],[$Bool],false)},{prop:"SharesCellsTags",name:"SharesCellsTags",pkg:"",typ:$funcType([AW],[$Bool],true)},{prop:"Center",name:"Center",pkg:"",typ:$funcType([],[$Float64,$Float64],false)},{prop:"SetCenter",name:"SetCenter",pkg:"",typ:$funcType([$Float64,$Float64],[],false)},{prop:"CellPosition",name:"CellPosition",pkg:"",typ:$funcType([],[$Int,$Int],false)},{prop:"SetRight",name:"SetRight",pkg:"",typ:$funcType([$Float64],[],false)},{prop:"SetBottom",name:"SetBottom",pkg:"",typ:$funcType([$Float64],[],false)},{prop:"Bottom",name:"Bottom",pkg:"",typ:$funcType([],[$Float64],false)},{prop:"Right",name:"Right",pkg:"",typ:$funcType([],[$Float64],false)},{prop:"SetBounds",name:"SetBounds",pkg:"",typ:$funcType([C,C],[],false)},{prop:"Check",name:"Check",pkg:"",typ:$funcType([$Float64,$Float64,AW],[AX],true)},{prop:"Overlaps",name:"Overlaps",pkg:"",typ:$funcType([AO],[$Bool],false)},{prop:"AddToIgnoreList",name:"AddToIgnoreList",pkg:"",typ:$funcType([AO],[],false)},{prop:"RemoveFromIgnoreList",name:"RemoveFromIgnoreList",pkg:"",typ:$funcType([AO],[],false)}];AX.methods=[{prop:"HasTags",name:"HasTags",pkg:"",typ:$funcType([AW],[$Bool],true)},{prop:"ObjectsByTags",name:"ObjectsByTags",pkg:"",typ:$funcType([AW],[AP],true)},{prop:"ContactWithObject",name:"ContactWithObject",pkg:"",typ:$funcType([AO],[C],false)},{prop:"ContactWithCell",name:"ContactWithCell",pkg:"",typ:$funcType([AK],[C],false)},{prop:"SlideAgainstCell",name:"SlideAgainstCell",pkg:"",typ:$funcType([AK,AW],[C],true)}];AK.methods=[{prop:"register",name:"register",pkg:"resolv",typ:$funcType([AO],[],false)},{prop:"unregister",name:"unregister",pkg:"resolv",typ:$funcType([AO],[],false)},{prop:"Contains",name:"Contains",pkg:"",typ:$funcType([AO],[$Bool],false)},{prop:"ContainsTags",name:"ContainsTags",pkg:"",typ:$funcType([AW],[$Bool],true)},{prop:"Occupied",name:"Occupied",pkg:"",typ:$funcType([],[$Bool],false)}];C.init($Float64);O.init("",[{prop:"Cells",name:"Cells",embedded:false,exported:true,typ:AM,tag:""},{prop:"CellWidth",name:"CellWidth",embedded:false,exported:true,typ:$Int,tag:""},{prop:"CellHeight",name:"CellHeight",embedded:false,exported:true,typ:$Int,tag:""}]);Q.init([{prop:"Bounds",name:"Bounds",pkg:"",typ:$funcType([],[C,C],false)},{prop:"Clone",name:"Clone",pkg:"",typ:$funcType([],[Q],false)},{prop:"Intersection",name:"Intersection",pkg:"",typ:$funcType([$Float64,$Float64,Q],[AV],false)},{prop:"Position",name:"Position",pkg:"",typ:$funcType([],[$Float64,$Float64],false)},{prop:"SetPosition",name:"SetPosition",pkg:"",typ:$funcType([$Float64,$Float64],[],false)}]);R.init("",[{prop:"Start",name:"Start",embedded:false,exported:true,typ:C,tag:""},{prop:"End",name:"End",embedded:false,exported:true,typ:C,tag:""}]);T.init("",[{prop:"Points",name:"Points",embedded:false,exported:true,typ:AQ,tag:""},{prop:"X",name:"X",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Y",name:"Y",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Closed",name:"Closed",embedded:false,exported:true,typ:$Bool,tag:""}]);V.init("",[{prop:"Points",name:"Points",embedded:false,exported:true,typ:AQ,tag:""},{prop:"MTV",name:"MTV",embedded:false,exported:true,typ:C,tag:""},{prop:"Center",name:"Center",embedded:false,exported:true,typ:C,tag:""}]);Y.init("",[{prop:"X",name:"X",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Y",name:"Y",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Radius",name:"Radius",embedded:false,exported:true,typ:$Float64,tag:""}]);AA.init("",[{prop:"Min",name:"Min",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Max",name:"Max",embedded:false,exported:true,typ:$Float64,tag:""}]);AB.init("resolv",[{prop:"Shape",name:"Shape",embedded:false,exported:true,typ:Q,tag:""},{prop:"Space",name:"Space",embedded:false,exported:true,typ:AN,tag:""},{prop:"X",name:"X",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Y",name:"Y",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"W",name:"W",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"H",name:"H",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"TouchingCells",name:"TouchingCells",embedded:false,exported:true,typ:AL,tag:""},{prop:"Data",name:"Data",embedded:false,exported:true,typ:$emptyInterface,tag:""},{prop:"ignoreList",name:"ignoreList",embedded:false,exported:false,typ:AZ,tag:""},{prop:"tags",name:"tags",embedded:false,exported:false,typ:AW,tag:""}]);AF.init("resolv",[{prop:"checkingObject",name:"checkingObject",embedded:false,exported:false,typ:AO,tag:""},{prop:"dx",name:"dx",embedded:false,exported:false,typ:$Float64,tag:""},{prop:"dy",name:"dy",embedded:false,exported:false,typ:$Float64,tag:""},{prop:"Objects",name:"Objects",embedded:false,exported:true,typ:AP,tag:""},{prop:"Cells",name:"Cells",embedded:false,exported:true,typ:AL,tag:""}]);AH.init("",[{prop:"X",name:"X",embedded:false,exported:true,typ:$Int,tag:""},{prop:"Y",name:"Y",embedded:false,exported:true,typ:$Int,tag:""},{prop:"Objects",name:"Objects",embedded:false,exported:true,typ:AP,tag:""}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})(); -$packages["jsexport/battle"]=(function(){var $pkg={},$init,B,A,C,D,E,F,H,I,J,M,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,L,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB;B=$packages["math"];A=$packages["resolv"];C=$pkg.Vec2D=$newType(0,$kindStruct,"battle.Vec2D",true,"jsexport/battle",true,function(X_,Y_){this.$val=this;if(arguments.length===0){this.X=0;this.Y=0;return;}this.X=X_;this.Y=Y_;});D=$pkg.Polygon2D=$newType(0,$kindStruct,"battle.Polygon2D",true,"jsexport/battle",true,function(Anchor_,Points_){this.$val=this;if(arguments.length===0){this.Anchor=AS.nil;this.Points=AT.nil;return;}this.Anchor=Anchor_;this.Points=Points_;});E=$pkg.PlayerDownsync=$newType(0,$kindStruct,"battle.PlayerDownsync",true,"jsexport/battle",true,function(Id_,VirtualGridX_,VirtualGridY_,DirX_,DirY_,VelX_,VelY_,Speed_,BattleState_,JoinIndex_,ColliderRadius_,Removed_,Score_,LastMoveGmtMillis_,FramesToRecover_,Hp_,MaxHp_,CharacterState_,InAir_){this.$val=this;if(arguments.length===0){this.Id=0;this.VirtualGridX=0;this.VirtualGridY=0;this.DirX=0;this.DirY=0;this.VelX=0;this.VelY=0;this.Speed=0;this.BattleState=0;this.JoinIndex=0;this.ColliderRadius=0;this.Removed=false;this.Score=0;this.LastMoveGmtMillis=0;this.FramesToRecover=0;this.Hp=0;this.MaxHp=0;this.CharacterState=0;this.InAir=false;return;}this.Id=Id_;this.VirtualGridX=VirtualGridX_;this.VirtualGridY=VirtualGridY_;this.DirX=DirX_;this.DirY=DirY_;this.VelX=VelX_;this.VelY=VelY_;this.Speed=Speed_;this.BattleState=BattleState_;this.JoinIndex=JoinIndex_;this.ColliderRadius=ColliderRadius_;this.Removed=Removed_;this.Score=Score_;this.LastMoveGmtMillis=LastMoveGmtMillis_;this.FramesToRecover=FramesToRecover_;this.Hp=Hp_;this.MaxHp=MaxHp_;this.CharacterState=CharacterState_;this.InAir=InAir_;});F=$pkg.InputFrameDecoded=$newType(0,$kindStruct,"battle.InputFrameDecoded",true,"jsexport/battle",true,function(Dx_,Dy_,BtnALevel_,BtnBLevel_){this.$val=this;if(arguments.length===0){this.Dx=0;this.Dy=0;this.BtnALevel=0;this.BtnBLevel=0;return;}this.Dx=Dx_;this.Dy=Dy_;this.BtnALevel=BtnALevel_;this.BtnBLevel=BtnBLevel_;});H=$pkg.Barrier=$newType(0,$kindStruct,"battle.Barrier",true,"jsexport/battle",true,function(Boundary_){this.$val=this;if(arguments.length===0){this.Boundary=AU.nil;return;}this.Boundary=Boundary_;});I=$pkg.MeleeBullet=$newType(0,$kindStruct,"battle.MeleeBullet",true,"jsexport/battle",true,function(BattleLocalId_,StartupFrames_,ActiveFrames_,RecoveryFrames_,RecoveryFramesOnBlock_,RecoveryFramesOnHit_,Moveforward_,HitboxOffset_,HitboxSize_,OriginatedRenderFrameId_,HitStunFrames_,BlockStunFrames_,Pushback_,ReleaseTriggerType_,Damage_,OffenderJoinIndex_,OffenderPlayerId_){this.$val=this;if(arguments.length===0){this.BattleLocalId=0;this.StartupFrames=0;this.ActiveFrames=0;this.RecoveryFrames=0;this.RecoveryFramesOnBlock=0;this.RecoveryFramesOnHit=0;this.Moveforward=AS.nil;this.HitboxOffset=0;this.HitboxSize=AS.nil;this.OriginatedRenderFrameId=0;this.HitStunFrames=0;this.BlockStunFrames=0;this.Pushback=0;this.ReleaseTriggerType=0;this.Damage=0;this.OffenderJoinIndex=0;this.OffenderPlayerId=0;return;}this.BattleLocalId=BattleLocalId_;this.StartupFrames=StartupFrames_;this.ActiveFrames=ActiveFrames_;this.RecoveryFrames=RecoveryFrames_;this.RecoveryFramesOnBlock=RecoveryFramesOnBlock_;this.RecoveryFramesOnHit=RecoveryFramesOnHit_;this.Moveforward=Moveforward_;this.HitboxOffset=HitboxOffset_;this.HitboxSize=HitboxSize_;this.OriginatedRenderFrameId=OriginatedRenderFrameId_;this.HitStunFrames=HitStunFrames_;this.BlockStunFrames=BlockStunFrames_;this.Pushback=Pushback_;this.ReleaseTriggerType=ReleaseTriggerType_;this.Damage=Damage_;this.OffenderJoinIndex=OffenderJoinIndex_;this.OffenderPlayerId=OffenderPlayerId_;});J=$pkg.RoomDownsyncFrame=$newType(0,$kindStruct,"battle.RoomDownsyncFrame",true,"jsexport/battle",true,function(Id_,PlayersArr_,CountdownNanos_,MeleeBullets_,BackendUnconfirmedMask_,ShouldForceResync_){this.$val=this;if(arguments.length===0){this.Id=0;this.PlayersArr=AL.nil;this.CountdownNanos=new $Int64(0,0);this.MeleeBullets=AQ.nil;this.BackendUnconfirmedMask=new $Uint64(0,0);this.ShouldForceResync=false;return;}this.Id=Id_;this.PlayersArr=PlayersArr_;this.CountdownNanos=CountdownNanos_;this.MeleeBullets=MeleeBullets_;this.BackendUnconfirmedMask=BackendUnconfirmedMask_;this.ShouldForceResync=ShouldForceResync_;});M=$pkg.SatResult=$newType(0,$kindStruct,"battle.SatResult",true,"jsexport/battle",true,function(Overlap_,OverlapX_,OverlapY_,AContainedInB_,BContainedInA_,Axis_){this.$val=this;if(arguments.length===0){this.Overlap=0;this.OverlapX=0;this.OverlapY=0;this.AContainedInB=false;this.BContainedInA=false;this.Axis=A.Vector.nil;return;}this.Overlap=Overlap_;this.OverlapX=OverlapX_;this.OverlapY=OverlapY_;this.AContainedInB=AContainedInB_;this.BContainedInA=BContainedInA_;this.Axis=Axis_;});AC=$sliceType($Int32);AD=$sliceType(AC);AE=$ptrType(M);AF=$sliceType(C);AG=$sliceType($String);AH=$ptrType(A.Collision);AI=$ptrType(H);AJ=$ptrType(A.ConvexPolygon);AK=$ptrType(E);AL=$sliceType(AK);AM=$sliceType(AF);AN=$sliceType($Uint64);AO=$ptrType(A.Object);AP=$ptrType(I);AQ=$sliceType(AP);AR=$sliceType($Float64);AS=$ptrType(C);AT=$sliceType(AS);AU=$ptrType(D);L=function(a){var a,b,c,d,e,f,g,h;b=new $Uint64(a.$high&0,(a.$low&15)>>>0);d=(((c=$shiftRightUint64(a,4),new $Uint64(c.$high&0,(c.$low&1)>>>0)).$low>>0));f=(((e=$shiftRightUint64(a,5),new $Uint64(e.$high&0,(e.$low&1)>>>0)).$low>>0));return new F.ptr((g=(($flatten64(b)<0||$flatten64(b)>=$pkg.DIRECTION_DECODER.$length)?($throwRuntimeError("index out of range"),undefined):$pkg.DIRECTION_DECODER.$array[$pkg.DIRECTION_DECODER.$offset+$flatten64(b)]),(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0])),(h=(($flatten64(b)<0||$flatten64(b)>=$pkg.DIRECTION_DECODER.$length)?($throwRuntimeError("index out of range"),undefined):$pkg.DIRECTION_DECODER.$array[$pkg.DIRECTION_DECODER.$offset+$flatten64(b)]),(1>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+1])),d,f);};N=function(a,b,c,d){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$deferred,$r,$c}=$restore(this,{a,b,c,d});$s=$s||0;var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$curGoroutine.deferStack.push($deferred);c=[c];e=[e];f=[f];g=c[0].Position();e[0]=g[0];f[0]=g[1];$deferred.push([(function(c,e,f){return function(){c[0].SetPosition(e[0],f[0]);};})(c,e,f),[]]);c[0].SetPosition(e[0]+a,f[0]+b);h=new M.ptr(0,0,0,true,true,new A.Vector([0,0]));i=O(c[0],d,h);if(i){$s=1;continue;}$s=2;continue;case 1:j=h.Overlap*h.OverlapX;k=h.Overlap*h.OverlapY;l=j;m=k;n=[true,l,m,h];$s=4;case 4:return n;case 2:o=[false,0,0,h];$s=5;case 5:return o;case 3:$s=-1;return[false,0,0,AE.nil];}return;}}catch(err){$err=err;$s=-1;return[false,0,0,AE.nil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){var $f={$blk:N,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$deferred};return $f;}}};$pkg.CalcPushbacks=N;O=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;d=a.Points.$length;e=b.Points.$length;f=d;g=e;if((1===f)&&(1===g)){if(!(AE.nil===c)){c.Overlap=0;}return((h=(i=a.Points,(0>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+0])),(0>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+0]))===(j=(k=b.Points,(0>=k.$length?($throwRuntimeError("index out of range"),undefined):k.$array[k.$offset+0])),(0>=j.$length?($throwRuntimeError("index out of range"),undefined):j.$array[j.$offset+0])))&&((l=(m=a.Points,(0>=m.$length?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+0])),(1>=l.$length?($throwRuntimeError("index out of range"),undefined):l.$array[l.$offset+1]))===(n=(o=b.Points,(0>=o.$length?($throwRuntimeError("index out of range"),undefined):o.$array[o.$offset+0])),(1>=n.$length?($throwRuntimeError("index out of range"),undefined):n.$array[n.$offset+1])));}if(1=p.$length)?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+q]);if(P(a,b,r.Unit(),c)){return false;}q++;}}if(1=s.$length)?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+t]);if(P(a,b,u.Unit(),c)){return false;}t++;}}return true;};P=function(a,b,c,d){var a,aa,ab,ac,ad,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;e=1.7e+308;f=-1.7e+308;g=1.7e+308;h=-1.7e+308;i=e;j=f;k=g;l=h;m=a.Points;n=0;while(true){if(!(n=m.$length)?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+n]);p=((0>=o.$length?($throwRuntimeError("index out of range"),undefined):o.$array[o.$offset+0])+a.X)*(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0])+((1>=o.$length?($throwRuntimeError("index out of range"),undefined):o.$array[o.$offset+1])+a.Y)*(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]);if(i>p){i=p;}if(j=q.$length)?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+r]);t=((0>=s.$length?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+0])+b.X)*(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0])+((1>=s.$length?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+1])+b.Y)*(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]);if(k>t){k=t;}if(ll||jl){u=i-l;d.AContainedInB=false;}else{x=j-k;y=l-i;if(x=ab.$length?($throwRuntimeError("index out of range"),undefined):ab.$array[ab.$offset+0])))&&(0===(ac=d.Axis,(1>=ac.$length?($throwRuntimeError("index out of range"),undefined):ac.$array[ac.$offset+1]))))||z>aa){ad=1;if(u<0){ad=-1;}d.Overlap=aa;d.OverlapX=(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0])*ad;d.OverlapY=(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1])*ad;}d.Axis=c;}return false;};Q=function(a,b,c){var a,b,c,d,e;d=((B.Round(a*c)>>0));e=((B.Round(b*c)>>0));return[d,e];};$pkg.WorldToVirtualGridPos=Q;R=function(a,b,c){var a,b,c,d,e;d=(a)*c;e=(b)*c;return[d,e];};$pkg.VirtualGridToWorldPos=R;S=function(a,b,c,d,e,f,g,h,i,j){var a,b,c,d,e,f,g,h,i,j;return[a-c-g+i,b-d-f+j];};$pkg.WorldToPolygonColliderBLPos=S;T=function(a,b,c,d,e,f,g,h,i,j){var a,b,c,d,e,f,g,h,i,j;return[a+c+g-i,b+d+f-j];};$pkg.PolygonColliderBLToWorldPos=T;U=function(a,b,c,d,e,f,g,h,i,j,k){var a,b,c,d,e,f,g,h,i,j,k,l,m,n;l=T(a,b,c,d,e,f,g,h,i,j);m=l[0];n=l[1];return Q(m,n,k);};$pkg.PolygonColliderBLToVirtualGridPos=U;V=function(a,b,c,d,e,f,g,h,i,j,k){var a,b,c,d,e,f,g,h,i,j,k,l,m,n;l=R(a,b,k);m=l[0];n=l[1];return S(m,n,c,d,e,f,g,h,i,j);};$pkg.VirtualGridToPolygonColliderBLPos=V;W=function(a,b,c,d){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,$s,$r,$c}=$restore(this,{a,b,c,d});$s=$s||0;s:while(true){switch($s){case 0:e=$makeSlice(AF,0,10);f=a.Check(0,0,new AG([]));$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if(AH.nil===g){$s=-1;return e;}h=g.Objects;i=0;case 2:if(!(i=h.$length)?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+i]);k=j.Data;if($assertType(k,AI,true)[1]){$s=4;continue;}$s=5;continue;case 4:l=$assertType(j.Shape,AJ);n=N(0,0,b,l);$s=7;case 7:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];q=m[2];r=m[3];if(!o){i++;$s=2;continue;}s=(r.Overlap-c)*r.OverlapX;t=(r.Overlap-c)*r.OverlapY;p=s;q=t;e=$append(e,new C.ptr(r.OverlapX,r.OverlapY));d.X=d.X+(p);d.Y=d.Y+(q);$s=6;continue;case 5:case 6:i++;$s=2;continue;case 3:$s=-1;return e;}return;}var $f={$blk:W,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,$s};return $f;};X=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var{a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,c,ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz,d,da,db,dc,dd,de,df,dg,dh,di,dj,dk,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p});$s=$s||0;s:while(true){switch($s){case 0:q=c.PlayersArr.$length;r=$makeSlice(AL,q);s=c.PlayersArr;t=0;while(true){if(!(t=s.$length)?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+t]);((u<0||u>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+u]=new E.ptr(v.Id,v.VirtualGridX,v.VirtualGridY,v.DirX,v.DirY,v.VelX,v.VelY,v.Speed,v.BattleState,v.JoinIndex,0,v.Removed,v.Score,0,v.FramesToRecover-1>>0,v.Hp,v.MaxHp,v.CharacterState,true));if(((u<0||u>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+u]).FramesToRecover<0){((u<0||u>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+u]).FramesToRecover=0;}t++;}w=$makeSlice(AF,q);x=$makeSlice(AM,q);if(!(AN.nil===a)){y=c.PlayersArr;z=0;while(true){if(!(z=y.$length)?($throwRuntimeError("index out of range"),undefined):y.$array[y.$offset+z]);ac=ab.JoinIndex;ad=((aa<0||aa>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+aa]);if(0>0,((ae<0||ae>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+ae])));ag=0;if(!(AN.nil===b)){ai=L((ah=ac-1>>0,((ah<0||ah>=b.$length)?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+ah])));ag=ai.BtnBLevel;}if(af.BtnBLevel>ag){aj=false;if((4===ad.CharacterState)||(5===ad.CharacterState)||(6===ad.CharacterState)){aj=true;}ak=false;if((0===ad.CharacterState)||(1===ad.CharacterState)||(4===ad.CharacterState)){ak=true;}if(!aj&&ak){ad.VelY=h;}}if(!((0===af.Dx))||!((0===af.Dy))){ad.DirX=af.Dx;ad.DirY=af.Dy;ad.VelX=$imul(af.Dx,ab.Speed);ad.CharacterState=1;}else{ad.CharacterState=0;ad.VelX=0;}z++;}}al=c.PlayersArr;am=0;case 1:if(!(am=al.$length)?($throwRuntimeError("index out of range"),undefined):al.$array[al.$offset+am]);ap=ao.JoinIndex;aq=0;ar=0;(as=ap-1>>0,((as<0||as>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+as])).X=aq;(at=ap-1>>0,((at<0||at>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+at])).Y=ar;au=131072+ap>>0;aw=(av=e[$Int32.keyFor(au)],av!==undefined?av.v:AO.nil);ax=((an<0||an>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+an]);ay=ao.VirtualGridX+ao.VelX>>0;az=ao.VirtualGridY+ao.VelY>>0;ba=ay;bb=az;if(ax.VelY===h){bb=bb+(ax.VelY)>>0;}bc=V(ba,bb,aw.W*0.5,aw.H*0.5,0,0,0,0,k,l,p);aw.X=bc[0];aw.Y=bc[1];$r=aw.Update();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(ao.InAir){ax.VelX=ax.VelX+(f)>>0;ax.VelY=ax.VelY+(g)>>0;}am++;$s=1;continue;case 2:bd=c.PlayersArr;be=0;case 4:if(!(be=bd.$length)?($throwRuntimeError("index out of range"),undefined):bd.$array[bd.$offset+be]);bh=bg.JoinIndex;bi=131072+bh>>0;bk=(bj=e[$Int32.keyFor(bi)],bj!==undefined?bj.v:AO.nil);bl=$assertType(bk.Shape,AJ);bn=W(bk,bl,m,(bm=bh-1>>0,((bm<0||bm>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+bm])));$s=6;case 6:if($c){$c=false;bn=bn.$blk();}if(bn&&bn.$blk!==undefined){break s;}(bo=bh-1>>0,((bo<0||bo>=x.$length)?($throwRuntimeError("index out of range"),undefined):x.$array[x.$offset+bo]=bn));bp=((bf<0||bf>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+bf]);bq=false;br=bk.Check(0,0,new AG([]));$s=7;case 7:if($c){$c=false;br=br.$blk();}if(br&&br.$blk!==undefined){break s;}bs=br;if(!(AH.nil===bs)){$s=8;continue;}$s=9;continue;case 8:bt=bs.Objects;bu=0;case 10:if(!(bu=bt.$length)?($throwRuntimeError("index out of range"),undefined):bt.$array[bt.$offset+bu]);bw=false;bx=false;by=false;bz=bw;ca=bx;cb=by;cc=bv.Data;if($assertType(cc,AK,true)[1]){ca=true;}else if($assertType(cc,AP,true)[1]){cb=true;}else{bz=true;}if(cb){bu++;$s=10;continue;}cd=$assertType(bv.Shape,AJ);cf=N(0,0,bl,cd);$s=12;case 12:if($c){$c=false;cf=cf.$blk();}if(cf&&cf.$blk!==undefined){break s;}ce=cf;cg=ce[0];ch=ce[1];ci=ce[2];cj=ce[3];if(!cg){bu++;$s=10;continue;}ck=cj.OverlapX*0+cj.OverlapY*-1;cl=n>0,((cr<0||cr>=x.$length)?($throwRuntimeError("index out of range"),undefined):x.$array[x.$offset+cr]));cs=0;while(true){if(!(cs=cq.$length)?($throwRuntimeError("index out of range"),undefined):cq.$array[cq.$offset+cs]),C);cu=ch*ct.X+ci*ct.Y;if(bz||(ca&&0>cu)){ch=ch-(cu*ct.X);ci=ci-(cu*ct.Y);}cs++;}cv=bh-1>>0;((cv<0||cv>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+cv]).X=((cv<0||cv>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+cv]).X+(ch);cw=bh-1>>0;((cw<0||cw>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+cw]).Y=((cw<0||cw>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+cw]).Y+(ci);if(bg.InAir&&cl){bq=true;}bu++;$s=10;continue;case 11:case 9:if(bq){bp.VelX=0;bp.VelY=0;bp.CharacterState=0;bp.FramesToRecover=0;}if(bg.InAir){cx=bp.CharacterState;cy=cx;if((cy===(0))||(cy===(1))){bp.CharacterState=4;}else if(cy===(2)){bp.CharacterState=5;}else if(cy===(3)){bp.CharacterState=6;}}be++;$s=4;continue;case 5:cz=c.PlayersArr;da=0;while(true){if(!(da=cz.$length)?($throwRuntimeError("index out of range"),undefined):cz.$array[cz.$offset+da]);dd=dc.JoinIndex;de=131072+dd>>0;dg=(df=e[$Int32.keyFor(de)],df!==undefined?df.v:AO.nil);dh=((db<0||db>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+db]);di=U(dg.X-(dj=dd-1>>0,((dj<0||dj>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+dj])).X,dg.Y-(dk=dd-1>>0,((dk<0||dk>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+dk])).Y,dg.W*0.5,dg.H*0.5,0,0,0,0,k,l,o);dh.VirtualGridX=di[0];dh.VirtualGridY=di[1];da++;}$s=-1;return new J.ptr(c.Id+1>>0,r,new $Int64(0,0),AQ.nil,new $Uint64(0,0),false);}return;}var $f={$blk:X,$c:true,$r,a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,c,ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz,d,da,db,dc,dd,de,df,dg,dh,di,dj,dk,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};$pkg.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame=X;Y=function(a,b,c,d,e,f,g,h,i,j,k,l){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s,$r,$c}=$restore(this,{a,b,c,d,e,f,g,h,i,j,k,l});$s=$s||0;s:while(true){switch($s){case 0:m=S(a,b,c*0.5,d*0.5,e,f,g,h,i,j);n=m[0];o=m[1];p=Z(n,o,g+c+h,f+d+e,k,l);$s=1;case 1:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=p;$s=2;case 2:return q;}return;}var $f={$blk:Y,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s};return $f;};$pkg.GenerateRectCollider=Y;Z=function(a,b,c,d,e,f){var{a,b,c,d,e,f,g,h,$s,$r,$c}=$restore(this,{a,b,c,d,e,f});$s=$s||0;s:while(true){switch($s){case 0:g=A.NewObject(a,b,c,d,new AG([f]));h=A.NewRectangle(0,0,c,d);$r=g.SetShape(h);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}g.Data=e;$s=-1;return g;}return;}var $f={$blk:Z,$c:true,$r,a,b,c,d,e,f,g,h,$s};return $f;};AA=function(a,b,c,d,e){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,$s,$r,$c}=$restore(this,{a,b,c,d,e});$s=$s||0;s:while(true){switch($s){case 0:f=AB(a);g=0;h=0;i=g;j=h;k=A.NewConvexPolygon(AR.nil);l=f.Points;m=0;while(true){if(!(m=l.$length)?($throwRuntimeError("index out of range"),undefined):l.$array[l.$offset+m]);p=f.Points;q=0;while(true){if(!(q=p.$length)?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+q]);if(n===r){q++;continue;}if(B.Abs(s.X-o.X)>i){i=B.Abs(s.X-o.X);}if(B.Abs(s.Y-o.Y)>j){j=B.Abs(s.Y-o.Y);}q++;}m++;}t=0;while(true){if(!(t=u.$length)?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+t]));k.AddPoints(new AR([v.X,v.Y]));t=t+(1)>>0;}w=A.NewObject(f.Anchor.X+b,f.Anchor.Y+c,i,j,new AG([e]));$r=w.SetShape(k);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}w.Data=d;$s=-1;return w;}return;}var $f={$blk:AA,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,$s};return $f;};$pkg.GenerateConvexPolygonCollider=AA;AB=function(a){var a,b,c,d,e,f,g,h,i,j,k;b=new C.ptr(1.7e+308,1.7e+308);c=a.Points;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(e.X=g.$length)?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+h]);(k=f.Points,((i<0||i>=k.$length)?($throwRuntimeError("index out of range"),undefined):k.$array[k.$offset+i]=new C.ptr(j.X-b.X,j.Y-b.Y)));h++;}return f;};$pkg.AlignPolygon2DToBoundingBox=AB;C.init("",[{prop:"X",name:"X",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Y",name:"Y",embedded:false,exported:true,typ:$Float64,tag:""}]);D.init("",[{prop:"Anchor",name:"Anchor",embedded:false,exported:true,typ:AS,tag:""},{prop:"Points",name:"Points",embedded:false,exported:true,typ:AT,tag:""}]);E.init("",[{prop:"Id",name:"Id",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"VirtualGridX",name:"VirtualGridX",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"VirtualGridY",name:"VirtualGridY",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"DirX",name:"DirX",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"DirY",name:"DirY",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"VelX",name:"VelX",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"VelY",name:"VelY",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Speed",name:"Speed",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"BattleState",name:"BattleState",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"JoinIndex",name:"JoinIndex",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"ColliderRadius",name:"ColliderRadius",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Removed",name:"Removed",embedded:false,exported:true,typ:$Bool,tag:""},{prop:"Score",name:"Score",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"LastMoveGmtMillis",name:"LastMoveGmtMillis",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"FramesToRecover",name:"FramesToRecover",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Hp",name:"Hp",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"MaxHp",name:"MaxHp",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"CharacterState",name:"CharacterState",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"InAir",name:"InAir",embedded:false,exported:true,typ:$Bool,tag:""}]);F.init("",[{prop:"Dx",name:"Dx",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Dy",name:"Dy",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"BtnALevel",name:"BtnALevel",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"BtnBLevel",name:"BtnBLevel",embedded:false,exported:true,typ:$Int32,tag:""}]);H.init("",[{prop:"Boundary",name:"Boundary",embedded:false,exported:true,typ:AU,tag:""}]);I.init("",[{prop:"BattleLocalId",name:"BattleLocalId",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"StartupFrames",name:"StartupFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"ActiveFrames",name:"ActiveFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"RecoveryFrames",name:"RecoveryFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"RecoveryFramesOnBlock",name:"RecoveryFramesOnBlock",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"RecoveryFramesOnHit",name:"RecoveryFramesOnHit",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Moveforward",name:"Moveforward",embedded:false,exported:true,typ:AS,tag:""},{prop:"HitboxOffset",name:"HitboxOffset",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"HitboxSize",name:"HitboxSize",embedded:false,exported:true,typ:AS,tag:""},{prop:"OriginatedRenderFrameId",name:"OriginatedRenderFrameId",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"HitStunFrames",name:"HitStunFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"BlockStunFrames",name:"BlockStunFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Pushback",name:"Pushback",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"ReleaseTriggerType",name:"ReleaseTriggerType",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Damage",name:"Damage",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"OffenderJoinIndex",name:"OffenderJoinIndex",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"OffenderPlayerId",name:"OffenderPlayerId",embedded:false,exported:true,typ:$Int32,tag:""}]);J.init("",[{prop:"Id",name:"Id",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"PlayersArr",name:"PlayersArr",embedded:false,exported:true,typ:AL,tag:""},{prop:"CountdownNanos",name:"CountdownNanos",embedded:false,exported:true,typ:$Int64,tag:""},{prop:"MeleeBullets",name:"MeleeBullets",embedded:false,exported:true,typ:AQ,tag:""},{prop:"BackendUnconfirmedMask",name:"BackendUnconfirmedMask",embedded:false,exported:true,typ:$Uint64,tag:""},{prop:"ShouldForceResync",name:"ShouldForceResync",embedded:false,exported:true,typ:$Bool,tag:""}]);M.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:A.Vector,tag:""}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=B.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.DIRECTION_DECODER=new AD([new AC([0,0]),new AC([0,2]),new AC([0,-2]),new AC([2,0]),new AC([-2,0]),new AC([1,1]),new AC([-1,-1]),new AC([1,-1]),new AC([-1,1])]);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})(); -$packages["jsexport"]=(function(){var $pkg={},$init,B,C,A,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,D,E,F,G,H,I,J,K,L,M,N;B=$packages["github.com/gopherjs/gopherjs/js"];C=$packages["jsexport/battle"];A=$packages["resolv"];O=$ptrType(C.Vec2D);P=$sliceType(O);Q=$ptrType(C.Polygon2D);R=$ptrType(C.PlayerDownsync);S=$sliceType(R);T=$ptrType(C.MeleeBullet);U=$sliceType(T);V=$ptrType(B.Object);W=$sliceType(V);X=$funcType([$Float64,$Float64],[V],false);Y=$funcType([O,P],[V],false);Z=$funcType([Q],[V],false);AA=$funcType([$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Bool,$Float64],[V],false);AB=$funcType([$Int32,S,U],[V],false);AC=$funcType([$Int,$Int,$Int,$Int],[V],false);AD=$funcType([$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$emptyInterface,$String],[V],false);AE=$funcType([Q,$Float64,$Float64,$emptyInterface,$String],[V],false);AF=$ptrType(A.Space);AG=$funcType([AF],[W],false);AH=$sliceType($Uint64);AI=$ptrType(C.RoomDownsyncFrame);AJ=$ptrType(A.Object);AK=$mapType($Int32,AJ);AL=$funcType([AH,AH,AI,AF,AK,$Int32,$Int32,$Int32,$Int32,$Int32,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64],[V],false);AM=$funcType([$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64],[$Float64,$Float64],false);AN=$mapType($String,$emptyInterface);D=function(a,b,c,d){var a,b,c,d;return B.MakeWrapper(A.NewSpace(a,b,c,d));};$pkg.NewCollisionSpaceJs=D;E=function(a,b){var{a,b,c,d,$s,$r,$c}=$restore(this,{a,b});$s=$s||0;s:while(true){switch($s){case 0:c=B.MakeFullWrapper(new C.Vec2D.ptr(a,b));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;$s=2;case 2:return d;}return;}var $f={$blk:E,$c:true,$r,a,b,c,d,$s};return $f;};$pkg.NewVec2DJs=E;F=function(a,b){var{a,b,c,d,$s,$r,$c}=$restore(this,{a,b});$s=$s||0;s:while(true){switch($s){case 0:c=B.MakeFullWrapper(new C.Polygon2D.ptr(a,b));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;$s=2;case 2:return d;}return;}var $f={$blk:F,$c:true,$r,a,b,c,d,$s};return $f;};$pkg.NewPolygon2DJs=F;G=function(a){var a;return B.MakeWrapper(new C.Barrier.ptr(a));};$pkg.NewBarrierJs=G;H=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;return B.MakeWrapper(new C.PlayerDownsync.ptr(a,b,c,d,e,f,g,h,i,k,o,false,0,0,0,l,m,j,n));};$pkg.NewPlayerDownsyncJs=H;I=function(a,b,c){var{a,b,c,d,e,$s,$r,$c}=$restore(this,{a,b,c});$s=$s||0;s:while(true){switch($s){case 0:d=B.MakeFullWrapper(new C.RoomDownsyncFrame.ptr(a,b,new $Int64(0,0),c,new $Uint64(0,0),false));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;$s=2;case 2:return e;}return;}var $f={$blk:I,$c:true,$r,a,b,c,d,e,$s};return $f;};$pkg.NewRoomDownsyncFrameJs=I;J=function(a){var{a,b,c,d,e,f,g,$s,$r,$c}=$restore(this,{a});$s=$s||0;s:while(true){switch($s){case 0:b=a.Objects();c=$makeSlice(W,0,b.$length);d=b;e=0;case 1:if(!(e=d.$length)?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+e]);g=B.MakeFullWrapper(f);$s=3;case 3:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}c=$append(c,g);e++;$s=1;continue;case 2:$s=-1;return c;}return;}var $f={$blk:J,$c:true,$r,a,b,c,d,e,f,g,$s};return $f;};$pkg.GetCollisionSpaceObjsJs=J;K=function(a,b,c,d,e,f,g,h,i,j,k,l){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$r,$c}=$restore(this,{a,b,c,d,e,f,g,h,i,j,k,l});$s=$s||0;s:while(true){switch($s){case 0:m=C.GenerateRectCollider(a,b,c,d,e,f,g,h,i,j,k,l);$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=B.MakeFullWrapper(m);$s=2;case 2:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}o=n;$s=3;case 3:return o;}return;}var $f={$blk:K,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s};return $f;};$pkg.GenerateRectColliderJs=K;L=function(a,b,c,d,e){var{a,b,c,d,e,f,g,h,$s,$r,$c}=$restore(this,{a,b,c,d,e});$s=$s||0;s:while(true){switch($s){case 0:f=C.GenerateConvexPolygonCollider(a,b,c,d,e);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=B.MakeFullWrapper(f);$s=2;case 2:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;$s=3;case 3:return h;}return;}var $f={$blk:L,$c:true,$r,a,b,c,d,e,f,g,h,$s};return $f;};$pkg.GenerateConvexPolygonColliderJs=L;M=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$r,$c}=$restore(this,{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p});$s=$s||0;s:while(true){switch($s){case 0:q=C.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);$s=1;case 1:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=B.MakeFullWrapper(q);$s=2;case 2:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}s=r;$s=3;case 3:return s;}return;}var $f={$blk:M,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s};return $f;};$pkg.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs=M;N=function(){$global.gopkgs=$externalize($makeMap($String.keyFor,[{k:"NewVec2DJs",v:new X(E)},{k:"NewPolygon2DJs",v:new Y(F)},{k:"NewBarrierJs",v:new Z(G)},{k:"NewPlayerDownsyncJs",v:new AA(H)},{k:"NewRoomDownsyncFrameJs",v:new AB(I)},{k:"NewCollisionSpaceJs",v:new AC(D)},{k:"GenerateRectColliderJs",v:new AD(K)},{k:"GenerateConvexPolygonColliderJs",v:new AE(L)},{k:"GetCollisionSpaceObjsJs",v:new AG(J)},{k:"ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs",v:new AL(M)},{k:"WorldToPolygonColliderBLPos",v:new AM(C.WorldToPolygonColliderBLPos)},{k:"PolygonColliderBLToWorldPos",v:new AM(C.PolygonColliderBLToWorldPos)}]),AN);};$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=B.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if($pkg===$mainPkg){N();$mainFinished=true;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})(); +$packages["jsexport/battle"]=(function(){var $pkg={},$init,A,B,C,D,E,F,H,I,J,M,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,L,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB;A=$packages["math"];B=$packages["resolv"];C=$pkg.Vec2D=$newType(0,$kindStruct,"battle.Vec2D",true,"jsexport/battle",true,function(X_,Y_){this.$val=this;if(arguments.length===0){this.X=0;this.Y=0;return;}this.X=X_;this.Y=Y_;});D=$pkg.Polygon2D=$newType(0,$kindStruct,"battle.Polygon2D",true,"jsexport/battle",true,function(Anchor_,Points_){this.$val=this;if(arguments.length===0){this.Anchor=AS.nil;this.Points=AT.nil;return;}this.Anchor=Anchor_;this.Points=Points_;});E=$pkg.PlayerDownsync=$newType(0,$kindStruct,"battle.PlayerDownsync",true,"jsexport/battle",true,function(Id_,VirtualGridX_,VirtualGridY_,DirX_,DirY_,VelX_,VelY_,Speed_,BattleState_,JoinIndex_,ColliderRadius_,Removed_,Score_,LastMoveGmtMillis_,FramesToRecover_,Hp_,MaxHp_,CharacterState_,InAir_){this.$val=this;if(arguments.length===0){this.Id=0;this.VirtualGridX=0;this.VirtualGridY=0;this.DirX=0;this.DirY=0;this.VelX=0;this.VelY=0;this.Speed=0;this.BattleState=0;this.JoinIndex=0;this.ColliderRadius=0;this.Removed=false;this.Score=0;this.LastMoveGmtMillis=0;this.FramesToRecover=0;this.Hp=0;this.MaxHp=0;this.CharacterState=0;this.InAir=false;return;}this.Id=Id_;this.VirtualGridX=VirtualGridX_;this.VirtualGridY=VirtualGridY_;this.DirX=DirX_;this.DirY=DirY_;this.VelX=VelX_;this.VelY=VelY_;this.Speed=Speed_;this.BattleState=BattleState_;this.JoinIndex=JoinIndex_;this.ColliderRadius=ColliderRadius_;this.Removed=Removed_;this.Score=Score_;this.LastMoveGmtMillis=LastMoveGmtMillis_;this.FramesToRecover=FramesToRecover_;this.Hp=Hp_;this.MaxHp=MaxHp_;this.CharacterState=CharacterState_;this.InAir=InAir_;});F=$pkg.InputFrameDecoded=$newType(0,$kindStruct,"battle.InputFrameDecoded",true,"jsexport/battle",true,function(Dx_,Dy_,BtnALevel_,BtnBLevel_){this.$val=this;if(arguments.length===0){this.Dx=0;this.Dy=0;this.BtnALevel=0;this.BtnBLevel=0;return;}this.Dx=Dx_;this.Dy=Dy_;this.BtnALevel=BtnALevel_;this.BtnBLevel=BtnBLevel_;});H=$pkg.Barrier=$newType(0,$kindStruct,"battle.Barrier",true,"jsexport/battle",true,function(Boundary_){this.$val=this;if(arguments.length===0){this.Boundary=AU.nil;return;}this.Boundary=Boundary_;});I=$pkg.MeleeBullet=$newType(0,$kindStruct,"battle.MeleeBullet",true,"jsexport/battle",true,function(BattleLocalId_,StartupFrames_,ActiveFrames_,RecoveryFrames_,RecoveryFramesOnBlock_,RecoveryFramesOnHit_,HitboxOffset_,OriginatedRenderFrameId_,HitStunFrames_,BlockStunFrames_,Pushback_,ReleaseTriggerType_,Damage_,OffenderJoinIndex_,OffenderPlayerId_,SelfMoveforwardX_,SelfMoveforwardY_,HitboxSizeX_,HitboxSizeY_){this.$val=this;if(arguments.length===0){this.BattleLocalId=0;this.StartupFrames=0;this.ActiveFrames=0;this.RecoveryFrames=0;this.RecoveryFramesOnBlock=0;this.RecoveryFramesOnHit=0;this.HitboxOffset=0;this.OriginatedRenderFrameId=0;this.HitStunFrames=0;this.BlockStunFrames=0;this.Pushback=0;this.ReleaseTriggerType=0;this.Damage=0;this.OffenderJoinIndex=0;this.OffenderPlayerId=0;this.SelfMoveforwardX=0;this.SelfMoveforwardY=0;this.HitboxSizeX=0;this.HitboxSizeY=0;return;}this.BattleLocalId=BattleLocalId_;this.StartupFrames=StartupFrames_;this.ActiveFrames=ActiveFrames_;this.RecoveryFrames=RecoveryFrames_;this.RecoveryFramesOnBlock=RecoveryFramesOnBlock_;this.RecoveryFramesOnHit=RecoveryFramesOnHit_;this.HitboxOffset=HitboxOffset_;this.OriginatedRenderFrameId=OriginatedRenderFrameId_;this.HitStunFrames=HitStunFrames_;this.BlockStunFrames=BlockStunFrames_;this.Pushback=Pushback_;this.ReleaseTriggerType=ReleaseTriggerType_;this.Damage=Damage_;this.OffenderJoinIndex=OffenderJoinIndex_;this.OffenderPlayerId=OffenderPlayerId_;this.SelfMoveforwardX=SelfMoveforwardX_;this.SelfMoveforwardY=SelfMoveforwardY_;this.HitboxSizeX=HitboxSizeX_;this.HitboxSizeY=HitboxSizeY_;});J=$pkg.RoomDownsyncFrame=$newType(0,$kindStruct,"battle.RoomDownsyncFrame",true,"jsexport/battle",true,function(Id_,PlayersArr_,CountdownNanos_,MeleeBullets_,BackendUnconfirmedMask_,ShouldForceResync_){this.$val=this;if(arguments.length===0){this.Id=0;this.PlayersArr=AL.nil;this.CountdownNanos=new $Int64(0,0);this.MeleeBullets=AQ.nil;this.BackendUnconfirmedMask=new $Uint64(0,0);this.ShouldForceResync=false;return;}this.Id=Id_;this.PlayersArr=PlayersArr_;this.CountdownNanos=CountdownNanos_;this.MeleeBullets=MeleeBullets_;this.BackendUnconfirmedMask=BackendUnconfirmedMask_;this.ShouldForceResync=ShouldForceResync_;});M=$pkg.SatResult=$newType(0,$kindStruct,"battle.SatResult",true,"jsexport/battle",true,function(Overlap_,OverlapX_,OverlapY_,AContainedInB_,BContainedInA_,Axis_){this.$val=this;if(arguments.length===0){this.Overlap=0;this.OverlapX=0;this.OverlapY=0;this.AContainedInB=false;this.BContainedInA=false;this.Axis=B.Vector.nil;return;}this.Overlap=Overlap_;this.OverlapX=OverlapX_;this.OverlapY=OverlapY_;this.AContainedInB=AContainedInB_;this.BContainedInA=BContainedInA_;this.Axis=Axis_;});AC=$sliceType($Int32);AD=$sliceType(AC);AE=$ptrType(M);AF=$sliceType(C);AG=$sliceType($String);AH=$ptrType(B.Collision);AI=$ptrType(H);AJ=$ptrType(B.ConvexPolygon);AK=$ptrType(E);AL=$sliceType(AK);AM=$sliceType(AF);AN=$sliceType($Uint64);AO=$ptrType(B.Object);AP=$ptrType(I);AQ=$sliceType(AP);AR=$sliceType($Float64);AS=$ptrType(C);AT=$sliceType(AS);AU=$ptrType(D);L=function(a){var a,b,c,d,e,f,g,h;b=new $Uint64(a.$high&0,(a.$low&15)>>>0);d=(((c=$shiftRightUint64(a,4),new $Uint64(c.$high&0,(c.$low&1)>>>0)).$low>>0));f=(((e=$shiftRightUint64(a,5),new $Uint64(e.$high&0,(e.$low&1)>>>0)).$low>>0));return new F.ptr((g=(($flatten64(b)<0||$flatten64(b)>=$pkg.DIRECTION_DECODER.$length)?($throwRuntimeError("index out of range"),undefined):$pkg.DIRECTION_DECODER.$array[$pkg.DIRECTION_DECODER.$offset+$flatten64(b)]),(0>=g.$length?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+0])),(h=(($flatten64(b)<0||$flatten64(b)>=$pkg.DIRECTION_DECODER.$length)?($throwRuntimeError("index out of range"),undefined):$pkg.DIRECTION_DECODER.$array[$pkg.DIRECTION_DECODER.$offset+$flatten64(b)]),(1>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+1])),d,f);};N=function(a,b,c,d){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$deferred,$r,$c}=$restore(this,{a,b,c,d});$s=$s||0;var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$curGoroutine.deferStack.push($deferred);c=[c];e=[e];f=[f];g=c[0].Position();e[0]=g[0];f[0]=g[1];$deferred.push([(function(c,e,f){return function(){c[0].SetPosition(e[0],f[0]);};})(c,e,f),[]]);c[0].SetPosition(e[0]+a,f[0]+b);h=new M.ptr(0,0,0,true,true,new B.Vector([0,0]));i=O(c[0],d,h);if(i){$s=1;continue;}$s=2;continue;case 1:j=h.Overlap*h.OverlapX;k=h.Overlap*h.OverlapY;l=j;m=k;n=[true,l,m,h];$s=4;case 4:return n;case 2:o=[false,0,0,h];$s=5;case 5:return o;case 3:$s=-1;return[false,0,0,AE.nil];}return;}}catch(err){$err=err;$s=-1;return[false,0,0,AE.nil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){var $f={$blk:N,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$deferred};return $f;}}};$pkg.CalcPushbacks=N;O=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;d=a.Points.$length;e=b.Points.$length;f=d;g=e;if((1===f)&&(1===g)){if(!(AE.nil===c)){c.Overlap=0;}return((h=(i=a.Points,(0>=i.$length?($throwRuntimeError("index out of range"),undefined):i.$array[i.$offset+0])),(0>=h.$length?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+0]))===(j=(k=b.Points,(0>=k.$length?($throwRuntimeError("index out of range"),undefined):k.$array[k.$offset+0])),(0>=j.$length?($throwRuntimeError("index out of range"),undefined):j.$array[j.$offset+0])))&&((l=(m=a.Points,(0>=m.$length?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+0])),(1>=l.$length?($throwRuntimeError("index out of range"),undefined):l.$array[l.$offset+1]))===(n=(o=b.Points,(0>=o.$length?($throwRuntimeError("index out of range"),undefined):o.$array[o.$offset+0])),(1>=n.$length?($throwRuntimeError("index out of range"),undefined):n.$array[n.$offset+1])));}if(1=p.$length)?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+q]);if(P(a,b,r.Unit(),c)){return false;}q++;}}if(1=s.$length)?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+t]);if(P(a,b,u.Unit(),c)){return false;}t++;}}return true;};P=function(a,b,c,d){var a,aa,ab,ac,ad,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;e=1.7e+308;f=-1.7e+308;g=1.7e+308;h=-1.7e+308;i=e;j=f;k=g;l=h;m=a.Points;n=0;while(true){if(!(n=m.$length)?($throwRuntimeError("index out of range"),undefined):m.$array[m.$offset+n]);p=((0>=o.$length?($throwRuntimeError("index out of range"),undefined):o.$array[o.$offset+0])+a.X)*(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0])+((1>=o.$length?($throwRuntimeError("index out of range"),undefined):o.$array[o.$offset+1])+a.Y)*(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]);if(i>p){i=p;}if(j=q.$length)?($throwRuntimeError("index out of range"),undefined):q.$array[q.$offset+r]);t=((0>=s.$length?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+0])+b.X)*(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0])+((1>=s.$length?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+1])+b.Y)*(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1]);if(k>t){k=t;}if(ll||jl){u=i-l;d.AContainedInB=false;}else{x=j-k;y=l-i;if(x=ab.$length?($throwRuntimeError("index out of range"),undefined):ab.$array[ab.$offset+0])))&&(0===(ac=d.Axis,(1>=ac.$length?($throwRuntimeError("index out of range"),undefined):ac.$array[ac.$offset+1]))))||z>aa){ad=1;if(u<0){ad=-1;}d.Overlap=aa;d.OverlapX=(0>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+0])*ad;d.OverlapY=(1>=c.$length?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+1])*ad;}d.Axis=c;}return false;};Q=function(a,b,c){var a,b,c,d,e;d=((A.Round(a*c)>>0));e=((A.Round(b*c)>>0));return[d,e];};$pkg.WorldToVirtualGridPos=Q;R=function(a,b,c){var a,b,c,d,e;d=(a)*c;e=(b)*c;return[d,e];};$pkg.VirtualGridToWorldPos=R;S=function(a,b,c,d,e,f,g,h,i,j){var a,b,c,d,e,f,g,h,i,j;return[a-c-g+i,b-d-f+j];};$pkg.WorldToPolygonColliderBLPos=S;T=function(a,b,c,d,e,f,g,h,i,j){var a,b,c,d,e,f,g,h,i,j;return[a+c+g-i,b+d+f-j];};$pkg.PolygonColliderBLToWorldPos=T;U=function(a,b,c,d,e,f,g,h,i,j,k){var a,b,c,d,e,f,g,h,i,j,k,l,m,n;l=T(a,b,c,d,e,f,g,h,i,j);m=l[0];n=l[1];return Q(m,n,k);};$pkg.PolygonColliderBLToVirtualGridPos=U;V=function(a,b,c,d,e,f,g,h,i,j,k){var a,b,c,d,e,f,g,h,i,j,k,l,m,n;l=R(a,b,k);m=l[0];n=l[1];return S(m,n,c,d,e,f,g,h,i,j);};$pkg.VirtualGridToPolygonColliderBLPos=V;W=function(a,b,c,d){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,$s,$r,$c}=$restore(this,{a,b,c,d});$s=$s||0;s:while(true){switch($s){case 0:e=$makeSlice(AF,0,10);f=a.Check(0,0,new AG([]));$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if(AH.nil===g){$s=-1;return e;}h=g.Objects;i=0;case 2:if(!(i=h.$length)?($throwRuntimeError("index out of range"),undefined):h.$array[h.$offset+i]);k=j.Data;if($assertType(k,AI,true)[1]){$s=4;continue;}$s=5;continue;case 4:l=$assertType(j.Shape,AJ);n=N(0,0,b,l);$s=7;case 7:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];q=m[2];r=m[3];if(!o){i++;$s=2;continue;}s=(r.Overlap-c)*r.OverlapX;t=(r.Overlap-c)*r.OverlapY;p=s;q=t;e=$append(e,new C.ptr(r.OverlapX,r.OverlapY));d.X=d.X+(p);d.Y=d.Y+(q);$s=6;continue;case 5:case 6:i++;$s=2;continue;case 3:$s=-1;return e;}return;}var $f={$blk:W,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,$s};return $f;};X=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var{a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,c,ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz,d,da,db,dc,dd,de,df,dg,dh,di,dj,dk,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r,$c}=$restore(this,{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p});$s=$s||0;s:while(true){switch($s){case 0:q=c.PlayersArr.$length;r=$makeSlice(AL,q);s=c.PlayersArr;t=0;while(true){if(!(t=s.$length)?($throwRuntimeError("index out of range"),undefined):s.$array[s.$offset+t]);((u<0||u>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+u]=new E.ptr(v.Id,v.VirtualGridX,v.VirtualGridY,v.DirX,v.DirY,v.VelX,v.VelY,v.Speed,v.BattleState,v.JoinIndex,0,v.Removed,v.Score,0,v.FramesToRecover-1>>0,v.Hp,v.MaxHp,v.CharacterState,true));if(((u<0||u>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+u]).FramesToRecover<0){((u<0||u>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+u]).FramesToRecover=0;}t++;}w=$makeSlice(AF,q);x=$makeSlice(AM,q);if(!(AN.nil===a)){y=c.PlayersArr;z=0;while(true){if(!(z=y.$length)?($throwRuntimeError("index out of range"),undefined):y.$array[y.$offset+z]);ac=ab.JoinIndex;ad=((aa<0||aa>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+aa]);if(0>0,((ae<0||ae>=a.$length)?($throwRuntimeError("index out of range"),undefined):a.$array[a.$offset+ae])));ag=0;if(!(AN.nil===b)){ai=L((ah=ac-1>>0,((ah<0||ah>=b.$length)?($throwRuntimeError("index out of range"),undefined):b.$array[b.$offset+ah])));ag=ai.BtnBLevel;}if(af.BtnBLevel>ag){aj=false;if((4===ad.CharacterState)||(5===ad.CharacterState)||(6===ad.CharacterState)){aj=true;}ak=false;if((0===ad.CharacterState)||(1===ad.CharacterState)||(4===ad.CharacterState)){ak=true;}if(!aj&&ak){ad.VelY=h;}}if(!((0===af.Dx))||!((0===af.Dy))){ad.DirX=af.Dx;ad.DirY=af.Dy;ad.VelX=$imul(af.Dx,ab.Speed);ad.CharacterState=1;}else{ad.CharacterState=0;ad.VelX=0;}z++;}}al=c.PlayersArr;am=0;case 1:if(!(am=al.$length)?($throwRuntimeError("index out of range"),undefined):al.$array[al.$offset+am]);ap=ao.JoinIndex;aq=0;ar=0;(as=ap-1>>0,((as<0||as>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+as])).X=aq;(at=ap-1>>0,((at<0||at>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+at])).Y=ar;au=131072+ap>>0;aw=(av=e[$Int32.keyFor(au)],av!==undefined?av.v:AO.nil);ax=((an<0||an>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+an]);ay=ao.VirtualGridX+ao.VelX>>0;az=ao.VirtualGridY+ao.VelY>>0;ba=ay;bb=az;if(ax.VelY===h){bb=bb+(ax.VelY)>>0;}bc=V(ba,bb,aw.W*0.5,aw.H*0.5,0,0,0,0,k,l,p);aw.X=bc[0];aw.Y=bc[1];$r=aw.Update();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(ao.InAir){ax.VelX=ax.VelX+(f)>>0;ax.VelY=ax.VelY+(g)>>0;}am++;$s=1;continue;case 2:bd=c.PlayersArr;be=0;case 4:if(!(be=bd.$length)?($throwRuntimeError("index out of range"),undefined):bd.$array[bd.$offset+be]);bh=bg.JoinIndex;bi=131072+bh>>0;bk=(bj=e[$Int32.keyFor(bi)],bj!==undefined?bj.v:AO.nil);bl=$assertType(bk.Shape,AJ);bn=W(bk,bl,m,(bm=bh-1>>0,((bm<0||bm>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+bm])));$s=6;case 6:if($c){$c=false;bn=bn.$blk();}if(bn&&bn.$blk!==undefined){break s;}(bo=bh-1>>0,((bo<0||bo>=x.$length)?($throwRuntimeError("index out of range"),undefined):x.$array[x.$offset+bo]=bn));bp=((bf<0||bf>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+bf]);bq=false;br=bk.Check(0,0,new AG([]));$s=7;case 7:if($c){$c=false;br=br.$blk();}if(br&&br.$blk!==undefined){break s;}bs=br;if(!(AH.nil===bs)){$s=8;continue;}$s=9;continue;case 8:bt=bs.Objects;bu=0;case 10:if(!(bu=bt.$length)?($throwRuntimeError("index out of range"),undefined):bt.$array[bt.$offset+bu]);bw=false;bx=false;by=false;bz=bw;ca=bx;cb=by;cc=bv.Data;if($assertType(cc,AK,true)[1]){ca=true;}else if($assertType(cc,AP,true)[1]){cb=true;}else{bz=true;}if(cb){bu++;$s=10;continue;}cd=$assertType(bv.Shape,AJ);cf=N(0,0,bl,cd);$s=12;case 12:if($c){$c=false;cf=cf.$blk();}if(cf&&cf.$blk!==undefined){break s;}ce=cf;cg=ce[0];ch=ce[1];ci=ce[2];cj=ce[3];if(!cg){bu++;$s=10;continue;}ck=cj.OverlapX*0+cj.OverlapY*-1;cl=n>0,((cr<0||cr>=x.$length)?($throwRuntimeError("index out of range"),undefined):x.$array[x.$offset+cr]));cs=0;while(true){if(!(cs=cq.$length)?($throwRuntimeError("index out of range"),undefined):cq.$array[cq.$offset+cs]),C);cu=ch*ct.X+ci*ct.Y;if(bz||(ca&&0>cu)){ch=ch-(cu*ct.X);ci=ci-(cu*ct.Y);}cs++;}cv=bh-1>>0;((cv<0||cv>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+cv]).X=((cv<0||cv>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+cv]).X+(ch);cw=bh-1>>0;((cw<0||cw>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+cw]).Y=((cw<0||cw>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+cw]).Y+(ci);if(bg.InAir&&cl){bq=true;}bu++;$s=10;continue;case 11:case 9:if(bq){bp.VelX=0;bp.VelY=0;bp.CharacterState=0;bp.FramesToRecover=0;}if(bg.InAir){cx=bp.CharacterState;cy=cx;if((cy===(0))||(cy===(1))){bp.CharacterState=4;}else if(cy===(2)){bp.CharacterState=5;}else if(cy===(3)){bp.CharacterState=6;}}be++;$s=4;continue;case 5:cz=c.PlayersArr;da=0;while(true){if(!(da=cz.$length)?($throwRuntimeError("index out of range"),undefined):cz.$array[cz.$offset+da]);dd=dc.JoinIndex;de=131072+dd>>0;dg=(df=e[$Int32.keyFor(de)],df!==undefined?df.v:AO.nil);dh=((db<0||db>=r.$length)?($throwRuntimeError("index out of range"),undefined):r.$array[r.$offset+db]);di=U(dg.X-(dj=dd-1>>0,((dj<0||dj>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+dj])).X,dg.Y-(dk=dd-1>>0,((dk<0||dk>=w.$length)?($throwRuntimeError("index out of range"),undefined):w.$array[w.$offset+dk])).Y,dg.W*0.5,dg.H*0.5,0,0,0,0,k,l,o);dh.VirtualGridX=di[0];dh.VirtualGridY=di[1];da++;}$s=-1;return new J.ptr(c.Id+1>>0,r,new $Int64(0,0),AQ.nil,new $Uint64(0,0),false);}return;}var $f={$blk:X,$c:true,$r,a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,c,ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz,d,da,db,dc,dd,de,df,dg,dh,di,dj,dk,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s};return $f;};$pkg.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame=X;Y=function(a,b,c,d,e,f,g,h,i,j,k,l){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s,$r,$c}=$restore(this,{a,b,c,d,e,f,g,h,i,j,k,l});$s=$s||0;s:while(true){switch($s){case 0:m=S(a,b,c*0.5,d*0.5,e,f,g,h,i,j);n=m[0];o=m[1];p=Z(n,o,g+c+h,f+d+e,k,l);$s=1;case 1:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=p;$s=2;case 2:return q;}return;}var $f={$blk:Y,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s};return $f;};$pkg.GenerateRectCollider=Y;Z=function(a,b,c,d,e,f){var{a,b,c,d,e,f,g,h,$s,$r,$c}=$restore(this,{a,b,c,d,e,f});$s=$s||0;s:while(true){switch($s){case 0:g=B.NewObject(a,b,c,d,new AG([f]));h=B.NewRectangle(0,0,c,d);$r=g.SetShape(h);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}g.Data=e;$s=-1;return g;}return;}var $f={$blk:Z,$c:true,$r,a,b,c,d,e,f,g,h,$s};return $f;};AA=function(a,b,c,d,e){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,$s,$r,$c}=$restore(this,{a,b,c,d,e});$s=$s||0;s:while(true){switch($s){case 0:f=AB(a);g=0;h=0;i=g;j=h;k=B.NewConvexPolygon(AR.nil);l=f.Points;m=0;while(true){if(!(m=l.$length)?($throwRuntimeError("index out of range"),undefined):l.$array[l.$offset+m]);p=f.Points;q=0;while(true){if(!(q=p.$length)?($throwRuntimeError("index out of range"),undefined):p.$array[p.$offset+q]);if(n===r){q++;continue;}if(A.Abs(s.X-o.X)>i){i=A.Abs(s.X-o.X);}if(A.Abs(s.Y-o.Y)>j){j=A.Abs(s.Y-o.Y);}q++;}m++;}t=0;while(true){if(!(t=u.$length)?($throwRuntimeError("index out of range"),undefined):u.$array[u.$offset+t]));k.AddPoints(new AR([v.X,v.Y]));t=t+(1)>>0;}w=B.NewObject(f.Anchor.X+b,f.Anchor.Y+c,i,j,new AG([e]));$r=w.SetShape(k);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}w.Data=d;$s=-1;return w;}return;}var $f={$blk:AA,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,$s};return $f;};$pkg.GenerateConvexPolygonCollider=AA;AB=function(a){var a,b,c,d,e,f,g,h,i,j,k;b=new C.ptr(1.7e+308,1.7e+308);c=a.Points;d=0;while(true){if(!(d=c.$length)?($throwRuntimeError("index out of range"),undefined):c.$array[c.$offset+d]);if(e.X=g.$length)?($throwRuntimeError("index out of range"),undefined):g.$array[g.$offset+h]);(k=f.Points,((i<0||i>=k.$length)?($throwRuntimeError("index out of range"),undefined):k.$array[k.$offset+i]=new C.ptr(j.X-b.X,j.Y-b.Y)));h++;}return f;};$pkg.AlignPolygon2DToBoundingBox=AB;C.init("",[{prop:"X",name:"X",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Y",name:"Y",embedded:false,exported:true,typ:$Float64,tag:""}]);D.init("",[{prop:"Anchor",name:"Anchor",embedded:false,exported:true,typ:AS,tag:""},{prop:"Points",name:"Points",embedded:false,exported:true,typ:AT,tag:""}]);E.init("",[{prop:"Id",name:"Id",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"VirtualGridX",name:"VirtualGridX",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"VirtualGridY",name:"VirtualGridY",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"DirX",name:"DirX",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"DirY",name:"DirY",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"VelX",name:"VelX",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"VelY",name:"VelY",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Speed",name:"Speed",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"BattleState",name:"BattleState",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"JoinIndex",name:"JoinIndex",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"ColliderRadius",name:"ColliderRadius",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"Removed",name:"Removed",embedded:false,exported:true,typ:$Bool,tag:""},{prop:"Score",name:"Score",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"LastMoveGmtMillis",name:"LastMoveGmtMillis",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"FramesToRecover",name:"FramesToRecover",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Hp",name:"Hp",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"MaxHp",name:"MaxHp",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"CharacterState",name:"CharacterState",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"InAir",name:"InAir",embedded:false,exported:true,typ:$Bool,tag:""}]);F.init("",[{prop:"Dx",name:"Dx",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Dy",name:"Dy",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"BtnALevel",name:"BtnALevel",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"BtnBLevel",name:"BtnBLevel",embedded:false,exported:true,typ:$Int32,tag:""}]);H.init("",[{prop:"Boundary",name:"Boundary",embedded:false,exported:true,typ:AU,tag:""}]);I.init("",[{prop:"BattleLocalId",name:"BattleLocalId",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"StartupFrames",name:"StartupFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"ActiveFrames",name:"ActiveFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"RecoveryFrames",name:"RecoveryFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"RecoveryFramesOnBlock",name:"RecoveryFramesOnBlock",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"RecoveryFramesOnHit",name:"RecoveryFramesOnHit",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"HitboxOffset",name:"HitboxOffset",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"OriginatedRenderFrameId",name:"OriginatedRenderFrameId",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"HitStunFrames",name:"HitStunFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"BlockStunFrames",name:"BlockStunFrames",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Pushback",name:"Pushback",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"ReleaseTriggerType",name:"ReleaseTriggerType",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"Damage",name:"Damage",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"OffenderJoinIndex",name:"OffenderJoinIndex",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"OffenderPlayerId",name:"OffenderPlayerId",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"SelfMoveforwardX",name:"SelfMoveforwardX",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"SelfMoveforwardY",name:"SelfMoveforwardY",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"HitboxSizeX",name:"HitboxSizeX",embedded:false,exported:true,typ:$Float64,tag:""},{prop:"HitboxSizeY",name:"HitboxSizeY",embedded:false,exported:true,typ:$Float64,tag:""}]);J.init("",[{prop:"Id",name:"Id",embedded:false,exported:true,typ:$Int32,tag:""},{prop:"PlayersArr",name:"PlayersArr",embedded:false,exported:true,typ:AL,tag:""},{prop:"CountdownNanos",name:"CountdownNanos",embedded:false,exported:true,typ:$Int64,tag:""},{prop:"MeleeBullets",name:"MeleeBullets",embedded:false,exported:true,typ:AQ,tag:""},{prop:"BackendUnconfirmedMask",name:"BackendUnconfirmedMask",embedded:false,exported:true,typ:$Uint64,tag:""},{prop:"ShouldForceResync",name:"ShouldForceResync",embedded:false,exported:true,typ:$Bool,tag:""}]);M.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:B.Vector,tag:""}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.DIRECTION_DECODER=new AD([new AC([0,0]),new AC([0,2]),new AC([0,-2]),new AC([2,0]),new AC([-2,0]),new AC([1,1]),new AC([-1,-1]),new AC([1,-1]),new AC([-1,1])]);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})(); +$packages["jsexport"]=(function(){var $pkg={},$init,A,B,C,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,D,E,F,G,H,J,K,L,M,N,O;A=$packages["github.com/gopherjs/gopherjs/js"];B=$packages["jsexport/battle"];C=$packages["resolv"];P=$ptrType(B.Vec2D);Q=$sliceType(P);R=$ptrType(B.Polygon2D);S=$ptrType(B.PlayerDownsync);T=$sliceType(S);U=$ptrType(B.MeleeBullet);V=$sliceType(U);W=$ptrType(A.Object);X=$sliceType(W);Y=$funcType([$Float64,$Float64],[W],false);Z=$funcType([P,Q],[W],false);AA=$funcType([R],[W],false);AB=$funcType([$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Int32,$Bool,$Float64],[W],false);AC=$funcType([$Int32,T,V],[W],false);AD=$funcType([$Int,$Int,$Int,$Int],[W],false);AE=$funcType([$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$emptyInterface,$String],[W],false);AF=$funcType([R,$Float64,$Float64,$emptyInterface,$String],[W],false);AG=$ptrType(C.Space);AH=$funcType([AG],[X],false);AI=$sliceType($Uint64);AJ=$ptrType(B.RoomDownsyncFrame);AK=$ptrType(C.Object);AL=$mapType($Int32,AK);AM=$funcType([AI,AI,AJ,AG,AL,$Int32,$Int32,$Int32,$Int32,$Uint32,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64],[W],false);AN=$funcType([$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64,$Float64],[$Float64,$Float64],false);AO=$mapType($String,$emptyInterface);D=function(a,b,c,d){var a,b,c,d;return A.MakeWrapper(C.NewSpace(a,b,c,d));};$pkg.NewCollisionSpaceJs=D;E=function(a,b){var{a,b,c,d,$s,$r,$c}=$restore(this,{a,b});$s=$s||0;s:while(true){switch($s){case 0:c=A.MakeFullWrapper(new B.Vec2D.ptr(a,b));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;$s=2;case 2:return d;}return;}var $f={$blk:E,$c:true,$r,a,b,c,d,$s};return $f;};$pkg.NewVec2DJs=E;F=function(a,b){var{a,b,c,d,$s,$r,$c}=$restore(this,{a,b});$s=$s||0;s:while(true){switch($s){case 0:c=A.MakeFullWrapper(new B.Polygon2D.ptr(a,b));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;$s=2;case 2:return d;}return;}var $f={$blk:F,$c:true,$r,a,b,c,d,$s};return $f;};$pkg.NewPolygon2DJs=F;G=function(a){var a;return A.MakeWrapper(new B.Barrier.ptr(a));};$pkg.NewBarrierJs=G;H=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;return A.MakeWrapper(new B.PlayerDownsync.ptr(a,b,c,d,e,f,g,h,i,k,o,false,0,0,0,l,m,j,n));};$pkg.NewPlayerDownsyncJs=H;J=function(a,b,c){var{a,b,c,d,e,$s,$r,$c}=$restore(this,{a,b,c});$s=$s||0;s:while(true){switch($s){case 0:d=A.MakeFullWrapper(new B.RoomDownsyncFrame.ptr(a,b,new $Int64(0,0),c,new $Uint64(0,0),false));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;$s=2;case 2:return e;}return;}var $f={$blk:J,$c:true,$r,a,b,c,d,e,$s};return $f;};$pkg.NewRoomDownsyncFrameJs=J;K=function(a){var{a,b,c,d,e,f,g,$s,$r,$c}=$restore(this,{a});$s=$s||0;s:while(true){switch($s){case 0:b=a.Objects();c=$makeSlice(X,0,b.$length);d=b;e=0;case 1:if(!(e=d.$length)?($throwRuntimeError("index out of range"),undefined):d.$array[d.$offset+e]);g=A.MakeFullWrapper(f);$s=3;case 3:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}c=$append(c,g);e++;$s=1;continue;case 2:$s=-1;return c;}return;}var $f={$blk:K,$c:true,$r,a,b,c,d,e,f,g,$s};return $f;};$pkg.GetCollisionSpaceObjsJs=K;L=function(a,b,c,d,e,f,g,h,i,j,k,l){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$r,$c}=$restore(this,{a,b,c,d,e,f,g,h,i,j,k,l});$s=$s||0;s:while(true){switch($s){case 0:m=B.GenerateRectCollider(a,b,c,d,e,f,g,h,i,j,k,l);$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=A.MakeFullWrapper(m);$s=2;case 2:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}o=n;$s=3;case 3:return o;}return;}var $f={$blk:L,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s};return $f;};$pkg.GenerateRectColliderJs=L;M=function(a,b,c,d,e){var{a,b,c,d,e,f,g,h,$s,$r,$c}=$restore(this,{a,b,c,d,e});$s=$s||0;s:while(true){switch($s){case 0:f=B.GenerateConvexPolygonCollider(a,b,c,d,e);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=A.MakeFullWrapper(f);$s=2;case 2:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;$s=3;case 3:return h;}return;}var $f={$blk:M,$c:true,$r,a,b,c,d,e,f,g,h,$s};return $f;};$pkg.GenerateConvexPolygonColliderJs=M;N=function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$r,$c}=$restore(this,{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p});$s=$s||0;s:while(true){switch($s){case 0:q=B.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);$s=1;case 1:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=A.MakeFullWrapper(q);$s=2;case 2:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}s=r;$s=3;case 3:return s;}return;}var $f={$blk:N,$c:true,$r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s};return $f;};$pkg.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs=N;O=function(){$global.gopkgs=$externalize($makeMap($String.keyFor,[{k:"NewVec2DJs",v:new Y(E)},{k:"NewPolygon2DJs",v:new Z(F)},{k:"NewBarrierJs",v:new AA(G)},{k:"NewPlayerDownsyncJs",v:new AB(H)},{k:"NewRoomDownsyncFrameJs",v:new AC(J)},{k:"NewCollisionSpaceJs",v:new AD(D)},{k:"GenerateRectColliderJs",v:new AE(L)},{k:"GenerateConvexPolygonColliderJs",v:new AF(M)},{k:"GetCollisionSpaceObjsJs",v:new AH(K)},{k:"ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs",v:new AM(N)},{k:"WorldToPolygonColliderBLPos",v:new AN(B.WorldToPolygonColliderBLPos)},{k:"PolygonColliderBLToWorldPos",v:new AN(B.PolygonColliderBLToWorldPos)}]),AO);};$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if($pkg===$mainPkg){O();$mainFinished=true;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})(); $synthesizeMethods(); $initAllLinknames(); var $mainPkg = $packages["jsexport"]; diff --git a/frontend/assets/resources/pbfiles/room_downsync_frame.proto b/frontend/assets/resources/pbfiles/room_downsync_frame.proto index 9a4a8c1..a1e58c3 100644 --- a/frontend/assets/resources/pbfiles/room_downsync_frame.proto +++ b/frontend/assets/resources/pbfiles/room_downsync_frame.proto @@ -146,6 +146,7 @@ message BattleColliderInfo { int32 jumpingInitVelY = 27; int32 gravityX = 28; int32 gravityY = 29; + int32 collisionMinStep = 30; } message RoomDownsyncFrame { @@ -155,6 +156,4 @@ 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; - - map players = 99; // TO BE DEPRECATED } diff --git a/frontend/assets/scripts/Map.js b/frontend/assets/scripts/Map.js index ec446d1..0f6aa2c 100644 --- a/frontend/assets/scripts/Map.js +++ b/frontend/assets/scripts/Map.js @@ -141,7 +141,7 @@ cc.Class({ let previousSelfInput = null, currSelfInput = null; - const joinIndex = self.selfPlayerInfo.joinIndex; + const joinIndex = self.selfPlayerInfo.joinIndex || self.selfPlayerInfo.JoinIndex; const existingInputFrame = self.recentInputCache.getByFrameId(inputFrameId); const previousInputFrameDownsyncWithPrediction = self.getCachedInputFrameDownsyncWithPrediction(inputFrameId - 1); previousSelfInput = (null == previousInputFrameDownsyncWithPrediction ? null : previousInputFrameDownsyncWithPrediction.inputList[joinIndex - 1]); @@ -159,7 +159,7 @@ cc.Class({ const prefabbedInputFrameDownsync = window.pb.protos.InputFrameDownsync.create({ inputFrameId: self.recentInputCache.edFrameId, inputList: prefabbedInputList, - confirmedList: (1 << (self.selfPlayerInfo.joinIndex - 1)) + confirmedList: (1 << (joinIndex - 1)) }); self.recentInputCache.put(prefabbedInputFrameDownsync); @@ -308,11 +308,15 @@ cc.Class({ self.selfPlayerInfo = null; // This field is kept for distinguishing "self" and "others". self.recentInputCache = new RingBuffer((self.renderCacheSize >> 1) + 1); - self.collisionSys = new collisions.Collisions(); + const spaceW = self.stageDiscreteW * self.stageTileW; + const spaceH = self.stageDiscreteH * self.stageTileH; + self.spaceOffsetX = (spaceW >> 1); + self.spaceOffsetY = (spaceH >> 1); + self.gopkgsCollisionSys = gopkgs.NewCollisionSpaceJs(spaceW, spaceH, self.collisionMinStep, self.collisionMinStep); + self.gopkgsCollisionSysMap = {}; // [WARNING] Don't use "JavaScript Map" which could cause loss of type information when passing through Golang transpiled functions! self.collisionBarrierIndexPrefix = (1 << 16); // For tracking the movements of barriers, though not yet actually used self.collisionBulletIndexPrefix = (1 << 15); // For tracking the movements of bullets - self.collisionSysMap = new Map(); console.log(`collisionSys & collisionSysMap reset`); @@ -454,21 +458,19 @@ cc.Class({ } let barrierIdCounter = 0; - const refBoundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node).barriers; - const boundaryObjs = parsedBattleColliderInfo.strToPolygon2DListMap; - for (let k = 0; k < boundaryObjs["Barrier"].eles.length; k++) { - let boundaryObj = boundaryObjs["Barrier"].eles[k]; - const refBoundaryObj = refBoundaryObjs[k]; - // boundaryObj = refBoundaryObj; - const [x0, y0] = [boundaryObj.anchor.x, boundaryObj.anchor.y]; - const newBarrierCollider = self.collisionSys.createPolygon(x0, y0, Array.from(boundaryObj.points, p => { - return [p.x, p.y]; - })); - newBarrierCollider.data = { - hardPushback: true - }; + const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node); + for (let boundaryObj of boundaryObjs.barriers) { + const gopkgsBoundaryAnchor = gopkgs.NewVec2DJs(boundaryObj.anchor.x, boundaryObj.anchor.y); + const gopkgsBoundaryPts = Array.from(boundaryObj, p => { + return gopkgs.NewVec2DJs(p.x, p.y); + }); + const gopkgsBoundary = gopkgs.NewPolygon2DJs(gopkgsBoundaryAnchor, gopkgsBoundaryPts); + const gopkgsBarrier = gopkgs.NewBarrierJs(gopkgsBoundary); - if (self.showCriticalCoordinateLabels) { + const newBarrierCollider = gopkgs.GenerateConvexPolygonColliderJs(gopkgsBoundary, self.spaceOffsetX, self.spaceOffsetY, gopkgsBarrier, "Barrier"); + self.gopkgsCollisionSys.Add(newBarrierCollider); + + if (false && self.showCriticalCoordinateLabels) { for (let i = 0; i < boundaryObj.length; ++i) { const barrierVertLabelNode = new cc.Node(); switch (i % 4) { @@ -499,12 +501,11 @@ cc.Class({ } } + // console.log("Created barrier: ", newBarrierCollider); ++barrierIdCounter; const collisionBarrierIndex = (self.collisionBarrierIndexPrefix + barrierIdCounter); - self.collisionSysMap.set(collisionBarrierIndex, newBarrierCollider); - // console.log(`Created new barrier collider: ${collisionBarrierIndex}`); + self.gopkgsCollisionSysMap[collisionBarrierIndex] = newBarrierCollider; } - self.selfPlayerInfo = JSON.parse(cc.sys.localStorage.getItem('selfPlayer')); Object.assign(self.selfPlayerInfo, { id: self.selfPlayerInfo.playerId @@ -578,8 +579,22 @@ cc.Class({ this._inputControlEnabled = false; }, - onRoomDownsyncFrame(rdf, accompaniedInputFrameDownsyncBatch) { + onRoomDownsyncFrame(pbRdf /* pb.RoomDownsyncFrame */ , accompaniedInputFrameDownsyncBatch /* pb.InputFrameDownsyncBatch */ ) { + const jsPlayersArr = new Array().fill(null); + for (let k in pbRdf.playersArr) { + const pbPlayer = pbRdf.playersArr[k]; + const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.inAir, pbPlayer.colliderRadius); + jsPlayersArr[k] = jsPlayer; + } + const jsMeleeBulletsArr = []; + for (let k in pbRdf.meleeBullets) { + const pbBullet = pbRdf.meleeBullets[k]; + const jsBullet = gopkgs.NewMeleeBullet(pbBullet.battleLocalId, pbBullet.startupFrames, pbBullet.activeFrames, pbBullet.recoveryFrames, pbBullet.recoveryFramesOnBlock, pbBullet.recoveryFramesOnHit, pbBullet.hitStunFrames, pbBullet.blockStunFrames, pbBullet.releaseTriggerType, pbBullet.damage, pbBullet.offenderJoinIndex, pbBullet.offenderPlayerId, pbBullet.pushback, pbBullet.hitboxOffset, pbBullet.selfMoveforwardX, pbBullet.selfMoveforwardY, pbBullet.hitboxSizeX, pbBullet.hitboxSizeY); + jsMeleeBulletsArr.push(jsBullet); + } + // This function is also applicable to "re-joining". + const rdf = gopkgs.NewRoomDownsyncFrameJs(pbRdf.id, jsPlayersArr, jsMeleeBulletsArr); const self = window.mapIns; self.onInputFrameDownsyncBatch(accompaniedInputFrameDownsyncBatch); // Important to do this step before setting IN_BATTLE if (!self.recentRenderCache) { @@ -588,14 +603,14 @@ cc.Class({ if (ALL_BATTLE_STATES.IN_SETTLEMENT == self.battleState) { return; } - const shouldForceDumping1 = (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.id); - let shouldForceDumping2 = (rdf.id >= self.renderFrameId + self.renderFrameIdLagTolerance); - let shouldForceResync = rdf.shouldForceResync; - const notSelfUnconfirmed = (0 == (rdf.backendUnconfirmedMask & (1 << (self.selfPlayerInfo.joinIndex - 1)))); + const shouldForceDumping1 = (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id); + let shouldForceDumping2 = (rdf.Id >= self.renderFrameId + self.renderFrameIdLagTolerance); + let shouldForceResync = rdf.ShouldForceResync; + const notSelfUnconfirmed = (0 == (rdf.BackendUnconfirmedMask & (1 << (self.selfPlayerInfo.joinIndex - 1)))); if (notSelfUnconfirmed) { shouldForceDumping2 = false; shouldForceResync = false; - self.othersForcedDownsyncRenderFrameDict.set(rdf.id, rdf); + self.othersForcedDownsyncRenderFrameDict.set(rdf.Id, rdf); } /* TODO @@ -616,47 +631,40 @@ cc.Class({ } // The logic below applies to (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.id || window.RING_BUFF_NON_CONSECUTIVE_SET == dumpRenderCacheRet) - const players = rdf.players; - self._initPlayerRichInfoDict(players); + self._initPlayerRichInfoDict(rdf.PlayersArr); // Show the top status indicators for IN_BATTLE if (self.playersInfoNode) { const playersInfoScriptIns = self.playersInfoNode.getComponent("PlayersInfo"); - for (let i in players) { - playersInfoScriptIns.updateData(players[i]); + for (let i in pbRdf.playersArr) { + playersInfoScriptIns.updateData(pbRdf.playersArr[i]); } } if (shouldForceDumping1 || shouldForceDumping2 || shouldForceResync) { // In fact, not having "window.RING_BUFF_CONSECUTIVE_SET == dumpRenderCacheRet" should already imply that "self.renderFrameId <= rdf.id", but here we double check and log the anomaly - if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.id) { - console.log('On battle started! renderFrameId=', rdf.id); - } else { - self.hideFindingPlayersGUI(rdf); - console.warn(`Got resync@localRenderFrameId=${self.renderFrameId} -> rdf.id=${rdf.id} & rdf.backendUnconfirmedMask=${rdf.backendUnconfirmedMask}, @lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, @chaserRenderFrameId=${self.chaserRenderFrameId}, @localRecentInputCache=${mapIns._stringifyRecentInputCache(false)}`); + if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id) { + console.log('On battle started! renderFrameId=', rdf.Id); } - - self.renderFrameId = rdf.id; + self.renderFrameId = rdf.Id; self.lastRenderFrameIdTriggeredAt = performance.now(); // In this case it must be true that "rdf.id > chaserRenderFrameId". - self.chaserRenderFrameId = rdf.id; + self.chaserRenderFrameId = rdf.Id; const canvasNode = self.canvasNode; self.ctrl = canvasNode.getComponent("TouchEventsManager"); self.enableInputControls(); self.transitToState(ALL_MAP_STATES.VISUAL); self.battleState = ALL_BATTLE_STATES.IN_BATTLE; + } - if (self.countdownToBeginGameNode && self.countdownToBeginGameNode.parent) { - self.countdownToBeginGameNode.parent.removeChild(self.countdownToBeginGameNode); - } + if (self.countdownToBeginGameNode && self.countdownToBeginGameNode.parent) { + self.countdownToBeginGameNode.parent.removeChild(self.countdownToBeginGameNode); + } - if (null != self.musicEffectManagerScriptIns) { - self.musicEffectManagerScriptIns.playBGM(); - } - } else { - console.warn(`Anomaly when onRoomDownsyncFrame is called by rdf=${JSON.stringify(rdf)}, recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`); + if (null != self.musicEffectManagerScriptIns) { + self.musicEffectManagerScriptIns.playBGM(); } // [WARNING] Leave all graphical updates in "update(dt)" by "applyRoomDownsyncFrameDynamics" @@ -769,14 +777,14 @@ lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}`); self.chaserRenderFrameId = renderFrameId1; }, - onPlayerAdded(rdf) { + onPlayerAdded(rdf /* pb.RoomDownsyncFrame */ ) { const self = this; // Update the "finding player" GUI and show it if not previously present if (!self.findingPlayerNode.parent) { self.showPopupInCanvas(self.findingPlayerNode); } let findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer"); - findingPlayerScriptIns.updatePlayersInfo(rdf.players); + findingPlayerScriptIns.updatePlayersInfo(rdf.playersArr); }, onBattleStopped() { @@ -815,29 +823,37 @@ lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}`); const [wx, wy] = self.virtualGridToWorldPos(vx, vy); newPlayerNode.setPosition(wx, wy); playerScriptIns.mapNode = self.node; - const halfColliderWidth = playerDownsyncInfo.colliderRadius, - halfColliderHeight = playerDownsyncInfo.colliderRadius + playerDownsyncInfo.colliderRadius; // avoid multiplying + const colliderRadius = playerDownsyncInfo.colliderRadius || playerDownsyncInfo.ColliderRadius; + const halfColliderWidth = colliderRadius, + halfColliderHeight = colliderRadius + colliderRadius; // avoid multiplying const colliderWidth = halfColliderWidth + halfColliderWidth, colliderHeight = halfColliderHeight + halfColliderHeight; // avoid multiplying - const leftPadding = self.snapIntoPlatformOverlap, - rightPadding = self.snapIntoPlatformOverlap, - topPadding = self.snapIntoPlatformOverlap, - bottomPadding = self.snapIntoPlatformOverlap; - const cpos = self.virtualGridToPolygonColliderBLPos(vx, vy, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding); // the collider center is kept having integer coords - const pts = [[0, 0], [leftPadding + colliderWidth + rightPadding, 0], [leftPadding + colliderWidth + rightPadding, bottomPadding + colliderHeight + topPadding], [0, bottomPadding + colliderHeight + topPadding]]; - // [WARNING] The animNode "anchor & offset" are tuned to fit in this collider by "ControlledCharacter prefab & AttackingCharacter.js"! - const newPlayerCollider = self.collisionSys.createPolygon(cpos[0], cpos[1], pts); + const [cx, cy] = gopkgs.WorldToPolygonColliderBLPos(wx, wy, halfColliderWidth, halfColliderHeight, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.spaceOffsetX, self.spaceOffsetY); + const gopkgsBoundaryAnchor = gopkgs.NewVec2DJs(cx, cy); + const gopkgsBoundaryPts = [ + gopkgs.NewVec2DJs(0, 0), + gopkgs.NewVec2DJs(self.snapIntoPlatformOverlap + colliderWidth + self.snapIntoPlatformOverlap, 0), + gopkgs.NewVec2DJs(self.snapIntoPlatformOverlap + colliderWidth + self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap + colliderHeight + self.snapIntoPlatformOverlap), + gopkgs.NewVec2DJs(0, self.snapIntoPlatformOverlap + colliderHeight + self.snapIntoPlatformOverlap) + ]; + const gopkgsBoundary = gopkgs.NewPolygon2DJs(gopkgsBoundaryAnchor, gopkgsBoundaryPts); + const newPlayerCollider = gopkgs.GenerateConvexPolygonColliderJs(gopkgsBoundary, self.spaceOffsetX, self.spaceOffsetY, playerDownsyncInfo, "Player"); + //const newPlayerCollider = gopkgs.GenerateRectColliderJs(wx, wy, colliderWidth, colliderHeight, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.spaceOffsetX, self.spaceOffsetY, playerDownsyncInfo, "Player"); + self.gopkgsCollisionSys.Add(newPlayerCollider); const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - newPlayerCollider.data = playerDownsyncInfo; - self.collisionSysMap.set(collisionPlayerIndex, newPlayerCollider); + self.gopkgsCollisionSysMap[collisionPlayerIndex] = newPlayerCollider; - console.log(`Created new player collider: joinIndex=${joinIndex}, colliderRadius=${playerDownsyncInfo.colliderRadius}`); + console.log(`Created new player collider: joinIndex=${joinIndex}, colliderRadius=${playerDownsyncInfo.ColliderRadius}`); safelyAddChild(self.node, newPlayerNode); setLocalZOrder(newPlayerNode, 5); newPlayerNode.active = true; + playerDownsyncInfo.characterState = playerDownsyncInfo.CharacterState; + playerDownsyncInfo.dirX = playerDownsyncInfo.DirX; + playerDownsyncInfo.dirY = playerDownsyncInfo.DirY; + playerDownsyncInfo.framesToRecover = playerDownsyncInfo.FrameToRecover; playerScriptIns.updateCharacterAnim(playerDownsyncInfo, null, true); return [newPlayerNode, playerScriptIns]; @@ -876,12 +892,12 @@ lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}`); } if (prevChaserRenderFrameId < nextChaserRenderFrameId) { // Do not execute "rollbackAndChase" when "prevChaserRenderFrameId == nextChaserRenderFrameId", otherwise if "nextChaserRenderFrameId == self.renderFrameId" we'd be wasting computing power once. - self.rollbackAndChase(prevChaserRenderFrameId, nextChaserRenderFrameId, self.collisionSys, self.collisionSysMap, true); + self.rollbackAndChase(prevChaserRenderFrameId, nextChaserRenderFrameId, self.gopkgsCollisionSys, self.gopkgsCollisionSysMap, true); } let t2 = performance.now(); // Inside the following "self.rollbackAndChase" actually ROLLS FORWARD w.r.t. the corresponding delayedInputFrame, REGARDLESS OF whether or not "self.chaserRenderFrameId == self.renderFrameId" now. - const latestRdfResults = self.rollbackAndChase(self.renderFrameId, self.renderFrameId + 1, self.collisionSys, self.collisionSysMap, false); + const latestRdfResults = self.rollbackAndChase(self.renderFrameId, self.renderFrameId + 1, self.gopkgsCollisionSys, self.gopkgsCollisionSysMap, false); let prevRdf = latestRdfResults[0], rdf = latestRdfResults[1]; /* @@ -1003,10 +1019,9 @@ ${self._stringifyRecentInputAndRenderCacheCorrespondingly()}`); self.findingPlayerNode.parent.removeChild(self.findingPlayerNode); }, - onBattleReadyToStart(rdf) { + onBattleReadyToStart(rdf /* pb.RoomDownsyncFrame */ ) { const self = this; - const players = rdf.players; - self._initPlayerRichInfoDict(players); + const players = rdf.playersArr; // Show the top status indicators for IN_BATTLE if (self.playersInfoNode) { @@ -1035,94 +1050,20 @@ ${self._stringifyRecentInputAndRenderCacheCorrespondingly()}`); applyRoomDownsyncFrameDynamics(rdf, prevRdf) { const self = this; - for (let [playerId, playerRichInfo] of self.playerRichInfoDict.entries()) { - const currPlayerDownsync = rdf.players[playerId]; - const prevRdfPlayer = (null == prevRdf ? null : prevRdf.players[playerId]); - const [wx, wy] = self.virtualGridToWorldPos(currPlayerDownsync.virtualGridX, currPlayerDownsync.virtualGridY); - //const justJiggling = (self.jigglingEps1D >= Math.abs(wx - playerRichInfo.node.x) && self.jigglingEps1D >= Math.abs(wy - playerRichInfo.node.y)); + const playersArr = rdf.PlayersArr; + for (let k in playersArr) { + const currPlayerDownsync = playersArr[k]; + const prevRdfPlayer = (null == prevRdf ? null : prevRdf.PlayersArr[k]); + const [wx, wy] = self.virtualGridToWorldPos(currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY); + const playerRichInfo = self.playerRichInfoArr[k]; playerRichInfo.node.setPosition(wx, wy); - playerRichInfo.scriptIns.updateSpeed(currPlayerDownsync.speed); + playerRichInfo.scriptIns.updateSpeed(currPlayerDownsync.Speed); + currPlayerDownsync.characterState = currPlayerDownsync.CharacterState; + currPlayerDownsync.dirX = currPlayerDownsync.DirX; + currPlayerDownsync.dirY = currPlayerDownsync.DirY; + currPlayerDownsync.framesToRecover = currPlayerDownsync.FrameToRecover; playerRichInfo.scriptIns.updateCharacterAnim(currPlayerDownsync, prevRdfPlayer, false); } - - // Update countdown - self.countdownNanos = self.battleDurationNanos - self.renderFrameId * self.rollbackEstimatedDtNanos; - if (self.countdownNanos <= 0) { - self.onBattleStopped(self.playerRichInfoDict); - } - }, - - showDebugBoundaries(rdf) { - const self = this; - const leftPadding = self.snapIntoPlatformOverlap, - rightPadding = self.snapIntoPlatformOverlap, - topPadding = self.snapIntoPlatformOverlap, - bottomPadding = self.snapIntoPlatformOverlap; - if (self.showCriticalCoordinateLabels) { - let g = self.g; - g.clear(); - - for (let k in self.collisionSys._bvh._bodies) { - const body = self.collisionSys._bvh._bodies[k]; - if (!body._polygon) continue; - if (null != body.data && null != body.data.joinIndex) { - // character - if (1 == body.data.joinIndex) { - g.strokeColor = cc.Color.BLUE; - } else { - g.strokeColor = cc.Color.RED; - } - } else { - // barrier - g.strokeColor = cc.Color.WHITE; - } - g.moveTo(body.x, body.y); - const cnt = body._coords.length; - for (let j = 0; j < cnt; j += 2) { - const x = body._coords[j], - y = body._coords[j + 1]; - g.lineTo(x, y); - } - g.lineTo(body.x, body.y); - g.stroke(); - } - // For convenience of recovery upon reconnection, active bullets are always created & immediately removed from "collisionSys" within "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" - - for (let k in rdf.meleeBullets) { - const meleeBullet = rdf.meleeBullets[k]; - if ( - meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames <= rdf.id - && - meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames + meleeBullet.activeFrames > rdf.id - ) { - const offender = rdf.players[meleeBullet.offenderPlayerId]; - if (1 == offender.joinIndex) { - g.strokeColor = cc.Color.BLUE; - } else { - g.strokeColor = cc.Color.RED; - } - - let xfac = 1; // By now, straight Punch offset doesn't respect "y-axis" - if (0 > offender.dirX) { - xfac = -1; - } - const [offenderWx, offenderWy] = self.virtualGridToWorldPos(offender.virtualGridX, offender.virtualGridY); - const bulletWx = offenderWx + xfac * meleeBullet.hitboxOffset; - const bulletWy = offenderWy; - const halfColliderWidth = meleeBullet.hitboxSize.x * 0.5, - halfColliderHeight = meleeBullet.hitboxSize.y * 0.5; // avoid multiplying - const bulletCpos = self.worldToPolygonColliderBLPos(bulletWx, bulletWy, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding); - const pts = [[0, 0], [leftPadding + meleeBullet.hitboxSize.x + rightPadding, 0], [leftPadding + meleeBullet.hitboxSize.x + rightPadding, bottomPadding + meleeBullet.hitboxSize.y + topPadding], [0, bottomPadding + meleeBullet.hitboxSize.y + topPadding]]; - - g.moveTo(bulletCpos[0], bulletCpos[1]); - for (let j = 0; j < pts.length; j += 1) { - g.lineTo(pts[j][0] + bulletCpos[0], pts[j][1] + bulletCpos[1]); - } - g.lineTo(bulletCpos[0], bulletCpos[1]); - g.stroke(); - } - } - } }, getCachedInputFrameDownsyncWithPrediction(inputFrameId) { @@ -1141,373 +1082,7 @@ ${self._stringifyRecentInputAndRenderCacheCorrespondingly()}`); return inputFrameDownsync; }, - // TODO: Write unit-test for this function to compare with its backend counter part - applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputFrame, currRenderFrame, collisionSys, collisionSysMap) { - const self = this; - const leftPadding = self.snapIntoPlatformOverlap, - rightPadding = self.snapIntoPlatformOverlap, - topPadding = self.snapIntoPlatformOverlap, - bottomPadding = self.snapIntoPlatformOverlap; - const nextRenderFramePlayers = {}; - for (let playerId in currRenderFrame.players) { - const currPlayerDownsync = currRenderFrame.players[playerId]; - nextRenderFramePlayers[playerId] = { - id: playerId, - virtualGridX: currPlayerDownsync.virtualGridX, - virtualGridY: currPlayerDownsync.virtualGridY, - dirX: currPlayerDownsync.dirX, - dirY: currPlayerDownsync.dirY, - velX: currPlayerDownsync.velX, - velY: currPlayerDownsync.velY, - characterState: currPlayerDownsync.characterState, - inAir: true, - speed: currPlayerDownsync.speed, - battleState: currPlayerDownsync.battleState, - score: currPlayerDownsync.score, - removed: currPlayerDownsync.removed, - joinIndex: currPlayerDownsync.joinIndex, - framesToRecover: (0 < currPlayerDownsync.framesToRecover ? currPlayerDownsync.framesToRecover - 1 : 0), - hp: currPlayerDownsync.hp, - maxHp: currPlayerDownsync.maxHp, - }; - } - - const nextRenderFrameMeleeBullets = []; - const effPushbacks = new Array(self.playerRichInfoArr.length); - const hardPushbackNorms = new Array(self.playerRichInfoArr.length); - - // 1. Process player inputs - /* - [WARNING] Player input alone WOULD NOT take "characterState" into any "ATK_CHARACTER_STATE_IN_AIR_SET", only after the calculation of "effPushbacks" do we know exactly whether or not a player is "inAir", the finalize the transition of "thatPlayerInNextFrame.characterState". - */ - if (null != delayedInputFrame) { - const delayedInputFrameForPrevRenderFrame = self.getCachedInputFrameDownsyncWithPrediction(self._convertToInputFrameId(currRenderFrame.id - 1, self.inputDelayFrames)); - const inputList = delayedInputFrame.inputList; - for (let j in self.playerRichInfoArr) { - const joinIndex = parseInt(j) + 1; - const playerRichInfo = self.playerRichInfoArr[j]; - const playerId = playerRichInfo.id; - const currPlayerDownsync = currRenderFrame.players[playerId]; - const thatPlayerInNextFrame = nextRenderFramePlayers[playerId]; - if (0 < thatPlayerInNextFrame.framesToRecover) { - // No need to process inputs for this player, but there might be bullet pushbacks on this player - continue; - } - - const decodedInput = self.ctrl.decodeInput(inputList[joinIndex - 1]); - const prevDecodedInput = (null == delayedInputFrameForPrevRenderFrame ? null : self.ctrl.decodeInput(delayedInputFrameForPrevRenderFrame.inputList[joinIndex - 1])); - const prevBtnALevel = (null == prevDecodedInput ? 0 : prevDecodedInput.btnALevel); - const prevBtnBLevel = (null == prevDecodedInput ? 0 : prevDecodedInput.btnBLevel); - if (1 == decodedInput.btnBLevel && 0 == prevBtnBLevel) { - const characStateAlreadyInAir = window.ATK_CHARACTER_STATE_IN_AIR_SET.has(thatPlayerInNextFrame.characterState); - const characStateIsInterruptWaivable = window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.has(thatPlayerInNextFrame.characterState); - if ( - !characStateAlreadyInAir - && - characStateIsInterruptWaivable - ) { - thatPlayerInNextFrame.velY = self.jumpingInitVelY; - if (1 == joinIndex) { - console.log(`playerId=${playerId}, joinIndex=${joinIndex} jumped at {renderFrame.id: ${currRenderFrame.id}, virtualX: ${currPlayerDownsync.virtualGridX}, virtualY: ${currPlayerDownsync.virtualGridY}, nextVelX: ${thatPlayerInNextFrame.velX}, nextVelY: ${thatPlayerInNextFrame.velY}}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); - } - } - } - - if (1 == decodedInput.btnALevel && 0 == prevBtnALevel) { - const punchSkillId = 1; - const punch = window.pb.protos.MeleeBullet.create(self.meleeSkillConfig[punchSkillId]); - thatPlayerInNextFrame.framesToRecover = punch.recoveryFrames; - punch.battleLocalId = self.bulletBattleLocalIdCounter++; - punch.offenderJoinIndex = joinIndex; - punch.offenderPlayerId = playerId; - punch.originatedRenderFrameId = currRenderFrame.id; - nextRenderFrameMeleeBullets.push(punch); - // console.log(`playerId=${playerId}, joinIndex=${joinIndex} triggered a rising-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); - - thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atk1[0]; - if (false == currPlayerDownsync.inAir) { - thatPlayerInNextFrame.velX = 0; // prohibits simultaneous movement with Atk1 on the ground - } - } else if (0 == decodedInput.btnALevel && 1 == prevBtnALevel) { - // console.log(`playerId=${playerId} triggered a falling-edge of btnA at renderFrame.id=${currRenderFrame.id}, delayedInputFrame.id=${delayedInputFrame.inputFrameId}`); - } else { - // No bullet trigger, process joystick movement inputs. - if (0 != decodedInput.dx || 0 != decodedInput.dy) { - // Update directions and thus would eventually update moving animation accordingly - thatPlayerInNextFrame.dirX = decodedInput.dx; - thatPlayerInNextFrame.dirY = decodedInput.dy; - thatPlayerInNextFrame.velX = decodedInput.dx * currPlayerDownsync.speed; - thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Walking[0]; - } else { - thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Idle1[0]; - thatPlayerInNextFrame.velX = 0; - } - } - } - } - - // 2. Process player movement - for (let j in self.playerRichInfoArr) { - const joinIndex = parseInt(j) + 1; - effPushbacks[joinIndex - 1] = [0.0, 0.0]; - const playerRichInfo = self.playerRichInfoArr[j]; - const playerId = playerRichInfo.id; - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - const playerCollider = collisionSysMap.get(collisionPlayerIndex); - const currPlayerDownsync = currRenderFrame.players[playerId]; - const thatPlayerInNextFrame = nextRenderFramePlayers[playerId]; - // Reset playerCollider position from the "virtual grid position" - const newVpos = [currPlayerDownsync.virtualGridX + currPlayerDownsync.velX, currPlayerDownsync.virtualGridY + currPlayerDownsync.velY]; - if (thatPlayerInNextFrame.velY == self.jumpingInitVelY) { - // This step can be waived, but putting the jumping inclination here makes it easier to read logs. - newVpos[1] += self.jumpingInitVelY; - } - const halfColliderWidth = self.playerRichInfoArr[j].colliderRadius, - halfColliderHeight = self.playerRichInfoArr[j].colliderRadius + self.playerRichInfoArr[j].colliderRadius; // avoid multiplying - const newCpos = self.virtualGridToPolygonColliderBLPos(newVpos[0], newVpos[1], halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding); - playerCollider.x = newCpos[0]; - playerCollider.y = newCpos[1]; - - if (currPlayerDownsync.inAir) { - thatPlayerInNextFrame.velX += self.gravityX; - thatPlayerInNextFrame.velY += self.gravityY; - } - } - - // 3. Add bullet colliders into collision system - const bulletColliders = new Map(); // Will all be removed at the end of `applyInputFrameDownsyncDynamicsOnSingleRenderFrame` due to the need for being rollback-compatible - const removedBulletsAtCurrFrame = new Set(); - for (let k in currRenderFrame.meleeBullets) { - const meleeBullet = currRenderFrame.meleeBullets[k]; - if ( - meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames <= currRenderFrame.id - && - meleeBullet.originatedRenderFrameId + meleeBullet.startupFrames + meleeBullet.activeFrames > currRenderFrame.id - ) { - const collisionBulletIndex = self.collisionBulletIndexPrefix + meleeBullet.battleLocalId; - const collisionOffenderIndex = self.collisionPlayerIndexPrefix + meleeBullet.offenderJoinIndex; - const offenderCollider = collisionSysMap.get(collisionOffenderIndex); - const offender = currRenderFrame.players[meleeBullet.offenderPlayerId]; - - let xfac = 1; // By now, straight Punch offset doesn't respect "y-axis" - if (0 > offender.dirX) { - xfac = -1; - } - const [offenderWx, offenderWy] = self.virtualGridToWorldPos(offender.virtualGridX, offender.virtualGridY); - const bulletWx = offenderWx + xfac * meleeBullet.hitboxOffset; - const bulletWy = offenderWy; - const halfColliderWidth = meleeBullet.hitboxSize.x * 0.5, - halfColliderHeight = meleeBullet.hitboxSize.y * 0.5; - const bulletCpos = self.worldToPolygonColliderBLPos(bulletWx, bulletWy, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding); - const pts = [[0, 0], [leftPadding + meleeBullet.hitboxSize.x + rightPadding, 0], [leftPadding + meleeBullet.hitboxSize.x + rightPadding, bottomPadding + meleeBullet.hitboxSize.y + topPadding], [0, bottomPadding + meleeBullet.hitboxSize.y + topPadding]]; - const newBulletCollider = collisionSys.createPolygon(bulletCpos[0], bulletCpos[1], pts); - newBulletCollider.data = meleeBullet; - collisionSysMap.set(collisionBulletIndex, newBulletCollider); - bulletColliders.set(collisionBulletIndex, newBulletCollider); - } - } - - // 4. Invoke collision system stepping - collisionSys.update(); - const result = collisionSys.createResult(); // Can I reuse a "self.collisionSysResult" object throughout the whole battle? - - // 5. Calc pushbacks for each player (after its movement) w/o bullets - for (let j in self.playerRichInfoArr) { - const joinIndex = parseInt(j) + 1; - const playerRichInfo = self.playerRichInfoArr[j]; - const playerId = playerRichInfo.id; - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - const playerCollider = collisionSysMap.get(collisionPlayerIndex); - const potentials = playerCollider.potentials(); - hardPushbackNorms[joinIndex - 1] = self.calcHardPushbacksNorms(playerCollider, potentials, result, self.snapIntoPlatformOverlap, effPushbacks[joinIndex - 1]); - - const currPlayerDownsync = currRenderFrame.players[playerId]; - const thatPlayerInNextFrame = nextRenderFramePlayers[playerId]; - const halfColliderWidth = self.playerRichInfoArr[j].colliderRadius, - halfColliderHeight = self.playerRichInfoArr[j].colliderRadius + self.playerRichInfoArr[j].colliderRadius; // avoid multiplying - - let fallStopping = false; - let possiblyFallStoppedOnAnotherPlayer = false; - for (const potential of potentials) { - let [isBarrier, isAnotherPlayer, isBullet] = [true == potential.data.hardPushback, null != potential.data.joinIndex, null != potential.data.offenderJoinIndex]; - // ignore bullets for this step - if (isBullet) continue; - // Test if the player collides with the wall/another player - if (!playerCollider.collides(potential, result)) continue; - - const normAlignmentWithGravity = (result.overlap_x * 0 + result.overlap_y * (-1.0)); - const landedOnGravityPushback = (self.snapIntoPlatformThreshold < normAlignmentWithGravity); // prevents false snapping on the lateral sides - let pushback = [result.overlap * result.overlap_x, result.overlap * result.overlap_y]; - if (landedOnGravityPushback) { - // kindly note that one player might land on top of another player - pushback = [(result.overlap - self.snapIntoPlatformOverlap) * result.overlap_x, (result.overlap - self.snapIntoPlatformOverlap) * result.overlap_y]; - thatPlayerInNextFrame.inAir = false; - } - if (isAnotherPlayer) { - /* - [WARNING] The "zero overlap collision" might be randomly detected/missed on either frontend or backend, to have deterministic result we added paddings to all sides of a playerCollider. As each velocity component of (velX, velY) being a multiple of 0.5 at any renderFrame, each position component of (x, y) can only be a multiple of 0.5 too, thus whenever a 1-dimensional collision happens between players from [player#1: i*0.5, player#2: j*0.5, not collided yet] to [player#1: (i+k)*0.5, player#2: j*0.5, collided], the overlap becomes (i+k-j)*0.5+2*s, and after snapping subtraction the effPushback magnitude for each player is (i+k-j)*0.5, resulting in 0.5-multiples-position for the next renderFrame. - */ - pushback = [(result.overlap - self.snapIntoPlatformOverlap * 2) * result.overlap_x, (result.overlap - self.snapIntoPlatformOverlap * 2) * result.overlap_y]; // will overwrite the previous pushback value if "landedOnGravityPushback" is also true - } - for (let hardPushbackNorm of hardPushbackNorms[joinIndex - 1]) { - // remove pushback component on the directions of "hardPushbackNorms[joinIndex-1]" (by now those hardPushbacks are already accounted in "effPushbacks[joinIndex-1]") - const projectedMagnitude = pushback[0] * hardPushbackNorm[0] + pushback[1] * hardPushbackNorm[1]; - if (isBarrier - || - (isAnotherPlayer && 0 > projectedMagnitude) - ) { - // [WARNING] Pushing by another player is different from pushing by barrier! - // Otherwise the player couldn't be pushed by another player to opposite dir of a side wall - pushback[0] -= projectedMagnitude * hardPushbackNorm[0]; - pushback[1] -= projectedMagnitude * hardPushbackNorm[1]; - } - } - - effPushbacks[joinIndex - 1][0] += pushback[0]; - effPushbacks[joinIndex - 1][1] += pushback[1]; - // It's not meaningful to log the virtual positions and velocities inside this step. - if (currPlayerDownsync.inAir && landedOnGravityPushback) { - fallStopping = true; - if (isAnotherPlayer) { - possiblyFallStoppedOnAnotherPlayer = true; - } - } - - if (1 == joinIndex) { - if (fallStopping) { - /* - console.info(`playerId=${playerId}, joinIndex=${thatPlayerInNextFrame.joinIndex} fallStopping#1: -{renderFrame.id: ${currRenderFrame.id}, possiblyFallStoppedOnAnotherPlayer: ${possiblyFallStoppedOnAnotherPlayer}} -playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}, overlayMag=${result.overlap.toFixed(4)}`); - */ - } else if (currPlayerDownsync.inAir && isBarrier && !landedOnGravityPushback) { - /* - console.warn(`playerId=${playerId}, joinIndex=${currPlayerDownsync.joinIndex} inAir & pushed back by barrier & not landed: -{renderFrame.id: ${currRenderFrame.id}} -playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}, overlayMag=${result.overlap.toFixed(4)}, len(hardPushbackNorms)=${hardPushbackNorms.length}`); - */ - } else if (currPlayerDownsync.inAir && isAnotherPlayer) { - console.warn(`playerId=${playerId}, joinIndex=${currPlayerDownsync.joinIndex} inAir and pushed back by another player -{renderFrame.id: ${currRenderFrame.id}} -playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, anotherPlayerColliderPos=${self.stringifyColliderCenterInWorld(potential, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}, landedOnGravityPushback=${landedOnGravityPushback}, fallStopping=${fallStopping}, overlayMag=${result.overlap.toFixed(4)}, len(hardPushbackNorms)=${hardPushbackNorms.length}`); - } - } - } - - if (fallStopping) { - thatPlayerInNextFrame.velX = 0; - thatPlayerInNextFrame.velY = 0; - thatPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Idle1[0]; - thatPlayerInNextFrame.framesToRecover = 0; - } - if (currPlayerDownsync.inAir) { - thatPlayerInNextFrame.characterState = window.toInAirConjugate(thatPlayerInNextFrame.characterState); - } - } - - // 6. Check bullet-anything collisions - bulletColliders.forEach((bulletCollider, collisionBulletIndex) => { - const potentials = bulletCollider.potentials(); - const offender = currRenderFrame.players[bulletCollider.data.offenderPlayerId]; - let shouldRemove = false; - for (const potential of potentials) { - if (null != potential.data && potential.data.joinIndex == bulletCollider.data.offenderJoinIndex) continue; - if (!bulletCollider.collides(potential, result)) continue; - if (null != potential.data && null != potential.data.joinIndex) { - const playerId = potential.data.id; - const joinIndex = potential.data.joinIndex; - let xfac = 1; - if (0 > offender.dirX) { - xfac = -1; - } - // Only for straight punch, there's no y-pushback - let bulletPushback = [-xfac * bulletCollider.data.pushback, 0]; - // console.log(`playerId=${playerId}, joinIndex=${joinIndex} is supposed to be pushed back by meleeBullet for bulletPushback=${JSON.stringify(bulletPushback)} at renderFrame.id=${currRenderFrame.id}`); - for (let hardPushbackNorm of hardPushbackNorms[joinIndex - 1]) { - const projectedMagnitude = bulletPushback[0] * hardPushbackNorm[0] + bulletPushback[1] * hardPushbackNorm[1]; - if (0 > projectedMagnitude) { - // Otherwise when smashing into a wall the atked player would be pushed into the wall first and only got back in the next renderFrame, not what I want here - bulletPushback[0] -= (projectedMagnitude * hardPushbackNorm[0]); - bulletPushback[1] -= (projectedMagnitude * hardPushbackNorm[1]); - // console.log(`playerId=${playerId}, joinIndex=${joinIndex} reducing bulletPushback=${JSON.stringify(bulletPushback)} by ${JSON.stringify([projectedMagnitude * hardPushbackNorm[0], projectedMagnitude * hardPushbackNorm[1]])} where hardPushbackNorm=${JSON.stringify(hardPushbackNorm)}, projectedMagnitude=${projectedMagnitude} at renderFrame.id=${currRenderFrame.id}`); - } - } - // console.log(`playerId=${playerId}, joinIndex=${joinIndex} is actually pushed back by meleeBullet for bulletPushback=${JSON.stringify(bulletPushback)} at renderFrame.id=${currRenderFrame.id}`); - effPushbacks[joinIndex - 1][0] += bulletPushback[0]; - effPushbacks[joinIndex - 1][1] += bulletPushback[1]; - const [atkedPlayerInCurFrame, atkedPlayerInNextFrame] = [currRenderFrame.players[potential.data.id], nextRenderFramePlayers[potential.data.id]]; - atkedPlayerInNextFrame.characterState = window.ATK_CHARACTER_STATE.Atked1[0]; - if (atkedPlayerInCurFrame.inAir) { - atkedPlayerInNextFrame.characterState = window.toInAirConjugate(atkedPlayerInNextFrame.characterState); - } - const oldFramesToRecover = atkedPlayerInNextFrame.framesToRecover; - atkedPlayerInNextFrame.framesToRecover = (oldFramesToRecover > bulletCollider.data.hitStunFrames ? oldFramesToRecover : bulletCollider.data.hitStunFrames); // In case the hit player is already stun, we extend it - } - shouldRemove = true; - } - if (shouldRemove) { - removedBulletsAtCurrFrame.add(collisionBulletIndex); - } - }); - - // [WARNING] Remove bullets from collisionSys ANYWAY for the convenience of rollback - for (let k in currRenderFrame.meleeBullets) { - const meleeBullet = currRenderFrame.meleeBullets[k]; - const collisionBulletIndex = self.collisionBulletIndexPrefix + meleeBullet.battleLocalId; - if (collisionSysMap.has(collisionBulletIndex)) { - const bulletCollider = collisionSysMap.get(collisionBulletIndex); - bulletCollider.remove(); - collisionSysMap.delete(collisionBulletIndex); - } - if (removedBulletsAtCurrFrame.has(collisionBulletIndex)) continue; - nextRenderFrameMeleeBullets.push(meleeBullet); - } - - // 7. Get players out of stuck barriers if there's any - for (let j in self.playerRichInfoArr) { - const joinIndex = parseInt(j) + 1; - const playerId = self.playerRichInfoArr[j].id; - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - const playerCollider = collisionSysMap.get(collisionPlayerIndex); - // Update "virtual grid position" - const currPlayerDownsync = currRenderFrame.players[playerId]; - const thatPlayerInNextFrame = nextRenderFramePlayers[playerId]; - const halfColliderWidth = self.playerRichInfoArr[j].colliderRadius, - halfColliderHeight = self.playerRichInfoArr[j].colliderRadius + self.playerRichInfoArr[j].colliderRadius; // avoid multiplying - const newVpos = self.polygonColliderBLToVirtualGridPos(playerCollider.x - effPushbacks[joinIndex - 1][0], playerCollider.y - effPushbacks[joinIndex - 1][1], halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding); - thatPlayerInNextFrame.virtualGridX = newVpos[0]; - thatPlayerInNextFrame.virtualGridY = newVpos[1]; - - if (1 == thatPlayerInNextFrame.joinIndex) { - if (currPlayerDownsync.inAir && !thatPlayerInNextFrame.inAir) { - console.warn(`playerId=${playerId}, joinIndex=${thatPlayerInNextFrame.joinIndex} fallStopping#2: -{nextRenderFrame.id: ${currRenderFrame.id + 1}, nextVirtualX: ${thatPlayerInNextFrame.virtualGridX}, nextVirtualY: ${thatPlayerInNextFrame.virtualGridY}, nextVelX: ${thatPlayerInNextFrame.velX}, nextVelY: ${thatPlayerInNextFrame.velY}} - calculated from <- playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}`); - } else if (!currPlayerDownsync.inAir && thatPlayerInNextFrame.inAir) { - console.warn(`playerId=${playerId}, joinIndex=${thatPlayerInNextFrame.joinIndex} took off: -{nextRenderFrame.id: ${currRenderFrame.id + 1}, nextVirtualX: ${thatPlayerInNextFrame.virtualGridX}, nextVirtualY: ${thatPlayerInNextFrame.virtualGridY}, nextVelX: ${thatPlayerInNextFrame.velX}, nextVelY: ${thatPlayerInNextFrame.velY}} - calculated from <- playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}`); - } else if (thatPlayerInNextFrame.inAir && 0 != thatPlayerInNextFrame.velY) { - /* - console.log(`playerId=${playerId}, joinIndex=${thatPlayerInNextFrame.joinIndex} inAir trajectory: -{nextRenderFrame.id: ${currRenderFrame.id + 1}, nextVirtualX: ${thatPlayerInNextFrame.virtualGridX}, nextVirtualY: ${thatPlayerInNextFrame.virtualGridY}, nextVelX: ${thatPlayerInNextFrame.velX}, nextVelY: ${thatPlayerInNextFrame.velY}}; - calculated from <- playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColliderWidth, halfColliderHeight, topPadding, bottomPadding, leftPadding, rightPadding)}, effPushback={${effPushbacks[joinIndex - 1][0].toFixed(3)}, ${effPushbacks[joinIndex - 1][1].toFixed(3)}}`); - */ - } - } - } - - return window.pb.protos.RoomDownsyncFrame.create({ - id: currRenderFrame.id + 1, - players: nextRenderFramePlayers, - meleeBullets: nextRenderFrameMeleeBullets, - }); - }, - rollbackAndChase(renderFrameIdSt, renderFrameIdEd, collisionSys, collisionSysMap, isChasing) { - /* - This function eventually calculates a "RoomDownsyncFrame" where "RoomDownsyncFrame.id == renderFrameIdEd" if not interruptted. - */ const self = this; let prevLatestRdf = null, latestRdf = null; @@ -1522,7 +1097,10 @@ playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColl // Shouldn't happen! throw `Failed to get cached delayedInputFrame for i=${i}, j=${j}, renderFrameId=${self.renderFrameId}, lastUpsyncInputFrameId=${self.lastUpsyncInputFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, chaserRenderFrameId=${self.chaserRenderFrameId}; recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`; } - const nextRdf = self.applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputFrame, currRdf, collisionSys, collisionSysMap); + + const jPrev = self._convertToInputFrameId(i - 1, self.inputDelayFrames); + const delayedInputFrameForPrevRenderFrame = self.recentInputCache.getByFrameId(jPrev); + const nextRdf = gopkgs.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(delayedInputFrame.inputList, (null == delayedInputFrameForPrevRenderFrame ? null : delayedInputFrameForPrevRenderFrame.inputList), currRdf, collisionSys, collisionSysMap, self.gravityX, self.gravityY, self.jumpingInitVelY, self.inputDelayFrames, self.inputScaleFrames, self.spaceOffsetX, self.spaceOffsetY, self.snapIntoPlatformOverlap, self.snapIntoPlatformThreshold, self.worldToVirtualGridRatio, self.virtualGridToWorldRatio); if (true == isChasing) { // [WARNING] Move the cursor "self.chaserRenderFrameId" when "true == isChasing", keep in mind that "self.chaserRenderFrameId" is not monotonic! @@ -1538,29 +1116,32 @@ playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColl return [prevLatestRdf, latestRdf]; }, - _initPlayerRichInfoDict(players) { + _initPlayerRichInfoDict(playersArr) { const self = this; - for (let k in players) { - const playerId = parseInt(k); + for (let k in playersArr) { + const immediatePlayerInfo = playersArr[k]; + const playerId = immediatePlayerInfo.id || immediatePlayerInfo.Id; if (self.playerRichInfoDict.has(playerId)) continue; // Skip already put keys - const immediatePlayerInfo = players[playerId]; self.playerRichInfoDict.set(playerId, immediatePlayerInfo); - - const nodeAndScriptIns = self.spawnPlayerNode(immediatePlayerInfo.joinIndex, immediatePlayerInfo.virtualGridX, immediatePlayerInfo.virtualGridY, immediatePlayerInfo); + const joinIndex = immediatePlayerInfo.joinIndex || immediatePlayerInfo.JoinIndex; + const vx = immediatePlayerInfo.virtualGridX || immediatePlayerInfo.VirtualGridX; + const vy = immediatePlayerInfo.virtualGridY || immediatePlayerInfo.VirtualGridY; + const nodeAndScriptIns = self.spawnPlayerNode(joinIndex, vx, vy, immediatePlayerInfo); Object.assign(self.playerRichInfoDict.get(playerId), { node: nodeAndScriptIns[0], scriptIns: nodeAndScriptIns[1], }); - if (self.selfPlayerInfo.id == playerId) { - self.selfPlayerInfo = Object.assign(self.selfPlayerInfo, immediatePlayerInfo); + const selfPlayerId = self.selfPlayerInfo.id || self.selfPlayerInfo.Id; + if (selfPlayerId == playerId) { + self.selfPlayerInfo.joinIndex = immediatePlayerInfo.joinIndex || immediatePlayerInfo.JoinIndex; nodeAndScriptIns[1].showArrowTipNode(); } } self.playerRichInfoArr = new Array(self.playerRichInfoDict.size); self.playerRichInfoDict.forEach((playerRichInfo, playerId) => { - self.playerRichInfoArr[playerRichInfo.joinIndex - 1] = playerRichInfo; + self.playerRichInfoArr[playerRichInfo.JoinIndex - 1] = playerRichInfo; }); }, @@ -1606,13 +1187,8 @@ playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColl return s.join('\n'); }, - worldToVirtualGridPos(x, y) { - // [WARNING] Introduces loss of precision! - const self = this; - // 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. - let virtualGridX = Math.round(x * self.worldToVirtualGridRatio); - let virtualGridY = Math.round(y * self.worldToVirtualGridRatio); - return [virtualGridX, virtualGridY]; + stringifyColliderCenterInWorld(playerCollider, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) { + return `{${(playerCollider.x + leftPadding + halfBoundingW).toFixed(2)}, ${(playerCollider.y + bottomPadding + halfBoundingH).toFixed(2)}}`; }, virtualGridToWorldPos(vx, vy) { @@ -1621,44 +1197,44 @@ playerColliderPos=${self.stringifyColliderCenterInWorld(playerCollider, halfColl return [vx * self.virtualGridToWorldRatio, vy * self.virtualGridToWorldRatio]; }, - worldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) { - return [wx - halfBoundingW - leftPadding, wy - halfBoundingH - bottomPadding]; - }, - - polygonColliderBLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) { - return [cx + halfBoundingW + leftPadding, cy + halfBoundingH + bottomPadding]; - }, - - polygonColliderBLToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) { + showDebugBoundaries(rdf) { const self = this; - const [wx, wy] = self.polygonColliderBLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding); - return self.worldToVirtualGridPos(wx, wy) - }, + const leftPadding = self.snapIntoPlatformOverlap, + rightPadding = self.snapIntoPlatformOverlap, + topPadding = self.snapIntoPlatformOverlap, + bottomPadding = self.snapIntoPlatformOverlap; + if (self.showCriticalCoordinateLabels) { + let g = self.g; + g.clear(); - virtualGridToPolygonColliderBLPos(vx, vy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) { - const self = this; - const [wx, wy] = self.virtualGridToWorldPos(vx, vy); - return self.worldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) - }, - - stringifyColliderCenterInWorld(playerCollider, halfBoundingW, halfBoundingH, topPadding, bottomPadding, leftPadding, rightPadding) { - return `{${(playerCollider.x + leftPadding + halfBoundingW).toFixed(2)}, ${(playerCollider.y + bottomPadding + halfBoundingH).toFixed(2)}}`; - }, - - calcHardPushbacksNorms(collider, potentials, result, snapIntoPlatformOverlap, effPushback) { - const self = this; - let ret = []; - for (const potential of potentials) { - if (null == potential.data || !(true == potential.data.hardPushback)) continue; - if (!collider.collides(potential, result)) continue; - // ALWAY snap into hardPushbacks! - // [overlay_x, overlap_y] is the unit vector that points into the platform - const pushback = [(result.overlap - snapIntoPlatformOverlap) * result.overlap_x, (result.overlap - snapIntoPlatformOverlap) * result.overlap_y]; - ret.push([result.overlap_x, result.overlap_y]); - effPushback[0] += pushback[0]; - effPushback[1] += pushback[1]; + const collisionSpaceObjs = gopkgs.GetCollisionSpaceObjsJs(self.gopkgsCollisionSys); + for (let k in collisionSpaceObjs) { + const body = collisionSpaceObjs[k]; + let padding = 0; + if (null != body.Data && null != body.Data.JoinIndex) { + // character + if (1 == body.Data.JoinIndex) { + g.strokeColor = cc.Color.BLUE; + } else { + g.strokeColor = cc.Color.RED; + } + padding = self.snapIntoPlatformOverlap; + } else { + // barrier + g.strokeColor = cc.Color.WHITE; + } + const points = body.Shape.Points; + const wpos = [body.X - self.spaceOffsetX, body.Y - self.spaceOffsetY]; + g.moveTo(wpos[0], wpos[1]); + const cnt = points.length; + for (let j = 0; j < cnt; j += 1) { + const x = wpos[0] + points[j][0], + y = wpos[1] + points[j][1]; + g.lineTo(x, y); + } + g.lineTo(wpos[0], wpos[1]); + g.stroke(); + } } - - return ret; }, }); diff --git a/frontend/assets/scripts/OfflineMapBackend.js b/frontend/assets/scripts/OfflineMapBackend.js index 70192e0..8153846 100644 --- a/frontend/assets/scripts/OfflineMapBackend.js +++ b/frontend/assets/scripts/OfflineMapBackend.js @@ -31,6 +31,7 @@ cc.Class({ self.inputDelayFrames = 8; self.inputScaleFrames = 2; self.inputFrameUpsyncDelayTolerance = 2; + self.collisionMinStep = 8; self.renderCacheSize = 1024; self.serverFps = 60; @@ -101,15 +102,12 @@ cc.Class({ self.node.setContentSize(newMapSize.width * newTileSize.width, newMapSize.height * newTileSize.height); self.node.setPosition(cc.v2(0, 0)); - self._resetCurrentMatch(); - const spaceW = newMapSize.width * newTileSize.width; - const spaceH = newMapSize.height * newTileSize.height; - self.spaceOffsetX = (spaceW >> 1); - self.spaceOffsetY = (spaceH >> 1); - const minStep = 8; - self.gopkgsCollisionSys = gopkgs.NewCollisionSpaceJs(spaceW, spaceH, minStep, minStep); - self.gopkgsCollisionSysMap = {}; // [WARNING] Don't use "JavaScript Map" which could cause loss of type information when passing through Golang transpiled functions! + self.stageDiscreteW = newMapSize.width; + self.stageDiscreteH = newMapSize.height; + self.stageTileW = newTileSize.width; + self.stageTileH = newTileSize.height; + self._resetCurrentMatch(); let barrierIdCounter = 0; const boundaryObjs = tileCollisionManager.extractBoundaryObjects(self.node); for (let boundaryObj of boundaryObjs.barriers) { @@ -160,11 +158,41 @@ cc.Class({ self.gopkgsCollisionSysMap[collisionBarrierIndex] = newBarrierCollider; } - const startPlayer1 = gopkgs.NewPlayerDownsyncJs(10, self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y)[0], self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y)[1], 0, 0, 0, 0, 1 * self.worldToVirtualGridRatio, 0, window.ATK_CHARACTER_STATE.InAirIdle1[0], 1, 100, 100, true, 12); - - const startPlayer2 = gopkgs.NewPlayerDownsyncJs(11, self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y)[0], self.worldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y)[1], 0, 0, 0, 0, 1 * self.worldToVirtualGridRatio, 0, window.ATK_CHARACTER_STATE.InAirIdle1[0], 2, 100, 100, true, 12); - - const startRdf = gopkgs.NewRoomDownsyncFrameJs(window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START, [startPlayer1, startPlayer2], []); + const startRdf = window.pb.protos.RoomDownsyncFrame.create({ + id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START, + playersArr: [ + window.pb.protos.PlayerDownsync.create({ + id: 10, + joinIndex: 1, + virtualGridX: boundaryObjs.playerStartingPositions[0].x * self.worldToVirtualGridRatio, + virtualGridY: boundaryObjs.playerStartingPositions[0].y * self.worldToVirtualGridRatio, + speed: 1 * self.worldToVirtualGridRatio, + colliderRadius: 12, + characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0], + framesToRecover: 0, + dirX: 0, + dirY: 0, + velX: 0, + velY: 0, + inAir: true, + }), + window.pb.protos.PlayerDownsync.create({ + id: 11, + joinIndex: 2, + virtualGridX: boundaryObjs.playerStartingPositions[1].x * self.worldToVirtualGridRatio, + virtualGridY: boundaryObjs.playerStartingPositions[1].y * self.worldToVirtualGridRatio, + speed: 1 * self.worldToVirtualGridRatio, + colliderRadius: 12, + characterState: window.ATK_CHARACTER_STATE.InAirIdle1[0], + framesToRecover: 0, + dirX: 0, + dirY: 0, + velX: 0, + velY: 0, + inAir: true, + }), + ] + }); self.selfPlayerInfo = { Id: 11, @@ -212,231 +240,4 @@ cc.Class({ } }, - onRoomDownsyncFrame(rdf, accompaniedInputFrameDownsyncBatch) { - // This function is also applicable to "re-joining". - const self = window.mapIns; - self.onInputFrameDownsyncBatch(accompaniedInputFrameDownsyncBatch); // Important to do this step before setting IN_BATTLE - if (!self.recentRenderCache) { - return; - } - if (ALL_BATTLE_STATES.IN_SETTLEMENT == self.battleState) { - return; - } - const shouldForceDumping1 = (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id); - let shouldForceDumping2 = (rdf.Id >= self.renderFrameId + self.renderFrameIdLagTolerance); - let shouldForceResync = rdf.ShouldForceResync; - const notSelfUnconfirmed = (0 == (rdf.BackendUnconfirmedMask & (1 << (self.selfPlayerInfo.joinIndex - 1)))); - if (notSelfUnconfirmed) { - shouldForceDumping2 = false; - shouldForceResync = false; - self.othersForcedDownsyncRenderFrameDict.set(rdf.Id, rdf); - } - /* - TODO - - If "BackendUnconfirmedMask" is non-all-1 and contains the current player, show a label/button to hint manual reconnection. Note that the continuity of "recentInputCache" is not a good indicator, because due to network delay upon a [type#1 forceConfirmation] a player might just lag in upsync networking and have all consecutive inputFrameIds locally. - */ - - const [dumpRenderCacheRet, oldStRenderFrameId, oldEdRenderFrameId] = (shouldForceDumping1 || shouldForceDumping2 || shouldForceResync) ? self.recentRenderCache.setByFrameId(rdf, rdf.id) : [window.RING_BUFF_CONSECUTIVE_SET, null, null]; - if (window.RING_BUFF_FAILED_TO_SET == dumpRenderCacheRet) { - throw `Failed to dump render cache#1 (maybe recentRenderCache too small)! rdf.id=${rdf.id}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}; recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`; - } - if (!shouldForceResync && (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START < rdf.id && window.RING_BUFF_CONSECUTIVE_SET == dumpRenderCacheRet)) { - /* - Don't change - - chaserRenderFrameId, it's updated only in "rollbackAndChase & onInputFrameDownsyncBatch" (except for when RING_BUFF_NON_CONSECUTIVE_SET) - */ - return dumpRenderCacheRet; - } - - // The logic below applies to (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.id || window.RING_BUFF_NON_CONSECUTIVE_SET == dumpRenderCacheRet) - self._initPlayerRichInfoDict(rdf.PlayersArr); - - if (shouldForceDumping1 || shouldForceDumping2 || shouldForceResync) { - // In fact, not having "window.RING_BUFF_CONSECUTIVE_SET == dumpRenderCacheRet" should already imply that "self.renderFrameId <= rdf.id", but here we double check and log the anomaly - - if (window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START == rdf.Id) { - console.log('On battle started! renderFrameId=', rdf.Id); - } - self.renderFrameId = rdf.Id; - self.lastRenderFrameIdTriggeredAt = performance.now(); - // In this case it must be true that "rdf.id > chaserRenderFrameId". - self.chaserRenderFrameId = rdf.Id; - - const canvasNode = self.canvasNode; - self.ctrl = canvasNode.getComponent("TouchEventsManager"); - self.enableInputControls(); - self.transitToState(ALL_MAP_STATES.VISUAL); - self.battleState = ALL_BATTLE_STATES.IN_BATTLE; - } - // [WARNING] Leave all graphical updates in "update(dt)" by "applyRoomDownsyncFrameDynamics" - return dumpRenderCacheRet; - }, - - rollbackAndChase(renderFrameIdSt, renderFrameIdEd, collisionSys, collisionSysMap, isChasing) { - const self = this; - let prevLatestRdf = null, - latestRdf = null; - for (let i = renderFrameIdSt; i < renderFrameIdEd; i++) { - const currRdf = self.recentRenderCache.getByFrameId(i); // typed "RoomDownsyncFrame"; [WARNING] When "true == isChasing" and using Firefox, this function could be interruptted by "onRoomDownsyncFrame(rdf)" asynchronously anytime, making this line return "null"! - if (null == currRdf) { - throw `Couldn't find renderFrame for i=${i} to rollback (are you using Firefox?), self.renderFrameId=${self.renderFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, might've been interruptted by onRoomDownsyncFrame`; - } - const j = self._convertToInputFrameId(i, self.inputDelayFrames); - const delayedInputFrame = self.recentInputCache.getByFrameId(j); // Don't make prediction here, the inputFrameDownsyncs in recentInputCache was already predicted while prefabbing - if (null == delayedInputFrame) { - // Shouldn't happen! - throw `Failed to get cached delayedInputFrame for i=${i}, j=${j}, renderFrameId=${self.renderFrameId}, lastUpsyncInputFrameId=${self.lastUpsyncInputFrameId}, lastAllConfirmedInputFrameId=${self.lastAllConfirmedInputFrameId}, chaserRenderFrameId=${self.chaserRenderFrameId}; recentRenderCache=${self._stringifyRecentRenderCache(false)}, recentInputCache=${self._stringifyRecentInputCache(false)}`; - } - - const jPrev = self._convertToInputFrameId(i - 1, self.inputDelayFrames); - const delayedInputFrameForPrevRenderFrame = self.recentInputCache.getByFrameId(jPrev); - const nextRdf = gopkgs.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(delayedInputFrame.inputList, (null == delayedInputFrameForPrevRenderFrame ? null : delayedInputFrameForPrevRenderFrame.inputList), currRdf, collisionSys, collisionSysMap, self.gravityX, self.gravityY, self.jumpingInitVelY, self.inputDelayFrames, self.inputScaleFrames, self.spaceOffsetX, self.spaceOffsetY, self.snapIntoPlatformOverlap, self.snapIntoPlatformThreshold, self.worldToVirtualGridRatio, self.virtualGridToWorldRatio); - - if (true == isChasing) { - // [WARNING] Move the cursor "self.chaserRenderFrameId" when "true == isChasing", keep in mind that "self.chaserRenderFrameId" is not monotonic! - self.chaserRenderFrameId = nextRdf.id; - } else if (nextRdf.id == self.chaserRenderFrameId + 1) { - self.chaserRenderFrameId = nextRdf.id; // To avoid redundant calculation - } - self.recentRenderCache.setByFrameId(nextRdf, nextRdf.id); - prevLatestRdf = currRdf; - latestRdf = nextRdf; - } - - return [prevLatestRdf, latestRdf]; - }, - - _initPlayerRichInfoDict(playersArr) { - const self = this; - for (let k in playersArr) { - const immediatePlayerInfo = playersArr[k]; - const playerId = immediatePlayerInfo.Id; - if (self.playerRichInfoDict.has(playerId)) continue; // Skip already put keys - self.playerRichInfoDict.set(playerId, immediatePlayerInfo); - - const nodeAndScriptIns = self.spawnPlayerNode(immediatePlayerInfo.JoinIndex, immediatePlayerInfo.VirtualGridX, immediatePlayerInfo.VirtualGridY, immediatePlayerInfo); - - Object.assign(self.playerRichInfoDict.get(playerId), { - node: nodeAndScriptIns[0], - scriptIns: nodeAndScriptIns[1], - }); - - if (self.selfPlayerInfo.Id == playerId) { - self.selfPlayerInfo = Object.assign(self.selfPlayerInfo, immediatePlayerInfo); - nodeAndScriptIns[1].showArrowTipNode(); - } - } - self.playerRichInfoArr = new Array(self.playerRichInfoDict.size); - self.playerRichInfoDict.forEach((playerRichInfo, playerId) => { - self.playerRichInfoArr[playerRichInfo.JoinIndex - 1] = playerRichInfo; - }); - }, - - applyRoomDownsyncFrameDynamics(rdf, prevRdf) { - const self = this; - const playersArr = rdf.PlayersArr; - for (let k in playersArr) { - const currPlayerDownsync = playersArr[k]; - const prevRdfPlayer = (null == prevRdf ? null : prevRdf.PlayersArr[k]); - const [wx, wy] = self.virtualGridToWorldPos(currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY); - const playerRichInfo = self.playerRichInfoArr[k]; - playerRichInfo.node.setPosition(wx, wy); - playerRichInfo.scriptIns.updateSpeed(currPlayerDownsync.Speed); - currPlayerDownsync.characterState = currPlayerDownsync.CharacterState; - currPlayerDownsync.dirX = currPlayerDownsync.DirX; - currPlayerDownsync.dirY = currPlayerDownsync.DirY; - currPlayerDownsync.framesToRecover = currPlayerDownsync.FrameToRecover; - playerRichInfo.scriptIns.updateCharacterAnim(currPlayerDownsync, prevRdfPlayer, false); - } - }, - - spawnPlayerNode(joinIndex, vx, vy, playerDownsyncInfo) { - const self = this; - const newPlayerNode = cc.instantiate(self.controlledCharacterPrefab) - const playerScriptIns = newPlayerNode.getComponent("ControlledCharacter"); - if (1 == joinIndex) { - playerScriptIns.setSpecies("SoldierWaterGhost"); - } else if (2 == joinIndex) { - playerScriptIns.setSpecies("UltramanTiga"); - } - - const [wx, wy] = self.virtualGridToWorldPos(vx, vy); - newPlayerNode.setPosition(wx, wy); - playerScriptIns.mapNode = self.node; - const halfColliderWidth = playerDownsyncInfo.ColliderRadius, - halfColliderHeight = playerDownsyncInfo.ColliderRadius + playerDownsyncInfo.ColliderRadius; // avoid multiplying - const colliderWidth = halfColliderWidth + halfColliderWidth, - colliderHeight = halfColliderHeight + halfColliderHeight; // avoid multiplying - - const [cx, cy] = gopkgs.WorldToPolygonColliderBLPos(wx, wy, halfColliderWidth, halfColliderHeight, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.spaceOffsetX, self.spaceOffsetY); - const gopkgsBoundaryAnchor = gopkgs.NewVec2DJs(cx, cy); - const gopkgsBoundaryPts = [ - gopkgs.NewVec2DJs(0, 0), - gopkgs.NewVec2DJs(self.snapIntoPlatformOverlap + colliderWidth + self.snapIntoPlatformOverlap, 0), - gopkgs.NewVec2DJs(self.snapIntoPlatformOverlap + colliderWidth + self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap + colliderHeight + self.snapIntoPlatformOverlap), - gopkgs.NewVec2DJs(0, self.snapIntoPlatformOverlap + colliderHeight + self.snapIntoPlatformOverlap) - ]; - const gopkgsBoundary = gopkgs.NewPolygon2DJs(gopkgsBoundaryAnchor, gopkgsBoundaryPts); - const newPlayerCollider = gopkgs.GenerateConvexPolygonColliderJs(gopkgsBoundary, self.spaceOffsetX, self.spaceOffsetY, playerDownsyncInfo, "Player"); - //const newPlayerCollider = gopkgs.GenerateRectColliderJs(wx, wy, colliderWidth, colliderHeight, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.snapIntoPlatformOverlap, self.spaceOffsetX, self.spaceOffsetY, playerDownsyncInfo, "Player"); - self.gopkgsCollisionSys.Add(newPlayerCollider); - const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex; - self.gopkgsCollisionSysMap[collisionPlayerIndex] = newPlayerCollider; - - console.log(`Created new player collider: joinIndex=${joinIndex}, colliderRadius=${playerDownsyncInfo.ColliderRadius}`); - - safelyAddChild(self.node, newPlayerNode); - setLocalZOrder(newPlayerNode, 5); - - newPlayerNode.active = true; - playerDownsyncInfo.characterState = playerDownsyncInfo.CharacterState; - playerDownsyncInfo.dirX = playerDownsyncInfo.DirX; - playerDownsyncInfo.dirY = playerDownsyncInfo.DirY; - playerDownsyncInfo.framesToRecover = playerDownsyncInfo.FrameToRecover; - playerScriptIns.updateCharacterAnim(playerDownsyncInfo, null, true); - - return [newPlayerNode, playerScriptIns]; - }, - - showDebugBoundaries(rdf) { - const self = this; - const leftPadding = self.snapIntoPlatformOverlap, - rightPadding = self.snapIntoPlatformOverlap, - topPadding = self.snapIntoPlatformOverlap, - bottomPadding = self.snapIntoPlatformOverlap; - if (self.showCriticalCoordinateLabels) { - let g = self.g; - g.clear(); - - const collisionSpaceObjs = gopkgs.GetCollisionSpaceObjsJs(self.gopkgsCollisionSys); - for (let k in collisionSpaceObjs) { - const body = collisionSpaceObjs[k]; - let padding = 0; - if (null != body.Data && null != body.Data.JoinIndex) { - // character - if (1 == body.Data.JoinIndex) { - g.strokeColor = cc.Color.BLUE; - } else { - g.strokeColor = cc.Color.RED; - } - padding = self.snapIntoPlatformOverlap; - } else { - // barrier - g.strokeColor = cc.Color.WHITE; - } - const points = body.Shape.Points; - const wpos = [body.X-self.spaceOffsetX, body.Y-self.spaceOffsetY]; - g.moveTo(wpos[0], wpos[1]); - const cnt = points.length; - for (let j = 0; j < cnt; j += 1) { - const x = wpos[0]+points[j][0], - y = wpos[1]+points[j][1]; - g.lineTo(x, y); - } - g.lineTo(wpos[0], wpos[1]); - g.stroke(); - } - } - }, }); 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 6e89a80..0970951 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 @@ -4607,6 +4607,7 @@ $root.protos = (function() { * @property {number|null} [jumpingInitVelY] BattleColliderInfo jumpingInitVelY * @property {number|null} [gravityX] BattleColliderInfo gravityX * @property {number|null} [gravityY] BattleColliderInfo gravityY + * @property {number|null} [collisionMinStep] BattleColliderInfo collisionMinStep */ /** @@ -4857,6 +4858,14 @@ $root.protos = (function() { */ BattleColliderInfo.prototype.gravityY = 0; + /** + * BattleColliderInfo collisionMinStep. + * @member {number} collisionMinStep + * @memberof protos.BattleColliderInfo + * @instance + */ + BattleColliderInfo.prototype.collisionMinStep = 0; + /** * Creates a new BattleColliderInfo instance using the specified properties. * @function create @@ -4942,6 +4951,8 @@ $root.protos = (function() { writer.uint32(/* id 28, wireType 0 =*/224).int32(message.gravityX); if (message.gravityY != null && Object.hasOwnProperty.call(message, "gravityY")) writer.uint32(/* id 29, wireType 0 =*/232).int32(message.gravityY); + if (message.collisionMinStep != null && Object.hasOwnProperty.call(message, "collisionMinStep")) + writer.uint32(/* id 30, wireType 0 =*/240).int32(message.collisionMinStep); return writer; }; @@ -5111,6 +5122,10 @@ $root.protos = (function() { message.gravityY = reader.int32(); break; } + case 30: { + message.collisionMinStep = reader.int32(); + break; + } default: reader.skipType(tag & 7); break; @@ -5244,6 +5259,9 @@ $root.protos = (function() { if (message.gravityY != null && message.hasOwnProperty("gravityY")) if (!$util.isInteger(message.gravityY)) return "gravityY: integer expected"; + if (message.collisionMinStep != null && message.hasOwnProperty("collisionMinStep")) + if (!$util.isInteger(message.collisionMinStep)) + return "collisionMinStep: integer expected"; return null; }; @@ -5339,6 +5357,8 @@ $root.protos = (function() { message.gravityX = object.gravityX | 0; if (object.gravityY != null) message.gravityY = object.gravityY | 0; + if (object.collisionMinStep != null) + message.collisionMinStep = object.collisionMinStep | 0; return message; }; @@ -5394,6 +5414,7 @@ $root.protos = (function() { object.jumpingInitVelY = 0; object.gravityX = 0; object.gravityY = 0; + object.collisionMinStep = 0; } if (message.stageName != null && message.hasOwnProperty("stageName")) object.stageName = message.stageName; @@ -5463,6 +5484,8 @@ $root.protos = (function() { object.gravityX = message.gravityX; if (message.gravityY != null && message.hasOwnProperty("gravityY")) object.gravityY = message.gravityY; + if (message.collisionMinStep != null && message.hasOwnProperty("collisionMinStep")) + object.collisionMinStep = message.collisionMinStep; return object; }; @@ -5507,7 +5530,6 @@ $root.protos = (function() { * @property {Array.|null} [meleeBullets] RoomDownsyncFrame meleeBullets * @property {number|Long|null} [backendUnconfirmedMask] RoomDownsyncFrame backendUnconfirmedMask * @property {boolean|null} [shouldForceResync] RoomDownsyncFrame shouldForceResync - * @property {Object.|null} [players] RoomDownsyncFrame players */ /** @@ -5521,7 +5543,6 @@ $root.protos = (function() { function RoomDownsyncFrame(properties) { this.playersArr = []; this.meleeBullets = []; - this.players = {}; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -5576,14 +5597,6 @@ $root.protos = (function() { */ RoomDownsyncFrame.prototype.shouldForceResync = false; - /** - * RoomDownsyncFrame players. - * @member {Object.} players - * @memberof protos.RoomDownsyncFrame - * @instance - */ - RoomDownsyncFrame.prototype.players = $util.emptyObject; - /** * Creates a new RoomDownsyncFrame instance using the specified properties. * @function create @@ -5622,11 +5635,6 @@ $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.players != null && Object.hasOwnProperty.call(message, "players")) - for (var keys = Object.keys(message.players), i = 0; i < keys.length; ++i) { - writer.uint32(/* id 99, wireType 2 =*/794).fork().uint32(/* id 1, wireType 0 =*/8).int32(keys[i]); - $root.protos.PlayerDownsync.encode(message.players[keys[i]], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim().ldelim(); - } return writer; }; @@ -5657,7 +5665,7 @@ $root.protos = (function() { RoomDownsyncFrame.decode = function decode(reader, length) { if (!(reader instanceof $Reader)) reader = $Reader.create(reader); - var end = length === undefined ? reader.len : reader.pos + length, message = new $root.protos.RoomDownsyncFrame(), key, value; + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.protos.RoomDownsyncFrame(); while (reader.pos < end) { var tag = reader.uint32(); switch (tag >>> 3) { @@ -5689,29 +5697,6 @@ $root.protos = (function() { message.shouldForceResync = reader.bool(); break; } - case 99: { - if (message.players === $util.emptyObject) - message.players = {}; - var end2 = reader.uint32() + reader.pos; - key = 0; - value = null; - while (reader.pos < end2) { - var tag2 = reader.uint32(); - switch (tag2 >>> 3) { - case 1: - key = reader.int32(); - break; - case 2: - value = $root.protos.PlayerDownsync.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag2 & 7); - break; - } - } - message.players[key] = value; - break; - } default: reader.skipType(tag & 7); break; @@ -5777,20 +5762,6 @@ $root.protos = (function() { if (message.shouldForceResync != null && message.hasOwnProperty("shouldForceResync")) if (typeof message.shouldForceResync !== "boolean") return "shouldForceResync: boolean expected"; - if (message.players != null && message.hasOwnProperty("players")) { - if (!$util.isObject(message.players)) - return "players: object expected"; - var key = Object.keys(message.players); - for (var i = 0; i < key.length; ++i) { - if (!$util.key32Re.test(key[i])) - return "players: integer key{k:int32} expected"; - { - var error = $root.protos.PlayerDownsync.verify(message.players[key[i]]); - if (error) - return "players." + error; - } - } - } return null; }; @@ -5848,16 +5819,6 @@ $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.players) { - if (typeof object.players !== "object") - throw TypeError(".protos.RoomDownsyncFrame.players: object expected"); - message.players = {}; - for (var keys = Object.keys(object.players), i = 0; i < keys.length; ++i) { - if (typeof object.players[keys[i]] !== "object") - throw TypeError(".protos.RoomDownsyncFrame.players: object expected"); - message.players[keys[i]] = $root.protos.PlayerDownsync.fromObject(object.players[keys[i]]); - } - } return message; }; @@ -5878,8 +5839,6 @@ $root.protos = (function() { object.playersArr = []; object.meleeBullets = []; } - if (options.objects || options.defaults) - object.players = {}; if (options.defaults) { object.id = 0; if ($util.Long) { @@ -5918,12 +5877,6 @@ $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; - var keys2; - if (message.players && (keys2 = Object.keys(message.players)).length) { - object.players = {}; - for (var j = 0; j < keys2.length; ++j) - object.players[keys2[j]] = $root.protos.PlayerDownsync.toObject(message.players[keys2[j]], options); - } return object; }; diff --git a/jsexport/battle/battle.go b/jsexport/battle/battle.go index 4aa6402..dee470b 100644 --- a/jsexport/battle/battle.go +++ b/jsexport/battle/battle.go @@ -1,8 +1,8 @@ package battle import ( - "resolv" "math" + "resolv" ) const ( @@ -35,7 +35,7 @@ const ( ATK_CHARACTER_STATE_INAIR_ATKED1 = int32(6) ) -func ConvertToInputFrameId(renderFrameId int32, inputDelayFrames int32, inputScaleFrames int32) int32 { +func ConvertToInputFrameId(renderFrameId int32, inputDelayFrames int32, inputScaleFrames uint32) int32 { if renderFrameId < inputDelayFrames { return 0 } @@ -281,7 +281,7 @@ func calcHardPushbacksNorms(playerCollider *resolv.Object, playerShape *resolv.C } // [WARNING] The params of this method is carefully tuned such that only "battle.RoomDownsyncFrame" is a necessary custom struct. -func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputList, delayedInputListForPrevRenderFrame []uint64, currRenderFrame *RoomDownsyncFrame, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, gravityX, gravityY, jumpingInitVelY, inputDelayFrames, inputScaleFrames int32, collisionSpaceOffsetX, collisionSpaceOffsetY, snapIntoPlatformOverlap, snapIntoPlatformThreshold, worldToVirtualGridRatio, virtualGridToWorldRatio float64) *RoomDownsyncFrame { +func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputList, delayedInputListForPrevRenderFrame []uint64, currRenderFrame *RoomDownsyncFrame, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, gravityX, gravityY, jumpingInitVelY, inputDelayFrames int32, inputScaleFrames uint32, collisionSpaceOffsetX, collisionSpaceOffsetY, snapIntoPlatformOverlap, snapIntoPlatformThreshold, worldToVirtualGridRatio, virtualGridToWorldRatio float64) *RoomDownsyncFrame { // [WARNING] On backend this function MUST BE called while "InputsBufferLock" is locked! roomCapacity := len(currRenderFrame.PlayersArr) nextRenderFramePlayers := make([]*PlayerDownsync, roomCapacity) diff --git a/jsexport/battle/room_downsync_frame.go b/jsexport/battle/room_downsync_frame.go index 3c5de71..680fae2 100644 --- a/jsexport/battle/room_downsync_frame.go +++ b/jsexport/battle/room_downsync_frame.go @@ -1,5 +1,7 @@ package battle +// TODO: Replace all "int32", "int64", "uint32" and "uint64" with just "int" for better performance in JavaScript! Reference https://github.com/gopherjs/gopherjs#performance-tips + type Vec2D struct { X float64 Y float64 @@ -56,9 +58,7 @@ type MeleeBullet struct { RecoveryFrames int32 RecoveryFramesOnBlock int32 RecoveryFramesOnHit int32 - Moveforward *Vec2D HitboxOffset float64 - HitboxSize *Vec2D OriginatedRenderFrameId int32 // for defender HitStunFrames int32 @@ -68,6 +68,11 @@ type MeleeBullet struct { Damage int32 OffenderJoinIndex int32 OffenderPlayerId int32 + + SelfMoveforwardX float64 + SelfMoveforwardY float64 + HitboxSizeX float64 + HitboxSizeY float64 } type RoomDownsyncFrame struct { diff --git a/jsexport/main.go b/jsexport/main.go index 5f60bc0..17fef62 100644 --- a/jsexport/main.go +++ b/jsexport/main.go @@ -1,9 +1,9 @@ package main import ( - "resolv" "github.com/gopherjs/gopherjs/js" . "jsexport/battle" + "resolv" ) func NewCollisionSpaceJs(spaceW, spaceH, minStepW, minStepH int) *js.Object { @@ -50,6 +50,31 @@ func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, }) } +func NewMeleeBulletJs(battleLocalId, startupFrames, activeFrames, recoveryFrames, recoveryFramesOnBlock, recoveryFramesOnHit, hitStunFrames, blockStunFrames, releaseTriggerType, damage, offenderJoinIndex, offenderPlayerId int32, pushback, hitboxOffset, selfMoveforwardX, selfMoveforwardY, hitboxSizeX, hitboxSizeY float64) *js.Object { + return js.MakeWrapper(&MeleeBullet{ + BattleLocalId: battleLocalId, + StartupFrames: startupFrames, + ActiveFrames: activeFrames, + RecoveryFrames: recoveryFrames, + RecoveryFramesOnBlock: recoveryFramesOnBlock, + RecoveryFramesOnHit: recoveryFramesOnHit, + HitboxOffset: hitboxOffset, + HitStunFrames: hitStunFrames, + BlockStunFrames: blockStunFrames, + Pushback: pushback, + ReleaseTriggerType: releaseTriggerType, + Damage: damage, + + SelfMoveforwardX: selfMoveforwardX, + SelfMoveforwardY: selfMoveforwardY, + HitboxSizeX: hitboxSizeX, + HitboxSizeY: hitboxSizeY, + + OffenderJoinIndex: offenderJoinIndex, + OffenderPlayerId: offenderPlayerId, + }) +} + func NewRoomDownsyncFrameJs(id int32, playersArr []*PlayerDownsync, meleeBullets []*MeleeBullet) *js.Object { // [WARNING] Avoid using "pb.RoomDownsyncFrame" here, in practive "MakeFullWrapper" doesn't expose the public fields for a "protobuf struct" as expected and requires helper functions like "GetCollisionSpaceObjsJs". return js.MakeFullWrapper(&RoomDownsyncFrame{ @@ -89,7 +114,7 @@ func GenerateConvexPolygonColliderJs(unalignedSrc *Polygon2D, spaceOffsetX, spac return js.MakeFullWrapper(GenerateConvexPolygonCollider(unalignedSrc, spaceOffsetX, spaceOffsetY, data, tag)) } -func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(delayedInputList, delayedInputListForPrevRenderFrame []uint64, currRenderFrame *RoomDownsyncFrame, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, gravityX, gravityY, jumpingInitVelY, inputDelayFrames, inputScaleFrames int32, collisionSpaceOffsetX, collisionSpaceOffsetY, snapIntoPlatformOverlap, snapIntoPlatformThreshold, worldToVirtualGridRatio, virtualGridToWorldRatio float64) *js.Object { +func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(delayedInputList, delayedInputListForPrevRenderFrame []uint64, currRenderFrame *RoomDownsyncFrame, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, gravityX, gravityY, jumpingInitVelY, inputDelayFrames int32, inputScaleFrames uint32, collisionSpaceOffsetX, collisionSpaceOffsetY, snapIntoPlatformOverlap, snapIntoPlatformThreshold, worldToVirtualGridRatio, virtualGridToWorldRatio float64) *js.Object { // We need access to all fields of RoomDownsyncFrame for displaying in frontend return js.MakeFullWrapper(ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputList, delayedInputListForPrevRenderFrame, currRenderFrame, collisionSys, collisionSysMap, gravityX, gravityY, jumpingInitVelY, inputDelayFrames, inputScaleFrames, collisionSpaceOffsetX, collisionSpaceOffsetY, snapIntoPlatformOverlap, snapIntoPlatformThreshold, worldToVirtualGridRatio, virtualGridToWorldRatio)) }