-
Notifications
You must be signed in to change notification settings - Fork 0
/
zone.go
133 lines (120 loc) · 3.84 KB
/
zone.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package spaces
import (
"errors"
"fmt"
"github.com/trasa/watchmud/mobile"
"github.com/trasa/watchmud/object"
"github.com/trasa/watchmud/zonereset"
"log"
"time"
)
type Zone struct {
Id string
Rooms map[string]*Room
ObjectDefinitions map[string]*object.Definition // id (no zone) -> object.Definition
MobileDefinitions map[string]*mobile.Definition // id -> mobile.Definition
Name string
Commands []ZoneCommand
ResetMode zonereset.Mode
LastReset time.Time
Lifetime time.Duration
}
func NewZone(id string, name string, resetMode zonereset.Mode, lifetime time.Duration) *Zone {
return &Zone{
Id: id,
Name: name,
Rooms: make(map[string]*Room),
ObjectDefinitions: make(map[string]*object.Definition),
MobileDefinitions: make(map[string]*mobile.Definition),
ResetMode: resetMode,
Lifetime: lifetime,
}
}
func (z *Zone) AddRoom(r *Room) {
r.Zone = z
z.Rooms[r.Id] = r
}
func (z *Zone) AddObjectDefinition(obj *object.Definition) {
obj.ZoneId = z.Id
z.ObjectDefinitions[obj.Identifier()] = obj
}
func (z *Zone) AddMobileDefinition(mob *mobile.Definition) {
mob.ZoneId = z.Id
z.MobileDefinitions[mob.Id] = mob
}
func (z *Zone) AddCommand(c ZoneCommand) {
z.Commands = append(z.Commands, c)
}
func (z *Zone) String() string {
return fmt.Sprintf("(Zone %s: '%s')", z.Id, z.Name)
}
func (z *Zone) Reset(mobileRoomMap *MobileRoomMap) (errors []error) {
log.Printf("Zone '%s': Reset", z.Name)
for _, cmd := range z.Commands {
switch cmd.(type) {
case CreateMobile:
var err error
if err = z.createMobile(mobileRoomMap, cmd.(CreateMobile)); err != nil {
log.Printf("Error processing CreateMobileCommand: %s - %s", cmd, err)
errors = append(errors, err)
}
case CreateObject:
var err error
if err = z.createObject(cmd.(CreateObject)); err != nil {
log.Printf("Error processing CreateObjectCommand: %s - %s", cmd, err)
errors = append(errors, err)
}
default:
log.Printf("Error: zone %s unhandled Zone Command Type: %s", z.Id, cmd)
}
}
z.LastReset = time.Now()
return nil
}
// Create a mobile. If there was an error, return error.
func (z *Zone) createMobile(mobileRoomMap *MobileRoomMap, cmd CreateMobile) error {
// TODO determine how many of the definition are in the zone
defn := z.MobileDefinitions[cmd.MobileDefinitionId]
if defn == nil {
return errors.New(fmt.Sprintf("createMobile: definition id not found: %s", cmd))
}
// how many of this mobile definition id are in the zone?
if mobileRoomMap.GetMobileDefinitionCount(defn.Id) < cmd.InstanceMax {
r := z.Rooms[cmd.RoomId]
if r == nil {
return errors.New(fmt.Sprintf("createMobile: room not found: %s", cmd))
}
log.Printf("Creating mobile: %s", defn.Id)
mobileRoomMap.Add(mobile.NewInstance(defn), r)
}
return nil
}
// Create an object and put it in a room. If there was an error, return the error.
func (z *Zone) createObject(cmd CreateObject) error {
defn := z.ObjectDefinitions[cmd.ObjectDefinitionId]
if defn == nil {
return errors.New(fmt.Sprintf("createObject: definition id not found: %s", cmd))
}
r := z.Rooms[cmd.RoomId]
if r == nil {
return errors.New(fmt.Sprintf("createObject: room not found: %s", cmd))
}
// Note that the amount only deals with how many are in the room (on the floor
// so to speak) - not lying around attached to mobs, other players, and so on.
count := 0
// TODO not the most efficient way of figuring this out ..
for _, inst := range r.GetAllInventory() {
if inst.Definition.Identifier() == cmd.ObjectDefinitionId {
// found one
count++
}
}
if count >= cmd.InstanceMax {
log.Printf("Room %s has %d %s, max is %d (not creating more objects)",
r.Id,
count, cmd.ObjectDefinitionId,
cmd.InstanceMax)
return nil
}
return r.AddInventory(object.NewInstance(defn))
}