You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
4.3 KiB

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