world.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. package world
  2. import "gitlab.com/beoran/woe/monolog"
  3. import "gitlab.com/beoran/woe/sitef"
  4. import "errors"
  5. /* Elements of the WOE game world.
  6. * Only Zones, Rooms and their Exits, Items,
  7. * Mobiles & Characters are saved
  8. * and loaded from disk. All the rest
  9. * is kept statically delared in code for simplicity.
  10. */
  11. type World struct {
  12. Name string
  13. MOTD string
  14. dirname string
  15. entitymap map[string]*Entity
  16. zonemap map[string]*Zone
  17. zones []*Zone
  18. charactermap map[string]*Character
  19. characters []Character
  20. roommap map[string]*Room
  21. rooms []Room
  22. itemmap map[string]*Item
  23. items []Item
  24. mobilemap map[string]*Mobile
  25. mobiles []Mobile
  26. accounts []*Account
  27. accountmap map[string]*Account
  28. }
  29. func (me *World) AddWoeDefaults() {
  30. /*
  31. me.AddSpecies(NewSpecies("sp_human" , "Human"))
  32. me.AddSpecies(NewSpecies("sp_neosa" , "Neosa"))
  33. me.AddSpecies(NewSpecies("sp_mantu" , "Mantu"))
  34. me.AddSpecies(NewSpecies("sp_cyborg" , "Cyborg"))
  35. me.AddSpecies(NewSpecies("sp_android", "Android"))
  36. */
  37. }
  38. func NewWorld(name string, motd string, dirname string) *World {
  39. world := new(World)
  40. world.Name = name
  41. world.MOTD = motd
  42. world.dirname = dirname
  43. world.accountmap = make(map[string]*Account)
  44. world.itemmap = make(map[string]*Item)
  45. world.roommap = make(map[string]*Room)
  46. world.charactermap = make(map[string]*Character)
  47. world.AddWoeDefaults()
  48. return world
  49. }
  50. func HaveID(ids []string, id string) bool {
  51. for index := 0; index < len(ids); index++ {
  52. if ids[index] == id {
  53. return true
  54. }
  55. }
  56. return false
  57. }
  58. func (me *World) AddEntity(entity *Entity) {
  59. me.entitymap[entity.ID] = entity
  60. }
  61. func (me *World) AddZone(zone *Zone) {
  62. me.zones = append(me.zones, zone)
  63. me.zonemap[zone.ID] = zone
  64. me.AddEntity(&zone.Entity)
  65. }
  66. // Save an account as a sitef file.
  67. func (me *World) Save(dirname string) (err error) {
  68. path := SavePathFor(dirname, "world", me.Name)
  69. rec := sitef.NewRecord()
  70. rec.Put("name", me.Name)
  71. rec.Put("motd", me.MOTD)
  72. monolog.Debug("Saving World record: %s %v", path, rec)
  73. return sitef.SaveRecord(path, *rec)
  74. }
  75. // Load a world from a sitef file.
  76. func LoadWorld(dirname string, name string) (world *World, err error) {
  77. path := SavePathFor(dirname, "world", name)
  78. records, err := sitef.ParseFilename(path)
  79. if err != nil {
  80. return nil, err
  81. }
  82. if len(records) < 1 {
  83. return nil, errors.New("No record found!")
  84. }
  85. record := records[0]
  86. monolog.Info("Loading World record: %s %v", path, record)
  87. world = NewWorld(record.Get("name"), record.Get("motd"), dirname)
  88. monolog.Info("Loaded World: %s %v", path, world)
  89. return world, nil
  90. }
  91. // Returns an acccount that has already been loaded or nil if not found
  92. func (me *World) GetAccount(name string) (account *Account) {
  93. account, ok := me.accountmap[name]
  94. if !ok {
  95. return nil
  96. }
  97. return account
  98. }
  99. // Loads an account to be used with this world. Characters will be linked.
  100. // If the account was already loaded, returns that in stead.
  101. func (me *World) LoadAccount(name string) (account *Account, err error) {
  102. account = me.GetAccount(name)
  103. if account != nil {
  104. return account, nil
  105. }
  106. account, err = LoadAccount(me.dirname, name)
  107. if err != nil {
  108. return account, err
  109. }
  110. me.accountmap[account.Name] = account
  111. return account, nil
  112. }
  113. // Removes an account from this world by name.
  114. func (me *World) RemoveAccount(name string) {
  115. _, have := me.accountmap[name]
  116. if !have {
  117. return
  118. }
  119. delete(me.accountmap, name)
  120. }
  121. // Default world pointer
  122. var DefaultWorld *World
  123. // Returns an item that has already been loaded or nil if not found
  124. func (me *World) GetItem(id string) (item *Item) {
  125. item, ok := me.itemmap[id]
  126. if !ok {
  127. return nil
  128. }
  129. return item
  130. }
  131. // Loads an item to be used with this world.
  132. // If the item was already loaded, returns that in stead.
  133. func (me *World) LoadItem(id string) (item *Item, err error) {
  134. item = me.GetItem(id)
  135. if item != nil {
  136. return item, nil
  137. }
  138. item, err = LoadItem(me.dirname, id)
  139. if err != nil {
  140. return item, err
  141. }
  142. me.itemmap[item.ID] = item
  143. return item, nil
  144. }
  145. // Removes an item from this world by ID.
  146. func (me *World) RemoveItem(id string) {
  147. _, have := me.itemmap[id]
  148. if !have {
  149. return
  150. }
  151. delete(me.itemmap, id)
  152. }
  153. // Returns a Room that has already been loaded or nil if not found
  154. func (me *World) GetRoom(id string) (room *Room) {
  155. room, ok := me.roommap[id]
  156. if !ok {
  157. return nil
  158. }
  159. return room
  160. }
  161. // Loads a Room to be used with this world.
  162. // If the room was already loaded, returns that in stead.
  163. func (me *World) LoadRoom(id string) (room *Room, err error) {
  164. room = me.GetRoom(id)
  165. if room != nil {
  166. return room, nil
  167. }
  168. room, err = LoadRoom(me.dirname, id)
  169. if err != nil {
  170. return room, err
  171. }
  172. me.roommap[room.ID] = room
  173. return room, nil
  174. }
  175. // Removes an item from this world by ID.
  176. func (me *World) RemoveRoom(id string) {
  177. _, have := me.roommap[id]
  178. if !have {
  179. return
  180. }
  181. delete(me.roommap, id)
  182. }