mirror of
https://github.com/DrBeef/Raze.git
synced 2025-02-20 18:52:43 +00:00
- marker stuff.
This commit is contained in:
parent
af7164c91d
commit
ffdb976f5b
5 changed files with 54 additions and 44 deletions
|
@ -1981,7 +1981,7 @@ void aiInitSprite(DBloodActor* actor)
|
|||
if (actor->GetTarget() == nullptr || actor->GetTarget()->s().type != kMarkerPath)
|
||||
{
|
||||
actor->SetTarget(nullptr);
|
||||
aiPatrolSetMarker(pSprite, pXSprite);
|
||||
aiPatrolSetMarker(actor);
|
||||
}
|
||||
|
||||
if (stateTimer > 0)
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
DUDEEXTRA dudeExtra;
|
||||
SPRITEMASS spriteMass;
|
||||
GENDUDEEXTRA genDudeExtra;
|
||||
DBloodActor* prevmarker; // needed by the nnext marker code. This originally hijacked targetX in XSPRITE
|
||||
|
||||
int cumulDamage; // this one's transient and does not need to be saved.
|
||||
bool explosionhackflag; // this originally hijacked the target field which is not safe when working with pointers.
|
||||
|
@ -106,6 +107,7 @@ public:
|
|||
void Clear()
|
||||
{
|
||||
explosionhackflag = false;
|
||||
prevmarker = nullptr;
|
||||
dudeSlope = 0;
|
||||
dudeExtra = {};
|
||||
spriteMass = {};
|
||||
|
|
|
@ -483,7 +483,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor& w, DB
|
|||
{
|
||||
arc("dudeslope", w.dudeSlope, def->dudeSlope)
|
||||
("dudeextra", w.dudeExtra, def->dudeExtra)
|
||||
("explosionflag", w.explosionhackflag, def->explosionhackflag);
|
||||
("explosionflag", w.explosionhackflag, def->explosionhackflag)
|
||||
("prevmarker", w.prevmarker, def->prevmarker);
|
||||
|
||||
if (gModernMap)
|
||||
{
|
||||
|
|
|
@ -7761,35 +7761,37 @@ bool markerIsNode(DBloodActor* mark, bool back)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void aiPatrolSetMarker(spritetype* pSprite, XSPRITE* pXSprite)
|
||||
void aiPatrolSetMarker(DBloodActor* actor)
|
||||
{
|
||||
auto actor = &bloodActors[pSprite->index];
|
||||
auto pSprite = &actor->s();
|
||||
auto pXSprite = &actor->x();
|
||||
auto targetactor = actor->GetTarget();
|
||||
|
||||
spritetype* pNext = NULL; XSPRITE* pXNext = NULL;
|
||||
spritetype* pPrev = NULL; XSPRITE* pXPrev = NULL;
|
||||
|
||||
int path = -1; int firstFinePath = -1; int prev = -1, next, i, closest = 200000;
|
||||
DBloodActor* selected = nullptr;
|
||||
int closest = 200000;
|
||||
|
||||
// select closest marker that dude can see
|
||||
if (pXSprite->target_i <= 0) {
|
||||
|
||||
if (targetactor == nullptr)
|
||||
{
|
||||
int zt1, zb1, zt2, zb2, dist;
|
||||
GetActorExtents(actor, &zt2, &zb2);
|
||||
for (i = headspritestat[kStatPathMarker]; i != -1; i = nextspritestat[i]) {
|
||||
|
||||
if (!xspriRangeIsFine(sprite[i].extra))
|
||||
continue;
|
||||
|
||||
pNext = &sprite[i]; pXNext = &xsprite[pNext->extra];
|
||||
BloodStatIterator it(kStatPathMarker);
|
||||
while (auto nextactor = it.Next())
|
||||
{
|
||||
if (!nextactor->hasX()) continue;
|
||||
|
||||
auto pNext = &nextactor->s();
|
||||
auto pXNext = &nextactor->x();
|
||||
|
||||
if (pXNext->locked || pXNext->isTriggered || pXNext->DudeLockout || (dist = approxDist(pNext->x - pSprite->x, pNext->y - pSprite->y)) > closest)
|
||||
continue;
|
||||
|
||||
GetSpriteExtents(pNext, &zt1, &zb1);
|
||||
GetActorExtents(nextactor, &zt1, &zb1);
|
||||
if (cansee(pNext->x, pNext->y, zt1, pNext->sectnum, pSprite->x, pSprite->y, zt2, pSprite->sectnum))
|
||||
{
|
||||
closest = dist;
|
||||
path = pNext->index;
|
||||
selected = nextactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7801,16 +7803,21 @@ void aiPatrolSetMarker(spritetype* pSprite, XSPRITE* pXSprite)
|
|||
// if reached marker is in radius of another marker with -3, but greater radius, use that marker
|
||||
// idea: for nodes only flag32 = specify if enemy must return back to node or allowed to select
|
||||
// another marker which belongs that node?
|
||||
spritetype* pPrev = NULL; XSPRITE* pXPrev = NULL;
|
||||
DBloodActor* prevactor = nullptr;
|
||||
|
||||
DBloodActor* firstFinePath = nullptr;
|
||||
int next;
|
||||
|
||||
int breakChance = 0;
|
||||
auto pCur = &targetactor->s();
|
||||
auto pXCur = &targetactor->x();
|
||||
if (pXSprite->targetX >= 0)
|
||||
if (actor->prevmarker)
|
||||
{
|
||||
pPrev = &sprite[pXSprite->targetX];
|
||||
pXPrev = &xsprite[pPrev->extra];
|
||||
prevactor = actor->prevmarker;
|
||||
pPrev = &prevactor->s();
|
||||
pXPrev = &prevactor->x();
|
||||
}
|
||||
prev = pCur->index;
|
||||
|
||||
bool node = markerIsNode(targetactor, false);
|
||||
pXSprite->unused2 = aiPatrolGetPathDir(pXSprite, pXCur); // decide if it should go back or forward
|
||||
|
@ -7818,21 +7825,23 @@ void aiPatrolSetMarker(spritetype* pSprite, XSPRITE* pXSprite)
|
|||
pXSprite->unused2 = kPatrolMoveForward;
|
||||
|
||||
bool back = (pXSprite->unused2 == kPatrolMoveBackward); next = (back) ? pXCur->data1 : pXCur->data2;
|
||||
for (i = headspritestat[kStatPathMarker]; i != -1; i = nextspritestat[i]) {
|
||||
|
||||
if (sprite[i].index == pXSprite->target_i || !xspriRangeIsFine(sprite[i].extra)) continue;
|
||||
else if (pXSprite->targetX >= 0 && sprite[i].index == pPrev->index && node) {
|
||||
BloodStatIterator it(kStatPathMarker);
|
||||
while(auto nextactor = it.Next())
|
||||
{
|
||||
if (nextactor == targetactor || !nextactor->hasX()) continue;
|
||||
else if (pXSprite->targetX >= 0 && nextactor == prevactor && node)
|
||||
{
|
||||
if (pXCur->data2 == pXPrev->data1)
|
||||
continue;
|
||||
}
|
||||
|
||||
pXNext = &xsprite[sprite[i].extra];
|
||||
auto pXNext = &nextactor->x();
|
||||
if ((pXNext->locked || pXNext->isTriggered || pXNext->DudeLockout) || (back && pXNext->data2 != next) || (!back && pXNext->data1 != next))
|
||||
continue;
|
||||
|
||||
if (firstFinePath == -1) firstFinePath = pXNext->reference;
|
||||
if (aiPatrolMarkerBusy(&bloodActors[pSprite->index], &bloodActors[pXNext->reference]) && !Chance(0x0010)) continue;
|
||||
else path = pXNext->reference;
|
||||
if (firstFinePath == nullptr) firstFinePath = nextactor;
|
||||
if (aiPatrolMarkerBusy(actor, nextactor) && !Chance(0x0010)) continue;
|
||||
else selected = nextactor;
|
||||
|
||||
breakChance += nnExtRandom(1, 5);
|
||||
if (breakChance >= 5)
|
||||
|
@ -7840,25 +7849,22 @@ void aiPatrolSetMarker(spritetype* pSprite, XSPRITE* pXSprite)
|
|||
|
||||
}
|
||||
|
||||
if (firstFinePath == -1) {
|
||||
|
||||
if (firstFinePath == nullptr)
|
||||
{
|
||||
viewSetSystemMessage("No markers with id #%d found for dude #%d! (back = %d)", next, pSprite->index, back);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (path == -1)
|
||||
path = firstFinePath;
|
||||
|
||||
if (selected == nullptr)
|
||||
selected = firstFinePath;
|
||||
}
|
||||
|
||||
if (!spriRangeIsFine(path))
|
||||
if (!selected)
|
||||
return;
|
||||
|
||||
pXSprite->target_i = path;
|
||||
pXSprite->targetX = prev; // keep previous marker index here, use actual sprite coords when selecting direction
|
||||
sprite[path].owner = pSprite->index;
|
||||
|
||||
actor->SetTarget(selected);
|
||||
selected->SetOwner(actor);
|
||||
actor->prevmarker = targetactor; // keep previous marker index here, use actual sprite coords when selecting direction
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -7876,6 +7882,7 @@ void aiPatrolStop(DBloodActor* actor, DBloodActor* targetactor, bool alarm)
|
|||
pXSprite->data3 = 0; // reset spot progress
|
||||
pXSprite->unused1 &= ~kDudeFlagCrouch; // reset the crouch status
|
||||
pXSprite->unused2 = kPatrolMoveForward; // reset path direction
|
||||
actor->prevmarker = nullptr;
|
||||
pXSprite->targetX = -1; // reset the previous marker index
|
||||
if (pXSprite->health <= 0)
|
||||
return;
|
||||
|
@ -8532,7 +8539,7 @@ void aiPatrolFlagsMgr(spritetype* pSource, XSPRITE* pXSource, spritetype* pDest,
|
|||
pXDest->stateTimer = 0;
|
||||
|
||||
|
||||
aiPatrolSetMarker(pDest, pXDest);
|
||||
aiPatrolSetMarker(destactor);
|
||||
if (spriteIsUnderwater(destactor)) aiPatrolState(destactor, kAiStatePatrolWaitW);
|
||||
else aiPatrolState(destactor, kAiStatePatrolWaitL);
|
||||
pXDest->data3 = 0; // reset the spot progress
|
||||
|
@ -8637,7 +8644,7 @@ void aiPatrolThink(DBloodActor* actor) {
|
|||
}
|
||||
|
||||
// move next marker
|
||||
aiPatrolSetMarker(pSprite, pXSprite);
|
||||
aiPatrolSetMarker(actor);
|
||||
|
||||
} else if (aiPatrolTurning(pXSprite->aiState)) {
|
||||
|
||||
|
@ -8753,7 +8760,7 @@ void aiPatrolThink(DBloodActor* actor) {
|
|||
}
|
||||
|
||||
// move the next marker
|
||||
aiPatrolSetMarker(pSprite, pXSprite);
|
||||
aiPatrolSetMarker(actor);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -388,7 +388,7 @@ XSPRITE* evrListRedirectors(int objType, int objXIndex, XSPRITE* pXRedir, int* t
|
|||
int listTx(XSPRITE* pXRedir, int tx);
|
||||
void seqSpawnerOffSameTx(XSPRITE* pXSource);
|
||||
// ------------------------------------------------------------------------- //
|
||||
void aiPatrolSetMarker(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
void aiPatrolSetMarker(DBloodActor* actor);
|
||||
void aiPatrolThink(DBloodActor* actor);
|
||||
void aiPatrolStop(DBloodActor* actor, DBloodActor* targetactor, bool alarm = false);
|
||||
void aiPatrolAlarmFull(spritetype* pSprite, XSPRITE* pXTarget, bool chain);
|
||||
|
|
Loading…
Reference in a new issue