Skip to content

Commit

Permalink
Increase kMaxSuperXSprites from 128 to 512.
Browse files Browse the repository at this point in the history
Fix mirror (ROR) intialization so it won't crash if more than 1024 sectors used.
Fix random item generator so items that inherits TX ID won't send command at respawn.
Fix for things (400 - 433) that affected by modern physics so it won't return to vanilla physics after getting damage.
Fix kTeleportTarget so teleported sprites won't stuck in floors or ceilings.
Corpses won't gib as gargoyles anymore (gModernMap).

kModernCondition:
 - remove bool comparison (condCmpb).
 - remove no extra comparison (condCmpne).
 - remove "else if" search at level start.
 - add global (game) conditions type.
 - add more conditions.
 - make error report a bit more informative.

Add more options and damage effects for kModernSpriteDamager.
Add more options for kModernMissileGen and allow to spawn projectile on TX ID sprites location.
Add more options and vertical wind processing for kModernWindGen.
Add more options and effects for kModernEffectGen.
Allow kMarkerDudeSpawn to spawn enemies on TX ID sprites location (gModernMap).
Allow kModernCustomDudeSpawn to spawn dude on TX ID sprites location.
Add Screen and Aim trigger flags for sprites that can be triggered with Sight (gModernMap).

Patrolling enemies:
 - add turn AI state.
 - add "return back" option for path markers.
 - add "turning while waiting" option for markers.
 - make enemies to hear some sounds assuming that player generates and hears it too.
 - add kModernStealthRegion type to affect current spot progress velocity.
 - replace AI's CanMove and aiChooseDirection to a better versions.
 - make flying enemies to not spin around the marker.
 - treat Phantasm as flying enemy!
 - allow to continue patrol when falling in water.

Fix compile warnings
Various minor fixes / cleanup.
  • Loading branch information
NoOneBlood authored and mjr4077au committed Jul 25, 2021
1 parent 8a029cb commit 754554a
Show file tree
Hide file tree
Showing 11 changed files with 2,022 additions and 780 deletions.
103 changes: 80 additions & 23 deletions source/games/blood/src/actor.cpp
Expand Up @@ -4817,6 +4817,8 @@ void MoveDude(spritetype *pSprite)
int tz = (pSprite->z-top)/4;
int wd = pSprite->clipdist<<2;
int nSector = pSprite->sectnum;
int nAiStateType = (pXSprite->aiState) ? pXSprite->aiState->stateType : -1;

