- Duke: SE20 + SE128 are wall-free

Also use symbolic constantfor SE_128 to make it easier to find.
This commit is contained in:
Christoph Oelckers 2021-11-15 23:32:41 +01:00
parent 010162261e
commit ad030d7e23
11 changed files with 58 additions and 31 deletions

View file

@ -428,6 +428,10 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1,
int32_t x2, int32_t y2, int32_t z2, int16_t sect2);
int32_t inside(int32_t x, int32_t y, int sectnum);
void dragpoint(int pointhighlight, int32_t dax, int32_t day, uint8_t flags = 0);
inline void dragpoint(walltype* pointhighlight, int32_t dax, int32_t day, uint8_t flags = 0)
{
dragpoint(int(pointhighlight - wall), dax, day, 0);
}
int32_t try_facespr_intersect(uspriteptr_t const spr, vec3_t const in,
int32_t vx, int32_t vy, int32_t vz,
vec3_t * const intp, int32_t strictly_smaller_than_p);

View file

@ -74,7 +74,7 @@ const char *GetVersionString();
#define MINSAVEVER_SW 13
#define MINSAVEVER_PS 15
#define SAVEVER_DN3D 11
#define SAVEVER_DN3D 12
#define SAVEVER_BLD 11
#define SAVEVER_SW 13
#define SAVEVER_PS 15

View file

@ -4276,8 +4276,9 @@ void handle_se20(DDukeActor* actor)
}
}
dragpoint(t[1], wall[t[1]].x + x, wall[t[1]].y + l);
dragpoint(t[2], wall[t[2]].x + x, wall[t[2]].y + l);
auto& wal = actor->temp_walls;
dragpoint(wal[0], wal[0]->x + x, wal[0]->y + l);
dragpoint(wal[1], wal[1]->x + x, wal[1]->y + l);
for (int p = connecthead; p >= 0; p = connectpoint2[p])
if (ps[p].cursectnum == s->sectnum && ps[p].on_ground)
@ -4709,9 +4710,10 @@ void handle_se128(DDukeActor *actor)
{
int* t = &actor->temp_data[0];
auto wal = &wall[t[2]];
auto wal = actor->temp_walls[0];
if (!wal) return; // E4L1 contains an uninitialized SE128 which would crash without this.
// if (wal->cstat | 32) // this has always been bugged, the condition can never be false.
//if (wal->cstat | 32) // this has always been bugged, the condition can never be false.
{
wal->cstat &= (255 - 32);
wal->cstat |= 16;
@ -4724,15 +4726,16 @@ void handle_se128(DDukeActor *actor)
// else return;
wal->overpicnum++;
if (wal->nextwall >= 0)
wal->nextWall()->overpicnum++;
auto nextwal = wal->nextWall();
if (nextwal)
nextwal->overpicnum++;
if (t[0] < t[1]) t[0]++;
else
{
wal->cstat &= (128 + 32 + 8 + 4 + 2);
if (wal->nextwall >= 0)
wal->nextWall()->cstat &= (128 + 32 + 8 + 4 + 2);
if (nextwal)
nextwal->cstat &= (128 + 32 + 8 + 4 + 2);
deletesprite(actor);
}
}

View file

@ -3745,7 +3745,7 @@ void moveeffectors_d(void) //STATNUM 3
}
break;
case 128: //SE to control glass breakage
case SE_128_GLASS_BREAKING:
handle_se128(act);
break;

View file

@ -3633,7 +3633,7 @@ void moveeffectors_r(void) //STATNUM 3
}
break;
case 128: //SE to control glass breakage
case SE_128_GLASS_BREAKING:
handle_se128(act);
break;

View file

@ -87,6 +87,7 @@ enum
SE_48_LIGHT_SWITCH = 48,
SE_49_POINT_LIGHT = 49,
SE_50_SPOT_LIGHT = 50,
SE_128_GLASS_BREAKING = 128,
SE_130 = 130,
SE_131 = 131,
};

View file

