arnaucube
arnaucube/gogame-oldPublic Self-hosted repository
gogame-old/models/user.go
models/user.goRaw
  1package models
  2
  3import (
  4	"errors"
  5	"fmt"
  6	"time"
  7
  8	"github.com/arnaucube/gogame/database"
  9	"gopkg.in/mgo.v2/bson"
 10)
 11
 12type Resources struct {
 13	Metal     int64
 14	Crystal   int64
 15	Deuterium int64
 16	Energy    int64
 17}
 18
 19// UserDb is the data in DB
 20type UserDb struct {
 21	Id          bson.ObjectId `json:"id" bson:"_id,omitempty"`
 22	Name        string
 23	Password    string
 24	Email       string
 25	LastUpdated time.Time
 26	Resources   Resources
 27	Planets     []bson.ObjectId
 28}
 29
 30// User is the data in memory, after getting it from DB
 31type User struct {
 32	Id          bson.ObjectId `json:"id" bson:"_id,omitempty"`
 33	Name        string
 34	LastUpdated time.Time
 35	db          *database.Db
 36	Resources   Resources
 37}
 38
 39func NewUser(db *database.Db, name, password, email string) (*User, error) {
 40	newUser := UserDb{
 41		Id:          bson.NewObjectId(),
 42		Name:        name,
 43		Password:    password,
 44		Email:       email,
 45		LastUpdated: time.Now(),
 46		Resources: Resources{
 47			Metal:     500,
 48			Crystal:   500,
 49			Deuterium: 500,
 50			Energy:    500,
 51		},
 52	}
 53	err := db.Users.Insert(newUser)
 54	if err != nil {
 55		return nil, err
 56	}
 57	user := UserDbToUser(db, newUser)
 58	return user, nil
 59}
 60
 61func UserDbToUser(db *database.Db, u UserDb) *User {
 62	return &User{
 63		Id:          u.Id,
 64		Name:        u.Name,
 65		LastUpdated: u.LastUpdated,
 66		db:          db,
 67		Resources:   u.Resources,
 68	}
 69}
 70
 71func (u *User) StoreInDb() error {
 72	userDb := UserDb{
 73		Id:          u.Id,
 74		Name:        u.Name,
 75		LastUpdated: time.Now(),
 76		Resources:   u.Resources,
 77	}
 78	err := u.db.Users.Update(bson.M{"_id": u.Id}, userDb)
 79	return err
 80
 81}
 82
 83func (u *User) GetFromDb() error {
 84	var userDb UserDb
 85	err := u.db.Users.Find(bson.M{"_id": u.Id}).One(&userDb)
 86	if err != nil {
 87		return err
 88	}
 89	u = UserDbToUser(u.db, userDb)
 90	return nil
 91}
 92
 93func (u *User) GetPlanets() ([]Planet, error) {
 94	var planets []Planet
 95	err := u.db.Planets.Find(bson.M{"ownerid": u.Id}).All(&planets)
 96	if err != nil {
 97		return planets, err
 98	}
 99	return planets, nil
100}
101
102// GetResources updates the values of resources and returns the value, also updates the user.Resources
103// Resource types: metal, crystal, deuterium, energy
104func (u *User) GetResources() (*Resources, error) {
105	// get current values
106	err := u.GetFromDb()
107	if err != nil {
108		return nil, err
109	}
110	// get u.LastUpdated
111	fmt.Println(u.LastUpdated)
112	// calculate Delta time = currentTime - u.LastUpdated
113	delta := time.Since(u.LastUpdated)
114
115	// get planets
116	planets, err := u.GetPlanets()
117	if err != nil {
118		return nil, err
119	}
120
121	// get Resource-Plant level in each planet
122	// and calculate growth = ResourcePlant.Level for each planet
123	var metalGrowth, crystalGrowth, deuteriumGrowth, energyGrowth int64
124	for _, planet := range planets {
125		fmt.Println("planet", planet)
126		// TODO find correct formulas
127		metalGrowth = metalGrowth + ((1 + planet.Buildings["metalmine"]) * int64(delta))
128		crystalGrowth = crystalGrowth + ((1 + planet.Buildings["crystalmine"]) * int64(delta))
129		deuteriumGrowth = deuteriumGrowth + ((1 + planet.Buildings["deuteriummine"]) * int64(delta))
130		energyGrowth = energyGrowth + ((1 + planet.Buildings["energymine"]) * int64(delta))
131	}
132	// calculate newAmount = oldAmount + growth
133	u.Resources.Metal = u.Resources.Metal + metalGrowth
134	u.Resources.Crystal = u.Resources.Crystal + crystalGrowth
135	u.Resources.Deuterium = u.Resources.Deuterium + deuteriumGrowth
136	u.Resources.Energy = u.Resources.Energy + energyGrowth
137
138	// store new amount to user db
139	err = u.StoreInDb()
140	if err != nil {
141		return nil, err
142	}
143
144	// return user
145	return &u.Resources, nil
146}
147
148// SpendResources checks if user has enough resources, then substracts the resources, and updates the amounts in the database
149func (u *User) SpendResources(r Resources) error {
150	err := u.GetFromDb()
151	if err != nil {
152		return err
153	}
154	if u.Resources.Metal < r.Metal {
155		return errors.New("not enough metal resources")
156	}
157	if u.Resources.Crystal < r.Crystal {
158		return errors.New("not enough crystal resources")
159	}
160	if u.Resources.Deuterium < r.Deuterium {
161		return errors.New("not enough deuterium resources")
162	}
163	if u.Resources.Energy < r.Energy {
164		return errors.New("not enough energy resources")
165	}
166
167	u.Resources.Metal = u.Resources.Metal - r.Metal
168	u.Resources.Crystal = u.Resources.Crystal - r.Crystal
169	u.Resources.Deuterium = u.Resources.Deuterium - r.Deuterium
170	u.Resources.Energy = u.Resources.Energy - r.Energy
171
172	err = u.StoreInDb()
173	if err != nil {
174		return err
175	}
176	return nil
177}