- movement and elevators.

This commit is contained in:
Christoph Oelckers 2021-10-21 23:41:54 +02:00
parent 9cfd682c9e
commit ee03eb1b3d
8 changed files with 69 additions and 76 deletions

View file

@ -208,7 +208,7 @@ struct BlockInfo
};
extern BlockInfo sBlockInfo[];
extern int hihit;
extern Collision hiHit;
extern DExhumedActor* nChunkSprite[];
extern DExhumedActor* nBodySprite[];
@ -222,7 +222,6 @@ DExhumedActor* UpdateEnemy(DExhumedActor** ppEnemy);
Collision MoveCreature(DExhumedActor* nSprite);
Collision MoveCreatureWithCaution(DExhumedActor* actor);
void WheresMyMouth(int nPlayer, int *x, int *y, int *z, short *sectnum);
int GetSpriteHeight(int nSprite);
int GetActorHeight(DExhumedActor* nSprite);
DExhumedActor* insertActor(int, int);
DExhumedActor* GrabBody();
@ -284,7 +283,7 @@ void FuncTrap(int, int, int, int);
void FuncEnergyBlock(int, int, int, int);
void FuncSpark(int, int, int, int);
void SnapBobs(short nSectorA, short nSectorB);
short FindWallSprites(short nSector);
DExhumedActor* FindWallSprites(short nSector);
void AddMovingSector(int nSector, int edx, int ebx, int ecx);
void ProcessTrailSprite(DExhumedActor* nSprite, int nLotag, int nHitag);
void AddSectorBob(int nSector, int nHitag, int bx);
@ -293,8 +292,8 @@ int BuildArrow(DExhumedActor* nSprite, int nVal);
int BuildFireBall(DExhumedActor*, int a, int b);
void BuildDrip(DExhumedActor* nSprite);
DExhumedActor* BuildEnergyBlock(short nSector);
int BuildElevC(int arg1, int nChannel, int nSector, int nWallSprite, int arg5, int arg6, int nCount, ...);
int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5, int nCount, ...);
int BuildElevC(int arg1, int nChannel, int nSector, DExhumedActor* nWallSprite, int arg5, int arg6, int nCount, ...);
int BuildElevF(int nChannel, int nSector, DExhumedActor* nWallSprite, int arg_4, int arg_5, int nCount, ...);
int BuildWallFace(short nChannel, short nWall, int nCount, ...);
int BuildSlide(int nChannel, int edx, int ebx, int ecx, int arg1, int arg2, int arg3);

View file

@ -100,8 +100,6 @@ short nFreeze;
short nSnakeCam = -1;
short nLocalSpr;
int nNetPlayerCount = 0;
short nClockVal;
@ -630,7 +628,6 @@ void SerializeState(FSerializer& arc)
("creatureskilled", nCreaturesKilled)
("freeze", nFreeze)
("snakecam", nSnakeCam)
("localspr", nLocalSpr)
("clockval", nClockVal) // kTile3603
("redticks", nRedTicks)
("alarmticks", nAlarmTicks)

View file

@ -133,8 +133,6 @@ extern short lastfps;
extern int flash;
extern short nLocalSpr;
extern short nSnakeCam;
extern short bCoordinates;

View file

