- AI JSON serialization.

This commit is contained in:
Christoph Oelckers 2020-11-21 23:40:33 +01:00
parent 18352a760c
commit 2cb3d44384
12 changed files with 258 additions and 182 deletions

View file

@ -2938,7 +2938,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
aiGenDudeNewState(pSprite, &genDudeBurnGoto);
actHealDude(pXSprite, dudeInfo[55].startHealth, dudeInfo[55].startHealth);
if (pXSprite->burnTime <= 0) pXSprite->burnTime = 1200;
gDudeExtra[pSprite->extra].TotalKills = gFrameClock + 360;
gDudeExtra[pSprite->extra].time = gFrameClock + 360;
return;
}
@ -3328,7 +3328,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
case kDudeSpiderBrown:
if (pSprite->owner != -1) {
spritetype *pOwner = &sprite[actSpriteOwnerToSpriteId(pSprite)];
gDudeExtra[pOwner->extra].at6.u1.Kills--;
gDudeExtra[pOwner->extra].at6.u1.xval2--;
}
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1805, -1, 0);
@ -3338,7 +3338,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
case kDudeSpiderRed:
if (pSprite->owner != -1) {
spritetype *pOwner = &sprite[actSpriteOwnerToSpriteId(pSprite)];
gDudeExtra[pOwner->extra].at6.u1.Kills--;
gDudeExtra[pOwner->extra].at6.u1.xval2--;
}
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1805, -1, 0);
@ -3348,7 +3348,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
case kDudeSpiderBlack:
if (pSprite->owner != -1) {
spritetype *pOwner = &sprite[actSpriteOwnerToSpriteId(pSprite)];
gDudeExtra[pOwner->extra].at6.u1.Kills--;
gDudeExtra[pOwner->extra].at6.u1.xval2--;
}
if (Chance(0x4000) && nSeq == 3) sfxPlay3DSound(pSprite, 1805, -1, 0);
@ -6954,12 +6954,24 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, POSTPONE& w, POSTP
return arc;
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, SPRITEHIT& w, SPRITEHIT* def)
{
if (arc.BeginObject(keyname))
{
arc("hit", w.hit)
("ceilhit", w.ceilhit)
("florhit", w.florhit)
.EndObject();
}
return arc;
}
void SerializeActor(FSerializer& arc)
{
if (arc.BeginObject("actor"))
{
arc("maxdist20", gVectorData[VECTOR_TYPE_20].maxDist) // The code messes around with this field so better save it.
.SparseArray("spritehit", gSpriteHit, kMaxSprites, activeSprites)
.SparseArray("spritehit", gSpriteHit, kMaxSprites, activeXSprites)
("postcount", gPostCount)
.Array("post", gPost, gPostCount)
.EndObject();

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "build.h"
#include "pragmas.h"
#include "savegamehelp.h"
#include "mmulti.h"
#include "common_game.h"
#include "actor.h"
@ -75,12 +76,12 @@ void aiPlay3DSound(spritetype *pSprite, int a2, AI_SFX_PRIORITY a3, int a4)
DUDEEXTRA *pDudeExtra = &gDudeExtra[pSprite->extra];
if (a3 == AI_SFX_PRIORITY_0)
sfxPlay3DSound(pSprite, a2, a4, 2);
else if (a3 > pDudeExtra->at5 || pDudeExtra->TotalKills <= gFrameClock)
else if (a3 > pDudeExtra->prio || pDudeExtra->time <= gFrameClock)
{
sfxKill3DSound(pSprite, -1, -1);
sfxPlay3DSound(pSprite, a2, a4, 0);
pDudeExtra->at5 = a3;
pDudeExtra->TotalKills = gFrameClock+120;
pDudeExtra->prio = a3;
pDudeExtra->time = gFrameClock+120;
}
}
@ -330,9 +331,9 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudePhantasm:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1)
aiNewState(pSprite, pXSprite, &ghostSearch);
else
@ -349,8 +350,8 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeCultistBeast:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1) {
switch (pXSprite->medium) {
case kMediumNormal:
@ -387,8 +388,8 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeModernCustom:
{
DUDEEXTRA_at6_u1* pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1) {
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeSearchW);
else aiGenDudeNewState(pSprite, &genDudeSearchL);
@ -406,7 +407,7 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
#endif
case kDudeCultistTommyProne: {
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = 1; pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 1; pDudeExtraE->xval1 = 0;
pSprite->type = kDudeCultistTommy;
if (pXSprite->target == -1) {
switch (pXSprite->medium) {
@ -439,8 +440,8 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeCultistShotgunProne:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
pSprite->type = kDudeCultistShotgun;
if (pXSprite->target == -1)
{
@ -483,9 +484,9 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBat:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
if (!pSprite->flags)
pSprite->flags = 9;
if (pXSprite->target == -1)
@ -501,9 +502,9 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBoneEel:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1)
aiNewState(pSprite, pXSprite, &eelSearch);
else
@ -521,9 +522,9 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
XSECTOR *pXSector = NULL;
if (sector[pSprite->sectnum].extra > 0)
pXSector = &xsector[sector[pSprite->sectnum].extra];
pDudeExtraE->TotalKills = 0;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 1;
pDudeExtraE->xval1 = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 1;
if (pXSprite->target == -1)
{
if (pXSector && pXSector->Underwater)
@ -546,8 +547,8 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
}
case kDudeZombieAxeNormal: {
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u2;
pDudeExtraE->Kills = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1)
aiNewState(pSprite, pXSprite, &zombieASearch);
else
@ -576,8 +577,8 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeZombieAxeBuried:
{
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u2;
pDudeExtraE->Kills = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->aiState == &zombieEIdle)
aiNewState(pSprite, pXSprite, &zombieEUp);
break;
@ -585,16 +586,16 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeZombieAxeLaying:
{
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u2;
pDudeExtraE->Kills = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->aiState == &zombieSIdle)
aiNewState(pSprite, pXSprite, &zombie13AC2C);
break;
}
case kDudeZombieButcher: {
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u2;
pDudeExtraE->Kills = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1)
aiNewState(pSprite, pXSprite, &zombieFSearch);
else
@ -621,9 +622,9 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
break;
case kDudeGargoyleFlesh: {
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1)
aiNewState(pSprite, pXSprite, &gargoyleFSearch);
else
@ -639,9 +640,9 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeGargoyleStone:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1)
aiNewState(pSprite, pXSprite, &gargoyleFSearch);
else
@ -756,8 +757,8 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
break;
case kDudeSpiderMother: {
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 1;
pDudeExtraE->xval1 = 0;
pSprite->flags |= 2;
pSprite->cstat &= ~8;
if (pXSprite->target == -1)
@ -772,8 +773,8 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeTinyCaleb:
{
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u2;
pDudeExtraE->Kills = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1)
{
switch (pXSprite->medium)
@ -805,8 +806,8 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBeast:
{
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u2;
pDudeExtraE->Kills = 1;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 1;
pDudeExtraE->xval1 = 0;
if (pXSprite->target == -1)
{
switch (pXSprite->medium)
@ -910,7 +911,7 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
if (nDmgType == DAMAGE_TYPE_6)
{
DUDEEXTRA *pDudeExtra = &gDudeExtra[pSprite->extra];
pDudeExtra->Kills = 1;
pDudeExtra->recoil = 1;
}
switch (pSprite->type)
{
@ -933,7 +934,7 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
aiNewState(pSprite, pXSprite, &cultistBurnGoto);
aiPlay3DSound(pSprite, 361, AI_SFX_PRIORITY_0, -1);
aiPlay3DSound(pSprite, 1031+Random(2), AI_SFX_PRIORITY_2, -1);
gDudeExtra[pSprite->extra].TotalKills = gFrameClock+360;
gDudeExtra[pSprite->extra].time = gFrameClock+360;
actHealDude(pXSprite, dudeInfo[40].startHealth, dudeInfo[40].startHealth);
evKill(nSprite, 3, kCallbackFXFlameLick);
}
@ -944,16 +945,16 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
pSprite->type = kDudeBurningInnocent;
aiNewState(pSprite, pXSprite, &cultistBurnGoto);
aiPlay3DSound(pSprite, 361, AI_SFX_PRIORITY_0, -1);
gDudeExtra[pSprite->extra].TotalKills = gFrameClock+360;
gDudeExtra[pSprite->extra].time = gFrameClock+360;
actHealDude(pXSprite, dudeInfo[39].startHealth, dudeInfo[39].startHealth);
evKill(nSprite, 3, kCallbackFXFlameLick);
}
break;
case kDudeBurningCultist:
if (Chance(0x4000) && gDudeExtra[pSprite->extra].TotalKills < gFrameClock)
if (Chance(0x4000) && gDudeExtra[pSprite->extra].time < gFrameClock)
{
aiPlay3DSound(pSprite, 1031+Random(2), AI_SFX_PRIORITY_2, -1);
gDudeExtra[pSprite->extra].TotalKills = gFrameClock+360;
gDudeExtra[pSprite->extra].time = gFrameClock+360;
}
if (Chance(0x600) && (pXSprite->medium == kMediumWater || pXSprite->medium == kMediumGoo))
{
@ -987,16 +988,16 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
pSprite->type = kDudeBurningInnocent;
aiNewState(pSprite, pXSprite, &cultistBurnGoto);
aiPlay3DSound(pSprite, 361, AI_SFX_PRIORITY_0, -1);
gDudeExtra[pSprite->extra].TotalKills = gFrameClock+360;
gDudeExtra[pSprite->extra].time = gFrameClock+360;
actHealDude(pXSprite, dudeInfo[39].startHealth, dudeInfo[39].startHealth);
evKill(nSprite, 3, kCallbackFXFlameLick);
}
break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustomBurning:
if (Chance(0x2000) && gDudeExtra[pSprite->extra].TotalKills < gFrameClock) {
if (Chance(0x2000) && gDudeExtra[pSprite->extra].time < gFrameClock) {
playGenDudeSound(pSprite, kGenDudeSndBurning);
gDudeExtra[pSprite->extra].TotalKills = gFrameClock + 360;
gDudeExtra[pSprite->extra].time = gFrameClock + 360;
}
if (pXSprite->burnTime == 0) pXSprite->burnTime = 2400;
if (spriteIsUnderwater(pSprite, false)) {
@ -1036,7 +1037,7 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
aiGenDudeNewState(pSprite, &genDudeBurnGoto);
actHealDude(pXSprite, dudeInfo[55].startHealth, dudeInfo[55].startHealth);
gDudeExtra[pSprite->extra].TotalKills = gFrameClock + 360;
gDudeExtra[pSprite->extra].time = gFrameClock + 360;
evKill(nSprite, 3, kCallbackFXFlameLick);
}
@ -1101,7 +1102,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
#ifdef NOONE_EXTENSIONS
case kDudeModernCustom: {
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); int rChance = getRecoilChance(pSprite);
if (pExtra->canElectrocute && pDudeExtra->Kills && !spriteIsUnderwater(pSprite, false)) {
if (pExtra->canElectrocute && pDudeExtra->recoil && !spriteIsUnderwater(pSprite, false)) {
if (Chance(rChance << 3) || (dudeIsMelee(pXSprite) && Chance(rChance << 4))) aiGenDudeNewState(pSprite, &genDudeRecoilTesla);
else if (pExtra->canRecoil && Chance(rChance)) aiGenDudeNewState(pSprite, &genDudeRecoilL);
@ -1142,7 +1143,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
}
pDudeExtra->Kills = 0;
pDudeExtra->recoil = 0;
break;
}
#endif
@ -1155,11 +1156,11 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
else aiPlay3DSound(pSprite, 1013+Random(2), AI_SFX_PRIORITY_2, -1);
if (!v4 && pXSprite->medium == kMediumNormal) {
if (pDudeExtra->Kills) aiNewState(pSprite, pXSprite, &cultistTeslaRecoil);
if (pDudeExtra->recoil) aiNewState(pSprite, pXSprite, &cultistTeslaRecoil);
else aiNewState(pSprite, pXSprite, &cultistRecoil);
} else if (v4 && pXSprite->medium == kMediumNormal) {
if (pDudeExtra->Kills) aiNewState(pSprite, pXSprite, &cultistTeslaRecoil);
if (pDudeExtra->recoil) aiNewState(pSprite, pXSprite, &cultistTeslaRecoil);
else if (gGameOptions.nDifficulty > 0) aiNewState(pSprite, pXSprite, &cultistProneRecoil);
else aiNewState(pSprite, pXSprite, &cultistRecoil);
}
@ -1167,7 +1168,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
aiNewState(pSprite, pXSprite, &cultistSwimRecoil);
else
{
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &cultistTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &cultistRecoil);
@ -1183,7 +1184,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
#endif
case kDudeZombieButcher:
aiPlay3DSound(pSprite, 1202, AI_SFX_PRIORITY_2, -1);
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &zombieFTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &zombieFRecoil);
@ -1191,7 +1192,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeZombieAxeNormal:
case kDudeZombieAxeBuried:
aiPlay3DSound(pSprite, 1106, AI_SFX_PRIORITY_2, -1);
if (pDudeExtra->Kills && pXSprite->data3 > pDudeInfo->startHealth/3)
if (pDudeExtra->recoil && pXSprite->data3 > pDudeInfo->startHealth/3)
aiNewState(pSprite, pXSprite, &zombieATeslaRecoil);
else if (pXSprite->data3 > pDudeInfo->startHealth/3)
aiNewState(pSprite, pXSprite, &zombieARecoil2);
@ -1213,7 +1214,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
break;
case kDudeCerberusTwoHead:
aiPlay3DSound(pSprite, 2302+Random(2), AI_SFX_PRIORITY_2, -1);
if (pDudeExtra->Kills && pXSprite->data3 > pDudeInfo->startHealth/3)
if (pDudeExtra->recoil && pXSprite->data3 > pDudeInfo->startHealth/3)
aiNewState(pSprite, pXSprite, &cerberusTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &cerberusRecoil);
@ -1224,7 +1225,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
break;
case kDudeHellHound:
aiPlay3DSound(pSprite, 1302, AI_SFX_PRIORITY_2, -1);
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &houndTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &houndRecoil);
@ -1262,7 +1263,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
}
case kDudePhantasm:
aiPlay3DSound(pSprite, 1602, AI_SFX_PRIORITY_2, -1);
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &ghostTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &ghostRecoil);
@ -1279,7 +1280,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
break;
case kDudeInnocent:
aiPlay3DSound(pSprite, 7007+Random(2), AI_SFX_PRIORITY_2, -1);
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &innocentTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &innocentRecoil);
@ -1287,7 +1288,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeTinyCaleb:
if (pXSprite->medium == kMediumNormal)
{
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &tinycalebTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &tinycalebRecoil);
@ -1296,7 +1297,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
aiNewState(pSprite, pXSprite, &tinycalebSwimRecoil);
else
{
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &tinycalebTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &tinycalebRecoil);
@ -1306,7 +1307,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
aiPlay3DSound(pSprite, 9004+Random(2), AI_SFX_PRIORITY_2, -1);
if (pXSprite->medium == kMediumNormal)
{
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &beastTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &beastRecoil);
@ -1315,7 +1316,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
aiNewState(pSprite, pXSprite, &beastSwimRecoil);
else
{
if (pDudeExtra->Kills)
if (pDudeExtra->recoil)
aiNewState(pSprite, pXSprite, &beastTeslaRecoil);
else
aiNewState(pSprite, pXSprite, &beastRecoil);
@ -1333,7 +1334,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
aiNewState(pSprite, pXSprite, &genRecoil);
break;
}
pDudeExtra->Kills = 0;
pDudeExtra->recoil = 0;
}
}
@ -1513,8 +1514,8 @@ void aiInitSprite(spritetype *pSprite)
if (nXSector > 0)
pXSector = &xsector[nXSector];
DUDEEXTRA *pDudeExtra = &gDudeExtra[pSprite->extra];
pDudeExtra->Kills = 0;
pDudeExtra->TotalKills = 0;
pDudeExtra->recoil = 0;
pDudeExtra->time = 0;
switch (pSprite->type) {
#ifdef NOONE_EXTENSIONS
@ -1533,63 +1534,63 @@ void aiInitSprite(spritetype *pSprite)
case kDudeCultistBeast:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->at8 = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &cultistIdle);
break;
}
case kDudeCultistTommyProne:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->at8 = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &fanaticProneIdle);
break;
}
case kDudeCultistShotgunProne:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->at8 = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &cultistProneIdle);
break;
}
case kDudeZombieButcher: {
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u2;
pDudeExtraE->Kills = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &zombieFIdle);
break;
}
case kDudeZombieAxeNormal: {
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u2;
pDudeExtraE->Kills = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &zombieAIdle);
break;
}
case kDudeZombieAxeLaying:
{
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u2;
pDudeExtraE->Kills = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &zombieSIdle);
pSprite->flags &= ~1;
break;
}
case kDudeZombieAxeBuried: {
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u2;
pDudeExtraE->Kills = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &zombieEIdle);
break;
}
case kDudeGargoyleFlesh:
case kDudeGargoyleStone: {
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &gargoyleFIdle);
break;
}
@ -1599,8 +1600,8 @@ void aiInitSprite(spritetype *pSprite)
break;
case kDudeCerberusTwoHead: {
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u2;
pDudeExtraE->Kills = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &cerberusIdle);
break;
}
@ -1613,9 +1614,9 @@ void aiInitSprite(spritetype *pSprite)
case kDudePhantasm:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &ghostIdle);
break;
}
@ -1628,9 +1629,9 @@ void aiInitSprite(spritetype *pSprite)
case kDudeBoneEel:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &eelIdle);
break;
}
@ -1640,9 +1641,9 @@ void aiInitSprite(spritetype *pSprite)
case kDudeBat:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->Kills = 0;
pDudeExtraE->at8 = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &batIdle);
break;
}
@ -1651,26 +1652,26 @@ void aiInitSprite(spritetype *pSprite)
case kDudeSpiderBlack:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->at8 = 0;
pDudeExtraE->Kills = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &spidIdle);
break;
}
case kDudeSpiderMother:
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->at8 = 0;
pDudeExtraE->Kills = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &spidIdle);
break;
}
case kDudeTchernobog:
{
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[nXSprite].at6.u2;
pDudeExtraE->Kills = 0;
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval2 = 0;
pDudeExtraE->xval1 = 0;
aiNewState(pSprite, pXSprite, &tchernobogIdle);
break;
}
@ -1741,31 +1742,85 @@ void aiInitSprite(spritetype *pSprite)
}
}
class AILoadSave : public LoadSave
{
virtual void Load(void);
virtual void Save(void);
};
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AILoadSave::Load(void)
FSerializer& Serialize(FSerializer& arc, const char* keyname, DUDEEXTRA& w, DUDEEXTRA* def)
{
//Read(cumulDamage, sizeof(cumulDamage));
Read(gDudeSlope, sizeof(gDudeSlope));
Read(gDudeExtra, sizeof(gDudeExtra));
Read(gGenDudeExtra, sizeof(gGenDudeExtra));
if (arc.BeginObject(keyname))
{
arc("time", w.time)
("recoil", w.recoil)
("prio", w.prio)
("x1", w.at6.u1.xval1)
("x2", w.at6.u1.xval2)
("x3", w.at6.u1.xval3)
.EndObject();
}
return arc;
}
void AILoadSave::Save(void)
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
FSerializer& Serialize(FSerializer& arc, const char* keyname, GENDUDEEXTRA& w, GENDUDEEXTRA* def)
{
//Write(cumulDamage, sizeof(cumulDamage)); data never crosses the end-of-frame barrier
Write(gDudeSlope, sizeof(gDudeSlope));
Write(gDudeExtra, sizeof(gDudeExtra));
Write(gGenDudeExtra, sizeof(gGenDudeExtra));
if (arc.BeginObject(keyname))
{
arc.Array("initvals", w.initVals, 3)
.Array("availdeaths", w.availDeaths, kDamageMax)
("movespeed", w.moveSpeed)
("firedist", w.fireDist)
("throwdist", w.throwDist)
("curweapon", w.curWeapon)
("weapontype", w.weaponType)
("basedispersion", w.baseDispersion)
("slavecount", w.slaveCount)
("lifeleech", w.nLifeLeech)
.Array("slaves", w.slave, w.slaveCount)
.Array("dmgcontrol", w.dmgControl, kDamageMax)
.Array("updreq", w.updReq, kGenDudePropertyMax)
("flags", w.flags)
.EndObject();
}
return arc;
}
void AILoadSaveConstruct(void)
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void SerializeAI(FSerializer& arc)
{
new AILoadSave();
if (arc.BeginObject("ai"))
{
arc.SparseArray("dudeslope", gDudeSlope, kMaxSprites, activeXSprites)
.SparseArray("dudeextra", gDudeExtra, kMaxSprites, activeXSprites);
// the GenDudeArray only contains valid info for kDudeModernCustom and kDudeModernCustomBurning so only save the relevant entries as these are not small.
bool foundsome = false;
for (int i = 0; i < kMaxSprites; i++)
{
if (activeSprites[i] && (sprite[i].type == kDudeModernCustom || sprite[i].type == kDudeModernCustomBurning))
{
if (!foundsome) arc.BeginArray("gendudeextra");
foundsome = true;
arc(nullptr, gGenDudeExtra[i]);
}
}
if (foundsome) arc.EndArray();
arc.EndObject();
}
}
END_BLD_NS

