mirror of
https://github.com/DrBeef/Raze.git
synced 2025-02-07 16:31:17 +00:00
- refactor the spider to use actors.
This commit is contained in:
parent
6821fef5e1
commit
2c8da6fe72
5 changed files with 60 additions and 113 deletions
|
@ -842,7 +842,6 @@ void FuncSnake(int, int, int, int);
|
||||||
|
|
||||||
// spider
|
// spider
|
||||||
|
|
||||||
void InitSpider();
|
|
||||||
DExhumedActor* BuildSpider(DExhumedActor* nSprite, int x, int y, int z, short nSector, int nAngle);
|
DExhumedActor* BuildSpider(DExhumedActor* nSprite, int x, int y, int z, short nSector, int nAngle);
|
||||||
void FuncSpider(int a, int, int b, int nRun);
|
void FuncSpider(int a, int, int b, int nRun);
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ enum ECounter
|
||||||
kCountRex,
|
kCountRex,
|
||||||
kCountRoach,
|
kCountRoach,
|
||||||
kCountScorp,
|
kCountScorp,
|
||||||
|
kCountSpider,
|
||||||
|
|
||||||
kNumCounters
|
kNumCounters
|
||||||
};
|
};
|
||||||
|
|
|
@ -106,7 +106,6 @@ uint8_t LoadLevel(MapRecord* map)
|
||||||
InitBubbles();
|
InitBubbles();
|
||||||
InitObjects();
|
InitObjects();
|
||||||
InitPushBlocks();
|
InitPushBlocks();
|
||||||
InitSpider();
|
|
||||||
InitPlayer();
|
InitPlayer();
|
||||||
InitItems();
|
InitItems();
|
||||||
InitInput();
|
InitInput();
|
||||||
|
|
|
@ -51,7 +51,6 @@ void SerializeView(FSerializer& arc);
|
||||||
void SerializeQueen(FSerializer& arc);
|
void SerializeQueen(FSerializer& arc);
|
||||||
void SerializeRat(FSerializer& arc);
|
void SerializeRat(FSerializer& arc);
|
||||||
void SerializeSet(FSerializer& arc);
|
void SerializeSet(FSerializer& arc);
|
||||||
void SerializeSpider(FSerializer& arc);
|
|
||||||
void SerializeWasp(FSerializer& arc);
|
void SerializeWasp(FSerializer& arc);
|
||||||
|
|
||||||
void GameInterface::SerializeGameState(FSerializer& arc)
|
void GameInterface::SerializeGameState(FSerializer& arc)
|
||||||
|
@ -81,7 +80,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
|
||||||
SerializeQueen(arc);
|
SerializeQueen(arc);
|
||||||
SerializeRat(arc);
|
SerializeRat(arc);
|
||||||
SerializeSet(arc);
|
SerializeSet(arc);
|
||||||
SerializeSpider(arc);
|
|
||||||
SerializeWasp(arc);
|
SerializeWasp(arc);
|
||||||
}
|
}
|
||||||
if (arc.isReading())
|
if (arc.isReading())
|
||||||
|
|
|
@ -25,18 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
BEGIN_PS_NS
|
BEGIN_PS_NS
|
||||||
|
|
||||||
struct Spider
|
|
||||||
{
|
|
||||||
short nHealth;
|
|
||||||
short nFrame;
|
|
||||||
short nAction;
|
|
||||||
short nSprite;
|
|
||||||
short nTarget;
|
|
||||||
short nRun;
|
|
||||||
};
|
|
||||||
|
|
||||||
static TArray<Spider> SpiderList;
|
|
||||||
|
|
||||||
static actionSeq SpiderSeq[] = {
|
static actionSeq SpiderSeq[] = {
|
||||||
{16, 0},
|
{16, 0},
|
||||||
{8, 0},
|
{8, 0},
|
||||||
|
@ -47,48 +35,19 @@ static actionSeq SpiderSeq[] = {
|
||||||
{41, 1}
|
{41, 1}
|
||||||
};
|
};
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* keyname, Spider& w, Spider* def)
|
|
||||||
{
|
|
||||||
if (arc.BeginObject(keyname))
|
|
||||||
{
|
|
||||||
arc("health", w.nHealth)
|
|
||||||
("frame", w.nFrame)
|
|
||||||
("action", w.nAction)
|
|
||||||
("sprite", w.nSprite)
|
|
||||||
("target", w.nTarget)
|
|
||||||
("run", w.nRun)
|
|
||||||
.EndObject();
|
|
||||||
}
|
|
||||||
return arc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerializeSpider(FSerializer& arc)
|
DExhumedActor* BuildSpider(DExhumedActor* spp, int x, int y, int z, short nSector, int nAngle)
|
||||||
{
|
{
|
||||||
arc("spider", SpiderList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitSpider()
|
|
||||||
{
|
|
||||||
SpiderList.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
DExhumedActor* BuildSpider(DExhumedActor* pActor, int x, int y, int z, short nSector, int nAngle)
|
|
||||||
{
|
|
||||||
auto nSpider = SpiderList.Reserve(1);
|
|
||||||
auto spp = &SpiderList[nSpider];
|
|
||||||
|
|
||||||
int nSprite;
|
|
||||||
spritetype* sp;
|
spritetype* sp;
|
||||||
if (pActor == nullptr)
|
if (spp == nullptr)
|
||||||
{
|
{
|
||||||
nSprite = insertsprite(nSector, 99);
|
spp = insertActor(nSector, 99);
|
||||||
sp = &sprite[nSprite];
|
sp = &spp->s();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nSprite = pActor->GetSpriteIndex();
|
ChangeActorStat(spp, 99);
|
||||||
changespritestat(nSprite, 99);
|
sp = &spp->s();
|
||||||
sp = &sprite[nSprite];
|
|
||||||
|
|
||||||
x = sp->x;
|
x = sp->x;
|
||||||
y = sp->y;
|
y = sp->y;
|
||||||
|
@ -96,8 +55,6 @@ DExhumedActor* BuildSpider(DExhumedActor* pActor, int x, int y, int z, short nSe
|
||||||
nAngle = sp->ang;
|
nAngle = sp->ang;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(nSprite >= 0 && nSprite < kMaxSprites);
|
|
||||||
|
|
||||||
sp->x = x;
|
sp->x = x;
|
||||||
sp->y = y;
|
sp->y = y;
|
||||||
sp->z = z;
|
sp->z = z;
|
||||||
|
@ -122,27 +79,25 @@ DExhumedActor* BuildSpider(DExhumedActor* pActor, int x, int y, int z, short nSe
|
||||||
|
|
||||||
spp->nAction = 0;
|
spp->nAction = 0;
|
||||||
spp->nFrame = 0;
|
spp->nFrame = 0;
|
||||||
spp->nSprite = nSprite;
|
spp->pTarget = nullptr;
|
||||||
spp->nTarget = -1;
|
|
||||||
spp->nHealth = 160;
|
spp->nHealth = 160;
|
||||||
|
spp->nPhase = Counters[kCountSpider]++;
|
||||||
|
|
||||||
sp->owner = runlist_AddRunRec(sp->lotag - 1, nSpider, 0xC0000);
|
sp->owner = runlist_AddRunRec(sp->lotag - 1, spp, 0xC0000);
|
||||||
|
|
||||||
spp->nRun = runlist_AddRunRec(NewRun, nSpider, 0xC0000);
|
spp->nRun = runlist_AddRunRec(NewRun, spp, 0xC0000);
|
||||||
|
|
||||||
nCreaturesTotal++;
|
nCreaturesTotal++;
|
||||||
|
|
||||||
return &exhumedActors[nSprite];
|
return spp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AISpider::Tick(RunListEvent* ev)
|
void AISpider::Tick(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
int nSpider = RunData[ev->nRun].nObjIndex;
|
auto spp = ev->pObjActor;
|
||||||
auto spp = &SpiderList[nSpider];
|
if (!spp) return;
|
||||||
assert(nSpider >= 0 && nSpider < (int)SpiderList.Size());
|
|
||||||
|
|
||||||
int nSprite = spp->nSprite;
|
auto sp = &spp->s();
|
||||||
auto sp = &sprite[nSprite];
|
|
||||||
short nAction = spp->nAction;
|
short nAction = spp->nAction;
|
||||||
|
|
||||||
int nVel = 6;
|
int nVel = 6;
|
||||||
|
@ -151,11 +106,11 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
if (sp->cstat & 8)
|
if (sp->cstat & 8)
|
||||||
{
|
{
|
||||||
sp->z = sector[sp->sectnum].ceilingz + GetSpriteHeight(nSprite);
|
sp->z = sector[sp->sectnum].ceilingz + GetActorHeight(spp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Gravity(nSprite);
|
Gravity(spp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +118,7 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
|
|
||||||
sp->picnum = seq_GetSeqPicnum2(nSeq, spp->nFrame);
|
sp->picnum = seq_GetSeqPicnum2(nSeq, spp->nFrame);
|
||||||
|
|
||||||
seq_MoveSequence(nSprite, nSeq, spp->nFrame);
|
seq_MoveSequence(spp, nSeq, spp->nFrame);
|
||||||
|
|
||||||
int nFrameFlag = FrameFlag[SeqBase[nSeq] + spp->nFrame];
|
int nFrameFlag = FrameFlag[SeqBase[nSeq] + spp->nFrame];
|
||||||
|
|
||||||
|
@ -172,9 +127,9 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
spp->nFrame = 0;
|
spp->nFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
short nTarget = spp->nTarget;
|
auto pTarget = spp->pTarget;
|
||||||
|
|
||||||
if (nTarget <= -1 || sprite[nTarget].cstat & 0x101)
|
if (pTarget == nullptr || pTarget->s().cstat & 0x101)
|
||||||
{
|
{
|
||||||
switch (nAction)
|
switch (nAction)
|
||||||
{
|
{
|
||||||
|
@ -183,17 +138,17 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
if ((nSpider & 0x1F) == (totalmoves & 0x1F))
|
if ((spp->nPhase & 0x1F) == (totalmoves & 0x1F))
|
||||||
{
|
{
|
||||||
if (nTarget < 0) {
|
if (pTarget == nullptr) {
|
||||||
nTarget = FindPlayer(nSprite, 100);
|
pTarget = FindPlayer(spp, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nTarget >= 0)
|
if (pTarget)
|
||||||
{
|
{
|
||||||
spp->nAction = 1;
|
spp->nAction = 1;
|
||||||
spp->nFrame = 0;
|
spp->nFrame = 0;
|
||||||
spp->nTarget = nTarget;
|
spp->pTarget = pTarget;
|
||||||
|
|
||||||
sp->xvel = bcos(sp->ang);
|
sp->xvel = bcos(sp->ang);
|
||||||
sp->yvel = bsin(sp->ang);
|
sp->yvel = bsin(sp->ang);
|
||||||
|
@ -205,7 +160,7 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
if (nTarget >= 0) {
|
if (pTarget) {
|
||||||
nVel++;
|
nVel++;
|
||||||
}
|
}
|
||||||
goto case_3;
|
goto case_3;
|
||||||
|
@ -218,7 +173,7 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
spp->nFrame = 0;
|
spp->nFrame = 0;
|
||||||
spp->nAction = 1;
|
spp->nAction = 1;
|
||||||
}
|
}
|
||||||
fallthrough__;
|
[[fallthrough]];
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
|
@ -240,9 +195,9 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((totalmoves & 0x1F) == (nSpider & 0x1F))
|
if ((totalmoves & 0x1F) == (spp->nPhase & 0x1F))
|
||||||
{
|
{
|
||||||
PlotCourseToSprite(nSprite, nTarget);
|
PlotCourseToSprite(spp, pTarget);
|
||||||
|
|
||||||
if (RandomSize(3))
|
if (RandomSize(3))
|
||||||
{
|
{
|
||||||
|
@ -261,7 +216,7 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
sp->cstat ^= 8;
|
sp->cstat ^= 8;
|
||||||
sp->zvel = 1;
|
sp->zvel = 1;
|
||||||
sp->z = sector[nSector].ceilingz + GetSpriteHeight(nSprite);
|
sp->z = sector[nSector].ceilingz + GetActorHeight(spp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -272,7 +227,7 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
spp->nFrame = 0;
|
spp->nFrame = 0;
|
||||||
|
|
||||||
if (!RandomSize(3)) {
|
if (!RandomSize(3)) {
|
||||||
D3PlayFX(StaticSound[kSound29], nSprite);
|
D3PlayFX(StaticSound[kSound29], spp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,21 +241,21 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
runlist_FreeRun(sp->lotag - 1);
|
runlist_FreeRun(sp->lotag - 1);
|
||||||
runlist_SubRunRec(spp->nRun);
|
runlist_SubRunRec(spp->nRun);
|
||||||
sp->cstat = 0x8000;
|
sp->cstat = 0x8000;
|
||||||
mydeletesprite(nSprite);
|
DeleteActor(spp);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
if (nTarget != -1)
|
if (pTarget)
|
||||||
{
|
{
|
||||||
if (nFrameFlag & 0x80)
|
if (nFrameFlag & 0x80)
|
||||||
{
|
{
|
||||||
runlist_DamageEnemy(nTarget, nSprite, 3);
|
runlist_DamageEnemy(pTarget, spp, 3);
|
||||||
D3PlayFX(StaticSound[kSound38], nSprite);
|
D3PlayFX(StaticSound[kSound38], spp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PlotCourseToSprite(nSprite, nTarget) < 1024) {
|
if (PlotCourseToSprite(spp, pTarget) < 1024) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +275,7 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
spp->nTarget = -1;
|
spp->pTarget = nullptr;
|
||||||
spp->nAction = 0;
|
spp->nAction = 0;
|
||||||
spp->nFrame = 0;
|
spp->nFrame = 0;
|
||||||
|
|
||||||
|
@ -328,18 +283,19 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
sp->yvel = 0;
|
sp->yvel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nMov = movesprite(nSprite, sp->xvel << nVel, sp->yvel << nVel, sp->zvel, 1280, -1280, CLIPMASK0);
|
auto nMov = movesprite(spp, sp->xvel << nVel, sp->yvel << nVel, sp->zvel, 1280, -1280, CLIPMASK0);
|
||||||
|
|
||||||
if (!nMov)
|
if (nMov.type == kHitNone && nMov.exbits == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (nMov & 0x10000
|
Collision HiHit(hihit); // fixme
|
||||||
|
if (nMov.exbits & kHitAux1
|
||||||
&& sp->zvel < 0
|
&& sp->zvel < 0
|
||||||
&& (hihit & 0xC000) != 0xC000
|
&& HiHit.type != kHitSprite
|
||||||
&& !((sector[sp->sectnum].ceilingstat) & 1))
|
&& !((sector[sp->sectnum].ceilingstat) & 1))
|
||||||
{
|
{
|
||||||
sp->cstat |= 8;
|
sp->cstat |= 8;
|
||||||
sp->z = GetSpriteHeight(nSprite) + sector[sp->sectnum].ceilingz;
|
sp->z = GetActorHeight(spp) + sector[sp->sectnum].ceilingz;
|
||||||
sp->zvel = 0;
|
sp->zvel = 0;
|
||||||
|
|
||||||
spp->nAction = 1;
|
spp->nAction = 1;
|
||||||
|
@ -348,20 +304,20 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (nMov & 0xC000)
|
switch (nMov.type)
|
||||||
{
|
{
|
||||||
case 0x8000:
|
case kHitWall:
|
||||||
{
|
{
|
||||||
sp->ang = (sp->ang + 256) & 0x7EF;
|
sp->ang = (sp->ang + 256) & 0x7EF;
|
||||||
sp->xvel = bcos(sp->ang);
|
sp->xvel = bcos(sp->ang);
|
||||||
sp->yvel = bsin(sp->ang);
|
sp->yvel = bsin(sp->ang);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0xC000:
|
case kHitSprite:
|
||||||
{
|
{
|
||||||
if ((nMov & 0x3FFF) == nTarget)
|
if (nMov.actor == pTarget)
|
||||||
{
|
{
|
||||||
int nAng = getangle(sprite[nTarget].x - sp->x, sprite[nTarget].y - sp->y);
|
int nAng = getangle(pTarget->s().x - sp->x, pTarget->s().y - sp->y);
|
||||||
if (AngleDiff(sp->ang, nAng) < 64)
|
if (AngleDiff(sp->ang, nAng) < 64)
|
||||||
{
|
{
|
||||||
spp->nAction = 2;
|
spp->nAction = 2;
|
||||||
|
@ -387,9 +343,8 @@ void AISpider::Tick(RunListEvent* ev)
|
||||||
|
|
||||||
void AISpider::Draw(RunListEvent* ev)
|
void AISpider::Draw(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
int nSpider = RunData[ev->nRun].nObjIndex;
|
auto spp = ev->pObjActor;
|
||||||
auto spp = &SpiderList[nSpider];
|
if (!spp) return;
|
||||||
assert(nSpider >= 0 && nSpider < (int)SpiderList.Size());
|
|
||||||
|
|
||||||
short nAction = spp->nAction;
|
short nAction = spp->nAction;
|
||||||
|
|
||||||
|
@ -398,29 +353,26 @@ void AISpider::Draw(RunListEvent* ev)
|
||||||
|
|
||||||
void AISpider::RadialDamage(RunListEvent* ev)
|
void AISpider::RadialDamage(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
int nSpider = RunData[ev->nRun].nObjIndex;
|
auto spp = ev->pObjActor;
|
||||||
assert(nSpider >= 0 && nSpider < (int)SpiderList.Size());
|
if (!spp) return;
|
||||||
auto spp = &SpiderList[nSpider];
|
|
||||||
|
|
||||||
if (spp->nHealth <= 0)
|
if (spp->nHealth <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ev->nDamage = runlist_CheckRadialDamage(spp->nSprite);
|
ev->nDamage = runlist_CheckRadialDamage(spp);
|
||||||
Damage(ev);
|
Damage(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AISpider::Damage(RunListEvent* ev)
|
void AISpider::Damage(RunListEvent* ev)
|
||||||
{
|
{
|
||||||
int nSpider = RunData[ev->nRun].nObjIndex;
|
auto spp = ev->pObjActor;
|
||||||
assert(nSpider >= 0 && nSpider < (int)SpiderList.Size());
|
if (!spp) return;
|
||||||
auto spp = &SpiderList[nSpider];
|
auto sp = &spp->s();
|
||||||
int nSprite = spp->nSprite;
|
|
||||||
auto sp = &sprite[nSprite];
|
|
||||||
|
|
||||||
if (!ev->nDamage)
|
if (!ev->nDamage)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
short nTarget = ev->nParam;
|
DExhumedActor* pTarget = ev->pOtherActor;
|
||||||
|
|
||||||
spp->nHealth -= dmgAdjust(ev->nDamage);
|
spp->nHealth -= dmgAdjust(ev->nDamage);
|
||||||
if (spp->nHealth > 0)
|
if (spp->nHealth > 0)
|
||||||
|
@ -431,9 +383,9 @@ void AISpider::Damage(RunListEvent* ev)
|
||||||
or should code below (action set, b set) happen?
|
or should code below (action set, b set) happen?
|
||||||
Other AI doesn't show consistency in this regard (see Scorpion code)
|
Other AI doesn't show consistency in this regard (see Scorpion code)
|
||||||
*/
|
*/
|
||||||
if (nTarget > -1 && sprite[nTarget].statnum == 100)
|
if (pTarget && pTarget->s().statnum == 100)
|
||||||
{
|
{
|
||||||
spp->nTarget = nTarget;
|
spp->pTarget = pTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
spp->nAction = 4;
|
spp->nAction = 4;
|
||||||
|
@ -452,11 +404,9 @@ void AISpider::Damage(RunListEvent* ev)
|
||||||
|
|
||||||
for (int i = 0; i < 7; i++)
|
for (int i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
BuildCreatureChunk(nSprite, seq_GetSeqPicnum(kSeqSpider, i + 41, 0));
|
BuildCreatureChunk(spp->GetSpriteIndex(), seq_GetSeqPicnum(kSeqSpider, i + 41, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuncSpider(int nObject, int nMessage, int nDamage, int nRun)
|
void FuncSpider(int nObject, int nMessage, int nDamage, int nRun)
|
||||||
|
|
Loading…
Reference in a new issue