Browse Source

Spring cleaning.

Beoran 8 years ago
parent
commit
10d4ccc743

+ 3 - 2
src/woe/server/client.go

@@ -93,7 +93,7 @@ func (me * Client) TryReadEvent(millis int) (event telnet.Event, timeout bool, c
     if millis >= 0 {
     if millis >= 0 {
         timerchan = time.Tick(time.Millisecond * time.Duration(millis))
         timerchan = time.Tick(time.Millisecond * time.Duration(millis))
     } else {
     } else {
-        /* If tiome is negative, block by using a fake time channel that never gets sent anyting */
+        /* If time is negative, block by using a fake time channel that never gets sent anyting */
         timerchan = make(<-chan(time.Time))
         timerchan = make(<-chan(time.Time))
     }
     }
     
     
@@ -142,7 +142,8 @@ func (me * Client) Serve() (err error) {
     }
     }
     if (!me.AccountDialog()) {
     if (!me.AccountDialog()) {
         time.Sleep(3); 
         time.Sleep(3); 
-        // sleep so output gets flushed, hopefully. Also slow down brute force attacks.
+        // sleep so output gets flushed, hopefully.
+        // Also slow down brute force attacks.
         me.Close()
         me.Close()
         return nil
         return nil
     }
     }

+ 5 - 5
src/woe/server/server.go

@@ -75,7 +75,7 @@ type Server struct {
     clients map[int]    * Client 
     clients map[int]    * Client 
     tickers map[string] * Ticker
     tickers map[string] * Ticker
     alive                 bool
     alive                 bool
-    World               * world.World             
+    World               * world.World
 }
 }
 
 
 
 
