- Exhumed: Bullet and Grenade.

This commit is contained in:
Christoph Oelckers 2020-11-30 01:10:52 +01:00
parent 54eec61828
commit 487d62e264
4 changed files with 103 additions and 71 deletions

View file

@ -88,7 +88,7 @@ extern int lasthitx;
extern int lasthity; extern int lasthity;
void InitBullets(); void InitBullets();
short GrabBullet(); int GrabBullet();
void DestroyBullet(short nRun); void DestroyBullet(short nRun);
int MoveBullet(short nBullet); int MoveBullet(short nBullet);
void SetBulletEnemy(short nBullet, short nEnemy); void SetBulletEnemy(short nBullet, short nEnemy);

View file

@ -36,7 +36,6 @@ BEGIN_PS_NS
enum { kMaxBullets = 500 }; enum { kMaxBullets = 500 };
short BulletFree[kMaxBullets];
// 32 bytes // 32 bytes
struct Bullet struct Bullet
@ -55,32 +54,60 @@ struct Bullet
int x; int x;
int y; int y;
int z; int z;
int enemy;
}; };
Bullet BulletList[kMaxBullets]; FreeListArray<Bullet, kMaxBullets> BulletList;
short nBulletEnemy[kMaxBullets];
int nBulletsFree;
int lasthitz, lasthitx, lasthity; int lasthitz, lasthitx, lasthity;
short lasthitsect, lasthitsprite, lasthitwall; short lasthitsect, lasthitsprite, lasthitwall;
int nBulletCount = 0;
short nRadialBullet = 0; short nRadialBullet = 0;
static SavegameHelper sghbullet("bullet", FSerializer& Serialize(FSerializer& arc, const char* keyname, Bullet& w, Bullet* def)
SV(BulletFree), {
SA(BulletList), static Bullet nul;
SA(nBulletEnemy), if (!def)
SV(nBulletsFree), {
SV(lasthitz), def = &nul;
SV(lasthitx), if (arc.isReading()) w = {};
SV(lasthity), }
SV(lasthitsect), if (arc.BeginObject(keyname))
SV(lasthitsprite), {
SV(lasthitwall), arc("seq", w.nSeq, def->nSeq)
SV(nBulletCount), ("frame", w.nFrame, def->nFrame)
SV(nRadialBullet), ("sprite", w.nSprite, def->nSprite)
nullptr); ("type", w.nType, def->nType)
("x", w.x, def->x)
("y", w.y, def->y)
("z", w.z, def->z)
("at6", w.field_6, def->field_6)
("at8", w.field_8, def->field_8)
("atc", w.field_C, def->field_C)
("ate", w.field_E, def->field_E)
("at10", w.field_10, def->field_10)
("at12", w.field_12, def->field_12)
("at13", w.field_13, def->field_13)
("enemy", w.enemy, def->enemy)
.EndObject();
}
return arc;
}
void SerializeBullet(FSerializer& arc)
{
if (arc.BeginObject("bullets"))
{
arc ("list", BulletList)
("lasthitx", lasthitx)
("lasthity", lasthity)
("lasthitz", lasthitz)
("lasthitsect", lasthitsect)
("lasthitspr", lasthitsprite)
("lasthitwall", lasthitwall)
("radialbullet", nRadialBullet)
.EndObject();
}
}
bulletInfo BulletInfo[] = { bulletInfo BulletInfo[] = {
{ 25, 1, 20, -1, -1, 13, 0, 0, -1 }, { 25, 1, 20, -1, -1, 13, 0, 0, -1 },
@ -105,21 +132,15 @@ bulletInfo BulletInfo[] = {
void InitBullets() void InitBullets()
{ {
nBulletCount = 0; BulletList.Clear();
for (int i = 0; i < kMaxBullets; i++) {
BulletFree[i] = i;
}
nBulletsFree = kMaxBullets;
memset(nBulletEnemy, -1, sizeof(nBulletEnemy));
} }
short GrabBullet() int GrabBullet()
{ {
nBulletsFree--; int grabbed = BulletList.Get();
return BulletFree[nBulletsFree]; if (grabbed < 0) return -1;
BulletList[grabbed].enemy = -1;
return grabbed;
} }
void DestroyBullet(short nBullet) void DestroyBullet(short nBullet)
@ -133,9 +154,7 @@ void DestroyBullet(short nBullet)
StopSpriteSound(nSprite); StopSpriteSound(nSprite);
mydeletesprite(nSprite); mydeletesprite(nSprite);
BulletList.Release(nBullet);
BulletFree[nBulletsFree] = nBullet;
nBulletsFree++;
} }
void IgniteSprite(int nSprite) void IgniteSprite(int nSprite)
@ -304,11 +323,11 @@ int MoveBullet(short nBullet)
if (pBullet->field_10 < 30000) if (pBullet->field_10 < 30000)
{ {
short nEnemySprite = nBulletEnemy[nBullet]; short nEnemySprite = BulletList[nBullet].enemy;
if (nEnemySprite > -1) if (nEnemySprite > -1)
{ {
if (!(sprite[nEnemySprite].cstat & 0x101)) if (!(sprite[nEnemySprite].cstat & 0x101))
nBulletEnemy[nBullet] = -1; BulletList[nBullet].enemy = -1;
else else
{ {
nVal = AngleChase(nSprite, nEnemySprite, pBullet->field_10, 0, 16); nVal = AngleChase(nSprite, nEnemySprite, pBullet->field_10, 0, 16);
@ -395,9 +414,9 @@ MOVEEND:
{ {
nVal = 1; nVal = 1;
if (nBulletEnemy[nBullet] > -1) if (BulletList[nBullet].enemy > -1)
{ {
hitsprite = nBulletEnemy[nBullet]; hitsprite = BulletList[nBullet].enemy;
x2 = sprite[hitsprite].x; x2 = sprite[hitsprite].x;
y2 = sprite[hitsprite].y; y2 = sprite[hitsprite].y;
z2 = sprite[hitsprite].z - (GetSpriteHeight(hitsprite) >> 1); z2 = sprite[hitsprite].z - (GetSpriteHeight(hitsprite) >> 1);
@ -530,7 +549,7 @@ HITWALL:
void SetBulletEnemy(short nBullet, short nEnemy) void SetBulletEnemy(short nBullet, short nEnemy)
{ {
if (nBullet >= 0) { if (nBullet >= 0) {
nBulletEnemy[nBullet] = nEnemy; BulletList[nBullet].enemy = nEnemy;
} }
} }
@ -573,7 +592,8 @@ int BuildBullet(short nSprite, int nType, int, int, int val1, int nAngle, int va
} }
} }
if (!nBulletsFree) { int nBullet = GrabBullet();
if (nBullet < 0) {
return -1; return -1;
} }
@ -603,10 +623,9 @@ int BuildBullet(short nSprite, int nType, int, int, int val1, int nAngle, int va
// why is this done here??? // why is this done here???
assert(nBulletSprite >= 0 && nBulletSprite < kMaxSprites); assert(nBulletSprite >= 0 && nBulletSprite < kMaxSprites);
short nBullet = GrabBullet();
Bullet *pBullet = &BulletList[nBullet]; Bullet *pBullet = &BulletList[nBullet];
nBulletEnemy[nBullet] = -1; pBullet->enemy = -1;
sprite[nBulletSprite].cstat = 0; sprite[nBulletSprite].cstat = 0;
sprite[nBulletSprite].shade = -64; sprite[nBulletSprite].shade = -64;
@ -701,7 +720,7 @@ int BuildBullet(short nSprite, int nType, int, int, int val1, int nAngle, int va
if ((unsigned int)pBulletInfo->field_4 > 30000) if ((unsigned int)pBulletInfo->field_4 > 30000)
{ {
nBulletEnemy[nBullet] = nTargetSprite; BulletList[nBullet].enemy = nTargetSprite;
} }
else else
{ {
@ -768,7 +787,7 @@ int BuildBullet(short nSprite, int nType, int, int, int val1, int nAngle, int va
pBullet->z = 0; pBullet->z = 0;
pBullet->x = (sprite[nSprite].clipdist << 2) * bcos(nAngle); pBullet->x = (sprite[nSprite].clipdist << 2) * bcos(nAngle);
pBullet->y = (sprite[nSprite].clipdist << 2) * bsin(nAngle); pBullet->y = (sprite[nSprite].clipdist << 2) * bsin(nAngle);
nBulletEnemy[nBullet] = -1; BulletList[nBullet].enemy = -1;
if (MoveBullet(nBullet)) if (MoveBullet(nBullet))
{ {

View file

@ -26,11 +26,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS BEGIN_PS_NS
int nGrenadeCount = 0;
int nGrenadesFree;
short GrenadeFree[kMaxGrenades];
struct Grenade struct Grenade
{ {
short field_0; short field_0;
@ -46,30 +41,48 @@ struct Grenade
int y; int y;
}; };
Grenade GrenadeList[kMaxGrenades]; FreeListArray<Grenade, kMaxGrenades> GrenadeList;
static SavegameHelper sghgrenade("grenade", FSerializer& Serialize(FSerializer& arc, const char* keyname, Grenade& w, Grenade* def)
SV(nGrenadeCount), {
SV(nGrenadesFree), static Grenade nul;
SA(GrenadeFree), if (!def)
SA(GrenadeList), {
nullptr); def = &nul;
if (arc.isReading()) w = {};
}
if (arc.BeginObject(keyname))
{
arc("sprite", w.nSprite, def->nSprite)
("at0", w.field_0, def->field_0)
("at2", w.field_2, def->field_2)
("at6", w.field_6, def->field_6)
("at8", w.field_8, def->field_8)
("ata", w.field_A, def->field_A)
("atc", w.field_C, def->field_C)
("ate", w.field_E, def->field_E)
("at10", w.field_10, def->field_10)
("x", w.x, def->x)
("y", w.y, def->y)
.EndObject();
}
return arc;
}
void SerializeGrenade(FSerializer& arc)
{
arc("grenades", GrenadeList);
}
void InitGrenades() void InitGrenades()
{ {
nGrenadeCount = 0; GrenadeList.Clear();
for (int i = 0; i < kMaxGrenades; i++) {
GrenadeFree[i] = i;
}
nGrenadesFree = kMaxGrenades;
} }
short GrabGrenade() short GrabGrenade()
{ {
return GrenadeFree[--nGrenadesFree]; return GrenadeList.Get();
} }
void DestroyGrenade(short nGrenade) void DestroyGrenade(short nGrenade)
@ -79,9 +92,7 @@ void DestroyGrenade(short nGrenade)
runlist_DoSubRunRec(sprite[GrenadeList[nGrenade].nSprite].lotag - 1); runlist_DoSubRunRec(sprite[GrenadeList[nGrenade].nSprite].lotag - 1);
mydeletesprite(GrenadeList[nGrenade].nSprite); mydeletesprite(GrenadeList[nGrenade].nSprite);
GrenadeFree[nGrenadesFree] = nGrenade; GrenadeList.Release(nGrenade);
nGrenadesFree++;
} }
void BounceGrenade(short nGrenade, short nAngle) void BounceGrenade(short nGrenade, short nAngle)
@ -149,10 +160,8 @@ int ThrowGrenade(short nPlayer, int, int, int ecx, int push1)
int BuildGrenade(int nPlayer) int BuildGrenade(int nPlayer)
{ {
if (nGrenadesFree == 0)
return -1;
int nGrenade = GrabGrenade(); int nGrenade = GrabGrenade();
if (nGrenade < 0) return -1;
int nSprite = insertsprite(nPlayerViewSect[nPlayer], 201); int nSprite = insertsprite(nPlayerViewSect[nPlayer], 201);
assert(nSprite >= 0 && nSprite < kMaxSprites); assert(nSprite >= 0 && nSprite < kMaxSprites);

View file

@ -31,6 +31,8 @@ BEGIN_PS_NS
void SerializeAnim(FSerializer& arc); void SerializeAnim(FSerializer& arc);
void SerializeBubbles(FSerializer& arc); void SerializeBubbles(FSerializer& arc);
void SerializeBullet(FSerializer& arc);
void SerializeGrenade(FSerializer& arc);
void SerializeGun(FSerializer& arc); void SerializeGun(FSerializer& arc);
void SerializeInit(FSerializer& arc); void SerializeInit(FSerializer& arc);
void SerializeItems(FSerializer& arc); void SerializeItems(FSerializer& arc);
@ -78,6 +80,8 @@ void GameInterface::SerializeGameState(FSerializer& arc)
{ {
SerializeAnim(arc); SerializeAnim(arc);
SerializeBubbles(arc); SerializeBubbles(arc);
SerializeBullet(arc);
SerializeGrenade(arc);
SerializeGun(arc); SerializeGun(arc);
SerializeInit(arc); SerializeInit(arc);
SerializeItems(arc); SerializeItems(arc);