assert(nSector >= 0 && nSector < kMaxSectors);
if (xvel[nSprite] || yvel[nSprite])
{
Expand Down Expand Up @@ -5028,6 +5030,7 @@ void MoveDude(spritetype *pSprite)
}
sfxPlay3DSound(pSprite, 721, -1, 0);
} else {

switch (pSprite->type) {
case kDudeCultistTommy:
case kDudeCultistShotgun:
Expand All @@ -5041,6 +5044,11 @@ void MoveDude(spritetype *pSprite)
actKillDude(pSprite->index, pSprite, kDamageFall, 1000<<4);
break;
}

#ifdef NOONE_EXTENSIONS
if (IsDudeSprite(pSprite) && pXSprite->health > 0 && aiInPatrolState(nAiStateType))
aiPatrolState(pSprite, kAiStatePatrolMoveL); // continue patrol when going from water
#endif
}
break;
case kMarkerUpWater:
Expand All @@ -5058,10 +5066,12 @@ void MoveDude(spritetype *pSprite)
{
#ifdef NOONE_EXTENSIONS
// look for palette in data2 of marker. If value <= 0, use default ones.
pPlayer->nWaterPal = 0;
int nXUpper = sprite[gUpperLink[nSector]].extra;
if (nXUpper >= 0)
pPlayer->nWaterPal = xsprite[nXUpper].data2;
if (gModernMap) {
pPlayer->nWaterPal = 0;
int nXUpper = sprite[gUpperLink[nSector]].extra;
if (nXUpper >= 0)
pPlayer->nWaterPal = xsprite[nXUpper].data2;
}
#endif

pPlayer->posture = 1;
Expand All @@ -5072,6 +5082,7 @@ void MoveDude(spritetype *pSprite)
}
else
{

switch (pSprite->type) {
case kDudeCultistTommy:
case kDudeCultistShotgun:
Expand Down Expand Up @@ -5130,13 +5141,25 @@ void MoveDude(spritetype *pSprite)
case kDudeBurningInnocent:
actKillDude(pSprite->index, pSprite, kDamageFall, 1000 << 4);
break;
}

#ifdef NOONE_EXTENSIONS
case kDudeModernCustom:
evPost(nSprite, 3, 0, kCallbackEnemeyBubble);
if (!canSwim(pSprite)) actKillDude(pSprite->index, pSprite, kDamageFall, 1000 << 4);
break;
#endif
if (gModernMap) {

if (pSprite->type == kDudeModernCustom) {

evPost(nSprite, 3, 0, kCallbackEnemeyBubble);
if (!canSwim(pSprite))
actKillDude(pSprite->index, pSprite, kDamageFall, 1000 << 4);

}

// continue patrol when fall into water
if (IsDudeSprite(pSprite) && pXSprite->health > 0 && aiInPatrolState(nAiStateType))
aiPatrolState(pSprite, kAiStatePatrolMoveW);

}
#endif

}
break;
Expand Down Expand Up @@ -5207,7 +5230,7 @@ void MoveDude(spritetype *pSprite)
case kDudeBat:
case kDudeRat:
case kDudeBurningInnocent:
actKillDude(pSprite->index, pSprite, DAMAGE_TYPE_0, 1000<<4);
actKillDude(pSprite->index, pSprite, kDamageFall, 1000<<4);
break;
}
}
Expand Down Expand Up @@ -7016,33 +7039,67 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6,
#ifdef NOONE_EXTENSIONS
// add impulse for sprites from physics list
if (gPhysSpritesCount > 0 && pVectorData->impulse) {
int nIndex = debrisGetIndex(pSprite->index);
if (nIndex != -1 && (xsprite[pSprite->extra].physAttr & kPhysDebrisVector)) {
int impulse = DivScale(pVectorData->impulse, ClipLow(gSpriteMass[pSprite->extra].mass, 10), 6);
xvel[nSprite] += MulScale(a4, impulse, 16);
yvel[nSprite] += MulScale(a5, impulse, 16);
zvel[nSprite] += MulScale(a6, impulse, 16);

if (pVectorData->burnTime != 0) {
if (!xsprite[nXSprite].burnTime) evPost(nSprite, 3, 0, kCallbackFXFlameLick);
actBurnSprite(sprite[nShooter].owner, &xsprite[nXSprite], pVectorData->burnTime);

if (xspriRangeIsFine(pSprite->extra)) {

XSPRITE* pXSprite = &xsprite[pSprite->extra];
if (pXSprite->physAttr & kPhysDebrisVector) {

int impulse = DivScale(pVectorData->impulse, ClipLow(gSpriteMass[pSprite->extra].mass, 10), 6);
xvel[nSprite] += MulScale(a4, impulse, 16);
yvel[nSprite] += MulScale(a5, impulse, 16);
zvel[nSprite] += MulScale(a6, impulse, 16);

if (pVectorData->burnTime != 0) {
if (!xsprite[nXSprite].burnTime) evPost(nSprite, 3, 0, kCallbackFXFlameLick);
actBurnSprite(sprite[nShooter].owner, &xsprite[nXSprite], pVectorData->burnTime);
}

if (pSprite->type >= kThingBase && pSprite->type < kThingMax) {
pSprite->statnum = kStatThing; // temporary change statnum property
actDamageSprite(nShooter, pSprite, pVectorData->dmgType, pVectorData->dmg << 4);
pSprite->statnum = kStatDecoration; // return statnum property back
}

}

//if (pSprite->type >= kThingBase && pSprite->type < kThingMax)
//changespritestat(pSprite->index, kStatThing);
//actPostSprite(pSprite->index, kStatThing); // if it was a thing, return it's statnum back

}


}
#endif
break;
}
}
}
assert(nSurf < kSurfMax);
#ifdef NOONE_EXTENSIONS

