package world import "gitlab.com/beoran/woe/monolog" import "gitlab.com/beoran/woe/sitef" import "errors" /* Elements of the WOE game world. * Only Zones, Rooms and their Exits, Items, * Mobiles & Characters are saved * and loaded from disk. All the rest * is kept statically delared in code for simplicity. */ type World struct { Name string MOTD string dirname string entitymap map[string]*Entity zonemap map[string]*Zone zones []*Zone charactermap map[string]*Character characters []Character roommap map[string]*Room rooms []Room itemmap map[string]*Item items []Item mobilemap map[string]*Mobile mobiles []Mobile accounts []*Account accountmap map[string]*Account } func (me *World) AddWoeDefaults() { /* me.AddSpecies(NewSpecies("sp_human" , "Human")) me.AddSpecies(NewSpecies("sp_neosa" , "Neosa")) me.AddSpecies(NewSpecies("sp_mantu" , "Mantu")) me.AddSpecies(NewSpecies("sp_cyborg" , "Cyborg")) me.AddSpecies(NewSpecies("sp_android", "Android")) */ } func NewWorld(name string, motd string, dirname string) *World { world := new(World) world.Name = name world.MOTD = motd world.dirname = dirname world.accountmap = make(map[string]*Account) world.itemmap = make(map[string]*Item) world.roommap = make(map[string]*Room) world.charactermap = make(map[string]*Character) world.AddWoeDefaults() return world } func HaveID(ids []string, id string) bool { for index := 0; index < len(ids); index++ { if ids[index] == id { return true } } return false } func (me *World) AddEntity(entity *Entity) { me.entitymap[entity.ID] = entity } func (me *World) AddZone(zone *Zone) { me.zones = append(me.zones, zone) me.zonemap[zone.ID] = zone me.AddEntity(&zone.Entity) } // Save an account as a sitef file. func (me *World) Save(dirname string) (err error) { path := SavePathFor(dirname, "world", me.Name) rec := sitef.NewRecord() rec.Put("name", me.Name) rec.Put("motd", me.MOTD) monolog.Debug("Saving World record: %s %v", path, rec) return sitef.SaveRecord(path, *rec) } // Load a world from a sitef file. func LoadWorld(dirname string, name string) (world *World, err error) { path := SavePathFor(dirname, "world", name) records, err := sitef.ParseFilename(path) if err != nil { return nil, err } if len(records) < 1 { return nil, errors.New("No record found!") } record := records[0] monolog.Info("Loading World record: %s %v", path, record) world = NewWorld(record.Get("name"), record.Get("motd"), dirname) monolog.Info("Loaded World: %s %v", path, world) return world, nil } // Returns an acccount that has already been loaded or nil if not found func (me *World) GetAccount(name string) (account *Account) { account, ok := me.accountmap[name] if !ok { return nil } return account } // Loads an account to be used with this world. Characters will be linked. // If the account was already loaded, returns that in stead. func (me *World) LoadAccount(name string) (account *Account, err error) { account = me.GetAccount(name) if account != nil { return account, nil } account, err = LoadAccount(me.dirname, name) if err != nil { return account, err } me.accountmap[account.Name] = account return account, nil } // Removes an account from this world by name. func (me *World) RemoveAccount(name string) { _, have := me.accountmap[name] if !have { return } delete(me.accountmap, name) } // Default world pointer var DefaultWorld *World // Returns an item that has already been loaded or nil if not found func (me *World) GetItem(id string) (item *Item) { item, ok := me.itemmap[id] if !ok { return nil } return item } // Loads an item to be used with this world. // If the item was already loaded, returns that in stead. func (me *World) LoadItem(id string) (item *Item, err error) { item = me.GetItem(id) if item != nil { return item, nil } item, err = LoadItem(me.dirname, id) if err != nil { return item, err } me.itemmap[item.ID] = item return item, nil } // Removes an item from this world by ID. func (me *World) RemoveItem(id string) { _, have := me.itemmap[id] if !have { return } delete(me.itemmap, id) } // Returns a Room that has already been loaded or nil if not found func (me *World) GetRoom(id string) (room *Room) { room, ok := me.roommap[id] if !ok { return nil } return room } // Loads a Room to be used with this world. // If the room was already loaded, returns that in stead. func (me *World) LoadRoom(id string) (room *Room, err error) { room = me.GetRoom(id) if room != nil { return room, nil } room, err = LoadRoom(me.dirname, id) if err != nil { return room, err } me.roommap[room.ID] = room return room, nil } // Removes an item from this world by ID. func (me *World) RemoveRoom(id string) { _, have := me.roommap[id] if !have { return } delete(me.roommap, id) }