Closed DukeVen closed 1 year ago
In theory ==
should be enough
>>> import bsp_tool
>>> from bsp_tool.branches.valve import source
>>> source.Contents(source.ContentsMask.PLAYER_SOLID)
<Contents.SOLID|WINDOW|GRATE|MOVEABLE|PLAYER_CLIP|MONSTER: 33636363>
>>> _ == source.ContentsMask.PLAYER_SOLID # exact match
True
But in practice it isn't that simple
>>> bsp = bsp_tool.load_bsp("D:/SteamLibrary/steamapps/common/Team Fortress 2/tf/maps/pl_upward.bsp")
>>> any([b.contents == source.ContentsMask.PLAYER_SOLID for b in bsp.BRUSHES])
False
You have to check if any of the bits inside the ContentsMask
are set:
>>> # brush must have at least 1 of these flags:
>>> [c.name for c in source.Contents(source.ContentsMask.PLAYER_SOLID)]
['SOLID', 'WINDOW', 'GRATE', 'MOVEABLE', 'PLAYER_CLIP', 'MONSTER']
>>> [i for i, b in enumerate(bsp.BRUSHES) if b.contents & source.ContentsMask.PLAYER_SOLID != 0][:16]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
>>> {bsp.BRUSHES[i].contents for i in _}
{<Contents.SOLID: 1>}
This line is where the check happens:
>>> [i for i, b in enumerate(bsp.BRUSHES) if b.contents & source.ContentsMask.PLAYER_SOLID != 0][:16]
Breaking it down into 1 line per step:
for i, brush in enumerate(bsp.BRUSHES):
solid_flags = brush.contents & ContentsMask.PLAYER_SOLID # apply mask to Contents
if solid_flags != 0: # at least 1 flag is set
print(i) # this brush is solid to the player
Iterating over the contents of an enum.IntFlag
(like source.Contents
) is new in Python 3.11
You could use that do to something like:
PLAYER_SOLID = source.Contents(source.ContentsMask.PLAYER_SOLID)
any([flag in PLAYER_SOLID for flag in brush.contents])
which is a bit more human-readable, tho probably slower performance-wise
Thank you! Very helpful
I want compare the content of a brush with ContentsMask - PLAYER_SOLID , but I cant seem to figure out how exactly to do that. https://github.com/snake-biscuits/bsp_tool/blob/master/bsp_tool/branches/valve/source.py#L240