Skip to content

Commit 2b848de

Browse files
committed
Fix entity baseline problems
The previous implementation of entity-baselines was broken which resulted in wrong property values being sent out & stored on the entities (#25). It also fired multiple updates for values that didn't match the default value set in the baseline (#24) when an entity was created. Now there is only one update right after the entity is created and the values should be correct.
1 parent 6735b09 commit 2b848de

File tree

3 files changed

+22
-16
lines changed

3 files changed

+22
-16
lines changed

entities.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func (p *Parser) handlePacketEntities(pe *msg.CSVCMsg_PacketEntities) {
4040
e := p.readEnterPVS(r, currentEntity)
4141
p.entities[currentEntity] = e
4242
e.ApplyUpdate(r)
43+
e.ServerClass.FireEntityCreatedEvent(e)
4344
} else {
4445
// Delta Update
4546
p.entities[currentEntity].ApplyUpdate(r)
@@ -54,23 +55,19 @@ func (p *Parser) readEnterPVS(reader *bit.BitReader, entityID int) *st.Entity {
5455
reader.Skip(10) // Serial Number
5556

5657
newEntity := st.NewEntity(entityID, p.stParser.ServerClasses()[scID])
57-
newEntity.ServerClass.FireEntityCreatedEvent(newEntity)
5858

5959
if p.preprocessedBaselines[scID] != nil {
6060
for idx, val := range p.preprocessedBaselines[scID] {
6161
newEntity.Props()[idx].FirePropertyUpdate(val)
6262
}
6363
} else {
64-
ppBase := make(map[int]st.PropValue)
6564
if p.instanceBaselines[scID] != nil {
66-
newEntity.CollectProperties(&ppBase)
6765
r := bit.NewSmallBitReader(bytes.NewReader(p.instanceBaselines[scID]))
68-
newEntity.ApplyUpdate(r)
66+
p.preprocessedBaselines[scID] = newEntity.InitializeBaseline(r)
6967
r.Pool()
70-
// TODO: Unregister PropertyUpdateHandlers from CollectProperties()
71-
// PropertyUpdateHandlers would have to be registered as pointers for that to work
68+
} else {
69+
p.preprocessedBaselines[scID] = make(map[int]st.PropValue)
7270
}
73-
p.preprocessedBaselines[scID] = ppBase
7471
}
7572

7673
return newEntity

sendtables/entity.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,34 +97,39 @@ func readFieldIndex(reader *bit.BitReader, lastIndex int, newWay bool) int {
9797
return lastIndex + 1 + int(res)
9898
}
9999

100-
// CollectProperties registers PropertyUpdateHandlers on the Entitiy
101-
// that will update a 'preprocessedBasleine' map with the most recent values.
102-
// This is used if entities leave and re-enter the PVS as entities will be re-created at that point
103-
// and we can then take the map as baseline for the new entity.
104-
func (e *Entity) CollectProperties(ppBase *map[int]PropValue) {
100+
// InitializeBaseline applies an update and collects a baseline (default values) from the update.
101+
func (e *Entity) InitializeBaseline(r *bit.BitReader) map[int]PropValue {
102+
baseline := make(map[int]PropValue)
105103
for i := range e.props {
106104
i2 := i // Copy for the adder
107105
adder := func(val PropValue) {
108-
(*ppBase)[e.props[i2].index] = val
106+
baseline[i2] = val
109107
}
110108

111109
e.props[i].RegisterPropertyUpdateHandler(adder)
112110
}
111+
112+
e.ApplyUpdate(r)
113+
114+
for i := range e.props {
115+
e.props[i].updateHandlers = nil
116+
}
117+
118+
return baseline
113119
}
114120

115121
// NewEntity creates a new Entity with a given id and ServerClass and returns it.
116122
func NewEntity(id int, serverClass *ServerClass) *Entity {
117-
props := make([]PropertyEntry, 0, len(serverClass.FlattenedProps))
123+
props := make([]PropertyEntry, len(serverClass.FlattenedProps))
118124
for i := range serverClass.FlattenedProps {
119-
props = append(props, PropertyEntry{index: i, entry: &serverClass.FlattenedProps[i]})
125+
props[i] = PropertyEntry{entry: &serverClass.FlattenedProps[i]}
120126
}
121127
return &Entity{ID: id, ServerClass: serverClass, props: props}
122128
}
123129

124130
// PropertyEntry wraps a FlattenedPropEntry and allows registering handlers
125131
// that can be triggered on a update of the property.
126132
type PropertyEntry struct {
127-
index int
128133
entry *FlattenedPropEntry
129134
updateHandlers []PropertyUpdateHandler
130135
value PropValue

sendtables/sendtables.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ func (sc *ServerClass) FireEntityCreatedEvent(entity *Entity) {
4646
h(EntityCreatedEvent{Entity: entity, ServerClass: sc})
4747
}
4848
}
49+
50+
for _, v := range entity.props {
51+
v.FirePropertyUpdate(v.value)
52+
}
4953
}
5054

5155
// RegisterEntityCreatedHandler registers a EntityCreatedHandler on the ServerClass.

0 commit comments

Comments
 (0)