- refactored Anim to use actors.

This commit is contained in:
Christoph Oelckers 2021-10-24 20:21:27 +02:00
parent 3b0df0e9b4
commit 5cc1a8934e
6 changed files with 75 additions and 149 deletions

View file

@ -25,29 +25,9 @@ BEGIN_PS_NS
// anims
struct Anim
{
short nIndex2;
short nIndex;
short field_4;
short nSprite;
short nRun;
uint8_t nAction;
};
enum { kMaxAnims = 400 };
extern FreeListArray<Anim, kMaxAnims> AnimList;
void InitAnims();
void DestroyAnim(int nAnim);
int BuildAnim(int nSprite, int val, int val2, int x, int y, int z, int nSector, int nRepeat, int nFlag);
int BuildAnim(DExhumedActor* nSprite, int val, int val2, int x, int y, int z, int nSector, int nRepeat, int nFlag)
{
return BuildAnim(nSprite? nSprite->GetSpriteIndex() : -1, val, val2, x, y, z, nSector, nRepeat, nFlag);
}
short GetAnimSprite(short nAnim);
void DestroyAnim(DExhumedActor* nAnim);
DExhumedActor* BuildAnim(DExhumedActor* actor, int val, int val2, int x, int y, int z, int nSector, int nRepeat, int nFlag);
void FuncAnim(int, int, int, int);
void BuildExplosion(DExhumedActor* actor);

View file

