Fix segfaults by avoiding models and animations for now
This commit is contained in:
88
game/game.go
88
game/game.go
@ -170,8 +170,18 @@ func (g *Game) DrawPlayer(player *types.Player, model rl.Model) {
|
||||
player.Lock()
|
||||
defer player.Unlock()
|
||||
|
||||
// Check for invalid model
|
||||
if model.Meshes == nil || model.Meshes.VertexCount <= 0 {
|
||||
// Don't try to draw invalid models
|
||||
return
|
||||
}
|
||||
|
||||
grid := GetMapGrid()
|
||||
modelIndex := int(player.ID) % len(g.Models)
|
||||
if modelIndex < 0 || modelIndex >= len(g.Models) {
|
||||
// Prevent out of bounds access
|
||||
modelIndex = 0
|
||||
}
|
||||
modelAsset := g.Models[modelIndex]
|
||||
|
||||
const defaultHeight = 8.0 // Default height above tile, fine tune per model in types.ModelAsset
|
||||
@ -185,16 +195,25 @@ func (g *Game) DrawPlayer(player *types.Player, model rl.Model) {
|
||||
if modelAsset.Animations.Idle != nil || modelAsset.Animations.Walk != nil {
|
||||
if player.IsMoving && len(modelAsset.Animations.Walk) > 0 {
|
||||
anim := modelAsset.Animations.Walk[0] // Use first walk animation
|
||||
player.AnimationFrame = player.AnimationFrame % anim.FrameCount
|
||||
rl.UpdateModelAnimation(model, anim, player.AnimationFrame)
|
||||
if anim.FrameCount > 0 {
|
||||
player.AnimationFrame = player.AnimationFrame % anim.FrameCount
|
||||
rl.UpdateModelAnimation(model, anim, player.AnimationFrame)
|
||||
}
|
||||
} else if len(modelAsset.Animations.Idle) > 0 {
|
||||
anim := modelAsset.Animations.Idle[0] // Use first idle animation
|
||||
player.AnimationFrame = player.AnimationFrame % anim.FrameCount
|
||||
rl.UpdateModelAnimation(model, anim, player.AnimationFrame)
|
||||
if anim.FrameCount > 0 {
|
||||
player.AnimationFrame = player.AnimationFrame % anim.FrameCount
|
||||
rl.UpdateModelAnimation(model, anim, player.AnimationFrame)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rl.DrawModel(model, playerPos, 16, rl.White)
|
||||
// Use placeholder color if it's set, otherwise use white
|
||||
var drawColor rl.Color = rl.White
|
||||
if player.PlaceholderColor.A > 0 {
|
||||
drawColor = player.PlaceholderColor
|
||||
}
|
||||
rl.DrawModel(model, playerPos, 16, drawColor)
|
||||
|
||||
// Draw floating messages and path indicators
|
||||
if player.FloatingMessage != nil {
|
||||
@ -228,20 +247,43 @@ func (g *Game) DrawPlayer(player *types.Player, model rl.Model) {
|
||||
|
||||
func (g *Game) Render() {
|
||||
rl.BeginDrawing()
|
||||
defer func() {
|
||||
// This defer will catch any panics that might occur during rendering
|
||||
// and ensure EndDrawing gets called to maintain proper graphics state
|
||||
if r := recover(); r != nil {
|
||||
rl.TraceLog(rl.LogError, "Panic during rendering: %v", r)
|
||||
}
|
||||
rl.EndDrawing()
|
||||
}()
|
||||
|
||||
rl.ClearBackground(rl.RayWhite)
|
||||
|
||||
if !g.isLoggedIn {
|
||||
g.loginScreen.Draw()
|
||||
rl.EndDrawing()
|
||||
return
|
||||
}
|
||||
|
||||
rl.BeginMode3D(g.Camera)
|
||||
g.DrawMap()
|
||||
g.DrawPlayer(g.Player, g.Player.Model)
|
||||
|
||||
// Draw player only if valid
|
||||
if g.Player != nil && g.Player.Model.Meshes != nil {
|
||||
g.DrawPlayer(g.Player, g.Player.Model)
|
||||
}
|
||||
|
||||
// Draw other players with defensive checks
|
||||
for _, other := range g.OtherPlayers {
|
||||
if other == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Make sure model is assigned
|
||||
if other.Model.Meshes == nil {
|
||||
g.AssignModelToPlayer(other)
|
||||
// Skip this frame if assignment failed
|
||||
if other.Model.Meshes == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
g.DrawPlayer(other, other.Model)
|
||||
}
|
||||
@ -268,12 +310,14 @@ func (g *Game) Render() {
|
||||
rl.DrawText(text, int32(pos.X)-textWidth/2, int32(pos.Y), 20, rl.Yellow)
|
||||
}
|
||||
|
||||
if g.Player.FloatingMessage != nil {
|
||||
if g.Player != nil && g.Player.FloatingMessage != nil {
|
||||
drawFloatingMessage(g.Player.FloatingMessage)
|
||||
}
|
||||
|
||||
for _, other := range g.OtherPlayers {
|
||||
drawFloatingMessage(other.FloatingMessage)
|
||||
if other != nil && other.FloatingMessage != nil {
|
||||
drawFloatingMessage(other.FloatingMessage)
|
||||
}
|
||||
}
|
||||
|
||||
// Draw menu if open
|
||||
@ -282,12 +326,11 @@ func (g *Game) Render() {
|
||||
}
|
||||
|
||||
// Only draw chat if menu is not open
|
||||
if !g.MenuOpen {
|
||||
if !g.MenuOpen && g.Chat != nil {
|
||||
g.Chat.Draw(int32(rl.GetScreenWidth()), int32(rl.GetScreenHeight()))
|
||||
}
|
||||
|
||||
rl.DrawFPS(10, 10)
|
||||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
func (g *Game) Cleanup() {
|
||||
@ -392,12 +435,33 @@ func (g *Game) HandleServerMessages(messages []*pb.ChatMessage) {
|
||||
}
|
||||
|
||||
func (g *Game) AssignModelToPlayer(player *types.Player) {
|
||||
if player == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Defensive check for empty models array
|
||||
if len(g.Models) == 0 {
|
||||
rl.TraceLog(rl.LogWarning, "No models available to assign to player")
|
||||
return
|
||||
}
|
||||
|
||||
modelIndex := int(player.ID) % len(g.Models)
|
||||
if modelIndex < 0 || modelIndex >= len(g.Models) {
|
||||
// Prevent out of bounds access
|
||||
modelIndex = 0
|
||||
}
|
||||
|
||||
modelAsset := g.Models[modelIndex]
|
||||
|
||||
// Just use the original model - don't try to copy it
|
||||
// Validate model before assigning
|
||||
if modelAsset.Model.Meshes == nil {
|
||||
rl.TraceLog(rl.LogWarning, "Trying to assign invalid model to player %d", player.ID)
|
||||
return
|
||||
}
|
||||
|
||||
player.Model = modelAsset.Model
|
||||
player.Texture = modelAsset.Texture
|
||||
player.PlaceholderColor = modelAsset.PlaceholderColor
|
||||
}
|
||||
|
||||
func (g *Game) QuitChan() <-chan struct{} {
|
||||
|
Reference in New Issue
Block a user