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 return m
} }
func (MakeBombState) String() string { return "Making a Bomb" }
func (m *MakeBombState) Exit(c *Connection) { func (m *MakeBombState) Exit(c *Connection) {
c.bombs += 1 c.bombs += 1
c.Printf("Done! You now have %v bombs.\n", c.bombs) 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 elapsedFrames := c.game.frame - m.start
elapsedDur := framesToDur(elapsedFrames) elapsedDur := framesToDur(elapsedFrames)
msg := fmt.Sprintf(` desc := fmt.Sprintf(`
Currently making a bomb! Currently making a bomb!
Current System: %s
Build time elapsed: %v Build time elapsed: %v
Build time remaining: %v Build time remaining: %v
`, m.System, elapsedDur, options.makeBombTime-elapsedDur) `, elapsedDur, options.makeBombTime-elapsedDur)
c.Printf(strings.TrimSpace(msg)) 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) c.Printf("Established colony on %v.\n", m.System)
} }
func (m *MakeColonyState) PrintStatus(c *Connection) { func (m *MakeColonyState) FillStatus(c *Connection, s *status) {
panic("not done") s.Location = m.System.String()
} }

@ -6,11 +6,42 @@ import (
"text/template" "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 var commandRegistry map[string]*Command
type Command struct { type Command struct {
name string name string
summary string summary string
usage string
help string
arity int arity int
variadic bool variadic bool
handler func(*Connection, ...string) handler func(*Connection, ...string)
@ -58,7 +89,14 @@ func (c CommandSet) Commands() []Command {
var helpCommand = Command{ var helpCommand = Command{
name: "help", 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) { handler: func(conn *Connection, args ...string) {
msg := ` msg := `
Exocolonus is a game of cunning text-based, real-time strategy. You play as 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) conn.Printf("no such command: %v\n", cmdName)
continue continue
} }
conn.Printf("%v: %v\n", cmdName, cmd.summary) printHelp(conn, cmd)
} }
}, },
} }
type status struct { type status struct {
GameCode string
State string State string
GameCode string
Balance int Balance int
Bombs int Bombs int
Kills int Kills int
@ -114,13 +152,15 @@ type status struct {
} }
var statusTemplate = template.Must(template.New("status").Parse(` var statusTemplate = template.Must(template.New("status").Parse(`
Current State: {{.State}}
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
{{- if .GameCode}}
Current Game: {{.GameCode}} Current Game: {{.GameCode}}
Current State: {{.State}}
Balance: {{.Balance}} Balance: {{.Balance}}
Bombs: {{.Bombs}} Bombs: {{.Bombs}}
Kills: {{.Kills}} Kills: {{.Kills}}
Location: {{.Location}} Location: {{.Location}}
{{end}}
{{.Description}} {{.Description}}
@ -130,7 +170,17 @@ var statusCommand = Command{
name: "status", name: "status",
summary: "display your current status", summary: "display your current status",
handler: func(conn *Connection, args ...string) { 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. // is weird and circular, this is a special case.
var commandsCommand = Command{ var commandsCommand = Command{
name: "commands", name: "commands",
summary: "gives you a handy list of commands", summary: "lists currently available commands",
} }
func BroadcastCommand(sys *System) Command { func BroadcastCommand(sys *System) Command {

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

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

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

@ -28,6 +28,7 @@ func Idle(sys *System) ConnectionState {
name: "bomb", name: "bomb",
summary: "bomb another star system", summary: "bomb another star system",
arity: 1, arity: 1,
usage: "bomb [system-name or system-id]",
handler: i.bomb, handler: i.bomb,
}, },
Command{ Command{
@ -36,12 +37,6 @@ func Idle(sys *System) ConnectionState {
arity: 0, arity: 0,
handler: i.mine, handler: i.mine,
}, },
Command{
name: "info",
summary: "gives you information about the current star system",
arity: 0,
handler: i.info,
},
Command{ Command{
name: "scan", name: "scan",
summary: "scans the galaxy for signs of life", 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)) 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) { func (i *IdleState) scan(c *Connection, args ...string) {
if time.Since(c.lastScan) < 1*time.Minute { if time.Since(c.lastScan) < 1*time.Minute {
return return
@ -119,6 +109,10 @@ func (i *IdleState) scan(c *Connection, args ...string) {
// "make" is already a keyword // "make" is already a keyword
func (i *IdleState) maek(c *Connection, args ...string) { 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] { switch args[0] {
case "bomb": case "bomb":
if c.money < options.bombCost { if c.money < options.bombCost {
@ -136,6 +130,7 @@ func (i *IdleState) maek(c *Connection, args ...string) {
} }
} }
func (i *IdleState) PrintStatus(c *Connection) { func (i *IdleState) FillStatus(c *Connection, s *status) {
panic("not done") 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 c.profile = profile
} else { } else {
c.profile = profile c.profile = profile
c.Printf("welcome back, %s.\n", profile.name) c.Printf("Welcome back, %s.\n", profile.name)
} }
break 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) Tick(c *Connection, frame int64) ConnectionState { return st }
func (st *LobbyState) PrintStatus(c *Connection) { func (st *LobbyState) FillStatus(c *Connection, s *status) {
panic("not done") 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{ var newGameCommand = Command{
@ -119,9 +122,18 @@ var newGameCommand = Command{
var joinGameCommand = Command{ var joinGameCommand = Command{
name: "join", name: "join",
summary: "joins an existing game", summary: "joins an existing game",
usage: "join [game-code]",
arity: 1, arity: 1,
variadic: false, variadic: false,
handler: func(c *Connection, args ...string) { 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] id := args[0]
c.game = gm.Get(id) c.game = gm.Get(id)
c.SetState(SpawnRandomly()) c.SetState(SpawnRandomly())

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

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

@ -107,17 +107,8 @@ func (t *TravelState) String() string {
return fmt.Sprintf("Traveling from %v to %v", t.start, t.dest) return fmt.Sprintf("Traveling from %v to %v", t.start, t.dest)
} }
func (t *TravelState) PrintStatus(c *Connection) { func (t *TravelState) FillStatus(c *Connection, s *status) {
desc := fmt.Sprintf("Traveling from %v to %v", t.start, t.dest) s.Location = fmt.Sprintf("between %s and %s", 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) progress(c *Connection, args ...string) { func (t *TravelState) progress(c *Connection, args ...string) {

Loading…
Cancel
Save