func saveGameState(gp *GamePanel) lua.GoFunction { return func(L *lua.State) int { if !LuaCheckParamsOk(L, "SaveGameState") { return 0 } gp.script.syncStart() defer gp.script.syncEnd() str, err := base.ToGobToBase64(gp.game) if err != nil { base.Error().Printf("Error gobbing game state: %v", err) return 0 } L.PushString(str) return 1 } }
func saveStore(gp *GamePanel, player *Player) lua.GoFunction { return func(L *lua.State) int { if !LuaCheckParamsOk(L, "SaveStore") { return 0 } gp.script.syncStart() defer gp.script.syncEnd() UpdatePlayer(player, gp.script.L) str, err := base.ToGobToBase64(gp.game) if err != nil { base.Error().Printf("Error gobbing game state: %v", err) return 0 } player.Game_state = str player.Name = "autosave" err = SavePlayer(player) if err != nil { base.Warn().Printf("Unable to save player: %v", err) } return 0 } }
// Runs RoundStart // Lets the game know that the round middle can begin // Runs RoundEnd func (gs *gameScript) OnRound(g *Game) { base.Log().Printf("Launching script.RoundStart") go func() { // // round begins automatically // <-round_middle // for // <-action stuff // <- round end // <- round end done base.Log().Printf("Game script: %p", gs) base.Log().Printf("Lua state: %p", gs.L) gs.L.SetExecutionLimit(250000) cmd := fmt.Sprintf("RoundStart(%t, %d)", g.Side == SideExplorers, (g.Turn+1)/2) base.Log().Printf("cmd: '%s'", cmd) gs.L.DoString(cmd) // signals to the game that we're done with the startup stuff g.comm.script_to_game <- nil base.Log().Printf("ScriptComm: Done with RoundStart") for { base.Log().Printf("ScriptComm: Waiting to verify action") _exec := <-g.comm.game_to_script base.Log().Printf("ScriptComm: Got exec: %v", _exec) if _exec == nil { base.Log().Printf("ScriptComm: No more exec: bailing") break } base.Log().Printf("ScriptComm: Verifying action") exec := _exec.(ActionExec) if vpath := exec.GetPath(); vpath != nil { gs.L.SetExecutionLimit(250000) exec.Push(gs.L, g) gs.L.NewTable() for i := range vpath { gs.L.PushInteger(i + 1) _, x, y := g.FromVertex(vpath[i]) LuaPushPoint(gs.L, x, y) gs.L.SetTable(-3) } base.Log().Printf("Pathlength: %d", len(vpath)) gs.L.SetGlobal("__path") LuaPushEntity(gs.L, g.EntityById(exec.EntityId())) gs.L.SetGlobal("__ent") cmd = fmt.Sprintf("__truncate = OnMove(__ent, __path)") base.Log().Printf("cmd: '%s'", cmd) func() { defer func() { if r := recover(); r != nil { base.Error().Printf("OnMove(): %v", r) } }() gs.L.DoString(cmd) gs.L.GetGlobal("__truncate") truncate := gs.L.ToInteger(-1) gs.L.Pop(1) base.Log().Printf("Truncating to length %d", truncate) exec.TruncatePath(truncate) }() } g.comm.script_to_game <- nil // The action is sent when it happens, and a nil is sent when it is done // being executed, we want to wait until then so that the game is in a // stable state before we do anything. <-g.comm.game_to_script base.Log().Printf("ScriptComm: Got action secondary") // Run OnAction here gs.L.SetExecutionLimit(250000) exec.Push(gs.L, g) str, err := base.ToGobToBase64([]ActionExec{exec}) if err != nil { base.Error().Printf("Unable to encode exec: %v", err) } else { gs.L.PushString("__encoded") gs.L.PushString(str) gs.L.SetTable(-3) } // base.Log().Printf("exec: ", LuaStringifyParam(gs.L, -1)) gs.L.SetGlobal("__exec") cmd = fmt.Sprintf("OnAction(%t, %d, %s)", g.Side == SideExplorers, (g.Turn+1)/2, "__exec") base.Log().Printf("cmd: '%s'", cmd) gs.L.DoString(cmd) g.comm.script_to_game <- nil base.Log().Printf("ScriptComm: Done with OnAction") } gs.L.SetExecutionLimit(250000) gs.L.DoString(fmt.Sprintf("RoundEnd(%t, %d)", g.Side == SideExplorers, (g.Turn+1)/2)) base.Log().Printf("ScriptComm: Starting the RoundEnd phase out") g.comm.script_to_game <- nil base.Log().Printf("ScriptComm: Starting the RoundEnd phase in") // Signal that we're done with the round end base.Log().Printf("ScriptComm: Done with the RoundEnd phase in") g.comm.script_to_game <- nil base.Log().Printf("ScriptComm: Done with the RoundEnd phase out") }() }