uniform status command for all states

master
Jordan Orelli 6 years ago
parent 15015a9d5b
commit bdc2783838

@ -78,21 +78,23 @@ func (m *MakeBombState) Tick(c *Connection, frame int64) ConnectionState {
return m
}
func (MakeBombState) String() string { return "Making a Bomb" }
func (m *MakeBombState) Exit(c *Connection) {
c.bombs += 1
c.Printf("Done! You now have %v bombs.\n", c.bombs)
}
func (m *MakeBombState) PrintStatus(c *Connection) {
func (m *MakeBombState) FillStatus(c *Connection, s *status) {
elapsedFrames := c.game.frame - m.start
elapsedDur := framesToDur(elapsedFrames)
msg := fmt.Sprintf(`
desc := fmt.Sprintf(`
Currently making a bomb!
Current System: %s
Build time elapsed: %v
Build time remaining: %v
`, m.System, elapsedDur, options.makeBombTime-elapsedDur)
c.Printf(strings.TrimSpace(msg))
`, elapsedDur, options.makeBombTime-elapsedDur)
s.Description = strings.TrimSpace(desc)
s.Location = m.System.String()
}

@ -49,6 +49,6 @@ func (m *MakeColonyState) Exit(c *Connection) {
c.Printf("Established colony on %v.\n", m.System)
}
func (m *MakeColonyState) PrintStatus(c *Connection) {
panic("not done")
func (m *MakeColonyState) FillStatus(c *Connection, s *status) {
s.Location = m.System.String()
}

@ -6,11 +6,42 @@ import (
"text/template"
)
var helpTemplate = template.Must(template.New("help").Parse(`
{{.Name}} Command Reference
Summary: {{.Summary}}
{{- if .Usage}}
Usage: {{.Usage}}
{{end}}
{{- if .Description}}
Details:
{{.Description}}
{{end}}
`))
func printHelp(conn *Connection, cmd *Command) {
desc := strings.ReplaceAll(strings.TrimSpace(cmd.help), "\n", "\n ")
helpTemplate.Execute(conn, struct {
Name string
Summary string
Usage string
Description string
}{
Name: cmd.name,
Summary: cmd.summary,
Usage: cmd.usage,
Description: desc,
})
}
var commandRegistry map[string]*Command
type Command struct {
name string
summary string
usage string
help string
arity int
variadic bool
handler func(*Connection, ...string)
@ -58,7 +89,14 @@ func (c CommandSet) Commands() []Command {
var helpCommand = Command{
name: "help",
summary: "helpful things to help you",
summary: "explains how to play the game",
usage: "help [command-name]",
help: `
help explains the usage of various commands in Exocolonus. On its own, the help
command displays some basic info about how the game is played. If given an
argument of a command name, the help command displays the detailed usage of the
specified command.
`,
handler: func(conn *Connection, args ...string) {
msg := `
Exocolonus is a game of cunning text-based, real-time strategy. You play as
@ -98,14 +136,14 @@ are farther away take longer to communicate with.
conn.Printf("no such command: %v\n", cmdName)
continue
}
conn.Printf("%v: %v\n", cmdName, cmd.summary)
printHelp(conn, cmd)
}
},
}
type status struct {
GameCode string
State string
GameCode string
Balance int
Bombs int
Kills int
@ -114,13 +152,15 @@ type status struct {
}
var statusTemplate = template.Must(template.New("status").Parse(`
Current State: {{.State}}
--------------------------------------------------------------------------------
{{- if .GameCode}}
Current Game: {{.GameCode}}
Current State: {{.State}}
Balance: {{.Balance}}
Bombs: {{.Bombs}}
Kills: {{.Kills}}
Location: {{.Location}}
{{end}}
{{.Description}}
@ -130,7 +170,17 @@ var statusCommand = Command{
name: "status",
summary: "display your current status",
handler: func(conn *Connection, args ...string) {
conn.ConnectionState.PrintStatus(conn)
s := status{
State: conn.ConnectionState.String(),
}
conn.ConnectionState.FillStatus(conn, &s)
if conn.game != nil {
s.GameCode = conn.game.id
s.Balance = conn.money
s.Bombs = conn.bombs
s.Kills = conn.kills
}
statusTemplate.Execute(conn, s)
},
}
@ -138,7 +188,7 @@ var statusCommand = Command{
// is weird and circular, this is a special case.
var commandsCommand = Command{
name: "commands",
summary: "gives you a handy list of commands",
summary: "lists currently available commands",
}
func BroadcastCommand(sys *System) Command {

@ -209,7 +209,7 @@ func (c *Connection) Die(frame int64) {
type ConnectionState interface {
CommandSuite
String() string
PrintStatus(c *Connection)
FillStatus(*Connection, *status)
Enter(c *Connection)
Tick(c *Connection, frame int64) ConnectionState
Exit(c *Connection)

@ -26,10 +26,6 @@ func (d *DeadState) Exit(c *Connection) {
c.Printf("You're alive again.\n")
}
func (d *DeadState) String() string {
return "dead"
}
func (d *DeadState) String() string { return "dead" }
func (d *DeadState) PrintStatus(c *Connection) {
panic("not done")
}
func (d *DeadState) FillStatus(c *Connection, s *status) {}

@ -63,6 +63,4 @@ func (e *ErrorState) RunCommand(c *Connection, name string, args ...string) Conn
return e
}
func (e *ErrorState) PrintStatus(c *Connection) {
panic("not done")
}
func (e *ErrorState) FillStatus(c *Connection, s *status) {}

@ -28,6 +28,7 @@ func Idle(sys *System) ConnectionState {
name: "bomb",
summary: "bomb another star system",
arity: 1,
usage: "bomb [system-name or system-id]",
handler: i.bomb,
},
Command{
@ -36,12 +37,6 @@ func Idle(sys *System) ConnectionState {
arity: 0,
handler: i.mine,
},
Command{
name: "info",
summary: "gives you information about the current star system",
arity: 0,
handler: i.info,
},
Command{
name: "scan",
summary: "scans the galaxy for signs of life",
@ -104,11 +99,6 @@ func (i *IdleState) mine(c *Connection, args ...string) {
c.SetState(Mine(i.System))
}
func (i *IdleState) info(c *Connection, args ...string) {
c.Printf("Currently idle on system %v\n", i.System)
c.Printf("Space duckets available: %v\n", i.money)
}
func (i *IdleState) scan(c *Connection, args ...string) {
if time.Since(c.lastScan) < 1*time.Minute {
return
@ -119,6 +109,10 @@ func (i *IdleState) scan(c *Connection, args ...string) {
// "make" is already a keyword
func (i *IdleState) maek(c *Connection, args ...string) {
if len(args) != 1 {
c.Printf("not sure what to do! Expecting a command like this: make [thing]\ne.g.:\nmake bomb\nmake colony")
return
}
switch args[0] {
case "bomb":
if c.money < options.bombCost {
@ -136,6 +130,7 @@ func (i *IdleState) maek(c *Connection, args ...string) {
}
}
func (i *IdleState) PrintStatus(c *Connection) {
panic("not done")
func (i *IdleState) FillStatus(c *Connection, s *status) {
s.Location = i.System.String()
s.Description = "Just hanging out, enjoying outer space."
}

@ -84,7 +84,7 @@ func (st *LobbyState) Enter(c *Connection) {
c.profile = profile
} else {
c.profile = profile
c.Printf("welcome back, %s.\n", profile.name)
c.Printf("Welcome back, %s.\n", profile.name)
}
break
}
@ -93,8 +93,11 @@ func (st *LobbyState) Enter(c *Connection) {
func (st *LobbyState) Tick(c *Connection, frame int64) ConnectionState { return st }
func (st *LobbyState) PrintStatus(c *Connection) {
panic("not done")
func (st *LobbyState) FillStatus(c *Connection, s *status) {
s.Description = strings.TrimSpace(`
Currently in the Lobby, waiting for you to issue a "new" command to start a new
game, or a "join" command to join an existing game.
`)
}
var newGameCommand = Command{
@ -119,9 +122,18 @@ var newGameCommand = Command{
var joinGameCommand = Command{
name: "join",
summary: "joins an existing game",
usage: "join [game-code]",
arity: 1,
variadic: false,
handler: func(c *Connection, args ...string) {
if len(args) == 0 {
c.Printf(strings.TrimLeft(`
Missing game code! When a player starts a game, they will be given a code to
identify their game. Use this game to join the other player's game.
Usage: join [game-code]`, " \n\t"))
return
}
id := args[0]
c.game = gm.Get(id)
c.SetState(SpawnRandomly())

@ -2,6 +2,7 @@ package main
import (
"fmt"
"strings"
)
type MiningState struct {
@ -23,12 +24,6 @@ func Mine(sys *System) ConnectionState {
arity: 0,
handler: m.stop,
},
Command{
name: "info",
summary: "gives you information about the current mining operation",
arity: 0,
handler: m.info,
},
}
return m
}
@ -65,12 +60,11 @@ func (m *MiningState) stop(c *Connection, args ...string) {
c.SetState(Idle(m.System))
}
func (m *MiningState) info(c *Connection, args ...string) {
c.Printf("Currently mining system %v\n", m.System)
c.Printf("Mined so far: %v\n", m.mined)
c.Printf("Remaining space duckets on %v: %v\n", m.System, m.money)
}
func (m *MiningState) PrintStatus(c *Connection) {
panic("not done")
func (m *MiningState) FillStatus(c *Connection, s *status) {
s.Location = m.System.String()
s.Description = strings.TrimSpace(fmt.Sprintf(`
Currently mining on system: %s
Mined so far: %d
Available space duckets: %d
`, m.System.String(), m.mined, m.money))
}

@ -46,8 +46,8 @@ func (m *MakeShieldState) String() string {
return fmt.Sprintf("Making shield on %v", m.System)
}
func (m *MakeShieldState) PrintStatus(c *Connection) {
panic("not done")
func (m *MakeShieldState) FillStatus(c *Connection, s *status) {
s.Location = m.System.String()
}
type Shield struct {

@ -107,17 +107,8 @@ func (t *TravelState) String() string {
return fmt.Sprintf("Traveling from %v to %v", t.start, t.dest)
}
func (t *TravelState) PrintStatus(c *Connection) {
desc := fmt.Sprintf("Traveling from %v to %v", t.start, t.dest)
statusTemplate.Execute(c, status{
GameCode: c.game.id,
State: "In Transit",
Balance: c.money,
Bombs: c.bombs,
Kills: c.kills,
Location: fmt.Sprintf("%s -> %s", t.start, t.dest),
Description: desc,
})
func (t *TravelState) FillStatus(c *Connection, s *status) {
s.Location = fmt.Sprintf("between %s and %s", t.start, t.dest)
}
func (t *TravelState) progress(c *Connection, args ...string) {

Loading…
Cancel
Save