From 7fa690082e5d2f2cb7d0b0cfd1871e74b6a80eb3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 4 May 2021 00:03:01 +0200 Subject: [PATCH] - fixed cherry picked commit. # Conflicts: # source/core/gamecontrol.h --- source/build/include/buildtypes.h | 1 + source/core/gamecontrol.h | 19 ++++++++ source/games/blood/src/ai.cpp | 16 ++++--- source/games/blood/src/db.cpp | 6 +-- source/games/blood/src/db.h | 2 + source/games/blood/src/nnexts.cpp | 68 ++++++++++++++++------------- source/games/blood/src/nnexts.h | 5 +-- source/games/blood/src/triggers.cpp | 8 ++-- source/games/blood/src/triggers.h | 7 ++- 9 files changed, 81 insertions(+), 51 deletions(-) diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 3ccba2923..4e9288795 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -197,6 +197,7 @@ enum CSTAT_SPRITE_ALIGNMENT_WALL = 1u<<4u, CSTAT_SPRITE_ALIGNMENT_FLOOR = 1u<<5u, CSTAT_SPRITE_ALIGNMENT_SLAB = 1u<<4u | 1u<<5u, + CSTAT_SPRITE_ALIGNMENT_SLOPE = 1u << 4u | 1u << 5u, CSTAT_SPRITE_ALIGNMENT_MASK = 1u<<4u | 1u<<5u, }; diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 748a5d80b..58a1c085e 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -11,6 +11,7 @@ #include "stats.h" #include "i_time.h" #include "palentry.h" +#include "build.h" EXTERN_CVAR(Bool, hud_textfont) @@ -249,3 +250,21 @@ enum gameaction_t : int ga_fullconsole, }; extern gameaction_t gameaction; + +inline void spriteSetSlope(int spritenum, int heinum) +{ + auto spr = &sprite[spritenum]; + int cstat = spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK; + if (spr->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR) + { + spr->xoffset = heinum & 255; + spr->yoffset = (heinum >> 8) & 255; + spr->cstat = (spr->cstat & ~CSTAT_SPRITE_ALIGNMENT_MASK) | (heinum != 0 ? CSTAT_SPRITE_ALIGNMENT_SLOPE : CSTAT_SPRITE_ALIGNMENT_FLOOR); + } +} + +inline int spriteGetSlope(int spritenum) +{ + auto spr = &sprite[spritenum]; + return ((spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLOPE)? 0 : uint8_t(spr->xoffset) + (uint8_t(spr->yoffset) << 8); +} diff --git a/source/games/blood/src/ai.cpp b/source/games/blood/src/ai.cpp index c1e6b6bd2..82c005b94 100644 --- a/source/games/blood/src/ai.cpp +++ b/source/games/blood/src/ai.cpp @@ -30,6 +30,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS +void RecoilDude(DBloodActor* actor); + int cumulDamage[kMaxXSprites]; DUDEEXTRA gDudeExtra[kMaxXSprites]; @@ -917,11 +919,11 @@ int aiDamageSprite(DBloodActor* source, DBloodActor* actor, DAMAGE_TYPE nDmgType int fullHp = (pXSprite->sysData2 > 0) ? ClipRange(pXSprite->sysData2 << 4, 1, 65535) : getDudeInfo(pSprite->type)->startHealth << 4; if (((100 * pXSprite->health) / fullHp) <= 75) { cumulDamage[pSprite->extra] += nDamage << 4; // to be sure any enemy will play the recoil animation - RecoilDude(pSprite, pXSprite); + RecoilDude(&bloodActors[pXSprite->reference]); } } - consoleSysMsg("Player #%d does the critical damage to patrol dude #%d!", pPlayer->nPlayer + 1, pSprite->index); + DPrintf(DMSG_SPAMMY, "Player #%d does the critical damage to patrol dude #%d!", pPlayer->nPlayer + 1, pSprite->index); } return nDamage; @@ -929,9 +931,9 @@ int aiDamageSprite(DBloodActor* source, DBloodActor* actor, DAMAGE_TYPE nDmgType if (pSprite->type == kDudeModernCustomBurning) { - if (Chance(0x2000) && gDudeExtra[pSprite->extra].at0 < (int)gFrameClock) { + if (Chance(0x2000) && gDudeExtra[pSprite->extra].time < (int)gFrameClock) { playGenDudeSound(pSprite, kGenDudeSndBurning); - gDudeExtra[pSprite->extra].at0 = (int)gFrameClock + 360; + gDudeExtra[pSprite->extra].time = (int)gFrameClock + 360; } if (pXSprite->burnTime == 0) pXSprite->burnTime = 2400; @@ -977,7 +979,7 @@ int aiDamageSprite(DBloodActor* source, DBloodActor* actor, DAMAGE_TYPE nDmgType aiGenDudeNewState(pSprite, &genDudeBurnGoto); actHealDude(pXSprite, dudeInfo[55].startHealth, dudeInfo[55].startHealth); - gDudeExtra[pSprite->extra].at0 = (int)gFrameClock + 360; + gDudeExtra[pSprite->extra].time = (int)gFrameClock + 360; evKill(nSprite, 3, kCallbackFXFlameLick); } @@ -991,13 +993,13 @@ int aiDamageSprite(DBloodActor* source, DBloodActor* actor, DAMAGE_TYPE nDmgType if (!dudeIsMelee(pXSprite)) { if (inIdle(pXSprite->aiState) || Chance(getDodgeChance(pSprite))) { if (!spriteIsUnderwater(pSprite)) { - if (!canDuck(pSprite) || !sub_5BDA8(pSprite, 14)) aiGenDudeNewState(pSprite, &genDudeDodgeShortL); + if (!canDuck(pSprite) || !dudeIsPlayingSeq(pSprite, 14)) aiGenDudeNewState(pSprite, &genDudeDodgeShortL); else aiGenDudeNewState(pSprite, &genDudeDodgeShortD); if (Chance(0x0200)) playGenDudeSound(pSprite, kGenDudeSndGotHit); - } else if (sub_5BDA8(pSprite, 13)) { + } else if (dudeIsPlayingSeq(pSprite, 13)) { aiGenDudeNewState(pSprite, &genDudeDodgeShortW); } } diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index cb6a53c9c..7537af480 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -718,7 +718,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor pXSector->Depth = bitReader.readUnsigned(3); pXSector->panVel = bitReader.readUnsigned(8); pXSector->panAngle = bitReader.readUnsigned(11); - bitReader.readUnsigned(1); + pXSector->unused1 = bitReader.readUnsigned(1); pXSector->decoupled = bitReader.readUnsigned(1); pXSector->triggerOnce = bitReader.readUnsigned(1); pXSector->isTriggered = bitReader.readUnsigned(1); @@ -730,7 +730,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor pXSector->Exit = bitReader.readUnsigned(1); pXSector->Wallpush = bitReader.readUnsigned(1); pXSector->color = bitReader.readUnsigned(1); - bitReader.readUnsigned(1); + /*pXSector->unused2 =*/ bitReader.readUnsigned(1); pXSector->busyTimeB = bitReader.readUnsigned(12); pXSector->waitTimeB = bitReader.readUnsigned(12); pXSector->stopOn = bitReader.readUnsigned(1); @@ -921,7 +921,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor pXSprite->Interrutable = bitReader.readUnsigned(1); bitReader.readUnsigned(2); pXSprite->respawnPending = bitReader.readUnsigned(2); - bitReader.readUnsigned(1); + pXSprite->unused2 = bitReader.readUnsigned(1); pXSprite->lT = bitReader.readUnsigned(1); pXSprite->dropMsg = bitReader.readUnsigned(8); pXSprite->Decoupled = bitReader.readUnsigned(1); diff --git a/source/games/blood/src/db.h b/source/games/blood/src/db.h index d1d10685f..bf3d4a429 100644 --- a/source/games/blood/src/db.h +++ b/source/games/blood/src/db.h @@ -95,6 +95,7 @@ struct XSPRITE { unsigned int wave : 2; // Wave unsigned int medium : 2; // medium unsigned int respawn : 2; // Respawn option + unsigned int unused2 : 1; // (new) patrol state }; }; int32_t targetX; // target x @@ -175,6 +176,7 @@ struct XSECTOR { unsigned int bobFloor : 1; // Motion bob floor unsigned int bobCeiling : 1; // Motion bob ceiling unsigned int bobRotate : 1; // Motion rotate + unsigned int unused1 : 1; // (new) pause motion }; }; diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 54acaaed3..8ed7147a7 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -36,6 +36,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS +inline int mulscale8(int a, int b) { return MulScale(a, b, 8); } + bool gAllowTrueRandom = false; bool gEventRedirectsUsed = false; SPRITEMASS gSpriteMass[]; // cache for getSpriteMassBySize(); @@ -2581,7 +2583,7 @@ void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) { sprite[nSprite].z = top; break; case 4: - sprite[nSprite].z = sprite[index].z + (tilesiz[sprite[index].picnum].y / 2 + picanm[sprite[index].picnum].yofs); + sprite[nSprite].z = sprite[index].z + tileHeight(sprite[index].picnum) / 2 + tileTopOffset(sprite[index].picnum); break; case 5: case 6: @@ -3901,7 +3903,7 @@ int aiFightGetFineTargetDist(spritetype* pSprite, spritetype* pTarget) { int sectorInMotion(int nSector) { for (int i = 0; i < kMaxBusyCount; i++) { - if (gBusy->at0 == nSector) return i; + if (gBusy->index == nSector) return i; } return -1; @@ -3909,7 +3911,7 @@ int sectorInMotion(int nSector) { void sectorPauseMotion(int nSector) { - dassert(xsectRangeIsFine(sector[nSector].extra)); + assert(xsectRangeIsFine(sector[nSector].extra)); xsector[sector[nSector].extra].unused1 = 1; SectorEndSound(nSector, xsector[sector[nSector].extra].state); /*for (int nSprite = headspritesect[nSector]; nSprite >= 0; nSprite = nextspritesect[nSprite]) { @@ -3929,7 +3931,7 @@ void sectorContinueMotion(int nSector, EVENT event) { if (gBusyCount >= kMaxBusyCount) return; - dassert(xsectRangeIsFine(sector[nSector].extra)); + assert(xsectRangeIsFine(sector[nSector].extra)); XSECTOR* pXSector = &xsector[sector[nSector].extra]; pXSector->unused1 = 0; @@ -3974,15 +3976,15 @@ void sectorContinueMotion(int nSector, EVENT event) { busyFunc = BUSYID_7; break; default: - ThrowError("Unsupported sector type %d", sector[nSector].type); + I_Error("Unsupported sector type %d", sector[nSector].type); break; } nDelta = (pXSector->state) ? -nDelta : nDelta; - gBusy[gBusyCount].at0 = nSector; - gBusy[gBusyCount].at4 = nDelta; - gBusy[gBusyCount].at8 = pXSector->busy; - gBusy[gBusyCount].atc = (BUSYID)busyFunc; + gBusy[gBusyCount].index = nSector; + gBusy[gBusyCount].delta = nDelta; + gBusy[gBusyCount].busy = pXSector->busy; + gBusy[gBusyCount].type = (BUSYID)busyFunc; gBusyCount++; SectorStartSound(nSector, pXSector->state); @@ -5620,7 +5622,7 @@ bool aiPatrolMoving(AISTATE* pAiState) { void aiPatrolState(spritetype* pSprite, int state) { - dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); + assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); XSPRITE* pXSprite = &xsprite[pSprite->extra]; int seq = -1, i, start, end; bool crouch; @@ -5667,7 +5669,7 @@ void aiPatrolState(spritetype* pSprite, int state) { if (curState->stateType != state || seq != curState->seqId) continue; aiChooseDirection(pSprite, pXSprite, getangle(pXSprite->targetX - pSprite->x, pXSprite->targetY - pSprite->y)); if (pSprite->type == kDudeModernCustom) aiGenDudeNewState(pSprite, &genPatrolStates[i]); - else aiNewState(pSprite, pXSprite, &genPatrolStates[i]); + else aiNewState(&bloodActors[pXSprite->reference], &genPatrolStates[i]); pXSprite->unused2 = crouch; @@ -5713,8 +5715,8 @@ bool aiPatrolMarkerReached(spritetype* pSprite, XSPRITE* pXSprite) { // ignore z of marker for ground spritetype* pMarker = &sprite[pXSprite->target]; - int oX = klabs(pMarker->x - pSprite->x) >> 4; - int oY = klabs(pMarker->y - pSprite->y) >> 4; + int oX = abs(pMarker->x - pSprite->x) >> 4; + int oY = abs(pMarker->y - pSprite->y) >> 4; return (approxDist(oX, oY) <= okDist); } @@ -5802,7 +5804,7 @@ void aiPatrolStop(spritetype* pSprite, int target, bool alarm) { if (spriRangeIsFine(target) && IsDudeSprite(&sprite[target]) && xspriRangeIsFine(sprite[target].extra)) { aiSetTarget(pXSprite, target); - aiActivateDude(pSprite, pXSprite); + aiActivateDude(&bloodActors[pXSprite->reference]); if (alarm) aiPatrolAlarm(pSprite, Chance(0x0500)); @@ -5830,7 +5832,7 @@ void aiPatrolMoveZ(spritetype* pSprite, XSPRITE* pXSprite) { int nAng = ((pXSprite->goalAng + 1024 - pSprite->ang) & 2047) - 1024; int nTurnRange = (pDudeInfo->angSpeed << 2) >> 4; pSprite->ang = (pSprite->ang + ClipRange(nAng, -nTurnRange, nTurnRange)) & 2047; - if (klabs(nAng) > 341) { + if (abs(nAng) > 341) { pSprite->ang = (pSprite->ang + 512) & 2047; return; } @@ -5840,7 +5842,10 @@ void aiPatrolMoveZ(spritetype* pSprite, XSPRITE* pXSprite) { } -void aiPatrolMove(spritetype* pSprite, XSPRITE* pXSprite) { + +void aiPatrolMove(DBloodActor* actor) { + auto pXSprite = &actor->x(); + auto pSprite = &actor->s(); if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax)) return; @@ -5863,7 +5868,7 @@ void aiPatrolMove(spritetype* pSprite, XSPRITE* pXSprite) { if (pSprite->type == kDudeModernCustom) { - aiGenDudeMoveForward(pSprite, pXSprite); + aiGenDudeMoveForward(&bloodActors[pXSprite->reference]); } else { @@ -5873,9 +5878,9 @@ void aiPatrolMove(spritetype* pSprite, XSPRITE* pXSprite) { int frontSpeed = pDudeInfo->frontSpeed; pSprite->ang = (pSprite->ang + ClipRange(nAng, -nTurnRange, nTurnRange)) & 2047; - if (klabs(nAng) <= 341) { - xvel[pSprite->index] += mulscale30(frontSpeed, Cos(pSprite->ang)); - yvel[pSprite->index] += mulscale30(frontSpeed, Sin(pSprite->ang)); + if (abs(nAng) <= 341) { + xvel[pSprite->index] += MulScale(frontSpeed, Cos(pSprite->ang), 30); + yvel[pSprite->index] += MulScale(frontSpeed, Sin(pSprite->ang), 30); } } @@ -5908,13 +5913,13 @@ void aiPatrolAlarm(spritetype* pSprite, bool chain) { if (spriRangeIsFine(target)) aiSetTarget(pXDude, target); else aiSetTarget(pXDude, pXSprite->targetX, pXSprite->targetY, pXSprite->targetZ); - aiActivateDude(pDude, pXDude); + aiActivateDude(&bloodActors[pXDude->reference]); if (chain) { aiPatrolAlarm(pDude, Chance(chainChance)); chainChance -= 0x0100; } - consoleSysMsg("Dude #%d alarms dude #%d", pSprite->index, pDude->index); + DPrintf(DMSG_SPAMMY, "Dude #%d alarms dude #%d", pSprite->index, pDude->index); } } @@ -5961,12 +5966,12 @@ bool readyForCrit(spritetype* pHunter, spritetype* pVictim) { DUDEINFO* pDudeInfo = getDudeInfo(pVictim->type); int nDeltaAngle = ((getangle(dx, dy) + 1024 - pVictim->ang) & 2047) - 1024; - return (klabs(nDeltaAngle) < (pDudeInfo->periphery >> 1)); + return (abs(nDeltaAngle) < (pDudeInfo->periphery >> 1)); } int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) { - dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); + assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); int i, x, y, z, dx, dy, nDist, eyeAboveZ; PLAYER* pPlayer = NULL; @@ -6049,12 +6054,12 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) { if (nDist < hearDist && hearChance > 0) { - consoleSysMsg("Patrol dude #%d hearing the Player #%d.", pSprite->index, pPlayer->nPlayer + 1); + DPrintf(DMSG_SPAMMY, "Patrol dude #%d hearing the Player #%d.", pSprite->index, pPlayer->nPlayer + 1); pXSprite->data3 += hearChance; } - if (nDist < seeDist && klabs(nDeltaAngle) < periphery && seeChance > 0) { - consoleSysMsg("Patrol dude #%d seeing the Player #%d.", pSprite->index, pPlayer->nPlayer + 1); + if (nDist < seeDist && abs(nDeltaAngle) < periphery && seeChance > 0) { + DPrintf(DMSG_SPAMMY, "Patrol dude #%d seeing the Player #%d.", pSprite->index, pPlayer->nPlayer + 1); pXSprite->data3 += seeChance; } @@ -6066,7 +6071,7 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) { } else { - consoleSysMsg("Patrol dude #%d spot the Player #%d via touch.", pSprite->index, pPlayer->nPlayer + 1); + DPrintf(DMSG_SPAMMY, "Patrol dude #%d spot the Player #%d via touch.", pSprite->index, pPlayer->nPlayer + 1); if (invisible) pPlayer->pwUpTime[kPwUpShadowCloak] = 0; target = pSpr->index; break; @@ -6083,9 +6088,12 @@ int aiPatrolSearchTargets(spritetype* pSprite, XSPRITE* pXSprite) { return -1; } -void aiPatrolThink(spritetype* pSprite, XSPRITE* pXSprite) { +void aiPatrolThink(DBloodActor*actor) { + + auto pXSprite = &actor->x(); + auto pSprite = &actor->s(); + assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); - dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax); int nTarget = -1; if ((nTarget = aiPatrolSearchTargets(pSprite, pXSprite)) != -1) { diff --git a/source/games/blood/src/nnexts.h b/source/games/blood/src/nnexts.h index 50c5a4d37..47d75a0a2 100644 --- a/source/games/blood/src/nnexts.h +++ b/source/games/blood/src/nnexts.h @@ -37,7 +37,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "actor.h" #include "dude.h" #include "player.h" -#include "triggers.h" BEGIN_BLD_NS @@ -372,11 +371,11 @@ int listTx(XSPRITE* pXRedir, int tx); void seqSpawnerOffSameTx(XSPRITE* pXSource); // ------------------------------------------------------------------------- // void aiPatrolSetMarker(spritetype* pSprite, XSPRITE* pXSprite); -void aiPatrolThink(spritetype* pSprite, XSPRITE* pXSprite); +void aiPatrolThink(DBloodActor* actor); void aiPatrolStop(spritetype* pSprite, int target, bool alarm = false); void aiPatrolAlarm(spritetype* pSprite, bool chain); void aiPatrolState(spritetype* pSprite, int state); -void aiPatrolMove(spritetype* pSprite, XSPRITE* pXSprite); +void aiPatrolMove(DBloodActor* actor); int aiPatrolMarkerBusy(int nExcept, int nMarker); bool aiPatrolMarkerReached(spritetype* pSprite, XSPRITE* pXSprite); AISTATE* aiInPatrolState(AISTATE* pAiState); diff --git a/source/games/blood/src/triggers.cpp b/source/games/blood/src/triggers.cpp index 535712cf5..f1ef8d700 100644 --- a/source/games/blood/src/triggers.cpp +++ b/source/games/blood/src/triggers.cpp @@ -1965,13 +1965,13 @@ void trProcessBusy(void) for (int i = gBusyCount-1; i >= 0; i--) { int nStatus; - int oldBusy = gBusy[i].at8; - gBusy[i].at8 = ClipRange(oldBusy+gBusy[i].at4*4, 0, 65536); + int oldBusy = gBusy[i].busy; + gBusy[i].busy = ClipRange(oldBusy+gBusy[i].delta*4, 0, 65536); #ifdef NOONE_EXTENSIONS - if (!gModernMap || !xsector[sector[gBusy[i].at0].extra].unused1) nStatus = gBusyProc[gBusy[i].atc](gBusy[i].at0, gBusy[i].at8); + if (!gModernMap || !xsector[sector[gBusy[i].index].extra].unused1) nStatus = gBusyProc[gBusy[i].type](gBusy[i].index, gBusy[i].busy); else nStatus = 3; // allow to pause/continue motion for sectors any time by sending special command #else - nStatus = gBusyProc[gBusy[i].atc](gBusy[i].at0, gBusy[i].at8); + nStatus = gBusyProc[gBusy[i].type](gBusy[i].at0, gBusy[i].at8); #endif switch (nStatus) { case 1: diff --git a/source/games/blood/src/triggers.h b/source/games/blood/src/triggers.h index f80b913cf..f65665ac4 100644 --- a/source/games/blood/src/triggers.h +++ b/source/games/blood/src/triggers.h @@ -29,6 +29,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "dude.h" #include "player.h" +BEGIN_BLD_NS + enum BUSYID { BUSYID_0 = 0, BUSYID_1, @@ -45,10 +47,7 @@ struct BUSY { int index; int delta; int busy; -/* int at0; - int at4; - int at8;*/ - BUSYID atc; + int/*BUSYID*/ type; }; extern BUSY gBusy[kMaxBusyCount];