Lot of bugfixes

* Adding clipper to generate the terrain's negative powder-contour offset.
* Fixing RDB issues (fracture, active trigger, performances)
* Fixing blood emission
* Fixing the freezing formula on liquids
* Fixing Steve spawning due to a missed test.
* Reaction table properly build
This commit is contained in:
Gaël committed 2026-10-21 20:46:13 +02:00
1 parent a34f42d53e
commit 00a9c1c26c
48 files changed
+5799 -435

No files matched your search

+8 -7
View File
@@ -44,14 +44,14 @@ void displaced_particle(uint id, FPart p) {
uint seed = id * 7u + uint(pc.frame);
ivec2 here = ivec2(floor(pos));
if (kind == 3u) { // waiting for a free place
if (reinsert(cw, here, seed, floatBitsToUint(p.b.z))) { fparts[id].b.x = 0.0; return; }
if (reinsert(cw, here, seed, floatBitsToUint(p.b.z))) { release_part(id); return; }
// No place: out of the window it is gone (00712390: a particle out of the loaded area dies; it waited there forever and filled the pool - 1000+ after 25 s).
// In the window the search of its column ended on a solid (a pocket under an overhang, a pool under ice, a column shifted into the rock): it drifts a cell,
// down into a free cell (air, gas), else sideways, and searches again from there; after 10 s it is dropped. (It used to wait where it was: blood and water
// pixels frozen in the air near pools.)
const ivec2 hq = here - ivec2(pc.view_x, pc.view_y);
const uint tries = p.c.w & 0xFFFFFu;
if (hq.x < 0 || hq.y < 0 || hq.x >= pc.gw || hq.y >= pc.gh || tries >= 600u) { fparts[id].b.x = 0.0; return; }
if (hq.x < 0 || hq.y < 0 || hq.x >= pc.gw || hq.y >= pc.gh || tries >= 600u) { release_part(id); return; }
ivec2 step = ivec2(0, 1);
if (hq.y + 1 >= pc.gh || (mflags(cell_mat(cells[(hq.y + 1) * pc.gw + hq.x])) & (F_STATIC | F_LIQUID)) != 0u) {
const int sx = (hash3(seed, tries, 67u) & 1u) != 0u ? 1 : -1;
@@ -112,7 +112,7 @@ void displaced_particle(uint id, FPart p) {
} else if (!dead) cur = target; // beyond the 60 probes the end point is taken as it is
pos = cur;
if (dead) {
if (reinsert(cw, ivec2(floor(pos)), seed, floatBitsToUint(p.b.z))) { fparts[id].b.x = 0.0; return; }
if (reinsert(cw, ivec2(floor(pos)), seed, floatBitsToUint(p.b.z))) { release_part(id); return; }
kind = 3u; // no place yet: it keeps trying
}
fparts[id].a = vec4(pos, vel);
@@ -129,7 +129,7 @@ void main() {
uint id = gl_GlobalInvocationID.x;
if (id >= uint(FPART_MAX)) return;
FPart p = fparts[id];
if (p.b.x <= 0.0) return;
if (p.b.x <= 0.0 || p.b.x >= 2.9e38) return; // Allocation may still be initializing this record.
if (p.c.y != 0u) { displaced_particle(id, p); return; }
const bool real = p.b.y < 0.0;
vec2 pos = p.a.xy, vel = p.a.zw;
@@ -217,7 +217,6 @@ void main() {
vel += vec2(-sin(ang), cos(ang)) * force / 60.0;
}
fparts[id].a = vec4(pos, vel);
fparts[id].b.x = p.b.x;
if (landed) { // 00716600 / 0071fba0: the cell goes back into the grid where the particle ended, else the first free (or lighter) cell up to 128 above, drifting
// sideways; with no place yet it waits as a returning cell (not lost: a barrel's 750 units of spill all come out)
const uint cw = uint(landMat) | (((hash3(id + uint(pc.frame) * 7u, uint(landMat), 91u) >> 16) & 0xFFu) << 16);
@@ -225,11 +224,13 @@ void main() {
const ivec2 lq = ivec2(floor(landPos)) - ivec2(pc.view_x, pc.view_y);
if (lq.x >= 0 && lq.y >= 0 && lq.x < pc.gw && lq.y < pc.gh && !reinsert(cw, ivec2(floor(landPos)), id * 7u + uint(pc.frame), bv)) {
fparts[id].a = vec4(landPos, 0.0, 0.0);
fparts[id].b = vec4(1.0e6, 1.0, uintBitsToFloat(bv), 0.0);
fparts[id].c = uvec4(cw, 3u, 0u, 0u);
}
fparts[id].b = vec4(1.0e6, 1.0, uintBitsToFloat(bv), 0.0);
} else release_part(id);
return;
}
if (p.b.x <= 0.0) release_part(id);
else fparts[id].b.x = p.b.x;
}
if (p.b.x <= 0.0) return;
ivec2 q = ivec2(floor(pos)) - ivec2(pc.view_x, pc.view_y);