areaLand and areaWater were created with a MapBoundsPlacer, which
evaluates the tileclass constraint on every tile of the map. However,
createArea only has an effect if either a painter is specified or the
returned Area is used. Here no painter was passed and the returned
values were never read, so these calls did nothing except waste time.
If a point at squared distance 0 is found, no closer point can exist, so
return it immediately instead of scanning the rest of the points. The
returned point is the same as before, since the first point with the
smallest distance was already the one kept.
Iterate with an indexed loop over a local reference to the points array
instead of for...of over this.points, which avoids iterator and property
lookup overhead in a loop that can run over thousands of points.
Every neighbor sample created a new Vector2D and went through
validHeight() and getHeight(). Use plain integer coordinates, an inline
bounds check and direct access to the height array instead, which also
removes the per-vertex allocation and the setHeight() call.
The distance of each brush point and the check for the center vertex
were recomputed for every vertex. Compute them once per paint() call
into typed arrays instead.
Replace the array of Uint8Arrays, which was rebuilt with fill().map()
on every iteration, by one flat Uint8Array that is allocated once and
cleared at the start of each iteration.
The clone of g_Map.height was only used to read its length, while all
neighbor heights are read from g_Map itself. Cloning the whole heightmap
on every iteration was therefore pure overhead.
Audio files referenced directly in GUI/simulation JS strings
(e.g. g_FlareSound, soundfile entries, Ambient tracks) were not
tracked. Add a js_audio_regex scan alongside the existing sprite
scan for both gui/ and simulation/ JS files.
Several categories of session UI textures were falsely reported as
unused because checkrefs only parsed XML/JSON data files and missed
texture references buried in JavaScript runtime logic.
Entity templates:
- Parse <Identity><Rank> to track session/icons/ranks/{rank}.png
- Parse <Minimap><Icon> to track session/icons/minimap/{icon}.png
Data-driven JSON files:
- Add add_resources(): scan simulation/data/resources/*.json for
resource 'code' fields -> session/icons/resources/{code}.png
- Add add_status_effects(): scan simulation/data/status_effects/*.json
for 'icon' fields -> session/icons/status_effects/{icon}.png
Technology files:
- In add_techs(): detect phase_*.json base techs (e.g. phase_city.json)
and add session/panel_phase_emblems_{phase}.png as a dep
JS scanning (extended):
- Extend the GUI JS literal-path regex to also recognise:
- 'texture:' sprite modifier prefix
- full 'art/textures/ui/...' literal paths
- bare 'session/...' paths used as runtime sprite components
- Also scan simulation/components, simulation/helpers and globalscripts
JS files (registered as roots) with the same regex so textures
referenced from simulation code are tracked
- Add _add_unit_action_icon_deps(): parse unit_actions.js for
'icon': 'X.png' properties -> session/icons/X
- Add _add_status_bar_icon_deps(): parse StatusBars.js AddBar() calls
for bar type strings -> session/icons/{type}_bg/fg.png
- Add _add_stance_icon_deps(): parse g_Stances in UnitAI.js for
selectable stance keys -> session/icons/stances/{stance}.png
Two sources of false-positive unused-file warnings:
1. Literal stretched:/cropped: sprite paths in GUI JS files (e.g.
bell_level0.png, cancel.png, minimap flare textures) were never
tracked because JS is not parsed for texture deps. Add a regex scan
of gui/*.js for complete literal sprite paths ending in a known
texture extension, filtering out dynamic string concatenations
(+ / ${...}).
2. Per-civ background circle textures (bkg/background_circle_<code>.png)
are constructed at runtime in MiniMapPanel.js via a template literal
using the player civ code. Add a dep from each civ JSON to its
corresponding background circle texture.
Icons defined in setup XML files (e.g. lobby/icons/public.xml) have
sprite attributes that reference UI textures, but the setup parser only
handled <scrollbar>, <tooltip> and <color> tags. This caused textures
like lobby/public.png to be falsely reported as unused by -u.
Some engine assets are loaded directly by C++ renderer code with no
corresponding reference in any XML template, actor, or data file that
checkrefs.py can statically trace. Files in mod layers that override
these paths were incorrectly reported as unused.
Introduce source/tools/entity/cpp_hardcoded_assets.json to maintain
the list of such VFS paths alongside their C++ source location and a
description. checkrefs.py reads this JSON via add_cpp_hardcoded_assets()
and marks every matching file in all loaded mod layers as a known-used
root, so mod overrides are no longer flagged.
Initial entries:
art/textures/terrain/types/water/coastalWave.png
art/textures/terrain/types/water/foam.png
Both are loaded unconditionally by WaterManager::LoadWaterTextures().
Fixes 2 false-positive unused-file warnings for mod/ water textures.
TerrainTextureManager::LoadAlphaMap() hardcodes 14 PNG filenames and
loads them from art/textures/terrain/alphamaps/<type>/ where <type>
comes from the terrain XML <alphamap> element (defaulting to
"standard"). checkrefs add_terrains() parsed <textures> and
<material> but never read <alphamap> and had no knowledge of the
filenames loaded by C++.
Changes:
- Read <alphamap> from each terrain XML (default "standard") and
add all 14 hardcoded PNG filenames as deps of the terrain file.
- Always register the "standard" set as roots since C++ loads it
unconditionally as a fallback, even when no terrain specifies it.
The filenames are kept in sync with the fnames[] array in
source/graphics/TerrainTextureManager.cpp.
Fixes 14 false-positive unused-file warnings for the standard/
alphamap set.
The entity parser handled LineTexture/LineTextureMask under
Heal/RangeOverlay and MainTexture/MainTextureMask under
Selectable/Overlay/Texture, but had no handling for the
Selectable/Overlay/Outline/{LineTexture,LineTextureMask} path
used by the outline selection ring renderer.
These textures are referenced in e.g. mixins/trading_post.xml and
any other template that sets a custom outline selection style.
Fixes 2 false-positive unused-file warnings:
art/textures/selection/outline_border_02.png
art/textures/selection/outline_border_02_mask.png
The sprites XML parser iterated sprite.attrib.items() — the attributes
of the <sprite> tag itself — and checked if el == "image". Since
<image texture="..."> elements are children of <sprite>, not its
attributes, this check could never be true. No texture dependency was
ever extracted from any sprites definition file.
Fix by iterating sprite.findall("image") and sprite.findall("effect")
to correctly traverse child elements, and read attributes from those
elements directly.
Fixes 99 false-positive unused-file warnings across global/border/,
global/button/, global/modern/, global/watermark/, loading/,
pregame/, session/, and tipdisplay/ UI texture directories.
checkrefs.py only traced music files referenced in civ JSON Music[]
arrays. Two additional sources were missed:
- gui/common/music.js DEFAULT_*_TRACKS prototype arrays define fallback
playlists used when a civ has no music entries. All .ogg filenames
found in that file are now added as deps of the music.js root.
- simulation/data/cheats/*.json files can reference audio files via
Data.DefaultParameter (e.g. retroMe.json -> 0_8Bit_Bonus_Track.ogg).
These are now tracked as deps of each cheat root.
Fixes 10 false-positive unused-file warnings.
The same "Placing docks" log call is already used inside placeDocks
function, which is called just after these log calls.
Remove as it is useless and confusing.
Since they got introduced, there were separate documents for the Terms
of Service and Terms of Use for the multiplayer lobby. However, these
documents were rather short and it wasn't immediately clear, what the
difference between them is.
To simplify the process of reading and acknowledging the terms of the
multiplayer lobby, this consolidates the former Terms of Service and
Terms of Use in a single document. This results in players having to
read two documents (Terms of Service and Privacy Policy) instead of
three when registering for the multiplayer lobby. This makes the
registration process smoother and will in the best case result in more
players actively reading the documents.
Scrolling up and down might not do anything (not even a little bit) not
only if the max pos is 0, but also if it's smaller than 1. It depends on
the parent's position and whether or how the rendered rounds positions
of the scroll content. E.g. text positions are rounded up.
It's preferable to hide the scrollbar if it's between 0 and 1, cutting of
1 single pixel in unfortunate cases is better than rendering a useless
scrollbar.
Needs bitwise AND instead of OR, else irrespective of filemode requested
all permissions are given in CreateDirectories.
Fixes: 43e7dbc6da
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
The issue was introduced by fd976456d7 and made appearant by
67c96094f0.
If a cinema path was played right at the start of a game, then the
smooth LOS rendering option was disabled before `InterpolateLOS` was
called for the first time, so in turn when `ConstructTextures` was
called for the first time, it didn't fill the `m_SmoothFrameBuffers`
and `m_SmoothTextures`. And when smooth LOS was enabled again (by the
cinema path ending), `ConstructTexture` wasn't called again by
`RecomputeTexture` since `m_Texture` already existed. This means that
the `m_SmoothTextures` and `m_SmoothFramebuffers` remained unfilled,
which then caused a crash when they were accessed and used in
`InterpolateLOS`.
Since creating the shader and filling `m_SmoothTextures` and
m_SmoothFramebuffer` isn't expensive, the simplest solution is to always
do that no matter if smooth LOS is enabled or not.
This allows to create nonextising relative paths, this is useful for
example for `HOME=tmp ./binaries/system/pyrogenesis` running pyrogenesis
with a default config.
Fixes: 43e7dbc6da
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
This patch fixes the issue that the CinemaOverlay was hiding one turn
after the cinema paths stopped playing.
That was happening because `CinemaOverlay.OnSimulationUpdate` was called
before `OnSimulationUpdate` in session.js, so it read last turn's sim
state. Making it a simulation update handler ensures the sim state is
up-to-date once it's called.
This patch fixes the previously broken implementation of the timescale
property of cinema paths, now cinema paths with timescale 0.5, for
example, play twice as fast.
Unlike the comment stated, negative timescales weren't actually
supported, which is now enforced.
For demonstration, the timescale of the demo map's path is changed to
0.85.
There is no point in calling `CCmpCinemaManager::StartPlayingQueue`
again after deserializing, `m_WasMapRevealed` is (de)serialized anyway
and that call always overwrote it to false, which caused OOS.
`UpdateActivePath`, which is called each frame during rendering, mustn't
call `StopPlayingQueue`, since that impacts the serialized simulation
state.
And it is safe to assume `!m_PathQueue.empty()` if
`m_IsPlayingPathQueue`
Only send the CinemaQueueEnded message at the end of
`CCmpCinemaManager::StopPlayingQueue`, after resetting everything.
The other components would expect the queue to actually have ended
(`CCmpCinemaManager::IsPlayingQueue` to be returning false) when
receiving the message.