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 Planets []bson.ObjectId
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 Planets: u.Planets,
69 }
70}
71
72func (u *User) StoreInDb() error {
73 err := u.db.Users.Update(bson.M{"_id": u.Id}, bson.M{"$set": bson.M{
74 "lastupdated": time.Now(),
75 "resources": u.Resources,
76 "planets": u.Planets,
77 }})
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 "fusionreactor":
185 return FussionReactorCost(planet.Buildings["fusionreactor"] + 1), nil
186 case "roboticsfactory":
187 return RoboticsFactoryCost(planet.Buildings["roboticsfactory"] + 1), nil
188 case "shipyard":
189 return ShipyardCost(planet.Buildings["shipyard"] + 1), nil
190 case "metalstorage":
191 return MetalStorageCost(planet.Buildings["metalstorage"] + 1), nil
192 case "crystalstorage":
193 return CrystalStorageCost(planet.Buildings["crystalstorage"] + 1), nil
194 case "deuteriumstorage":
195 return DeuteriumStorageCost(planet.Buildings["deuteriumstorage"] + 1), nil
196 case "ressearchlab":
197 return RessearchLabCost(planet.Buildings["ressearchlab"] + 1), nil
198 case "alliancedepot":
199 return AllianceDepotCost(planet.Buildings["alliancedepot"] + 1), nil
200 case "missilesilo":
201 return MissileSiloCost(planet.Buildings["missilesilo"] + 1), nil
202 case "spacedock":
203 return SpaceDockCost(planet.Buildings["spacedock"] + 1), nil
204 default:
205 return Resources{}, errors.New("building not found")
206 }
207
208}