Fix another extremely rare pmap corruption

The real fix was made in Simulation::kill_part, where photons[y][x] wasn't cleared when i = 0 because the pmap branch triggered instead. Broken since ff7428fc70, which only partially fixed some related bug. I decided to also fix every other case, even if they are not strictly necessary because they write 0 to pmap/photons anyway.

Reproduce with

	sim.loadSave(3062273, 1)
	sim.ensureDeterminism(true)
	tpt.setfpscap(2)
	local function F()
		print(sim.framerender(), sim.randomseed())
		if sim.framerender() == 0 then
			local a = 3498763327
			print(sim.hash(), a)
			sim.framerender(1200)
			sim.reloadSave()
			sim.randomseed(a, a + 1, a + 2, a + 3)
			tpt.set_pause(0)
		end
	end
	event.register(event.tick, F)
This commit is contained in:
Tamás Bálint Misius 2023-12-12 22:08:31 +01:00
parent 6433eb04f2
commit 2eee738a9f
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
2 changed files with 12 additions and 12 deletions

View File

@ -1411,7 +1411,7 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny)
return 1; return 1;
} }
if (ID(pmap[ny][nx]) == ri) if (pmap[ny][nx] && ID(pmap[ny][nx]) == ri)
pmap[ny][nx] = 0; pmap[ny][nx] = 0;
parts[ri].x += float(x - nx); parts[ri].x += float(x - nx);
parts[ri].y += float(y - ny); parts[ri].y += float(y - ny);
@ -1469,9 +1469,9 @@ bool Simulation::move(int i, int x, int y, float nxf, float nyf)
parts[i].y = nyf; parts[i].y = nyf;
if (ny != y || nx != x) if (ny != y || nx != x)
{ {
if (ID(pmap[y][x]) == i) if (pmap[y][x] && ID(pmap[y][x]) == i)
pmap[y][x] = 0; pmap[y][x] = 0;
if (ID(photons[y][x]) == i) if (photons[y][x] && ID(photons[y][x]) == i)
photons[y][x] = 0; photons[y][x] = 0;
// kill_part if particle is out of bounds // kill_part if particle is out of bounds
if (nx < CELL || nx >= XRES - CELL || ny < CELL || ny >= YRES - CELL) if (nx < CELL || nx >= XRES - CELL || ny < CELL || ny >= YRES - CELL)
@ -1676,9 +1676,9 @@ void Simulation::kill_part(int i)//kills particle number i
if (x >= 0 && y >= 0 && x < XRES && y < YRES) if (x >= 0 && y >= 0 && x < XRES && y < YRES)
{ {
if (ID(pmap[y][x]) == i) if (pmap[y][x] && ID(pmap[y][x]) == i)
pmap[y][x] = 0; pmap[y][x] = 0;
else if (ID(photons[y][x]) == i) else if (photons[y][x] && ID(photons[y][x]) == i)
photons[y][x] = 0; photons[y][x] = 0;
} }
@ -1726,13 +1726,13 @@ bool Simulation::part_change_type(int i, int x, int y, int t)
if (elements[t].Properties & TYPE_ENERGY) if (elements[t].Properties & TYPE_ENERGY)
{ {
photons[y][x] = PMAP(i, t); photons[y][x] = PMAP(i, t);
if (ID(pmap[y][x]) == i) if (pmap[y][x] && ID(pmap[y][x]) == i)
pmap[y][x] = 0; pmap[y][x] = 0;
} }
else else
{ {
pmap[y][x] = PMAP(i, t); pmap[y][x] = PMAP(i, t);
if (ID(photons[y][x]) == i) if (photons[y][x] && ID(photons[y][x]) == i)
photons[y][x] = 0; photons[y][x] = 0;
} }
return false; return false;
@ -1828,9 +1828,9 @@ int Simulation::create_part(int p, int x, int y, int t, int v)
{ {
int oldX = (int)(parts[p].x + 0.5f); int oldX = (int)(parts[p].x + 0.5f);
int oldY = (int)(parts[p].y + 0.5f); int oldY = (int)(parts[p].y + 0.5f);
if (ID(pmap[oldY][oldX]) == p) if (pmap[oldY][oldX] && ID(pmap[oldY][oldX]) == p)
pmap[oldY][oldX] = 0; pmap[oldY][oldX] = 0;
if (ID(photons[oldY][oldX]) == p) if (photons[oldY][oldX] && ID(photons[oldY][oldX]) == p)
photons[oldY][oldX] = 0; photons[oldY][oldX] = 0;
oldType = parts[p].type; oldType = parts[p].type;
@ -2889,9 +2889,9 @@ killed:
} }
if (ny!=y || nx!=x) if (ny!=y || nx!=x)
{ {
if (ID(pmap[y][x]) == i) if (pmap[y][x] && ID(pmap[y][x]) == i)
pmap[y][x] = 0; pmap[y][x] = 0;
else if (ID(photons[y][x]) == i) else if (photons[y][x] && ID(photons[y][x]) == i)
photons[y][x] = 0; photons[y][x] = 0;
if (nx<CELL || nx>=XRES-CELL || ny<CELL || ny>=YRES-CELL) if (nx<CELL || nx>=XRES-CELL || ny<CELL || ny>=YRES-CELL)
{ {

View File

@ -73,7 +73,7 @@ static int update(UPDATE_FUNC_ARGS)
} }
else if(parts[i].tmp==1) else if(parts[i].tmp==1)
{ {
if ((ID(pmap[y][x]) == i)) if (pmap[y][x] && ID(pmap[y][x]) == i)
{ {
sim->flood_prop(x, y, Particle::GetProperties()[FIELD_TMP], 2); sim->flood_prop(x, y, Particle::GetProperties()[FIELD_TMP], 2);
} }