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