package main import ( "codehub.onpointcoding.net/sean/go-susapp/collision" "codehub.onpointcoding.net/sean/go-susapp/enum" "codehub.onpointcoding.net/sean/go-susapp/gamedata" "codehub.onpointcoding.net/sean/go-susapp/innernetobjects" "codehub.onpointcoding.net/sean/go-susapp/packets" "codehub.onpointcoding.net/sean/go-susapp/protocol" "codehub.onpointcoding.net/sean/go-susapp/util" ) type MovementProcessor struct { sus *SusApp } func (proc *MovementProcessor) Tick(delta int64) { if proc.sus.state.CurrentGame != nil && proc.sus.state.CurrentGame.NetObjects != nil && proc.sus.networkHandler != nil { p := protocol.NewEmptyPacket() cp, ok := proc.sus.state.CurrentGame.PlayerNetObjects.ByPlayerNetID[proc.sus.state.CurrentGame.ClientPlayerNetID] if ok { netId := cp.PlayerNetworkTransform var c0 innernetobjects.InnerNetObject = *proc.sus.state.CurrentGame.NetObjects[netId] a, ok := c0.(*innernetobjects.PlayerNetworkTransform) if ok { a.LastSequenceID++ prevVelocityZero := a.TargetVelocity.X == 0 && a.TargetVelocity.Y == 0 a.TargetVelocity.X = enum.PLAYER_SPEED * proc.sus.state.CurrentGame.GameOptions.PlayerSpeedModifier * proc.sus.state.MovementX / 2 a.TargetVelocity.Y = enum.PLAYER_SPEED * proc.sus.state.CurrentGame.GameOptions.PlayerSpeedModifier * proc.sus.state.MovementY / 2 nextVelocityZero := a.TargetVelocity.X == 0 && a.TargetVelocity.Y == 0 if !nextVelocityZero || prevVelocityZero != nextVelocityZero { a.TargetPosition.X += a.TargetVelocity.X * (float32(delta) / 1000) a.TargetPosition.Y -= a.TargetVelocity.Y * (float32(delta) / 1000) proc.sus.state.PosX = a.TargetPosition.X proc.sus.state.PosY = a.TargetPosition.Y if !proc.sus.state.Settings.Debug.DisableCollision { proc.ProcessCollision(&a.TargetPosition) } c0.Write(p, false) var c1 protocol.UpdateComponent = protocol.UpdateComponent{NetID: netId, RawData: p} var c2 packets.GameDataSubpacket = &gamedata.DataH2G{Component: &c1} var c3 protocol.HazelPayload = packets.NewGameDataSingleSubpacket(proc.sus.state.CurrentGame.GameID, &c2) proc.sus.networkHandler.SendNormalPacket([]*protocol.Hazel{protocol.NewHazelFromPayload(&c3)}) } } } } } func (proc *MovementProcessor) ProcessCollision(p *util.Vec2) { a := util.NewVec2(p.X, p.Y+enum.PLAYER_COLLISION_OFFSET_Y) if proc.sus.state.Collision != nil { for _, item := range *proc.sus.state.Collision { _, a = proc.ProcessPolygonCollision(a, item) } } (*p) = util.NewVec2(a.X, a.Y-enum.PLAYER_COLLISION_OFFSET_Y) } func (proc *MovementProcessor) ProcessPolygonCollision(p util.Vec2, item []util.Vec2) (bool, util.Vec2) { lastPoint := util.Vec2{} y := false for i, point := range item { if i != 0 { yes, closest := collision.CollisionLineCircle(lastPoint, point, p, enum.PLAYER_COLLISION_RADIUS) if yes { p = proc.CalculatePlayerRejectPosition(closest, p, enum.PLAYER_COLLISION_RADIUS) y = true } } lastPoint = point } for _, point := range item { yes := collision.CollisionPointCircle(point, p, enum.PLAYER_COLLISION_RADIUS) if yes { p = proc.CalculatePlayerRejectPosition(point, p, enum.PLAYER_COLLISION_RADIUS) } } return y, p } func (proc *MovementProcessor) CalculatePlayerRejectPosition(a util.Vec2, b util.Vec2, dt float32) util.Vec2 { c := util.NewVec2(b.X-a.X, b.Y-a.Y) d := util.Sqrt32((c.X * c.X) + (c.Y * c.Y)) t := dt / d return util.NewVec2(((1-t)*a.X + t*b.X), ((1-t)*a.Y + t*b.Y)) }