@ -40,7 +40,8 @@ short NearCount = -1;
DExhumedActor* nBodySprite[50];
int hihit, sprceiling, sprfloor, lohit;
int sprceiling, sprfloor;
Collision loHit, hiHit;
enum
{
@ -77,10 +78,6 @@ void SerializeMove(FSerializer& arc)
("chunkcount", nCurChunkNum)
.Array("chunks", nChunkSprite, kMaxMoveChunks)
("overridesect", overridesect)
("hihit", hihit)
("lohit", lohit)
("sprceiling", sprceiling)
("sprfloor", sprfloor)
.Array("bodysprite", nBodySprite, 50)
.EndObject();
}
@ -288,12 +285,11 @@ int BelowNear(DExhumedActor* pActor)
short nSector = pSprite->sectnum;
int z = pSprite->z;
int var_24, z2;
int z2;
if ((lohit & 0xC000) == 0xC000)
if (loHit.type == kHitSprite)
{
var_24 = lohit & 0xC000;
z2 = sprite[lohit & 0x3FFF].z;
z2 = loHit.actor->s().z;
}
else
{
@ -333,7 +329,7 @@ int BelowNear(DExhumedActor* pActor)
bTouchFloor = true;
return 0x20000;
return kHitAux2;
}
else
{
@ -341,9 +337,9 @@ int BelowNear(DExhumedActor* pActor)
}
}
int movespritez(short nSprite, int z, int height, int, int clipdist)
Collision movespritez(DExhumedActor* pActor, int z, int height, int, int clipdist)
{
spritetype* pSprite = &sprite[nSprite];
spritetype* pSprite = &pActor->s();
short nSector = pSprite->sectnum;
assert(nSector >= 0 && nSector < kMaxSectors);
@ -355,7 +351,7 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
pSprite->cstat &= ~CSTAT_SPRITE_BLOCK;
int nRet = 0;
Collision nRet(0);
short nSectFlags = SectFlag[nSector];
@ -378,7 +374,7 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
{
edi = SectBelow[pSprite->sectnum];
ChangeActorSect(&exhumedActors[nSprite], edi);
ChangeActorSect(pActor, edi);
}
if (edi != nSector)
@ -387,8 +383,8 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
if (SectFlag[edi] & kSectUnderwater)
{
if (nSprite == PlayerList[nLocalPlayer].Actor()->GetSpriteIndex()) {
D3PlayFX(StaticSound[kSound2], nSprite);
if (pActor == PlayerList[nLocalPlayer].Actor()) {
D3PlayFX(StaticSound[kSound2], pActor);
}
if (pSprite->statnum <= 107) {
@ -402,18 +398,21 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
{
edi = SectAbove[pSprite->sectnum];
ChangeActorSect(&exhumedActors[nSprite], edi);
ChangeActorSect(pActor, edi);
}
}
// This function will keep the player from falling off cliffs when you're too close to the edge.
// This function finds the highest and lowest z coordinates that your clipping BOX can get to.
int hihit, lohit;
getzrange_old(pSprite->x, pSprite->y, pSprite->z - 256, pSprite->sectnum,
&sprceiling, &hihit, &sprfloor, &lohit, 128, CLIPMASK0);
hiHit.setFromEngine(hihit);
loHit.setFromEngine(lohit);
int mySprfloor = sprfloor;
if ((lohit & 0xC000) != 0xC000) {
if (loHit.type != kHitSprite) {
mySprfloor += SectDepth[pSprite->sectnum];
}
@ -423,30 +422,30 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
{
bTouchFloor = true;
if ((lohit & 0xC000) == 0xC000)
if (loHit.type == kHitSprite)
{
// Path A
short nFloorSprite = lohit & 0x3FFF;
auto pFloorSprite = &loHit.actor->s();
if (pSprite->statnum == 100 && sprite[nFloorSprite].statnum != 0 && sprite[nFloorSprite].statnum < 100)
if (pSprite->statnum == 100 && pFloorSprite->statnum != 0 && pFloorSprite->statnum < 100)
{
short nDamage = (z >> 9);
if (nDamage)
{
runlist_DamageEnemy(nFloorSprite, nSprite, nDamage << 1);
runlist_DamageEnemy(loHit.actor, pActor, nDamage << 1);
}
pSprite->zvel = -z;
}
else
{
if (sprite[nFloorSprite].statnum == 0 || sprite[nFloorSprite].statnum > 199)
if (pFloorSprite->statnum == 0 || pFloorSprite->statnum > 199)
{
nRet |= 0x20000;
nRet.exbits |= kHitAux2;
}
else
{
nRet |= lohit;
nRet = loHit;
}
pSprite->zvel = 0;
@ -457,7 +456,7 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
// Path B
if (SectBelow[pSprite->sectnum] == -1)
{
nRet |= 0x20000;
nRet.exbits |= kHitAux2;
short nSectDamage = SectDamage[pSprite->sectnum];
@ -465,13 +464,13 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
{
if (pSprite->hitag < 15)
{
IgniteSprite(&exhumedActors[nSprite]);
IgniteSprite(pActor);
pSprite->hitag = 20;
}
nSectDamage >>= 2;
nSectDamage = nSectDamage - (nSectDamage>>2);
if (nSectDamage) {
runlist_DamageEnemy(nSprite, -1, nSectDamage);
runlist_DamageEnemy(pActor, nullptr, nSectDamage);
}
}
@ -486,10 +485,10 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
}
else
{
if ((ebp - height) < sprceiling && ((hihit & 0xC000) == 0xC000 || SectAbove[pSprite->sectnum] == -1))
if ((ebp - height) < sprceiling && (hiHit.type == kHitSprite || SectAbove[pSprite->sectnum] == -1))
{
ebp = sprceiling + height;
nRet |= 0x10000;
nRet.exbits |= kHitAux1;
}
}
@ -498,7 +497,7 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
if ((SectDepth[nSector] != 0) || (edi != nSector && (SectFlag[edi] & kSectUnderwater)))
{
assert(nSector >= 0 && nSector < kMaxSectors);
BuildSplash(&exhumedActors[nSprite], nSector);
BuildSplash(pActor, nSector);
}
}
@ -508,7 +507,7 @@ int movespritez(short nSprite, int z, int height, int, int clipdist)
if (pSprite->statnum == 100)
{
BuildNear(pSprite->x, pSprite->y, clipdist + (clipdist / 2), pSprite->sectnum);
nRet |= BelowNear(&exhumedActors[nSprite]);
nRet.exbits |= BelowNear(pActor);
}
return nRet;
@ -544,15 +543,13 @@ Collision movesprite(DExhumedActor* pActor, int dx, int dy, int dz, int ceildist
int floorZ = sector[nSector].floorz;
int nRet = 0;
if ((SectFlag[nSector] & kSectUnderwater) || (floorZ < z))
{
dx >>= 1;
dy >>= 1;
}
nRet |= movespritez(pActor->GetSpriteIndex(), dz, nSpriteHeight, flordist, nClipDist);
Collision nRet = movespritez(pActor, dz, nSpriteHeight, flordist, nClipDist);
nSector = pSprite->sectnum; // modified in movespritez so re-grab this variable
@ -579,11 +576,17 @@ Collision movesprite(DExhumedActor* pActor, int dx, int dy, int dz, int ceildist
CheckSectorFloor(overridesect, pSprite->z, &dx, &dy);
}
nRet |= (uint16_t)clipmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask);
int colv = clipmove_old(&pSprite->x, &pSprite->y, &pSprite->z, &nSector, dx, dy, nClipDist, nSpriteHeight, flordist, clipmask);
Collision coll(colv);
if (coll.type != kHitNone) // originally this or'ed the two values which can create unpredictable bad values in some edge cases.
{
coll.exbits = nRet.exbits;
nRet = coll;
}
if ((nSector != pSprite->sectnum) && nSector >= 0)
{
if (nRet & 0x20000) {
if (nRet.exbits & kHitAux2) {
dz = 0;
}
@ -603,7 +606,7 @@ Collision movesprite(DExhumedActor* pActor, int dx, int dy, int dz, int ceildist
}
}
return Collision(nRet);
return nRet;
}
void Gravity(DExhumedActor* actor)

View file

@ -75,6 +75,7 @@ struct Drip
// 56 bytes
struct Elev
{
DExhumedActor* pActor;
short field_0;
short nChannel;
short nSector;
@ -84,7 +85,6 @@ struct Elev
short nCurZOffset;
int zOffsets[8]; // different Z offsets
short field_32;
short nSprite;
short field_36;
};
@ -245,7 +245,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Elev& w, Elev* def
("curz", w.nCurZOffset)
.Array("zofs", w.zOffsets, 8)
("at32", w.field_32)
("sprite", w.nSprite)
("sprite", w.pActor)
("at36", w.field_36)
.EndObject();
}
@ -415,7 +415,7 @@ DExhumedActor* BuildWallSprite(int nSector)
}
// done
short FindWallSprites(short nSector)
DExhumedActor* FindWallSprites(short nSector)
{
int var_24 = 0x7FFFFFFF;
int ecx = 0x7FFFFFFF;
@ -490,10 +490,10 @@ short FindWallSprites(short nSector)
pSprite->hitag = 0;
}
return pAct->GetSpriteIndex();
return pAct;
}
int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5, int nCount, ...)
int BuildElevF(int nChannel, int nSector, DExhumedActor* nWallSprite, int arg_4, int arg_5, int nCount, ...)
{
auto ElevCount = Elevator.Reserve(1);
@ -507,11 +507,11 @@ int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5,
Elevator[ElevCount].nCurZOffset = 0;
Elevator[ElevCount].field_36 = 0;
if (nWallSprite < 0) {
nWallSprite = BuildWallSprite(nSector)->GetSpriteIndex();
if (nWallSprite == nullptr) {
nWallSprite = BuildWallSprite(nSector);
}
Elevator[ElevCount].nSprite = nWallSprite;
Elevator[ElevCount].pActor = nWallSprite;
va_list zlist;
va_start(zlist, nCount);
@ -533,7 +533,7 @@ int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5,
return ElevCount;
}
int BuildElevC(int arg1, int nChannel, int nSector, int nWallSprite, int arg5, int arg6, int nCount, ...)
int BuildElevC(int arg1, int nChannel, int nSector, DExhumedActor* nWallSprite, int arg5, int arg6, int nCount, ...)
{
int edi = arg5;
@ -555,11 +555,11 @@ int BuildElevC(int arg1, int nChannel, int nSector, int nWallSprite, int arg5, i
Elevator[ElevCount].nChannel = nChannel;
Elevator[ElevCount].nSector = nSector;
if (nWallSprite < 0) {
nWallSprite = BuildWallSprite(nSector)->GetSpriteIndex();
if (nWallSprite == nullptr) {
nWallSprite = BuildWallSprite(nSector);
}
Elevator[ElevCount].nSprite = nWallSprite;
Elevator[ElevCount].pActor = nWallSprite;
va_list zlist;
va_start(zlist, nCount);
@ -677,7 +677,7 @@ void MoveSectorSprites(int nSector, int z)
}
}
void StartElevSound(short nSprite, int nVal)
void StartElevSound(DExhumedActor* pActor, int nVal)
{
short nSound;
@ -688,7 +688,7 @@ void StartElevSound(short nSprite, int nVal)
nSound = nStoneSound;
}
D3PlayFX(StaticSound[nSound], nSprite);
D3PlayFX(StaticSound[nSound], pActor);
}
void AIElev::ProcessChannel(RunListEvent* ev)
@ -724,7 +724,7 @@ void AIElev::ProcessChannel(RunListEvent* ev)
if (Elevator[nElev].field_32 < 0)
{
Elevator[nElev].field_32 = runlist_AddRunRec(NewRun, &RunData[nRun]);
StartElevSound(Elevator[nElev].nSprite, var_18);
StartElevSound(Elevator[nElev].pActor, var_18);
edi = 1;
}
@ -759,7 +759,7 @@ void AIElev::ProcessChannel(RunListEvent* ev)
{
Elevator[nElev].field_32 = runlist_AddRunRec(NewRun, &RunData[nRun]);
StartElevSound(Elevator[nElev].nSprite, var_18);
StartElevSound(Elevator[nElev].pActor, var_18);
}
}
else
@ -785,7 +785,7 @@ void AIElev::Tick(RunListEvent* ev)
assert(nChannel >= 0 && nChannel < kMaxChannels);
short nSector = Elevator[nElev].nSector;
auto pElevSpr = &exhumedActors[Elevator[nElev].nSprite];
auto pElevSpr = Elevator[nElev].pActor;
int ebp = 0; // initialise to *something*
@ -805,7 +805,7 @@ void AIElev::Tick(RunListEvent* ev)
if (var_18 & 0x10)
{
Elevator[nElev].nCurZOffset ^= 1;
StartElevSound(pElevSpr->GetSpriteIndex(), var_18);
StartElevSound(pElevSpr, var_18);
}
else
{
@ -814,7 +814,7 @@ void AIElev::Tick(RunListEvent* ev)
Elevator[nElev].field_32 = -1;
runlist_ReadyChannel(nChannel);
D3PlayFX(StaticSound[nStopSound], Elevator[nElev].nSprite);
D3PlayFX(StaticSound[nStopSound], Elevator[nElev].pActor);
}
}
else
@ -848,14 +848,14 @@ void AIElev::Tick(RunListEvent* ev)
{
Elevator[nElev].nCurZOffset ^= 1;
StartElevSound(Elevator[nElev].nSprite, var_18);
StartElevSound(Elevator[nElev].pActor, var_18);
}
else
{
runlist_SubRunRec(nRun);
Elevator[nElev].field_32 = -1;
StopSpriteSound(Elevator[nElev].nSprite);
D3PlayFX(StaticSound[nStopSound], Elevator[nElev].nSprite);
StopActorSound(Elevator[nElev].pActor);
D3PlayFX(StaticSound[nStopSound], Elevator[nElev].pActor);
runlist_ReadyChannel(nChannel);
}

View file

@ -410,10 +410,7 @@ void RestartPlayer(short nPlayer)
if (nPlayer == nLocalPlayer)
{
nLocalSpr = pActor->GetSpriteIndex();
RestoreGreenPal();
plr->bPlayerPan = plr->bLockPan = false;
}

View file

@ -648,7 +648,7 @@ void PlayFX2(unsigned short nSound, short nSprite, int sectf, EChanFlags chanfla
}
// Nuke: added nSprite >= 0 check
if (nSprite != nLocalSpr && nSprite >= 0 && (sprite[nSprite].cstat&257))
if (nSprite != PlayerList[nLocalPlayer].Actor()->GetSpriteIndex() && nSprite >= 0 && (sprite[nSprite].cstat&257))
nCreepyTimer = kCreepyCount;
}

View file

@ -288,10 +288,9 @@ void AISpider::Tick(RunListEvent* ev)
if (nMov.type == kHitNone && nMov.exbits == 0)
return;
Collision HiHit(hihit); // fixme
if (nMov.exbits & kHitAux1
&& sp->zvel < 0
&& HiHit.type != kHitSprite
&& hiHit.type != kHitSprite
&& !((sector[sp->sectnum].ceilingstat) & 1))
{
sp->cstat |= 8;