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