mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-26 03:30:46 +00:00
Increase kMaxSuperXSprites from 128 to 512.
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.
This commit is contained in:
parent
8a029cb4e1
commit
754554a493
11 changed files with 2057 additions and 815 deletions
|
@ -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])
|
||||
{
|
||||
|
@ -5028,6 +5030,7 @@ void MoveDude(spritetype *pSprite)
|
|||
}
|
||||
sfxPlay3DSound(pSprite, 721, -1, 0);
|
||||
} else {
|
||||
|
||||
switch (pSprite->type) {
|
||||
case kDudeCultistTommy:
|
||||
case kDudeCultistShotgun:
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -5072,6 +5082,7 @@ void MoveDude(spritetype *pSprite)
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch (pSprite->type) {
|
||||
case kDudeCultistTommy:
|
||||
case kDudeCultistShotgun:
|
||||
|
@ -5130,14 +5141,26 @@ 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
|
||||
}
|
||||
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -7016,22 +7039,34 @@ 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 (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 (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)
|
||||
//changespritestat(pSprite->index, kStatThing);
|
||||
//actPostSprite(pSprite->index, kStatThing); // if it was a thing, return it's statnum back
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
@ -7039,10 +7074,32 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6,
|
|||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
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 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 drop items
|
||||
pXDude->dropMsg = pXSource->dropMsg;
|
||||
|
||||
// inherit required key so it can be dropped
|
||||
pXDude->key = pXSource->key;
|
||||
// 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;
|
||||
// inherit dude flags
|
||||
pXDude->dudeDeaf = pXSource->dudeDeaf;
|
||||
pXDude->dudeGuard = pXSource->dudeGuard;
|
||||
pXDude->dudeAmbush = pXSource->dudeAmbush;
|
||||
pXDude->dudeFlag4 = pXSource->dudeFlag4;
|
||||
pXDude->unused1 = pXSource->unused1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1697,6 +1704,7 @@ spritetype* genDudeSpawn(spritetype* pSprite, int nDist) {
|
|||
pDude->yrepeat = pSource->yrepeat;
|
||||
}
|
||||
|
||||
gKillMgr.AddNewKill(1);
|
||||
aiInitSprite(pDude);
|
||||
return pDude;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -408,6 +408,9 @@ kAiStatePatrolWaitW,
|
|||
kAiStatePatrolMoveL,
|
||||
kAiStatePatrolMoveC,
|
||||
kAiStatePatrolMoveW,
|
||||
kAiStatePatrolTurnL,
|
||||
kAiStatePatrolTurnC,
|
||||
kAiStatePatrolTurnW,
|
||||
kAiStatePatrolMax,
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -44,7 +44,7 @@ enum
|
|||
{
|
||||
// CONSTANTS
|
||||
// additional non-thing proximity, sight and physics sprites
|
||||
kMaxSuperXSprites = 128,
|
||||
kMaxSuperXSprites = 512,
|
||||
kMaxTrackingConditions = 64,
|
||||
kMaxTracedObjects = 32, // per one tracking condition
|
||||
|
||||
|
@ -62,21 +62,30 @@ enum
|
|||
kModernTypeFlag2 = 0x0002,
|
||||
kModernTypeFlag3 = 0x0003,
|
||||
kModernTypeFlag4 = 0x0004,
|
||||
kModernTypeFlag8 = 0x0008,
|
||||
kModernTypeFlag16 = 0x0010,
|
||||
|
||||
kMaxRandomizeRetries = 16,
|
||||
kPercFull = 100,
|
||||
kCondRange = 100,
|
||||
};
|
||||
|
||||
#define kPatrolStateSize 27
|
||||
#define kPatrolStateSize 42
|
||||
#define kPatrolAlarmSeeDist 10000
|
||||
#define kPatrolAlarmHearDist 10000
|
||||
#define kMaxPatrolVelocity 500000
|
||||
#define kMaxPatrolCrouchVelocity (kMaxPatrolVelocity >> 1)
|
||||
#define kMaxPatrolSpotValue 500
|
||||
#define kMinPatrolTurnDelay 8
|
||||
#define kPatrolTurnDelayRange 20
|
||||
|
||||
#define kDudeFlagStealth 0x0001
|
||||
#define kDudeFlagCrouch 0x0002
|
||||
|
||||
#define kSlopeDist 0x20
|
||||
#define kEffectGenCallbackBase 200
|
||||
#define kTriggerSpriteScreen 0x0001
|
||||
#define kTriggerSpriteAim 0x0002
|
||||
|
||||
// modern statnums
|
||||
enum {
|
||||
|
@ -87,13 +96,15 @@ kStatModernEventRedirector = 22,
|
|||
kStatModernPlayerLinker = 23,
|
||||
kStatModernBrokenDudeLeech = 24,
|
||||
kStatModernQavScene = 25,
|
||||
kStatModernWindGen = 26,
|
||||
kStatModernStealthRegion = 27,
|
||||
kStatModernTmp = 39,
|
||||
kStatModernMax = 40,
|
||||
};
|
||||
|
||||
// modern sprite types
|
||||
enum {
|
||||
kModernSlopeChanger = 16,
|
||||
kModernStealthRegion = 16,
|
||||
kModernCustomDudeSpawn = 24,
|
||||
kModernRandomTX = 25,
|
||||
kModernSequentialTX = 26,
|
||||
|
@ -121,6 +132,7 @@ kModernThingEnemyLifeLeech = 435, // the same as normal, except it aims
|
|||
kModernPlayerControl = 500, /// WIP
|
||||
kModernCondition = 501, /// WIP, sends command only if specified conditions == true
|
||||
kModernConditionFalse = 502, /// WIP, sends command only if specified conditions != true
|
||||
kModernSlopeChanger = 504,
|
||||
kGenModernMissileUniversal = 704,
|
||||
kGenModernSound = 708,
|
||||
};
|
||||
|
@ -140,6 +152,8 @@ OBJ_SECTOR = 6,
|
|||
};
|
||||
|
||||
enum {
|
||||
kCondGameBase = 0,
|
||||
kCondGameMax = 50,
|
||||
kCondMixedBase = 100,
|
||||
kCondMixedMax = 200,
|
||||
kCondWallBase = 200,
|
||||
|
@ -155,10 +169,15 @@ kCondSpriteMax = 600,
|
|||
};
|
||||
|
||||
enum {
|
||||
kCondSerialSector = 10000,
|
||||
kCondSerialWall = 20000,
|
||||
kCondSerialSprite = 30000,
|
||||
kCondSerialMax = 40000,
|
||||
kCondSerialSector = 100000,
|
||||
kCondSerialWall = 200000,
|
||||
kCondSerialSprite = 300000,
|
||||
kCondSerialMax = 400000,
|
||||
};
|
||||
|
||||
enum {
|
||||
kPatrolMoveForward = 0,
|
||||
kPatrolMoveBackward = 1,
|
||||
};
|
||||
|
||||
// - STRUCTS ------------------------------------------------------------------
|
||||
|
@ -202,6 +221,7 @@ struct DUDEINFO_EXTRA {
|
|||
int mvewseqofs : 6; // used for patrol
|
||||
int idlcseqofs : 6; // used for patrol
|
||||
int mvecseqofs : 6; // used for patrol
|
||||
|
||||
};
|
||||
|
||||
struct TRPLAYERCTRL { // this one for controlling the player using triggers (movement speed, jumps and other stuff)
|
||||
|
@ -220,6 +240,22 @@ struct TRCONDITION {
|
|||
OBJECTS_TO_TRACK obj[kMaxTracedObjects];
|
||||
};
|
||||
|
||||
struct PATROL_FOUND_SOUNDS {
|
||||
|
||||
int snd;
|
||||
int max;
|
||||
int cur;
|
||||
|
||||
};
|
||||
|
||||
struct CONDITION_TYPE_NAMES {
|
||||
|
||||
int rng1;
|
||||
int rng2;
|
||||
char name[32];
|
||||
|
||||
};
|
||||
|
||||
// - VARIABLES ------------------------------------------------------------------
|
||||
extern bool gModernMap;
|
||||
extern bool gTeamsSpawnUsed;
|
||||
|
@ -244,6 +280,11 @@ extern short gImpactSpritesCount;
|
|||
extern short gTrackingCondsCount;
|
||||
extern AISTATE genPatrolStates[kPatrolStateSize];
|
||||
|
||||
|
||||
// - INLINES -------------------------------------------------------------------
|
||||
inline bool xsprIsFine(spritetype* pSpr) {
|
||||
return (pSpr && xspriRangeIsFine(pSpr->extra) && !(pSpr->flags & kHitagFree) && !(pSpr->flags & kHitagRespawn));
|
||||
}
|
||||
// - FUNCTIONS ------------------------------------------------------------------
|
||||
bool nnExtEraseModernStuff(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
void nnExtInitModernStuff(bool bSaveLoad);
|
||||
|
@ -254,7 +295,7 @@ void nnExtResetGlobals();
|
|||
void nnExtTriggerObject(int objType, int objIndex, int command);
|
||||
// ------------------------------------------------------------------------- //
|
||||
spritetype* randomDropPickupObject(spritetype* pSprite, short prevItem);
|
||||
spritetype* randomSpawnDude(spritetype* pSprite);
|
||||
spritetype* randomSpawnDude(XSPRITE* pXSource, spritetype* pSprite, int a3, int a4);
|
||||
int GetDataVal(spritetype* pSprite, int data);
|
||||
int randomGetDataValue(XSPRITE* pXSprite, int randType);
|
||||
void sfxPlayMissileSound(spritetype* pSprite, int missileId);
|
||||
|
@ -295,7 +336,7 @@ void damageSprites(XSPRITE* pXSource, spritetype* pSprite);
|
|||
void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite);
|
||||
void useObjResizer(XSPRITE* pXSource, short objType, int objIndex);
|
||||
void useRandomItemGen(spritetype* pSource, XSPRITE* pXSource);
|
||||
void useUniMissileGen(int, int nXSprite);
|
||||
void useUniMissileGen(XSPRITE* pXSource, spritetype* pSprite);
|
||||
void useSoundGen(XSPRITE* pXSource, spritetype* pSprite);
|
||||
void useIncDecGen(XSPRITE* pXSource, short objType, int objIndex);
|
||||
void useDataChanger(XSPRITE* pXSource, int objType, int objIndex);
|
||||
|
@ -305,6 +346,8 @@ void usePictureChanger(XSPRITE* pXSource, int objType, int objIndex);
|
|||
void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex);
|
||||
void useSequentialTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState);
|
||||
void useRandomTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState);
|
||||
void useDudeSpawn(XSPRITE* pXSource, spritetype* pSprite);
|
||||
void useCustomDudeSpawn(XSPRITE* pXSource, spritetype* pSprite);
|
||||
bool txIsRanged(XSPRITE* pXSource);
|
||||
void seqTxSendCmdAll(XSPRITE* pXSource, int nIndex, COMMAND_ID cmd, bool modernSend);
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
@ -377,15 +420,43 @@ void seqSpawnerOffSameTx(XSPRITE* pXSource);
|
|||
void aiPatrolSetMarker(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
void aiPatrolThink(DBloodActor* actor);
|
||||
void aiPatrolStop(spritetype* pSprite, int target, bool alarm = false);
|
||||
void aiPatrolAlarm(spritetype* pSprite, bool chain);
|
||||
void aiPatrolAlarmFull(spritetype* pSprite, XSPRITE* pXTarget, bool chain);
|
||||
void aiPatrolAlarmLite(spritetype* pSprite, XSPRITE* pXTarget);
|
||||
void aiPatrolState(spritetype* pSprite, int state);
|
||||
void aiPatrolMove(DBloodActor* actor);
|
||||
int aiPatrolMarkerBusy(int nExcept, int nMarker);
|
||||
bool aiPatrolMarkerReached(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
AISTATE* aiInPatrolState(AISTATE* pAiState);
|
||||
bool aiPatrolGetPathDir(XSPRITE* pXSprite, XSPRITE* pXMarker);
|
||||
void aiPatrolFlagsMgr(spritetype* pSource, XSPRITE* pXSource, spritetype* pDest, XSPRITE* pXDest, bool copy, bool init);
|
||||
void aiPatrolRandGoalAng(DBloodActor* actor);
|
||||
void aiPatrolTurn(DBloodActor* actor);
|
||||
inline int aiPatrolGetVelocity(int speed, int value) {
|
||||
return (value > 0) ? ClipRange((speed / 3) + (2500 * value), 0, 0x47956) : speed;
|
||||
}
|
||||
|
||||
inline bool aiPatrolWaiting(AISTATE* pAiState) {
|
||||
return (pAiState->stateType >= kAiStatePatrolWaitL && pAiState->stateType <= kAiStatePatrolWaitW);
|
||||
}
|
||||
|
||||
inline bool aiPatrolMoving(AISTATE* pAiState) {
|
||||
return (pAiState->stateType >= kAiStatePatrolMoveL && pAiState->stateType <= kAiStatePatrolMoveW);
|
||||
}
|
||||
|
||||
inline bool aiPatrolTurning(AISTATE* pAiState) {
|
||||
return (pAiState->stateType >= kAiStatePatrolTurnL && pAiState->stateType <= kAiStatePatrolTurnW);
|
||||
}
|
||||
|
||||
inline bool aiInPatrolState(AISTATE* pAiState) {
|
||||
return (pAiState->stateType >= kAiStatePatrolBase && pAiState->stateType < kAiStatePatrolMax);
|
||||
}
|
||||
|
||||
inline bool aiInPatrolState(int nAiStateType) {
|
||||
return (nAiStateType >= kAiStatePatrolBase && nAiStateType < kAiStatePatrolMax);
|
||||
}
|
||||
// ------------------------------------------------------------------------- //
|
||||
bool readyForCrit(spritetype* pHunter, spritetype* pVictim);
|
||||
int sectorInMotion(int nSector);
|
||||
void clampSprite(spritetype* pSprite, int which = 0x03);
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue