refactor lobby state

master
Jordan Orelli 5 years ago
parent 938348ce26
commit a330d87b4c

@ -1,24 +1,5 @@
space-dragons-in-outer-space space-dragons-in-outer-space
============================ ============================
there's no url because it's not a web app This is a [real-time strategy
game](https://en.wikipedia.org/wiki/Real-time_strategy) in the style of a [MUD](https://en.wikipedia.org/wiki/MUD).
it's just a tcp server
you go
like this
`nc 104.236.57.163 9220`
and that is how
you be a dragon
in space
in space
in space

@ -2,8 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"sort"
// "strconv"
"strings" "strings"
) )
@ -54,31 +52,34 @@ var helpCommand = Command{
help: "helpful things to help you", help: "helpful things to help you",
handler: func(conn *Connection, args ...string) { handler: func(conn *Connection, args ...string) {
msg := ` msg := `
Star Dragons is a stupid name, but it's the name that Brian suggested. It has Exocolonus is a game of cunning text-based, real-time strategy. You play as
nothing to do with Dragons. some kind of space-faring entity, faring space in your inspecific space-faring
vessel. If you want a big one, it's big; if you want a small one, it's small.
Anyway, Star Dragons is a game of cunning text-based, real-time strategy. You If you want a pink one, it's pink, if you want a black one, it's black. And so
play as some kind of space-faring entity, faring space in your inspecific on, and so forth. It is the space craft of your dreams. Or perhaps you are
space-faring vessel. If you want a big one, it's big; if you want a small one, one of those insect-like alien races and you play as the queen. Yeah, that's
it's small. If you want a pink one, it's pink, if you want a black one, it's the ticket! You're the biggest baddest queen bug in space.
black. And so on, and so forth. It is the space craft of your dreams. Or
perhaps you are one of those insect-like alien races and you play as the queen. In Exocolonus, you issue your spacecraft textual commands to control it. The
Yeah, that's the ticket! You're the biggest baddest queen bug in space. objective of the game is to be the first person or alien or bug or magical
space ponycorn to eradicate three enemy species. Right now that is the only
In Star Dragons, you issue your spacecraft (which is *not* called a Dragon) win condition.
textual commands to control it. The objective of the game is to be the first
person or alien or bug or magical space ponycorn to eradicate three enemy All of the systems present in Exocolonus are named and positioned after known
species. Right now that is the only win condition. exoplanet systems. Each star system in Exocolonus is a real star system that
has been researched by astronomers, and the number of planets in each system
All of the systems present in Star Dragons are named and positioned after known corresponds to the number of known exoplanets in those systems. When
exoplanet systems. When attempting to communicate from one star system to attempting to communicate from one star system to another, it takes time for
another, it takes time for the light of your message to reach the other star the light of your message to reach the other star systems. Star systems that
systems. Star systems that are farther away take longer to communicate with. are farther away take longer to communicate with.
` `
msg = strings.TrimSpace(msg) msg = strings.TrimSpace(msg)
fmt.Fprintln(conn, msg) fmt.Fprintln(conn, msg)
if len(args) == 0 { if len(args) == 0 {
fmt.Fprint(conn, "\n")
conn.Line()
fmt.Fprint(conn, "\n")
fmt.Fprintln(conn, `use the "commands" command for a list of commands.`) fmt.Fprintln(conn, `use the "commands" command for a list of commands.`)
fmt.Fprintln(conn, `use "help [command-name]" to get info for a specific command.`) fmt.Fprintln(conn, `use "help [command-name]" to get info for a specific command.`)
return return
@ -94,22 +95,11 @@ systems. Star systems that are farther away take longer to communicate with.
}, },
} }
// this isn't a real command it just puts command in the list of commands, this
// is weird and circular, this is a special case.
var commandsCommand = Command{ var commandsCommand = Command{
name: "commands", name: "commands",
help: "gives you a handy list of commands", help: "gives you a handy list of commands",
handler: func(conn *Connection, args ...string) {
names := make([]string, 0, len(commandRegistry))
for name, _ := range commandRegistry {
names = append(names, name)
}
sort.Strings(names)
fmt.Fprintln(conn, "--------------------------------------------------------------------------------")
for _, name := range names {
cmd := commandRegistry[name]
conn.Printf("%-16s %s\n", name, cmd.help)
}
fmt.Fprintln(conn, "--------------------------------------------------------------------------------")
},
} }
func BroadcastCommand(sys *System) Command { func BroadcastCommand(sys *System) Command {

@ -31,44 +31,10 @@ func NewConnection(conn net.Conn) *Connection {
bombs: options.startBombs, bombs: options.startBombs,
money: options.startMoney, money: options.startMoney,
} }
c.SetState(new(LobbyState)) c.SetState(EnterLobby())
return c return c
} }
func (c *Connection) Login() {
for {
c.Printf("what is your name, adventurer?\n")
name, err := c.ReadString('\n')
if err == nil {
name = strings.TrimSpace(name)
} else {
log_error("player failed to connect: %v", err)
return
}
if !ValidName(name) {
c.Printf("that name is illegal.\n")
continue
}
log_info("player connected: %v", name)
profile, err := loadProfile(name)
if err != nil {
log_error("could not read profile: %v", err)
profile = &Profile{name: name}
if err := profile.Create(); err != nil {
log_error("unable to create profile record: %v", err)
}
c.Printf("you look new around these parts, %s.\n", profile.name)
c.Printf(`if you'd like a description of how to play, type the "help" command\n`)
c.profile = profile
} else {
c.profile = profile
c.Printf("welcome back, %s.\n", profile.name)
}
break
}
}
func (c *Connection) Dead() bool { func (c *Connection) Dead() bool {
return false return false
} }
@ -260,63 +226,3 @@ func SpawnRandomly() ConnectionState {
} }
return Idle(sys) return Idle(sys)
} }
type LobbyState struct {
NopExit
}
func (st *LobbyState) String() string { return "Lobby" }
func (st *LobbyState) Enter(c *Connection) {
c.Login()
}
func (st *LobbyState) Tick(c *Connection, frame int64) ConnectionState { return st }
func (st *LobbyState) Commands() []Command {
return []Command{newGameCommand, joinGameCommand}
}
func (st *LobbyState) GetCommand(name string) *Command {
switch name {
case "new":
return &newGameCommand
case "join":
return &joinGameCommand
default:
return nil
}
}
var newGameCommand = Command{
name: "new",
help: "starts a new game",
arity: 0,
variadic: false,
handler: func(c *Connection, args ...string) {
c.Printf("Starting a new game...\n")
game := gm.NewGame()
log_info("Created game: %s", game.id)
go game.Run()
c.game = game
c.Printf("Now playing in game: %s\n\n", game.id)
c.Line()
c.game.Join(c)
c.SetState(SpawnRandomly())
},
debug: false,
}
var joinGameCommand = Command{
name: "join",
help: "joins an existing game",
arity: 1,
variadic: false,
handler: func(c *Connection, args ...string) {
id := args[0]
c.game = gm.Get(id)
c.SetState(SpawnRandomly())
c.game.Join(c)
},
debug: false,
}

