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:
1 parent
a34f42d53e
commit
00a9c1c26c
48 files changed
+5799
-435
No files matched your search
@@ -20,6 +20,53 @@ layout(std430, set = 0, binding = 8) readonly buffer Tables { uint tbl[]; }; /
|
||||
uint flame_material(uint m, uint dflt) { const uint v = tbl[1024u + 4u * mats[mats.length() - 1u].w + 2u * m]; return v != 0u ? v - 1u : dflt; }
|
||||
uint smoke_material(uint m, uint dflt) { const uint v = tbl[1024u + 4u * mats[mats.length() - 1u].w + 2u * m + 1u]; return v != 0u ? v - 1u : dflt; }
|
||||
|
||||
#include "biome_mods.glsl"
|
||||
layout(std430, set = 0, binding = 28) readonly buffer RHead { uint rhead[]; };
|
||||
layout(std430, set = 0, binding = 29) readonly buffer RRec { uint rrec[]; };
|
||||
const ivec2 TD4[4] = ivec2[4](ivec2(0,-1), ivec2(-1,0), ivec2(1,0), ivec2(0,1));
|
||||
uint native_material(uint m) { const uint n = mats[mats.length()-1u].w; return rhead[2u*n*(n+1u)+m]; }
|
||||
uint body_neighbor(ivec2 q, Body B, int s, vec2 com, float cs, float sn, uint m, uint base) {
|
||||
const ivec2 grid = q - ivec2(pc.view_x, pc.view_y);
|
||||
if (grid.x < 0 || grid.y < 0 || grid.x >= pc.gw || grid.y >= pc.gh) return NONE;
|
||||
const ivec2 local = ivec2(floor(rot2(cs, -sn, vec2(q) + 0.5 - B.p.xy) + com));
|
||||
if (shape_solid(s, local.x, local.y) && (burn[base + uint(local.y*shi(s,0)+local.x)] & BURNT) == 0u) return m;
|
||||
return cell_mat(cells[grid.y*pc.gw+grid.x]);
|
||||
}
|
||||
// Solid-cell 0070e060 calls the combined/fast paths when body record +0x2e
|
||||
// permits them. Ice glass must keep that path after leaving the terrain grid.
|
||||
int solid_conversion(ivec2 wc, Body B, int s, vec2 com, float cs, float sn, uint m, uint base, uint seed) {
|
||||
if ((B.i.z & 65536) != 0) return -1; // native collapse record disables reactions
|
||||
const uint r = hash3(seed, uint(pc.frame), 40u) & 32767u;
|
||||
const uint R = r % 10001u;
|
||||
const uint dir = hash3(seed, uint(pc.frame), 41u) & 3u;
|
||||
const ivec2 q = wc + TD4[dir];
|
||||
const uint nm = body_neighbor(q, B, s, com, cs, sn, m, base);
|
||||
if (nm == NONE) return -1;
|
||||
const bool full = (pc.frame % 11) == 0;
|
||||
if (full) {
|
||||
const uint bb = bm_bytes(vec2(wc));
|
||||
const uint fc = (bb >> 16) & 255u, uc = bb >> 24;
|
||||
const uvec2 cv = bm_conversions(m);
|
||||
const bool cold = fc != 0u && (cv.x & 65535u) != 0u && (hash3(seed,uint(pc.frame),42u)&32767u) % ((cv.x>>16)+1u) < fc;
|
||||
const bool warm = uc != 0u && (cv.y & 65535u) != 0u && (hash3(seed,uint(pc.frame),43u)&32767u) % ((cv.y>>16)+1u) < uc;
|
||||
if (cold) return nm == 0u || (mflags(nm)&F_LIQCELL) == 0u || (mflags(nm)&F_POWDER) != 0u ? int((cv.x&65535u)-1u) : -1;
|
||||
if (warm) return native_material(nm) != native_material(m) ? int((cv.y&65535u)-1u) : -1;
|
||||
}
|
||||
const uint n = mats[mats.length()-1u].w, table = full ? 0u : n*(n+1u);
|
||||
const uint h = rhead[table + m*n+nm], count = h & 255u;
|
||||
if (count == 0u || rhead[table+n*n+m] == 0u || R > rhead[table+n*n+m]) return -1;
|
||||
const uint e = ((h>>8) + R%count)*5u, pw = rrec[e+1u];
|
||||
const uint requiredDir = (pw>>16)&7u, actualDir = dir == 0u ? 1u : dir == 1u ? 3u : dir == 2u ? 4u : 2u;
|
||||
if (R > (pw&65535u) || (requiredDir != 0u && requiredDir != actualDir)) return -1;
|
||||
// Complex sprite reactions need per-pixel material storage; leave those to
|
||||
// the existing fracture path rather than applying only half their outputs.
|
||||
if ((rrec[e+2u]&65535u) != 65535u || (rrec[e+3u]&65535u) != 0u || (rrec[e+4u]&0x7FFFFFFFu) != 0u) return -1;
|
||||
const uint target = rrec[e]&65535u, other = rrec[e]>>16;
|
||||
if (target == 65535u || native_material(target) == native_material(m)) return -1;
|
||||
if (other != 65535u && native_material(other) != native_material(nm)) return -1;
|
||||
return int(target);
|
||||
}
|
||||
|
||||
void main() {
|
||||
int bi = int(gl_WorkGroupID.x);
|
||||
if (bi >= bhdr.x) return;
|
||||
@@ -29,6 +76,13 @@ void main() {
|
||||
if (matp1 == 0u) return;
|
||||
const uint m = matp1 - 1u;
|
||||
const uint mz = mats[3u * m + 2u].z, mw = mats[3u * m + 2u].w;
|
||||
// Most rigid materials have no fast reactions. Avoid visiting their pixels
|
||||
// on the ten ordinary updates between combined updates.
|
||||
if (((mz >> 16) & 1u) == 0u) {
|
||||
if ((B.i.z & 65536) != 0) return;
|
||||
const uint n = mats[mats.length()-1u].w;
|
||||
if ((pc.frame % 11) != 0 && rhead[n*(n+1u)+n*n+m] == 0u) return;
|
||||
}
|
||||
const int s = B.i.x;
|
||||
const int w = shi(s, 0), h = shi(s, 1);
|
||||
if (w * h > 4096) return;
|
||||
@@ -50,6 +104,24 @@ void main() {
|
||||
const ivec2 wc = ivec2(floor(wp));
|
||||
const uint seed = uint(bi) * 4099u + uint(px);
|
||||
if ((st & BURNING) == 0u) {
|
||||
const int target = solid_conversion(wc, B, s, com, cs, sn, m, base, seed);
|
||||
if (target >= 0 && (mflags(uint(target)) & (F_LIQCELL | F_GAS | F_FIRE | F_AIR)) != 0u) {
|
||||
const ivec2 grid = wc - ivec2(pc.view_x, pc.view_y);
|
||||
if (grid.x >= 0 && grid.y >= 0 && grid.x < pc.gw && grid.y < pc.gh) {
|
||||
const int index = grid.y*pc.gw+grid.x;
|
||||
const int ei = atomicAdd(ctrl.burnN.x, 1);
|
||||
if (ei < 256) {
|
||||
if (atomicCompSwap(cells[index], 0u, uint(target)) == 0u) {
|
||||
material_changed(index, 0u, uint(target));
|
||||
ctrl.burnEv[ei] = ivec4(bi, px, target+1, 0);
|
||||
burn[base+uint(px)] = BURNT;
|
||||
continue;
|
||||
}
|
||||
ctrl.burnEv[ei] = ivec4(-1);
|
||||
} else atomicAdd(ctrl.burnN.x, -1);
|
||||
}
|
||||
}
|
||||
if (((mz >> 16) & 1u) == 0u) continue;
|
||||
// fire sources in the pixel's cell and the four around it (cells are free under a body)
|
||||
float keep = 1.0, bestFade = -1.0;
|
||||
bool wet = false;
|
||||
|
||||
Reference in new issue
Block a user