View file

@ -53,22 +53,23 @@ enum AI_SFX_PRIORITY {
struct DUDEEXTRA_at6_u1
{
int TotalKills;
int Kills;
char at8;
int xval1;
int xval2;
char xval3;
};
struct DUDEEXTRA_at6_u2
{
int TotalKills;
char Kills;
int xval1;
char xval2;
};
struct DUDEEXTRA
{
int TotalKills;
char Kills;
AI_SFX_PRIORITY at5;
int time;
int recoil;
int prio;
// Broken by design... :?
union
{
DUDEEXTRA_at6_u1 u1;

View file

@ -92,11 +92,11 @@ static void batThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type);
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
if (pDudeExtraE->at8 && pDudeExtraE->Kills < 10)
pDudeExtraE->Kills++;
else if (pDudeExtraE->Kills >= 10 && pDudeExtraE->at8)
if (pDudeExtraE->xval3 && pDudeExtraE->xval2 < 10)
pDudeExtraE->xval2++;
else if (pDudeExtraE->xval2 >= 10 && pDudeExtraE->xval3)
{
pDudeExtraE->Kills = 0;
pDudeExtraE->xval2 = 0;
pXSprite->goalAng += 256;
POINT3D *pTarget = &baseSprite[pSprite->index];
aiSetTarget(pXSprite, pTarget->x, pTarget->y, pTarget->z);
@ -426,7 +426,7 @@ void batMoveToCeil(spritetype *pSprite, XSPRITE *pXSprite)
if (z - pXSprite->targetZ < 0x1000)
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = 0;
pDudeExtraE->xval3 = 0;
pSprite->flags = 0;
aiNewState(pSprite, pXSprite, &batIdle);
}

View file

@ -105,11 +105,11 @@ static void eelThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type);
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
if (pDudeExtraE->at8 && pDudeExtraE->Kills < 10)
pDudeExtraE->Kills++;
else if (pDudeExtraE->Kills >= 10 && pDudeExtraE->at8)
if (pDudeExtraE->xval3 && pDudeExtraE->xval2 < 10)
pDudeExtraE->xval2++;
else if (pDudeExtraE->xval2 >= 10 && pDudeExtraE->xval3)
{
pDudeExtraE->Kills = 0;
pDudeExtraE->xval2 = 0;
pXSprite->goalAng += 256;
POINT3D *pTarget = &baseSprite[pSprite->index];
aiSetTarget(pXSprite, pTarget->x, pTarget->y, pTarget->z);
@ -137,13 +137,13 @@ static void eelThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
{
pDudeExtraE->Kills = 0;
pDudeExtraE->xval2 = 0;
aiSetTarget(pXSprite, pPlayer->nSprite);
aiActivateDude(pSprite, pXSprite);
}
else if (nDist < pDudeInfo->hearDist)
{
pDudeExtraE->Kills = 0;
pDudeExtraE->xval2 = 0;
aiSetTarget(pXSprite, x, y, z);
aiActivateDude(pSprite, pXSprite);
}
@ -431,7 +431,7 @@ void eelMoveToCeil(spritetype *pSprite, XSPRITE *pXSprite)
if (z - pXSprite->targetZ < 0x1000)
{
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = 0;
pDudeExtraE->xval3 = 0;
pSprite->flags = 0;
aiNewState(pSprite, pXSprite, &eelIdle);
}

View file

@ -277,9 +277,9 @@ static void cerberusThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
}
DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type);
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
if (pDudeExtraE->at8 && pDudeExtraE->Kills < 10)
pDudeExtraE->Kills++;
else if (pDudeExtraE->Kills >= 10 && pDudeExtraE->at8)
if (pDudeExtraE->xval3 && pDudeExtraE->xval2 < 10)
pDudeExtraE->xval2++;
else if (pDudeExtraE->xval2 >= 10 && pDudeExtraE->xval3)
{
pXSprite->goalAng += 256;
POINT3D *pTarget = &baseSprite[pSprite->index];
@ -311,13 +311,13 @@ static void cerberusThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
{
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval1 = 0;
aiSetTarget(pXSprite, pPlayer->nSprite);
aiActivateDude(pSprite, pXSprite);
}
else if (nDist < pDudeInfo->hearDist)
{
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval1 = 0;
aiSetTarget(pXSprite, x, y, z);
aiActivateDude(pSprite, pXSprite);
}

View file

@ -231,9 +231,9 @@ static void gargThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
}
DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type);
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
if (pDudeExtraE->at8 && pDudeExtraE->Kills < 10)
pDudeExtraE->Kills++;
else if (pDudeExtraE->Kills >= 10 && pDudeExtraE->at8)
if (pDudeExtraE->xval3 && pDudeExtraE->xval2 < 10)
pDudeExtraE->xval2++;
else if (pDudeExtraE->xval2 >= 10 && pDudeExtraE->xval3)
{
pXSprite->goalAng += 256;
POINT3D *pTarget = &baseSprite[pSprite->index];
@ -262,13 +262,13 @@ static void gargThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
{
pDudeExtraE->Kills = 0;
pDudeExtraE->xval2 = 0;
aiSetTarget(pXSprite, pPlayer->nSprite);
aiActivateDude(pSprite, pXSprite);
}
else if (nDist < pDudeInfo->hearDist)
{
pDudeExtraE->Kills = 0;
pDudeExtraE->xval2 = 0;
aiSetTarget(pXSprite, x, y, z);
aiActivateDude(pSprite, pXSprite);
}

View file

@ -208,9 +208,9 @@ static void ghostThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
}
DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type);
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
if (pDudeExtraE->at8 && pDudeExtraE->Kills < 10)
pDudeExtraE->Kills++;
else if (pDudeExtraE->Kills >= 10 && pDudeExtraE->at8)
if (pDudeExtraE->xval3 && pDudeExtraE->xval2 < 10)
pDudeExtraE->xval2++;
else if (pDudeExtraE->xval2 >= 10 && pDudeExtraE->xval3)
{
pXSprite->goalAng += 256;
POINT3D *pTarget = &baseSprite[pSprite->index];
@ -239,14 +239,14 @@ static void ghostThinkTarget(spritetype *pSprite, XSPRITE *pXSprite)
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
{
pDudeExtraE->Kills = 0;
pDudeExtraE->xval2 = 0;
aiSetTarget(pXSprite, pPlayer->nSprite);
aiActivateDude(pSprite, pXSprite);
return;
}
else if (nDist < pDudeInfo->hearDist)
{
pDudeExtraE->Kills = 0;
pDudeExtraE->xval2 = 0;
aiSetTarget(pXSprite, x, y, z);
aiActivateDude(pSprite, pXSprite);
return;

View file

@ -172,7 +172,7 @@ void sub_71370(int, int nXSprite)
int nDist = approxDist(dx, dy);
spritetype *pSpawn = NULL;
if (IsPlayerSprite(pTarget) && pDudeExtraE->Kills < 10) {
if (IsPlayerSprite(pTarget) && pDudeExtraE->xval2 < 10) {
if (nDist < 0x1a00 && nDist > 0x1400 && klabs(pSprite->ang-nAngle) < pDudeInfo->periphery)
pSpawn = actSpawnDude(pSprite, kDudeSpiderRed, pSprite->clipdist, 0);
@ -182,7 +182,7 @@ void sub_71370(int, int nXSprite)
pSpawn = actSpawnDude(pSprite, kDudeSpiderBrown, pSprite->clipdist, 0);
if (pSpawn) {
pDudeExtraE->Kills++;
pDudeExtraE->xval2++;
pSpawn->owner = nSprite;
gKillMgr.AddNewKill(1);
}

View file

@ -246,9 +246,9 @@ static void sub_725A4(spritetype *pSprite, XSPRITE *pXSprite)
}
DUDEINFO *pDudeInfo = getDudeInfo(pSprite->type);
DUDEEXTRA_at6_u2 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u2;
if (pDudeExtraE->Kills && pDudeExtraE->TotalKills < 10)
pDudeExtraE->TotalKills++;
else if (pDudeExtraE->TotalKills >= 10 && pDudeExtraE->Kills)
if (pDudeExtraE->xval2 && pDudeExtraE->xval1 < 10)
pDudeExtraE->xval1++;
else if (pDudeExtraE->xval1 >= 10 && pDudeExtraE->xval2)
{
pXSprite->goalAng += 256;
POINT3D *pTarget = &baseSprite[pSprite->index];
@ -277,13 +277,13 @@ static void sub_725A4(spritetype *pSprite, XSPRITE *pXSprite)
int nDeltaAngle = ((getangle(dx,dy)+1024-pSprite->ang)&2047)-1024;
if (nDist < pDudeInfo->seeDist && klabs(nDeltaAngle) <= pDudeInfo->periphery)
{
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval1 = 0;
aiSetTarget(pXSprite, pPlayer->nSprite);
aiActivateDude(pSprite, pXSprite);
}
else if (nDist < pDudeInfo->hearDist)
{
pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval1 = 0;
aiSetTarget(pXSprite, x, y, z);
aiActivateDude(pSprite, pXSprite);
}

View file

@ -2195,7 +2195,7 @@ void aiGenDudeInitSprite(spritetype* pSprite, XSPRITE* pXSprite) {
switch (pSprite->type) {
case kDudeModernCustom: {
DUDEEXTRA_at6_u1* pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = pDudeExtraE->TotalKills = 0;
pDudeExtraE->xval3 = pDudeExtraE->xval1 = 0;
aiGenDudeNewState(pSprite, &genDudeIdleL);
break;
}

View file

@ -157,7 +157,8 @@ struct GENDUDESND
extern const GENDUDESND gCustomDudeSnd[];
// temporary, until normal DUDEEXTRA gets refactored
struct GENDUDEEXTRA {
struct GENDUDEEXTRA
{
unsigned short initVals[3]; // xrepeat, yrepeat, clipdist
unsigned short availDeaths[kDamageMax]; // list of seqs with deaths for each damage type
unsigned int moveSpeed;
@ -172,17 +173,24 @@ struct GENDUDEEXTRA {
signed short slave[kGenDudeMaxSlaves]; // index of the ones dude is summon
signed short dmgControl[kDamageMax]; // depends of current weapon, drop armor item, sprite yrepeat and surface type
bool updReq[kGenDudePropertyMax]; // update requests
bool sndPlaying; // indicate if sound of AISTATE currently playing
bool forcePunch; // indicate if there is no fire trigger in punch state seq
bool isMelee;
bool canBurn; // can turn in Burning dude or not
bool canElectrocute;
bool canAttack;
bool canRecoil;
bool canWalk;
bool canDuck;
bool canSwim;
bool canFly;
union
{
struct
{
bool sndPlaying : 1; // indicate if sound of AISTATE currently playing
bool forcePunch : 1; // indicate if there is no fire trigger in punch state seq
bool isMelee : 1;
bool canBurn : 1; // can turn in Burning dude or not
bool canElectrocute : 1;
bool canAttack : 1;
bool canRecoil : 1;
bool canWalk : 1;
bool canDuck : 1;
bool canSwim : 1;
bool canFly : 1;
};
int flags;
};
};
extern GENDUDEEXTRA gGenDudeExtra[kMaxSprites];