@ -0,0 +1,128 @@
package main
import (
"strings"
"time"
)
var banner = `
##############################################################################################
/$$$$$$$$ /$$
| $$_____/ | $$
| $$ /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$ | $$ /$$$$$$ /$$$$$$$ /$$ /$$ /$$$$$$$
| $$$$$ | $$ /$$/ /$$__ $$ /$$_____/ /$$__ $$| $$ /$$__ $$| $$__ $$| $$ | $$ /$$_____/
| $$__/ \ $$$$/ | $$ \ $$| $$ | $$ \ $$| $$| $$ \ $$| $$ \ $$| $$ | $$| $$$$$$
| $$ >$$ $$ | $$ | $$| $$ | $$ | $$| $$| $$ | $$| $$ | $$| $$ | $$ \____ $$
| $$$$$$$$ /$$/\ $$| $$$$$$/| $$$$$$$| $$$$$$/| $$| $$$$$$/| $$ | $$| $$$$$$/ /$$$$$$$/
|________/|__/ \__/ \______/ \_______/ \______/ |__/ \______/ |__/ |__/ \______/ |_______/
~+
* +
' |
() .-.,="''"=. - o -
'=/_ \ |
* | '=._ |
\ '=./', '
. '=.__.=' '=' *
+ +
O * ' .
##############################################################################################
`
type LobbyState struct {
CommandSuite
NopExit
}
func EnterLobby() ConnectionState {
return &LobbyState{
CommandSuite: CommandSet{
commandsCommand,
helpCommand,
newGameCommand,
joinGameCommand,
},
}
}
func (st *LobbyState) String() string { return "Lobby" }
func (st *LobbyState) Enter(c *Connection) {
c.Printf(strings.TrimSpace(banner))
time.Sleep(1 * time.Second)
for {
c.Printf("\n\nwhat is your name, adventurer?\n")
name, err := c.ReadString('\n')
if err == nil {
name = strings.TrimSpace(name)
} else {
log_error("player failed to connect: %v", err)
return
}
if !ValidName(name) {
c.Printf("that name is illegal.\n")
continue
}
log_info("player connected: %v", name)
profile, err := loadProfile(name)
if err != nil {
log_error("could not read profile: %v", err)
profile = &Profile{name: name}
if err := profile.Create(); err != nil {
log_error("unable to create profile record: %v", err)
}
c.Printf("you look new around these parts, %s.\n", profile.name)
c.Printf(`if you'd like a description of how to play, type the "help" command\n`)
c.profile = profile
} else {
c.profile = profile
c.Printf("welcome back, %s.\n", profile.name)
}
break
}
}
func (st *LobbyState) Tick(c *Connection, frame int64) ConnectionState { return st }
var newGameCommand = Command{
name: "new",
help: "starts a new game",
arity: 0,
variadic: false,
handler: func(c *Connection, args ...string) {
c.Printf("Starting a new game...\n")
game := gm.NewGame()
log_info("Created game: %s", game.id)
go game.Run()
c.game = game
c.Printf("Now playing in game: %s\n\n", game.id)
c.Line()
c.game.Join(c)
c.SetState(SpawnRandomly())
},
debug: false,
}
var joinGameCommand = Command{
name: "join",
help: "joins an existing game",
arity: 1,
variadic: false,
handler: func(c *Connection, args ...string) {
id := args[0]
c.game = gm.Get(id)
c.SetState(SpawnRandomly())
c.game.Join(c)
},
debug: false,
}
Loading…
Cancel
Save