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).Seconds()
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 metalGrowth = metalGrowth + MetalGrowth(planet.Buildings["metalmine"], int64(delta))
123 crystalGrowth = crystalGrowth + MetalGrowth(planet.Buildings["crystalmine"], int64(delta))
124 deuteriumGrowth = deuteriumGrowth + MetalGrowth(planet.Buildings["deuteriummine"], int64(delta))
125 energyGrowth = energyGrowth + MetalGrowth(planet.Buildings["energymine"], int64(delta))
126 }
127 // calculate newAmount = oldAmount + growth
128 u.Resources.Metal = u.Resources.Metal + metalGrowth
129 u.Resources.Crystal = u.Resources.Crystal + crystalGrowth
130 u.Resources.Deuterium = u.Resources.Deuterium + deuteriumGrowth
131 u.Resources.Energy = u.Resources.Energy + energyGrowth
132
133 // store new amount to user db
134 err = u.StoreInDb()
135 if err != nil {
136 return nil, err
137 }
138
139 // return user
140 return &u.Resources, nil
141}
142
143// SpendResources checks if user has enough resources, then substracts the resources, and updates the amounts in the database
144func (u *User) SpendResources(r Resources) error {
145 err := u.GetFromDb()
146 if err != nil {
147 return err
148 }
149 if u.Resources.Metal < r.Metal {
150 return errors.New("not enough metal resources")
151 }
152 if u.Resources.Crystal < r.Crystal {
153 return errors.New("not enough crystal resources")
154 }
155 if u.Resources.Deuterium < r.Deuterium {
156 return errors.New("not enough deuterium resources")
157 }
158 if u.Resources.Energy < r.Energy {
159 return errors.New("not enough energy resources")
160 }
161
162 u.Resources.Metal = u.Resources.Metal - r.Metal
163 u.Resources.Crystal = u.Resources.Crystal - r.Crystal
164 u.Resources.Deuterium = u.Resources.Deuterium - r.Deuterium
165 u.Resources.Energy = u.Resources.Energy - r.Energy
166
167 err = u.StoreInDb()
168 if err != nil {
169 return err
170 }
171 return nil
172}
173
174func (u *User) GetBuildingCost(planet Planet, building string) (Resources, error) {
175 switch building {
176 case "metalmine":
177 return MetalMineCost(planet.Buildings["metalmine"] + 1), nil
178 case "crystalmine":
179 return CrystalMineCost(planet.Buildings["crystalmine"] + 1), nil
180 case "deuteriummine":
181 return DeuteriumMineCost(planet.Buildings["deuteriummine"] + 1), nil
182 case "energymine":
183 return EnergyMineCost(planet.Buildings["energymine"] + 1), nil
184 case "ressearchlab":
185 return RessearchLabCost(planet.Buildings["ressearchlab"] + 1), nil
186 default:
187 return Resources{}, errors.New("building not found")
188 }
189
190}