Skip to content

Support PVS visibility changes for entities #507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 80 additions & 50 deletions pkg/demoinfocs/sendtables2/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,14 +438,45 @@ func (e *Entity) readFields(r *reader, paths *[]*fieldPath) {
}
}

const (
updateFlagDelete = 0b10
updateFlagVisibleInPVS = 0b10000
)

type updateType = uint32

const (
updateTypeEnter updateType = iota
updateTypeLeave
updateTypeDelta
updateTypePreserve
)

func readEntityUpdateType(r *reader, hasVisBits uint32) (updateType, uint32) {
flags := r.readBits(2)
if flags&0x01 != 0 {
return updateTypeLeave, flags
}
if flags&0x02 != 0 {
return updateTypeEnter, flags
}
if hasVisBits != 0 {
flags = r.readBits(2) << 3
if flags&0x08 != 0 {
return updateTypePreserve, flags
}
}

return updateTypeDelta, flags
}

// Internal Callback for OnCSVCMsg_PacketEntities.
func (p *Parser) OnPacketEntities(m *msgs2.CSVCMsg_PacketEntities) error {
r := newReader(m.GetEntityData())

var (
index = int32(-1)
updates = int(m.GetUpdatedEntries())
cmd uint32
classId int32
serial int32
)
Expand All @@ -467,6 +498,7 @@ func (p *Parser) OnPacketEntities(m *msgs2.CSVCMsg_PacketEntities) error {
paths = make([]*fieldPath, 0)
)

hasVisBits := m.GetHasPvsVisBits()
for ; updates > 0; updates-- {
var (
e *Entity
Expand All @@ -476,64 +508,62 @@ func (p *Parser) OnPacketEntities(m *msgs2.CSVCMsg_PacketEntities) error {
next := index + int32(r.readUBitVar()) + 1
index = next

cmd = r.readBits(2)
if cmd == 0 && m.GetHasPvsVisBits() > 0 {
cmd = r.readBits(2) << 3
if cmd&0x08 == 8 {
continue
}
}
if cmd&0x01 == 0 {
if cmd&0x02 != 0 {
classId = int32(r.readBits(p.classIdSize))
serial = int32(r.readBits(17))
r.readVarUint32()

class := p.classesById[classId]
if class == nil {
_panicf("unable to find new class %d", classId)
}
updateType, flags := readEntityUpdateType(r, hasVisBits)
switch updateType {
case updateTypeEnter:
classId = int32(r.readBits(p.classIdSize))
serial = int32(r.readBits(17))
r.readVarUint32()

baseline := p.classBaselines[classId]
if baseline == nil {
_panicf("unable to find new baseline %d", classId)
}
class := p.classesById[classId]
if class == nil {
_panicf("unable to find new class %d", classId)
}

e = newEntity(index, serial, class)
p.entities[index] = e
baseline := p.classBaselines[classId]
if baseline == nil {
_panicf("unable to find new baseline %d", classId)
}

e.readFields(newReader(baseline), &paths)
paths = paths[:0]
e = newEntity(index, serial, class)
p.entities[index] = e

e.readFields(r, &paths)
paths = paths[:0]
e.readFields(newReader(baseline), &paths)
paths = paths[:0]

// Fire created-handlers so update-handlers can be registered
for _, h := range class.createdHandlers {
h(e)
}
e.readFields(r, &paths)
paths = paths[:0]

// Fire all post-creation actions
for _, f := range e.onCreateFinished {
f()
}
// Fire created-handlers so update-handlers can be registered
for _, h := range class.createdHandlers {
h(e)
}

op = st.EntityOpCreated | st.EntityOpEntered
} else {
if e = p.entities[index]; e == nil {
_panicf("unable to find existing entity %d", index)
}
// Fire all post-creation actions
for _, f := range e.onCreateFinished {
f()
}

op = st.EntityOpUpdated
if !e.active {
e.active = true
op |= st.EntityOpEntered
}
op = st.EntityOpCreated | st.EntityOpEntered
case updateTypeDelta:
if e = p.entities[index]; e == nil {
_panicf("unable to find existing entity %d", index)
}

e.readFields(r, &paths)
paths = paths[:0]
op = st.EntityOpUpdated
if !e.active {
e.active = true
op |= st.EntityOpEntered
}
} else {

e.readFields(r, &paths)
paths = paths[:0]
// todo: handle visibility
// visibleInPVS := hasVisBits == 0 || flags&updateFlagVisibleInPVS != 0
// fmt.Println("visible in pvs", visibleInPVS)
case updateTypePreserve:
// visibleInPVS := hasVisBits == 0 || flags&updateFlagVisibleInPVS != 0
case updateTypeLeave:
e = p.entities[index]
if e == nil {
continue
Expand All @@ -545,7 +575,7 @@ func (p *Parser) OnPacketEntities(m *msgs2.CSVCMsg_PacketEntities) error {
}

op = st.EntityOpLeft
if cmd&0x02 != 0 {
if flags&updateFlagDelete != 0 {
op |= st.EntityOpDeleted

e.Destroy()
Expand Down