Previously, the indentation level was hardcoded everywhere. This was
tedious before in that changing the log structure would require changing
many manual indentation values. Now that objects can be trivially
generated at export time, the export code might be much more nested that
before. So, it's better to let indentation be more implicit. This,
therefore, adds a context manager to increase the indentation using
`with` blocks. Manual indentation specification remains for
compatibility with Python 2.2 where required.
This adds a page type distinction. It will primarily be geared toward
things like GUIs and avatar animations. However, for now, we can abuse
it to allow externally created pages, such as those created by PRPShop
hacking (for particles) or from 3dsMax (avatar animations, GUIs, etc.)
to coexist more easily with our Korman-generated .age files.
If a sound message was being sent to a random sound modifier, the
responder tree might crash on export. This fixes that particular problem
and adds a mitigation to the responder code itself. Remember kids that,
in Python `None and True` is `None`...
- The object the modifier is on is now the clickable (matches the
behavior of journals).
- Improved object selector icons.
- Automatically generate a clickable region.
- Alert if no camera is set.
These attributes are strings, not paths. It is safe to format with a
path -- paths are implicitly convertible to strings by formatters. We
use a `PurePath` because we only care about getting the string name and
not actually performing any path manipulation.
This was fixed in H-uru/libhsplasma#242 originally, but Win32 APIs seem
to have terrible performance without user mode buffering, which
negatively impacted PRP loading in other tools, such as PRP Shop.
Therefore, the fix was reverted in H-uru/libhsplasma#246. This fixes the
race condition closer to the point of impact using the Win32 stream
introduced by H-uru/libhsplasma#264.
If a wind object is *not* animated but rather moved via logic nodes (eg
a Python script), then the previous logic wouldn't allow for the in-game
wind direction to change. It's important to check if the wind object has
a coordinate interface (can it move?) instead of if it's animated (did
the artist move it?).
This fixes#334 by sorting everything before writing it out to the
localization file. Note that we need to sort each step along the way
because the nested dicts are not sorted by a call to `sorted()` - it
appears to only sort the key.
There were logic problems around exporting references to objects that
exist only in disabled pages (or default pages that are disabled because
no enabled objects are exported into the default page).