@ -293,7 +293,27 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DDukeActor& w, DDu
("temp_actor", w.temp_actor, def->temp_actor)
("seek_actor", w.seek_actor, def->seek_actor)
.Array("temp_data", w.temp_data, def->temp_data, 6)
.Array("temo_wall", w.temp_walls, def->temp_walls,2)
("temp_sect", w.temp_sect, def->temp_sect)
.EndObject();
#ifdef OLD_SAVEGAME
// compat handling
if (SaveVersion < 12 && arc.isReading())
{
if (w.s->picnum == SECTOREFFECTOR)
{
if (w.s->lotag == SE_20_STRETCH_BRIDGE)
{
for (int i : {0, 1}) w.temp_walls[i] = &wall[w.temp_data[i+1]];
}
if (w.s->lotag == SE_128_GLASS_BREAKING)
{
w.temp_walls[0] = &wall[w.temp_data[2]];
}
}
}
#endif
}
return arc;
}

View file

@ -723,7 +723,7 @@ void checkhitwall_d(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw
auto spawned = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3);
spawned->s->lotag = 128;
spawned->temp_data[1] = 5;
spawned->temp_data[2] = dawallnum;
spawned->temp_walls[0] = wal;
S_PlayActorSound(GLASS_BREAKING, spawned);
return;
}

View file

@ -1040,9 +1040,9 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw
wal->nextWall()->cstat = 0;
auto spawned = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3);
spawned->s->lotag = 128;
spawned->s->lotag = SE_128_GLASS_BREAKING;
spawned->temp_data[1] = 2;
spawned->temp_data[2] = dawallnum;
spawned->temp_walls[0] = wal;
S_PlayActorSound(GLASS_BREAKING, spawned);
return;
}
@ -1057,9 +1057,9 @@ void checkhitwall_r(DDukeActor* spr, int dawallnum, int x, int y, int z, int atw
wal->nextWall()->cstat = 0;
auto spawned = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3);
spawned->s->lotag = 128;
spawned->s->lotag = SE_128_GLASS_BREAKING;
spawned->temp_data[1] = 2;
spawned->temp_data[2] = dawallnum;
spawned->temp_walls[0] = wal;
S_PlayActorSound(GLASS_BREAKING, spawned);
return;
}

View file

@ -796,6 +796,7 @@ void spawneffector(DDukeActor* actor)
case SE_20_STRETCH_BRIDGE:
{
int q;
walltype* closewall = nullptr;
startwall = sectp->wallptr;
endwall = startwall + sectp->wallnum;
@ -803,37 +804,31 @@ void spawneffector(DDukeActor* actor)
//find the two most clostest wall x's and y's
q = 0x7fffffff;
for (s = startwall; s < endwall; s++)
for (auto& wal : wallsofsector(sectp))
{
x = wall[s].x;
y = wall[s].y;
d = FindDistance2D(sp->x - x, sp->y - y);
d = FindDistance2D(sp->x - wal.x, sp->y - wal.y);
if (d < q)
{
q = d;
clostest = s;
closewall = &wal;
}
}
t[1] = clostest;
actor->temp_walls[0] = closewall;
q = 0x7fffffff;
for (s = startwall; s < endwall; s++)
for (auto& wal : wallsofsector(sectp))
{
x = wall[s].x;
y = wall[s].y;
d = FindDistance2D(sp->x - x, sp->y - y);
if (d < q && s != t[1])
d = FindDistance2D(sp->x - wal.x, sp->y - wal.y);
if (d < q && &wal != actor->temp_walls[0])
{
q = d;
clostest = s;
closewall = &wal;
}
}
t[2] = clostest;
actor->temp_walls[1] = closewall;
StartInterpolation(sect, Interp_Sect_FloorPanX);
StartInterpolation(sect, Interp_Sect_FloorPanY);
break;

View file

@ -35,6 +35,10 @@ struct DDukeActor
int palvals;
};
int temp_data[6];
// Some SE's stored indices in temp_data. For purposes of clarity avoid that. These variables are meant to store these elements now
walltype* temp_walls[2]; // SE20 + SE128
sectortype* temp_sect;
DDukeActor* temp_actor, *seek_actor;
spritetype* s; // direct reference to the corresponding sprite.