// let the patrol enemies hear surface hit sounds!

if (pVectorData->surfHit[nSurf].fx2 >= 0) {

spritetype* pFX2 = gFX.fxSpawn(pVectorData->surfHit[nSurf].fx2, nSector, x, y, z, 0);
if (pFX2 && gModernMap)
pFX2->owner = pShooter->index;
}

if (pVectorData->surfHit[nSurf].fx3 >= 0) {

spritetype* pFX3 = gFX.fxSpawn(pVectorData->surfHit[nSurf].fx3, nSector, x, y, z, 0);
if (pFX3 && gModernMap)
pFX3->owner = pShooter->index;

}

#else
if (pVectorData->surfHit[nSurf].fx2 >= 0)
gFX.fxSpawn(pVectorData->surfHit[nSurf].fx2, nSector, x, y, z, 0);
if (pVectorData->surfHit[nSurf].fx3 >= 0)
gFX.fxSpawn(pVectorData->surfHit[nSurf].fx3, nSector, x, y, z, 0);
#endif

if (pVectorData->surfHit[nSurf].fxSnd >= 0)
sfxPlay3DSound(x, y, z, pVectorData->surfHit[nSurf].fxSnd, nSector);
}
Expand Down
6 changes: 6 additions & 0 deletions source/games/blood/src/actor.h
Expand Up @@ -209,6 +209,12 @@ void actAddGameLight(int lightRadius, int spriteNum, int zOffset, int lightRange
void actDoLight(int spriteNum);
#endif

void FireballSeqCallback(int, int);
void sub_38938(int, int);
void NapalmSeqCallback(int, int);
void sub_3888C(int, int);
void TreeToGibCallback(int, int);

bool IsUnderwaterSector(int nSector);
void actInit(bool bSaveLoad);
int actWallBounceVector(int *x, int *y, int nWall, int a4);
Expand Down
4 changes: 4 additions & 0 deletions source/games/blood/src/ai.cpp
Expand Up @@ -1813,6 +1813,10 @@ void aiInitSprite(spritetype *pSprite)

// make dude follow the markers
bool uwater = spriteIsUnderwater(pSprite);
if (pXSprite->target <= 0 || sprite[pXSprite->target].type != kMarkerPath) {
pXSprite->target = -1; aiPatrolSetMarker(pSprite, pXSprite);
}

if (stateTimer > 0) {
if (uwater) aiPatrolState(pSprite, kAiStatePatrolWaitW);
else if (pXSprite->unused1 & kDudeFlagCrouch) aiPatrolState(pSprite, kAiStatePatrolWaitC);
Expand Down
74 changes: 41 additions & 33 deletions source/games/blood/src/aiunicult.cpp
Expand Up @@ -104,6 +104,13 @@ const GENDUDESND gCustomDudeSnd[] = {
{ 9008, 0, 17, false, false }, // transforming in other dude
};

// for kModernThingThrowableRock
short gCustomDudeDebrisPics[6] = {

2406, 2280, 2185, 2155, 2620, 3135

};

GENDUDEEXTRA gGenDudeExtra[kMaxSprites]; // savegame handling in ai.cpp

static void forcePunch(DBloodActor* actor)
Expand Down Expand Up @@ -318,12 +325,7 @@ static void ThrowThing(DBloodActor* actor, bool impact)
impact = true;
break;
case kModernThingThrowableRock:
int sPics[6];
sPics[0] = 2406; sPics[1] = 2280;
sPics[2] = 2185; sPics[3] = 2155;
sPics[4] = 2620; sPics[5] = 3135;

pThing->picnum = sPics[Random(5)];
pThing->picnum = gCustomDudeDebrisPics[Random(5)];
pThing->xrepeat = pThing->yrepeat = 24 + Random(42);
pThing->cstat |= 0x0001;
pThing->pal = 5;
Expand Down Expand Up @@ -1624,19 +1626,23 @@ bool doExplosion(spritetype* pSprite, int nType) {

// this function allows to spawn new custom dude and inherit spawner settings,
// so custom dude can have different weapons, hp and so on...
spritetype* genDudeSpawn(spritetype* pSprite, int nDist) {
spritetype* genDudeSpawn(XSPRITE* pXSource, spritetype* pSprite, int nDist) {

spritetype* pSource = pSprite; XSPRITE* pXSource = &xsprite[pSource->extra];
spritetype* pDude = actSpawnSprite(pSprite, 6); XSPRITE* pXDude = &xsprite[pDude->extra];
spritetype* pSource = &sprite[pXSource->reference];
spritetype* pDude = actSpawnSprite(pSprite, kStatDude); XSPRITE* pXDude = &xsprite[pDude->extra];

int x, y, z = pSprite->z, nAngle = pSprite->ang, nType = kDudeModernCustom;

if (nDist > 0) {

x = pSprite->x + mulscale30r(Cos(nAngle), nDist);
y = pSprite->y + mulscale30r(Sin(nAngle), nDist);

} else {

x = pSprite->x;
y = pSprite->y;

}

pDude->type = nType; pDude->ang = nAngle;
Expand All @@ -1656,7 +1662,8 @@ spritetype* genDudeSpawn(spritetype* pSprite, int nDist) {
pXDude->busyTime = pXSource->busyTime;

// inherit clipdist?
if (pSource->clipdist > 0) pDude->clipdist = pSource->clipdist;
if (pSource->clipdist > 0)
pDude->clipdist = pSource->clipdist;

// inherit custom hp settings
if (pXSource->data4 <= 0) pXDude->health = dudeInfo[nType - kDudeBase].startHealth << 4;
Expand All @@ -1665,29 +1672,29 @@ spritetype* genDudeSpawn(spritetype* pSprite, int nDist) {

if (pSource->flags & kModernTypeFlag1) {
switch (pSource->type) {
case kModernCustomDudeSpawn:
//inherit pal?
if (pDude->pal <= 0) pDude->pal = pSource->pal;

// inherit spawn sprite trigger settings, so designer can count monsters.
pXDude->txID = pXSource->txID;
pXDude->command = pXSource->command;
pXDude->triggerOn = pXSource->triggerOn;
pXDude->triggerOff = pXSource->triggerOff;

// inherit drop items
pXDude->dropMsg = pXSource->dropMsg;

// inherit required key so it can be dropped
pXDude->key = pXSource->key;

// inherit dude flags
pXDude->dudeDeaf = pXSource->dudeDeaf;
pXDude->dudeGuard = pXSource->dudeGuard;
pXDude->dudeAmbush = pXSource->dudeAmbush;
pXDude->dudeFlag4 = pXSource->dudeFlag4;
pXDude->unused1 = pXSource->unused1;
break;
case kModernCustomDudeSpawn:
//inherit pal?
if (pDude->pal <= 0) pDude->pal = pSource->pal;

// inherit spawn sprite trigger settings, so designer can count monsters.
pXDude->txID = pXSource->txID;
pXDude->command = pXSource->command;
pXDude->triggerOn = pXSource->triggerOn;
pXDude->triggerOff = pXSource->triggerOff;

// inherit drop items
pXDude->dropMsg = pXSource->dropMsg;

// inherit required key so it can be dropped
pXDude->key = pXSource->key;

// inherit dude flags
pXDude->dudeDeaf = pXSource->dudeDeaf;
pXDude->dudeGuard = pXSource->dudeGuard;
pXDude->dudeAmbush = pXSource->dudeAmbush;
pXDude->dudeFlag4 = pXSource->dudeFlag4;
pXDude->unused1 = pXSource->unused1;
break;
}
}

Expand All @@ -1697,6 +1704,7 @@ spritetype* genDudeSpawn(spritetype* pSprite, int nDist) {
pDude->yrepeat = pSource->yrepeat;
}

gKillMgr.AddNewKill(1);
aiInitSprite(pDude);
return pDude;
}
Expand Down
2 changes: 1 addition & 1 deletion source/games/blood/src/aiunicult.h
Expand Up @@ -209,7 +209,7 @@ void aiGenDudeNewState(spritetype* pSprite, AISTATE* pAIState);
int getGenDudeMoveSpeed(spritetype* pSprite, int which, bool mul, bool shift);
int checkAttackState(DBloodActor* actor);
bool doExplosion(spritetype* pSprite, int nType);
spritetype* genDudeSpawn(spritetype* pSprite, int nDist);
spritetype* genDudeSpawn(XSPRITE* pXSource, spritetype* pSprite, int nDist);
void genDudeTransform(spritetype* pSprite);
void dudeLeechOperate(spritetype* pSprite, XSPRITE* pXSprite, EVENT a3);
int getDodgeChance(spritetype* pSprite);
Expand Down
3 changes: 3 additions & 0 deletions source/games/blood/src/common_game.h
Expand Up @@ -408,6 +408,9 @@ kAiStatePatrolWaitW,
kAiStatePatrolMoveL,
kAiStatePatrolMoveC,
kAiStatePatrolMoveW,
kAiStatePatrolTurnL,
kAiStatePatrolTurnC,
kAiStatePatrolTurnW,
kAiStatePatrolMax,
};

Expand Down
4 changes: 2 additions & 2 deletions source/games/blood/src/db.cpp
Expand Up @@ -935,7 +935,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
pXSprite->Touch = bitReader.readUnsigned(1);
pXSprite->Sight = bitReader.readUnsigned(1);
pXSprite->Proximity = bitReader.readUnsigned(1);
bitReader.readUnsigned(2);
pXSprite->unused3 = bitReader.readUnsigned(2);
pXSprite->lSkill = bitReader.readUnsigned(5);
pXSprite->lS = bitReader.readUnsigned(1);
pXSprite->lB = bitReader.readUnsigned(1);
Expand All @@ -950,7 +950,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
pXSprite->medium = bitReader.readUnsigned(2);
pXSprite->respawn = bitReader.readUnsigned(2);
pXSprite->data4 = bitReader.readUnsigned(16);
bitReader.readUnsigned(6);
pXSprite->unused4 = bitReader.readUnsigned(6);
pXSprite->lockMsg = bitReader.readUnsigned(8);
pXSprite->health = bitReader.readUnsigned(12);
pXSprite->dudeDeaf = bitReader.readUnsigned(1);
Expand Down
2 changes: 2 additions & 0 deletions source/games/blood/src/db.h
Expand Up @@ -96,6 +96,8 @@ struct XSPRITE {
unsigned int medium : 2; // medium
unsigned int respawn : 2; // Respawn option
unsigned int unused2 : 1; // (new) patrol state
unsigned int unused3 : 2; // "unused"
unsigned int unused4 : 6; // "unused"
};
};
int32_t targetX; // target x
Expand Down
2 changes: 1 addition & 1 deletion source/games/blood/src/mirrors.cpp
Expand Up @@ -113,7 +113,7 @@ void InitMirrors(void)
int nLink = gUpperLink[i];
if (nLink < 0)
continue;
int nLink2 = sprite[nLink].owner & 0xfff;
int nLink2 = sprite[nLink].owner /*& 0xfff*/;
int j = sprite[nLink2].sectnum;
if (sector[j].ceilingpicnum != 504)
I_Error("Lower link sector %d doesn't have mirror picnum\n", j);
Expand Down

0 comments on commit 754554a

Please sign in to comment.