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}