@@ -120,10 +120,11 @@ func (me * Server) SetupWorld() error {
 func NewServer(address string) (server * Server, err error) {
 func NewServer(address string) (server * Server, err error) {
     listener, err := net.Listen("tcp", address);
     listener, err := net.Listen("tcp", address);
     if (err != nil) { 
     if (err != nil) { 
+        io.Printf("")
         return nil, err
         return nil, err
     }
     }
     
     
-    logfile, err := os.OpenFile("log.woe", os.O_WRONLY | os.O_APPEND | os.O_CREATE, 0660) 
+    logfile, err := os.OpenFile("log.woe", os.O_WRONLY | os.O_APPEND | os.O_CREATE, 0660)
     if (err != nil) {
     if (err != nil) {
         return nil, err
         return nil, err
     }
     }
@@ -132,11 +133,10 @@ func NewServer(address string) (server * Server, err error) {
     clients := make(map[int] * Client)
     clients := make(map[int] * Client)
     tickers := make(map[string] * Ticker)
     tickers := make(map[string] * Ticker)
 
 
-    server = &Server{address, listener, logger, logfile, clients, tickers, true, nil}    
+    server = &Server{address, listener, logger, logfile, clients, tickers, true, nil}
     err = server.SetupWorld()
     err = server.SetupWorld()
     server.AddDefaultTickers()
     server.AddDefaultTickers()
     
     
-    
     return server, err
     return server, err
 }
 }
 
 
@@ -233,7 +233,7 @@ func (me * Server) findFreeID() (id int, err error) {
 func (me * Server) onConnect(conn net.Conn) (err error) {
 func (me * Server) onConnect(conn net.Conn) (err error) {
     id, err := me.findFreeID()
     id, err := me.findFreeID()
     if err != nil {
     if err != nil {
-        monolog.Info("Refusing connection because no ID is available for %s. ", conn.RemoteAddr().String())
+        monolog.Info("Refusing connection for %s: too many clients. ", conn.RemoteAddr().String())
         conn.Close()
         conn.Close()
         return nil
         return nil
     }
     }

+ 44 - 71
src/woe/telnet/telnet.go

@@ -8,7 +8,7 @@ import "compress/zlib"
 import "github.com/beoran/woe/monolog"
 import "github.com/beoran/woe/monolog"
 
 
 
 
-// This Telnet struct implements a subset of the Telnet protocol.
+// This Telnet module implements a subset of the Telnet protocol.
 
 
 // Telnet states
 // Telnet states
 type TelnetState int
 type TelnetState int
@@ -25,26 +25,45 @@ const (
     sb_data_iac_state       = iota
     sb_data_iac_state       = iota
 )
 )
 
 
+// Telnet event type constants
+type EventType int
 
 
+const (
+    TELNET_DATA_EVENT           EventType =  iota
+    TELNET_NAWS_EVENT           EventType =  iota
+    TELNET_TTYPE_EVENT          EventType =  iota
+    TELNET_SUBNEGOTIATE_EVENT   EventType =  iota
+    TELNET_IAC_EVENT            EventType =  iota
+    TELNET_COMPRESS_EVENT       EventType =  iota
+    TELNET_ENVIRONMENT_EVENT    EventType =  iota
+    TELNET_MSSP_EVENT           EventType =  iota
+    TELNET_ZMP_EVENT            EventType =  iota
+    TELNET_WILL_EVENT           EventType =  iota
+    TELNET_WONT_EVENT           EventType =  iota
+    TELNET_DO_EVENT             EventType =  iota
+    TELNET_DONT_EVENT           EventType =  iota
+    TELNET_ERROR_EVENT          EventType =  iota
+    TELNET_UNKNOWN_EVENT        EventType =  iota
+)
 
 
 // Telnet event types
 // Telnet event types
 
 
 type Event interface {
 type Event interface {
-    isEvent()
+    Type() EventType
 }
 }
 
 
 type DataEvent struct {
 type DataEvent struct {
     Data [] byte
     Data [] byte
 }
 }
 
 
-func (me DataEvent) isEvent() {}
+func (me DataEvent) Type() EventType { return TELNET_DATA_EVENT; }
 
 
 type NAWSEvent struct {
 type NAWSEvent struct {
     W   int
     W   int
     H   int
     H   int
 }
 }
 
 
-func (me NAWSEvent) isEvent() {}
+func (me NAWSEvent) Type() EventType { return TELNET_NAWS_EVENT; }
 
 
 
 
 type TTypeEvent struct {
 type TTypeEvent struct {
@@ -52,7 +71,7 @@ type TTypeEvent struct {
     Name    string
     Name    string
 }
 }
 
 
-func (me TTypeEvent) isEvent() {}
+func (me TTypeEvent) Type() EventType { return TELNET_TTYPE_EVENT; }
 
 
 
 
 type SubnegotiateEvent struct {
 type SubnegotiateEvent struct {
@@ -60,24 +79,24 @@ type SubnegotiateEvent struct {
     Buffer [] byte
     Buffer [] byte
 }
 }
 
 
-func (me SubnegotiateEvent) isEvent() {}
+func (me SubnegotiateEvent) Type() EventType { return TELNET_SUBNEGOTIATE_EVENT; }
 
 
 
 
 type IACEvent struct {
 type IACEvent struct {
     Telopt    byte
     Telopt    byte
 }
 }
 
 
-func (me IACEvent) isEvent() {}
+func (me IACEvent) Type() EventType { return TELNET_IAC_EVENT; }
 
 
 
 
 type CompressEvent struct {
 type CompressEvent struct {
     Compress  bool
     Compress  bool
 }
 }
 
 
-func (me CompressEvent) isEvent() {}
+func (me CompressEvent) Type() EventType { return TELNET_COMPRESS_EVENT; }
 
 
 
 
-//Storage for environment values
+// Storage for environment values
 type Environment struct {
 type Environment struct {
     Type byte
     Type byte
     Value string
     Value string
@@ -89,7 +108,7 @@ type EnvironmentEvent struct {
     Vars      [] Environment
     Vars      [] Environment
 }
 }
 
 
-func (me EnvironmentEvent) isEvent() {}
+func (me EnvironmentEvent) Type() EventType { return TELNET_ENVIRONMENT_EVENT; }
 
 
 
 
 type MSSPEvent struct {
 type MSSPEvent struct {
@@ -97,95 +116,52 @@ type MSSPEvent struct {
     Vars      map[string] string
     Vars      map[string] string
 }
 }
 
 
-func (me MSSPEvent) isEvent() {}
+func (me MSSPEvent) Type() EventType { return TELNET_MSSP_EVENT; }
 
 
 
 
 type ZMPEvent struct {
 type ZMPEvent struct {
     Vars      []string
     Vars      []string
 }
 }
 
 
-func (me ZMPEvent) isEvent() {}
+func (me ZMPEvent) Type() EventType { return TELNET_ZMP_EVENT; }
 
 
 type WillEvent struct {
 type WillEvent struct {
     Telopt byte
     Telopt byte
 }
 }
 
 
-func (me WillEvent) isEvent() {}
+func (me WillEvent) Type() EventType { return TELNET_WILL_EVENT; }
 
 
 type WontEvent struct {
 type WontEvent struct {
     Telopt byte
     Telopt byte
 }
 }
 
 
-func (me WontEvent) isEvent() {}
+func (me WontEvent) Type() EventType { return TELNET_WONT_EVENT; }
 
 
 
 
 type DoEvent struct {
 type DoEvent struct {
     Telopt byte
     Telopt byte
 }
 }
 
 
-func (me DoEvent) isEvent() {}
+func (me DoEvent) Type() EventType { return TELNET_DO_EVENT; }
 
 
 type DontEvent struct {
 type DontEvent struct {
     Telopt byte
     Telopt byte
 }
 }
 
 
-func (me DontEvent) isEvent() {}
+func (me DontEvent) Type() EventType { return TELNET_DONT_EVENT; }
 
 
 
 
-// Telnet event type constants
-type EventType int
+// For protocol errors.
+type ErrorEvent struct {
+    error string
+}
 
 
-const (
-    TELNET_DATA_EVENT           EventType =  iota
-    TELNET_NAWS_EVENT           EventType =  iota
-    TELNET_TTYPE_EVENT          EventType =  iota
-    TELNET_SUBNEGOTIATE_EVENT   EventType =  iota
-    TELNET_IAC_EVENT            EventType =  iota
-    TELNET_COMPRESS_EVENT       EventType =  iota
-    TELNET_ENVIRONMENT_EVENT    EventType =  iota
-    TELNET_MSSP_EVENT           EventType =  iota
-    TELNET_ZMP_EVENT            EventType =  iota
-    TELNET_WILL_EVENT           EventType =  iota
-    TELNET_WONT_EVENT           EventType =  iota
-    TELNET_DO_EVENT             EventType =  iota
-    TELNET_DONT_EVENT           EventType =  iota
-    TELNET_UNKNOWN_EVENT        EventType =  iota
-)
+func (me ErrorEvent) Type() EventType { return TELNET_ERROR_EVENT; }
 
 
 
 
-/* Returns the numerical event type of an event. Useful for direct comparison. */
+// Returns the numerical event type of an event. Useful for direct comparison.
 func EventTypeOf(event Event) EventType {
 func EventTypeOf(event Event) EventType {
-    switch event.(type) {
-        case DataEvent, *DataEvent:
-            return TELNET_DATA_EVENT
-        case NAWSEvent, *NAWSEvent:
-            return TELNET_NAWS_EVENT
-        case TTypeEvent, *TTypeEvent:
-            return TELNET_TTYPE_EVENT
-        case SubnegotiateEvent, *SubnegotiateEvent:
-            return TELNET_SUBNEGOTIATE_EVENT
-        case IACEvent, *IACEvent:
-            return TELNET_IAC_EVENT
-        case CompressEvent, *CompressEvent:
-            return TELNET_COMPRESS_EVENT
-        case EnvironmentEvent, *EnvironmentEvent:
-            return TELNET_ENVIRONMENT_EVENT
-        case MSSPEvent, *MSSPEvent:
-            return TELNET_MSSP_EVENT
-        case ZMPEvent, *ZMPEvent:
-            return TELNET_ZMP_EVENT
-        case WillEvent, *WillEvent:
-            return TELNET_WILL_EVENT
-        case WontEvent, *WontEvent:
-            return TELNET_WONT_EVENT
-        case DoEvent, *DoEvent:
-            return TELNET_DO_EVENT
-        case DontEvent, *DontEvent:
-            return TELNET_DONT_EVENT
-        default:
-            monolog.Error("Unknown event type %T %v", event, event)
-            return TELNET_UNKNOWN_EVENT
-    }
+    return event.Type()
 }
 }
 
 
 // Returns true if the event is of the given type, or false if not
 // Returns true if the event is of the given type, or false if not
@@ -193,7 +169,6 @@ func IsEventType(event Event, typ EventType) bool {
     return EventTypeOf(event) == typ;
     return EventTypeOf(event) == typ;
 }
 }
 
 
-
 type EventChannel chan(Event)
 type EventChannel chan(Event)
 
 
 
 
@@ -206,8 +181,8 @@ type Telopt struct {
 type Telnet struct { 
 type Telnet struct { 
   Events            EventChannel
   Events            EventChannel
   ToClient          chan([]byte)
   ToClient          chan([]byte)
-  telopts map[byte] Telopt 
-  state             TelnetState 
+  telopts map[byte] Telopt
+  state             TelnetState
   compress          bool
   compress          bool
   zwriter           zlib.Writer
   zwriter           zlib.Writer
   zreader           io.ReadCloser
   zreader           io.ReadCloser
@@ -216,7 +191,6 @@ type Telnet struct {
 }
 }
 
 
 func New() (telnet * Telnet) {
 func New() (telnet * Telnet) {
-    
     events     := make(EventChannel, 64)
     events     := make(EventChannel, 64)
     toclient   := make(chan([]byte), 64)
     toclient   := make(chan([]byte), 64)
     telopts    := make (map[byte] Telopt)
     telopts    := make (map[byte] Telopt)
@@ -501,7 +475,6 @@ func (me * Telnet) maybeSendDataEventAndEmptyBuffer() {
 }
 }
 
 
 // Append a byte to the data buffer
 // Append a byte to the data buffer
-// Also empties the buffer if it wasn't emmpty
 func (me * Telnet) appendByte(bin byte) {
 func (me * Telnet) appendByte(bin byte) {
     monolog.Debug("Appending to telnet buffer: %d %d", len(me.buffer), cap(me.buffer))
     monolog.Debug("Appending to telnet buffer: %d %d", len(me.buffer), cap(me.buffer))
     me.buffer = append(me.buffer, bin)
     me.buffer = append(me.buffer, bin)

+ 1 - 0
src/woe/woe.go

@@ -13,6 +13,7 @@ func main() {
     monolog.Info("Server runs at port %d!", 7000)
     monolog.Info("Server runs at port %d!", 7000)
     woe, err := server.NewServer(":7000")
     woe, err := server.NewServer(":7000")
     if err != nil {
     if err != nil {
+        monolog.Error(err.Error())
         panic(err)
         panic(err)
     }
     }
     defer woe.Close()
     defer woe.Close()

+ 9 - 9
src/woe/world/being.go

@@ -139,8 +139,8 @@ with techniques`,
         // AGI+1 EMO+1 STR-1 TOU-1 
         // AGI+1 EMO+1 STR-1 TOU-1 
         Talents : Talents { Strength : -1, Toughness: -1, 
         Talents : Talents { Strength : -1, Toughness: -1, 
             Agility : 1, Emotion : 1, },
             Agility : 1, Emotion : 1, },
-        Arts        : 1.5,
-        Techniques  : 0.5,
+        Arts        : 1.2,
+        Techniques  : 0.8,
         Playable    : true,
         Playable    : true,
     },
     },
     {   Entity: Entity {
     {   Entity: Entity {
@@ -173,7 +173,7 @@ is not as effective on them, but they can be repaired.`,
         Talents : Talents { Strength : +1, Toughness: +1, 
         Talents : Talents { Strength : +1, Toughness: +1, 
             Dexterity : +1, Intelligence: +1, },
             Dexterity : +1, Intelligence: +1, },
         Arts : 0.5,
         Arts : 0.5,
-        Techniques : 1.25,
+        Techniques : 1.5,
         Mechanical : 0.5,
         Mechanical : 0.5,
         Playable : true,
         Playable : true,
     },
     },
@@ -189,7 +189,7 @@ any Nummen arts. Since thay are not alive, they technically cannot die.`,
         Talents : Talents { Strength : +2, Toughness: +2, 
         Talents : Talents { Strength : +2, Toughness: +2, 
             Dexterity : +2, Intelligence: +2, },
             Dexterity : +2, Intelligence: +2, },
         Arts : 0.0,
         Arts : 0.0,
-        Techniques : 1.5,
+        Techniques : 2.0,
         Mechanical : 1.0,
         Mechanical : 1.0,
         Playable : true,
         Playable : true,
     },
     },
@@ -207,7 +207,7 @@ technically cannot die.  They are feared by Humans and hated by Androids.`,
         Talents : Talents { Strength : +3, Toughness: +3, 
         Talents : Talents { Strength : +3, Toughness: +3, 
             Dexterity : +2, Intelligence: +2, Charisma: -2 },
             Dexterity : +2, Intelligence: +2, Charisma: -2 },
         Arts : 0.0,
         Arts : 0.0,
-        Techniques : 1.5,
+        Techniques : 2.0,
         Mechanical : 1.0,
         Mechanical : 1.0,
         Playable : false,
         Playable : false,
     },
     },
@@ -215,7 +215,7 @@ technically cannot die.  They are feared by Humans and hated by Androids.`,
     
     
     {   Entity: Entity {
     {   Entity: Entity {
             ID: "kin_robot", Name: "Robot",
             ID: "kin_robot", Name: "Robot",
-            Short: "Nonconscious mechanical robot. ",
+            Short: "Non conscious mechanical robot.",
             Long: 
             Long: 
 `In the wars of the past many robots were built for offense or defense. 
 `In the wars of the past many robots were built for offense or defense. 
 Unfortunately, they are self repairing and often even able to replicate 
 Unfortunately, they are self repairing and often even able to replicate 
@@ -226,7 +226,7 @@ the Earth millennia after.`,
         Talents : Talents { Strength : +4, Toughness: +4, 
         Talents : Talents { Strength : +4, Toughness: +4, 
             Dexterity : +2, Intelligence: +2, Charisma: -4},
             Dexterity : +2, Intelligence: +2, Charisma: -4},
         Arts : 0.0,
         Arts : 0.0,
-        Techniques : 1.5,
+        Techniques : 2.0,
         Mechanical: 1.0,
         Mechanical: 1.0,
         Playable : false,
         Playable : false,
     },
     },
@@ -242,7 +242,7 @@ They might be less though than normal robots, but they move extremely quickly.
         Talents : Talents { Strength : +2, Toughness: +2, 
         Talents : Talents { Strength : +2, Toughness: +2, 
             Agility: +4, Dexterity : +2, Intelligence: +2, Charisma: -4},
             Agility: +4, Dexterity : +2, Intelligence: +2, Charisma: -4},
         Arts : 0.0,
         Arts : 0.0,
-        Techniques : 1.5,
+        Techniques : 2.0,
         Mechanical : 1.0,
         Mechanical : 1.0,
         Playable : false,
         Playable : false,
 
 
@@ -261,7 +261,7 @@ No wonder they are still actve after all these years.
         Talents : Talents { Strength : +2, Toughness: +4, 
         Talents : Talents { Strength : +2, Toughness: +4, 
             Agility: -4, Dexterity : +4, Intelligence: +4, Charisma: -4},
             Agility: -4, Dexterity : +4, Intelligence: +4, Charisma: -4},
         Arts : 0.0,
         Arts : 0.0,
-        Techniques : 1.5,
+        Techniques : 2.0,
         Mechanical : 1.0,
         Mechanical : 1.0,
         Playable : false,
         Playable : false,
     },
     },

+ 2 - 2
src/woe/world/entity.go

@@ -5,14 +5,14 @@ import "encoding/xml"
 
 
 
 
 
 
-// Anything insdie the WOE World can be identified by a unique short string 
+// Anything inside the WOE World can be identified by a unique short string 
 // description, the Label
 // description, the Label
 type Labeled interface {
 type Labeled interface {
     Label() string // Returns a unique label of the thing.
     Label() string // Returns a unique label of the thing.
 }
 }
 
 
 type Typed interface {
 type Typed interface {
-    Type() string // Returns a tring description of the type of the thing. 
+    Type() string // Returns a string description of the type of the thing. 
 }
 }
 
 
 
 

+ 11 - 7
src/woe/world/item.go

@@ -166,19 +166,23 @@ type Item struct {
     Price         int
     Price         int
     Kind          ItemKind
     Kind          ItemKind
     Damage        DamageKind
     Damage        DamageKind
-    // equipment location,  "none" if not equippable
+    // Equipment location,  "none" if not equippable
     Equippable    EquipWhere
     Equippable    EquipWhere
-    // Level of crafing skill needed to craft this, or of harvesting skill to harvest this, 
-    // or of mining skill to mine this. Negative if cannot be crafted nor harvested, nor mined.    
+    // Level of crafing skill needed to craft this, or of harvesting skill 
+    // to harvest this, or of mining skill to mine this. Negative if cannot 
+    // be crafted nor harvested, nor mined.    
     Level         int
     Level         int
     // Id's of ingredients to craft this item. Empty if it cannot be crafted.
     // Id's of ingredients to craft this item. Empty if it cannot be crafted.
     Ingredients []ID
     Ingredients []ID
-    // Id of item this item can be upgraded/enhanced to. empty or "none" if cannot be upgraded.
+    // Id of item this item can be upgraded/enhanced to. empty or "none"
+    // if it cannot be upgraded.
     Upgrade       ID
     Upgrade       ID
-    // ID of item this item can degrade into. empty or "none" if cannot be degraded.
+    // ID of item this item can degrade into. empty or "none" if cannot be 
+    // degraded.
     Degrade       ID
     Degrade       ID
-    // ID of technique/art/item to craft this item teaches when used, empty or none if it teaches nothing.
-    // If it'ss a skill, the XP of teaching is determine by the Quality of the item.   
+    // ID of technique/art/item to craft this item teaches when used, empty or 
+    // none if it teaches nothing. If it's a skill, the XP of teaching is 
+    // determined by the Quality of the item.   
     Teaches       ID
     Teaches       ID
 }
 }
 
 

+ 2 - 2
src/woe/world/room.go

@@ -4,9 +4,9 @@ package world
 type Direction  string
 type Direction  string
 
 
 type Exit struct {
 type Exit struct {
-    Direction 
+    Direction
     ToRoomID    int
     ToRoomID    int
-    toRoom    * Room         
+    toRoom    * Room
 }
 }
 
 
 type Room struct {
 type Room struct {

+ 21 - 63
src/woe/world/world.go

@@ -4,11 +4,11 @@ import "os"
 import "encoding/xml"
 import "encoding/xml"
 import "github.com/beoran/woe/monolog"
 import "github.com/beoran/woe/monolog"
 
 
-/* Ekements of the WOE game world.  
+/* Elements of the WOE game world.  
  * Only Zones, Rooms and their Exits, Items, 
  * Only Zones, Rooms and their Exits, Items, 
  * Mobiles & Characters are saved
  * Mobiles & Characters are saved
  * and loaded from disk. All the rest 
  * and loaded from disk. All the rest 
- * is kept statically delared in code for simplocoty.
+ * is kept statically delared in code for simplicity.
 */
 */
 
 
 /* ID used for anything in a world but the world itself and the account. */
 /* ID used for anything in a world but the world itself and the account. */
@@ -16,66 +16,23 @@ type ID string
 
 
 
 
 type World struct {
 type World struct {
-    Name                 string
-    ZoneIDS         []   ID
-    zones           [] * Zone
-    CharacterIDS    []   ID
-    characters      [] * Character
-    MOTD                 string
-    
-    /* Skills, etc that exist in this world */
-    genders         map[ID] *Gender    
-    kins            map[ID] *Kin
-    professions     map[ID] *Job
-    skills          map[ID] *Skill
-    arts            map[ID] *Art
-    techniques      map[ID] *Technique
-    exploits        map[ID] *Exploit
-    
-    /* Botha array and map are needed for serialization. */
-    Genders         [] Gender
-    Kins            [] Kin
-    Jobs     [] Job
-    Skills          [] Skill
-    Arts            [] Art
-    Techniques      [] Technique
-    Exploits        [] Exploit
-        
+    Name                      string
+    MOTD                      string
+    entitymap       map[ID] * Entity
+    zonemap         map[ID] * Zone
+    zones                [] * Zone
+    charactermap    map[ID] * Character
+    characters           []   Character
+    roommap         map[ID] * Room
+    rooms                []   Room
+    itemmap         map[ID] * Item
+    items                []   Item
+    mobilemap       map[ID] * Mobile
+    mobiles              []   Mobile
 }
 }
 
 
 
 
 
 
-func (me * World) AddKin(toadd * Kin) {
-    me.kins[toadd.ID] = toadd
-    me.Kins = append(me.Kins, *toadd)
-}
-
-func (me * World) AddJob(toadd * Job) {
-    me.professions[toadd.ID] = toadd
-    me.Jobs = append(me.Jobs, *toadd)
-}
-
-func (me * World) AddSkill(toadd * Skill) {
-    me.skills[toadd.ID] = toadd
-    me.Skills = append(me.Skills, *toadd)
-}
-
-func (me * World) AddArt(toadd * Art) {
-    me.arts[toadd.ID] = toadd
-    me.Arts = append(me.Arts, *toadd)
-}
-
-func (me * World) AddTechnique(toadd * Technique) {
-    me.techniques[toadd.ID] = toadd
-    me.Techniques = append(me.Techniques, *toadd)
-}
-
-func (me * World) AddExploit(toadd * Exploit) {
-    me.exploits[toadd.ID] = toadd
-    me.Exploits = append(me.Exploits, *toadd)
-}
-
-
 func (me * World) AddWoeDefaults() {
 func (me * World) AddWoeDefaults() {
     /*
     /*
     me.AddSpecies(NewSpecies("sp_human"  , "Human"))
     me.AddSpecies(NewSpecies("sp_human"  , "Human"))
@@ -90,7 +47,6 @@ func NewWorld(name string, motd string) (*World) {
     world := new(World)
     world := new(World)
     world.Name = name
     world.Name = name
     world.MOTD = motd
     world.MOTD = motd
-    world.kins = make(map[ID] *Kin)
     
     
     world.AddWoeDefaults()
     world.AddWoeDefaults()
     return world;
     return world;
@@ -104,11 +60,14 @@ func HaveID(ids [] ID, id ID) bool {
     return false
     return false
 }
 }
 
 
+func (me * World) AddEntity(entity * Entity) {
+    me.entitymap[entity.ID] = entity;
+}
+
 func (me * World) AddZone(zone * Zone) {
 func (me * World) AddZone(zone * Zone) {
     me.zones = append(me.zones, zone)
     me.zones = append(me.zones, zone)
-    if (!HaveID(me.ZoneIDS, zone.ID)) {
-        me.ZoneIDS = append(me.ZoneIDS, zone.ID)
-    }    
+    me.zonemap[zone.ID] = zone;
+    me.AddEntity(&zone.Entity);
 }
 }
 
 
 func (me * World) Save(dirname string) (err error) {
 func (me * World) Save(dirname string) (err error) {
@@ -129,7 +88,6 @@ func (me * World) Save(dirname string) (err error) {
 }
 }
 
 
 func (me * World) onLoad() {
 func (me * World) onLoad() {
-    for _, v := range me.Kins {me.kins[v.ID] = &v }
 }
 }
 
 
 func LoadWorld(dirname string, name string) (result *World, err error) {
 func LoadWorld(dirname string, name string) (result *World, err error) {

+ 1 - 1
woe.geany

@@ -44,7 +44,7 @@ FILE_NAME_16=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld
 FILE_NAME_17=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fitem.go;0;4
 FILE_NAME_17=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fitem.go;0;4
 FILE_NAME_18=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fmobile.go;0;4
 FILE_NAME_18=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fmobile.go;0;4
 FILE_NAME_19=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Froom.go;0;4
 FILE_NAME_19=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Froom.go;0;4
-FILE_NAME_20=5576;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fskill.go;0;4
+FILE_NAME_20=8284;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fskill.go;0;4
 FILE_NAME_21=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Ftechnique.go;0;4
 FILE_NAME_21=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Ftechnique.go;0;4
 FILE_NAME_22=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fworld.go;0;4
 FILE_NAME_22=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fworld.go;0;4
 FILE_NAME_23=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fzone.go;0;4
 FILE_NAME_23=0;Go;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fwoe%2Fworld%2Fzone.go;0;4