@ -28,24 +28,9 @@ BEGIN_PS_NS
short nMagicSeq = -1;
short nPreMagicSeq = -1;
short nSavePointSeq = -1;
FreeListArray<Anim, kMaxAnims> AnimList;
//FreeListArray<Anim, kMaxAnims> AnimList;
FSerializer& Serialize(FSerializer& arc, const char* keyname, Anim& w, Anim* def)
{
if (arc.BeginObject(keyname))
{
arc("seq", w.nIndex2)
("val1", w.nIndex)
("val2", w.field_4)
("sprite", w.nSprite)
("runrec", w.nRun)
("flags", w.nAction)
.EndObject();
}
return arc;
}
void SerializeAnim(FSerializer& arc)
{
if (arc.BeginObject("anims"))
@ -53,48 +38,36 @@ void SerializeAnim(FSerializer& arc)
arc("magic", nMagicSeq)
("premagic", nPreMagicSeq)
("savepoint", nSavePointSeq)
("list", AnimList)
.EndObject();
}
}
void InitAnims()
{
AnimList.Clear();
nMagicSeq = SeqOffsets[kSeqItems] + 21;
nPreMagicSeq = SeqOffsets[kSeqMagic2];
nSavePointSeq = SeqOffsets[kSeqItems] + 12;
}
void DestroyAnim(int nAnim)
void DestroyAnim(DExhumedActor* pActor)
{
auto pActor = &AnimList[nAnim];
short nSprite = pActor->nSprite;
if (nSprite >= 0)
if (pActor)
{
auto pSprite = &sprite[nSprite];
StopSpriteSound(nSprite);
auto pSprite = &pActor->s();
StopActorSound(pActor);
runlist_SubRunRec(pActor->nRun);
runlist_DoSubRunRec(pSprite->extra);
runlist_FreeRun(pSprite->lotag - 1);
DeleteActor(pActor);
}
AnimList.Release(nAnim);
}
int BuildAnim(int nSprite, int val, int val2, int x, int y, int z, int nSector, int nRepeat, int nFlag)
DExhumedActor* BuildAnim(DExhumedActor* pActor, int val, int val2, int x, int y, int z, int nSector, int nRepeat, int nFlag)
{
int nAnim = AnimList.Get();
if (nAnim < 0) {
return -1;
}
auto pActor = &AnimList[nAnim];
if (nSprite == -1) {
nSprite = insertsprite(nSector, 500);
if (pActor == nullptr) {
pActor = insertActor(nSector, 500);
}
auto pSprite = &sprite[nSprite];
auto pSprite = &pActor->s();
pSprite->x = x;
pSprite->y = y;
@ -131,53 +104,44 @@ int BuildAnim(int nSprite, int val, int val2, int x, int y, int z, int nSector,
pSprite->lotag = runlist_HeadRun() + 1;
pSprite->owner = -1;
pSprite->extra = runlist_AddRunRec(pSprite->lotag - 1, nAnim, 0x100000);
pSprite->extra = runlist_AddRunRec(pSprite->lotag - 1, pActor, 0x100000);
pActor->nRun = runlist_AddRunRec(NewRun, nAnim, 0x100000);
pActor->nSprite = nSprite;
pActor->nRun = runlist_AddRunRec(NewRun, pActor, 0x100000);
pActor->nAction = nFlag;
pActor->nIndex = 0;
pActor->nIndex2 = SeqOffsets[val] + val2;
pActor->field_4 = 256;
pActor->pTarget = nullptr;
if (nFlag & 0x80) {
pSprite->cstat |= 0x2; // set transluscence
}
return nAnim;
}
short GetAnimSprite(short nAnim)
{
auto pActor = &AnimList[nAnim];
return pActor->nSprite;
return pActor;
}
void AIAnim::Tick(RunListEvent* ev)
{
short nAnim = RunData[ev->nRun].nObjIndex;
assert(nAnim >= 0 && nAnim < kMaxAnims);
auto pActor = &AnimList[nAnim];
auto pActor = ev->pObjActor;
if (!pActor) return;
short nSprite = pActor->nSprite;
short nSeq = pActor->nIndex2;
auto pSprite = &sprite[nSprite];
//short nSprite = pActor->nSprite;
short nIndex2 = pActor->nIndex2;
auto pSprite = &pActor->s();
assert(nSprite != -1);
short var_1C = pActor->nIndex;
short nIndex = pActor->nIndex;
if (!(pSprite->cstat & 0x8000))
{
seq_MoveSequence(nSprite, nSeq, var_1C);
seq_MoveSequence(pActor, nIndex2, nIndex);
}
if (pSprite->statnum == kStatIgnited)
{
short nSpriteB = pSprite->hitag;
if (nSpriteB > -1)
auto pIgniter = pActor->pTarget;
if (pIgniter)
{
auto pSpriteB = &sprite[nSpriteB];
auto pSpriteB = &pActor->pTarget->s();
pSprite->x = pSpriteB->x;
pSprite->y = pSpriteB->y;
pSprite->z = pSpriteB->z;
@ -186,17 +150,16 @@ void AIAnim::Tick(RunListEvent* ev)
{
if (pSpriteB->sectnum < 0 || pSpriteB->sectnum >= kMaxSectors)
{
DestroyAnim(nAnim);
mydeletesprite(nSprite);
DestroyAnim(pActor);
return;
}
else
{
mychangespritesect(nSprite, pSpriteB->sectnum);
ChangeActorSect(pActor, pSpriteB->sectnum);
}
}
if (!var_1C)
if (!nIndex)
{
if (pSpriteB->cstat != 0x8000)
{
@ -205,7 +168,7 @@ void AIAnim::Tick(RunListEvent* ev)
if (hitag2 >= 15)
{
runlist_DamageEnemy(nSpriteB, -1, (pSpriteB->hitag - 14) * 2);
runlist_DamageEnemy(pIgniter, nullptr, (pSpriteB->hitag - 14) * 2);
if (pSpriteB->shade < 100)
{
@ -215,44 +178,40 @@ void AIAnim::Tick(RunListEvent* ev)
if (!(pSpriteB->cstat & 101))
{
DestroyAnim(nAnim);
mydeletesprite(nSprite);
DestroyAnim(pActor);
return;
}
}
else
{
pSpriteB->hitag = 1;
DestroyAnim(nAnim);
mydeletesprite(nSprite);
DestroyAnim(pActor);
}
}
else
{
pSpriteB->hitag = 1;
DestroyAnim(nAnim);
mydeletesprite(nSprite);
DestroyAnim(pActor);
}
}
}
}
pActor->nIndex++;
if (pActor->nIndex >= SeqSize[nSeq])
if (pActor->nIndex >= SeqSize[nIndex2])
{
if (pActor->nAction & 0x10)
{
pActor->nIndex = 0;
}
else if (nSeq == nPreMagicSeq)
else if (nIndex2 == nPreMagicSeq)
{
pActor->nIndex = 0;
pActor->nIndex2 = nMagicSeq;
short nAnimSprite = pActor->nSprite;
pActor->nAction |= 0x10;
sprite[nAnimSprite].cstat |= 2;
pSprite->cstat |= 2;
}
else if (nSeq == nSavePointSeq)
else if (nIndex2 == nSavePointSeq)
{
pActor->nIndex = 0;
pActor->nIndex2++;
@ -260,20 +219,18 @@ void AIAnim::Tick(RunListEvent* ev)
}
else
{
DestroyAnim(nAnim);
mydeletesprite(nSprite);
DestroyAnim(pActor);
}
}
}
void AIAnim::Draw(RunListEvent* ev)
{
short nAnim = RunData[ev->nRun].nObjIndex;
assert(nAnim >= 0 && nAnim < kMaxAnims);
auto pActor = &AnimList[nAnim];
short nSeq = pActor->nIndex2;
auto pActor = ev->pObjActor;
if (!pActor) return;
short nIndex2 = pActor->nIndex2;
seq_PlotSequence(ev->nParam, nSeq, pActor->nIndex, 0x101);
seq_PlotSequence(ev->nParam, nIndex2, pActor->nIndex, 0x101);
ev->pTSprite->owner = -1;
}

View file

@ -164,17 +164,19 @@ void IgniteSprite(int nSprite)
pSprite->hitag += 2;
int nAnim = BuildAnim(-1, 38, 0, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, 40, 20);
short nAnimSprite = GetAnimSprite(nAnim);
auto pAnimActor = BuildAnim(nullptr, 38, 0, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, 40, 20);
if (pAnimActor)
{
pAnimActor->pTarget = &exhumedActors[nSprite];
ChangeActorStat(pAnimActor, kStatIgnited);
sprite[nAnimSprite].hitag = nSprite;
changespritestat(nAnimSprite, kStatIgnited);
short yRepeat = (tileHeight(pAnimActor->s().picnum) * 32) / nFlameHeight;
if (yRepeat < 1)
yRepeat = 1;
short yRepeat = (tileHeight(sprite[nAnimSprite].picnum) * 32) / nFlameHeight;
if (yRepeat < 1)
yRepeat = 1;
sprite[nAnimSprite].yrepeat = (uint8_t)yRepeat;
pAnimActor->s().yrepeat = (uint8_t)yRepeat;
}
}
void BulletHitsSprite(Bullet *pBullet, short nBulletSprite, short nHitSprite, int x, int y, int z, int nSector)

View file

@ -128,17 +128,15 @@ void BuildItemAnim(short nSprite)
if (nItemAnimInfo[nItem].a >= 0)
{
int nAnim = BuildAnim(nSprite, 41, nItemAnimInfo[nItem].a, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, nItemAnimInfo[nItem].repeat, 20);
int nAnimSprite = GetAnimSprite(nAnim);
auto pAnimActor = BuildAnim(&exhumedActors[nSprite], 41, nItemAnimInfo[nItem].a, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, nItemAnimInfo[nItem].repeat, 20);
if (nItem == 44) {
sprite[nAnimSprite].cstat |= 2;
pAnimActor->s().cstat |= 2;
}
changespritestat(nAnimSprite, pSprite->statnum);
sprite[nAnimSprite].owner = nAnim;
sprite[nAnimSprite].hitag = pSprite->hitag;
ChangeActorStat(pAnimActor, pSprite->statnum);
pAnimActor->s().hitag = pSprite->hitag;
pSprite->owner = 0;
}
else
{
@ -150,13 +148,8 @@ void BuildItemAnim(short nSprite)
void DestroyItemAnim(short nSprite)
{
auto pSprite = &sprite[nSprite];
short nAnim = pSprite->owner;
if (nAnim >= 0) {
DestroyAnim(nAnim);
}
if (sprite[nSprite].owner == 0)
DestroyAnim(&exhumedActors[nSprite]);
}
void ItemFlash()
@ -349,8 +342,8 @@ void DropMagic(short nSprite)
if (nMagicCount <= 0)
{
int nAnim = BuildAnim(
-1,
auto pAnimActor = BuildAnim(
nullptr,
64,
0,
pSprite->x,
@ -360,13 +353,11 @@ void DropMagic(short nSprite)
48,
4);
int nAnimSprite = GetAnimSprite(nAnim);
sprite[nAnimSprite].owner = nAnim;
AddFlash(sprite[nAnimSprite].sectnum, sprite[nAnimSprite].x, sprite[nAnimSprite].y, sprite[nAnimSprite].z, 128);
changespritestat(nAnimSprite, 950);
if (pAnimActor)
{
AddFlash(pAnimActor->s().sectnum, pAnimActor->s().x, pAnimActor->s().y, pAnimActor->s().z, 128);
ChangeActorStat(pAnimActor, 950);
}
nMagicCount = RandomSize(2);
}
}

View file

@ -1362,11 +1362,7 @@ DExhumedActor* GrabBodyGunSprite()
else
{
pSprite = &pActor->s();
int nAnim = pSprite->owner;
if (nAnim != -1) {
DestroyAnim(nAnim);
}
DestroyAnim(pActor);
pSprite->lotag = -1;
pSprite->owner = -1;

View file

@ -1372,7 +1372,8 @@ sectdone:
feebtag(pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->z, pPlayerSprite->sectnum,
&nValB, var_30, 768);
auto pSprite = &sprite[nValB];
auto pActor = &exhumedActors[nValB];
auto pSprite = &pActor->s();
// Item pickup code
if (nValB >= 0 && pSprite->statnum >= 900)
{
@ -2256,12 +2257,11 @@ sectdone:
{
if (nLocalPlayer == nPlayer)
{
short nAnim = pSprite->owner;
AnimList[nAnim].nIndex2++;
AnimList[nAnim].nAction &= 0xEF;
AnimList[nAnim].nIndex = 0;
pActor->nIndex2++;
pActor->nAction &= 0xEF;
pActor->nIndex = 0;
changespritestat(nValB, 899);
ChangeActorStat(pActor, 899);
}
SetSavePoint(nPlayer, pPlayerSprite->x, pPlayerSprite->y, pPlayerSprite->z, pPlayerSprite->sectnum, pPlayerSprite->ang);