spacetea/simulator/simulator.go

189 lines
4.1 KiB
Go
Raw Normal View History

2022-05-17 23:29:59 -04:00
package simulator
import (
2022-05-24 18:26:34 -04:00
"fmt"
2022-05-25 16:45:23 -04:00
"log"
2022-05-19 12:58:37 -04:00
"strings"
2022-05-17 23:29:59 -04:00
"time"
)
//Simulator contains the main game state
type Simulator struct {
Place *Pod
Player *Player
Px, Py int
Time int
stop chan bool
}
2022-08-22 19:34:53 -04:00
func Demo(p *Player, s *Simulator) {
2022-05-17 23:29:59 -04:00
pod := newPod()
2022-08-22 19:00:15 -04:00
pod.Place(newResource(lookupByName("tea").ID()), 4, 4)
2022-08-22 19:34:53 -04:00
p.AddItem(itemType(1), 30)
p.AddItem(itemType(3), 5)
pod.Tiles[0][0].User = p
p.Announce("Game started")
2022-08-22 19:00:15 -04:00
s.Place = pod
2022-08-22 19:34:53 -04:00
s.Player = p
2022-08-22 19:00:15 -04:00
}
//NewSimulator creates a new simulator instance
func NewSimulator() *Simulator {
2022-05-25 16:45:23 -04:00
log.Println("loading items")
initItems()
log.Println("loading techs")
2022-05-24 21:12:35 -04:00
loadTechs("data/tech.toml")
2022-05-25 16:45:23 -04:00
log.Println("loading resources")
2022-05-25 16:48:27 -04:00
loadResources("data/resources.toml")
2022-05-25 16:45:23 -04:00
log.Println("loading converters")
loadConverters("data/converters.toml")
log.Println("loading journal")
loadPages("data/journal.toml")
2022-08-22 18:39:41 -04:00
log.Println("loading landmarks")
loadLandmarks("data/landmark.toml")
2022-05-25 16:45:23 -04:00
if len(GlobalItems) < 1 {
panic("Loaded items but nothing in global items table")
}
if len(GlobalTechs) < 1 {
panic("Loaded items but nothing in global items table")
}
if len(GlobalPages) < 1 {
panic("Loaded journal but no pages in table")
}
2022-08-22 18:39:41 -04:00
if len(GlobalLandmarks) < 1 {
panic("Loaded landmarks but nothing in table")
}
2022-08-22 19:00:15 -04:00
return &Simulator{nil, nil, 0, 0, 0, make(chan bool)}
2022-05-17 23:29:59 -04:00
}
//Start begins the simulation, non blocking
func (s *Simulator) Start() {
go s.main()
}
//Stop ends the simulation
func (s *Simulator) Stop() {
s.stop <- true
}
//Input sends a command to the simulator
func (s *Simulator) Input(cmd string) {
cur := s.Place.Tiles[s.Px][s.Py]
2022-05-19 12:58:37 -04:00
cmdS := strings.Split(cmd, " ")
switch cmdS[0] {
2022-05-17 23:29:59 -04:00
case "get":
2022-05-19 17:09:46 -04:00
if cur.Building != nil {
2022-05-25 16:45:23 -04:00
if cur.Building.Type() == resourceObject {
build := cur.Building.(*Resource)
2022-05-19 17:09:46 -04:00
prod := build.Get()
if prod.Kind != 0 && prod.Value > 0 {
s.Player.AddItem(prod.Kind, prod.Value)
2022-05-25 16:45:23 -04:00
s.Player.Announce(fmt.Sprintf("Gathered %v %v", prod.Value, GlobalItems[prod.Kind].Describe()))
2022-05-19 17:09:46 -04:00
}
2022-05-17 23:29:59 -04:00
}
}
case "pickup":
if cur.Building != nil {
s.Player.AddItem(cur.Building.ID(), 1)
s.Place.Delete(s.Px, s.Py)
}
case "destroy":
s.Place.Delete(s.Px, s.Py)
2022-05-19 12:58:37 -04:00
case "place":
if len(cmdS) < 2 {
return
}
item := cmdS[1]
2022-05-25 16:45:23 -04:00
s.Player.Announce(fmt.Sprintf("placing %v", item))
obj := lookupByName(item)
switch obj.Type() {
case emptyObject:
return
//case producerObject:
//obj = obj.(Producer)
case consumerObject:
obj2 := obj.(Converter)
res := s.Place.Place(newConverter(obj2.ID(), s.Player), s.Px, s.Py)
2022-05-19 12:58:37 -04:00
if res {
s.Player.DelItem(obj2.ID(), 1)
2022-05-19 17:09:46 -04:00
}
2022-05-25 16:45:23 -04:00
case resourceObject:
obj2 := obj.(Resource)
if obj2.Buildable {
res := s.Place.Place(newResource(obj2.ID()), s.Px, s.Py)
if res {
s.Player.DelItem(obj2.ID(), 1)
2022-05-25 16:45:23 -04:00
}
2022-05-19 12:58:37 -04:00
}
}
2022-05-24 18:26:34 -04:00
case "craft":
if len(cmdS) < 2 {
return
}
item := cmdS[1]
2022-05-25 16:45:23 -04:00
s.Player.Announce(fmt.Sprintf("Crafting %v", item))
obj := lookupByName(item)
switch obj.Type() {
case emptyObject:
return
case consumerObject:
obj2 := obj.(Converter)
i := 0
for _, v := range obj2.Costs {
if s.Player.Resources[lookupByName(v.Name).ID()] >= v.Value {
i++
2022-05-24 18:26:34 -04:00
}
}
2022-05-25 16:45:23 -04:00
if i == len(obj2.Costs) {
for _, v := range obj2.Costs {
s.Player.DelItemByName(v.Name, v.Value)
2022-05-25 16:45:23 -04:00
}
s.Player.AddItemByName(obj2.String(), 1)
2022-05-25 16:45:23 -04:00
}
2022-05-24 18:26:34 -04:00
}
2022-05-25 16:45:23 -04:00
2022-05-17 23:29:59 -04:00
case "left":
res := s.Place.MovePlayer(s.Px, s.Py, s.Px, s.Py-1)
2022-05-19 15:18:03 -04:00
if res != nil {
2022-05-17 23:29:59 -04:00
s.Py = s.Py - 1
2022-05-19 15:18:03 -04:00
s.Player.CurrentTile = res
2022-05-17 23:29:59 -04:00
}
case "right":
res := s.Place.MovePlayer(s.Px, s.Py, s.Px, s.Py+1)
2022-05-19 15:18:03 -04:00
if res != nil {
2022-05-17 23:29:59 -04:00
s.Py = s.Py + 1
2022-05-19 15:18:03 -04:00
s.Player.CurrentTile = res
2022-05-17 23:29:59 -04:00
}
case "up":
res := s.Place.MovePlayer(s.Px, s.Py, s.Px-1, s.Py)
2022-05-19 15:18:03 -04:00
if res != nil {
2022-05-17 23:29:59 -04:00
s.Px = s.Px - 1
2022-05-19 15:18:03 -04:00
s.Player.CurrentTile = res
2022-05-17 23:29:59 -04:00
}
case "down":
res := s.Place.MovePlayer(s.Px, s.Py, s.Px+1, s.Py)
2022-05-19 15:18:03 -04:00
if res != nil {
2022-05-17 23:29:59 -04:00
s.Px = s.Px + 1
2022-05-19 15:18:03 -04:00
s.Player.CurrentTile = res
2022-05-17 23:29:59 -04:00
}
case "quit":
s.Stop()
}
}
func (s *Simulator) main() {
ticker := time.NewTicker(1 * time.Second)
for {
select {
case <-s.stop:
return
case <-ticker.C:
s.Time = s.Time + 1
s.Place.Tick()
2022-05-24 18:26:34 -04:00
s.Player.research()
s.Player.journal()
2022-05-17 23:29:59 -04:00
}
}
}