refactor lobby state

master
Jordan Orelli 5 years ago
parent 938348ce26
commit a330d87b4c

@ -1,24 +1,5 @@
space-dragons-in-outer-space
============================
there's no url because it's not a web app
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
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).

@ -2,8 +2,6 @@ package main
import (
"fmt"
"sort"
// "strconv"
"strings"
)
@ -54,31 +52,34 @@ var helpCommand = Command{
help: "helpful things to help you",
handler: func(conn *Connection, args ...string) {
msg := `
Star Dragons is a stupid name, but it's the name that Brian suggested. It has
nothing to do with Dragons.
Anyway, Star Dragons is a game of cunning text-based, real-time strategy. You
play as 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. If you want a pink one, it's pink, if you want a black one, it's
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.
Yeah, that's the ticket! You're the biggest baddest queen bug in space.
In Star Dragons, you issue your spacecraft (which is *not* called a Dragon)
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
species. Right now that is the only win condition.
All of the systems present in Star Dragons are named and positioned after known
exoplanet systems. When attempting to communicate from one star system to
another, it takes time for the light of your message to reach the other star
systems. Star systems that are farther away take longer to communicate with.
Exocolonus is a game of cunning text-based, real-time strategy. You play as
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.
If you want a pink one, it's pink, if you want a black one, it's 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. Yeah, that's
the ticket! You're the biggest baddest queen bug in space.
In Exocolonus, you issue your spacecraft 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 species. Right now that is the only
win condition.
All of the systems present in Exocolonus are named and positioned after known
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
corresponds to the number of known exoplanets in those systems. When
attempting to communicate from one star system to another, it takes time for
the light of your message to reach the other star systems. Star systems that
are farther away take longer to communicate with.
`
msg = strings.TrimSpace(msg)
fmt.Fprintln(conn, msg)
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 "help [command-name]" to get info for a specific command.`)
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{
name: "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 {

@ -31,44 +31,10 @@ func NewConnection(conn net.Conn) *Connection {
bombs: options.startBombs,
money: options.startMoney,
}
c.SetState(new(LobbyState))
c.SetState(EnterLobby())
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 {
return false
}
@ -260,63 +226,3 @@ func SpawnRandomly() ConnectionState {
}
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