mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 08:52:00 +00:00
- manual update of some missed content.
This commit is contained in:
parent
f60fa44efb
commit
6a0785bbd4
10 changed files with 429 additions and 366 deletions
|
@ -2262,9 +2262,9 @@ const THINGINFO thingInfo[] = {
|
||||||
800,
|
800,
|
||||||
(char)-128,
|
(char)-128,
|
||||||
0,
|
0,
|
||||||
48,
|
44,
|
||||||
48,
|
44,
|
||||||
64, 64, 112, 64, 0, 96, 96,
|
0, 1024, 512, 1024, 0, 64, 512,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2359,7 +2359,7 @@ const EXPLOSION explodeInfo[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int gDudeDrag = 0x2a00;
|
||||||
|
|
||||||
short gAffectedSectors[kMaxSectors];
|
short gAffectedSectors[kMaxSectors];
|
||||||
short gAffectedXWalls[kMaxXWalls];
|
short gAffectedXWalls[kMaxXWalls];
|
||||||
|
@ -5260,7 +5260,8 @@ void actExplodeSprite(spritetype *pSprite)
|
||||||
return;
|
return;
|
||||||
sfxKill3DSound(pSprite, -1, -1);
|
sfxKill3DSound(pSprite, -1, -1);
|
||||||
evKill(pSprite->index, 3);
|
evKill(pSprite->index, 3);
|
||||||
int nType;
|
int nType = kExplosionStandard;
|
||||||
|
|
||||||
switch (pSprite->type)
|
switch (pSprite->type)
|
||||||
{
|
{
|
||||||
case kMissileFireballNapam:
|
case kMissileFireballNapam:
|
||||||
|
|
|
@ -365,14 +365,14 @@ static void ThrowThing(int nXIndex, bool impact) {
|
||||||
case kModernThingEnemyLifeLeech:
|
case kModernThingEnemyLifeLeech:
|
||||||
XSPRITE* pXThing = &xsprite[pThing->extra];
|
XSPRITE* pXThing = &xsprite[pThing->extra];
|
||||||
if (pLeech != NULL) pXThing->health = pXLeech->health;
|
if (pLeech != NULL) pXThing->health = pXLeech->health;
|
||||||
else pXThing->health = 300 * gGameOptions.nDifficulty;
|
else pXThing->health = ((pThinkInfo->startHealth << 4) * gGameOptions.nDifficulty) >> 1;
|
||||||
|
|
||||||
sfxPlay3DSound(pSprite, 490, -1, 0);
|
sfxPlay3DSound(pSprite, 490, -1, 0);
|
||||||
|
|
||||||
if (gGameOptions.nDifficulty <= 2) pXThing->data3 = 32700;
|
pXThing->data3 = 512 / (gGameOptions.nDifficulty + 1);
|
||||||
else pXThing->data3 = Random(10);
|
|
||||||
pThing->cstat &= ~CSTAT_SPRITE_BLOCK;
|
pThing->cstat &= ~CSTAT_SPRITE_BLOCK;
|
||||||
pThing->pal = 6;
|
pThing->pal = 6;
|
||||||
|
pThing->clipdist = 0;
|
||||||
pXThing->target = pTarget->index;
|
pXThing->target = pTarget->index;
|
||||||
pXThing->Proximity = true;
|
pXThing->Proximity = true;
|
||||||
pXThing->stateTimer = 1;
|
pXThing->stateTimer = 1;
|
||||||
|
@ -438,6 +438,7 @@ static void thinkChase( spritetype* pSprite, XSPRITE* pXSprite ) {
|
||||||
if (pXTarget == NULL) { // target lost
|
if (pXTarget == NULL) { // target lost
|
||||||
if(spriteIsUnderwater(pSprite,false)) aiGenDudeNewState(pSprite, &genDudeSearchShortW);
|
if(spriteIsUnderwater(pSprite,false)) aiGenDudeNewState(pSprite, &genDudeSearchShortW);
|
||||||
else aiGenDudeNewState(pSprite, &genDudeSearchShortL);
|
else aiGenDudeNewState(pSprite, &genDudeSearchShortL);
|
||||||
|
pXSprite->target = -1;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (pXTarget->health <= 0) { // target is dead
|
} else if (pXTarget->health <= 0) { // target is dead
|
||||||
|
@ -449,6 +450,7 @@ static void thinkChase( spritetype* pSprite, XSPRITE* pXSprite ) {
|
||||||
}
|
}
|
||||||
else if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeGotoW);
|
else if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeGotoW);
|
||||||
else aiGenDudeNewState(pSprite, &genDudeGotoL);
|
else aiGenDudeNewState(pSprite, &genDudeGotoL);
|
||||||
|
pXSprite->target = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,6 +479,7 @@ static void thinkChase( spritetype* pSprite, XSPRITE* pXSprite ) {
|
||||||
if (powerupCheck(pPlayer, kPwUpShadowCloak) > 0) {
|
if (powerupCheck(pPlayer, kPwUpShadowCloak) > 0) {
|
||||||
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeSearchShortW);
|
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeSearchShortW);
|
||||||
else aiGenDudeNewState(pSprite, &genDudeSearchShortL);
|
else aiGenDudeNewState(pSprite, &genDudeSearchShortL);
|
||||||
|
pXSprite->target = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1388,57 +1391,57 @@ void scaleDamage(XSPRITE* pXSprite) {
|
||||||
switch (surfType) {
|
switch (surfType) {
|
||||||
case 1: // stone
|
case 1: // stone
|
||||||
curScale[kDmgFall] = 0;
|
curScale[kDmgFall] = 0;
|
||||||
curScale[kDmgBullet] -= 128;
|
curScale[kDmgBullet] -= 200;
|
||||||
curScale[kDmgBurn] -= 50;
|
curScale[kDmgBurn] -= 100;
|
||||||
curScale[kDmgExplode] -= 40;
|
curScale[kDmgExplode] -= 80;
|
||||||
curScale[kDmgChoke] += 30;
|
curScale[kDmgChoke] += 30;
|
||||||
curScale[kDmgElectric] += 20;
|
curScale[kDmgElectric] += 20;
|
||||||
break;
|
break;
|
||||||
case 2: // metal
|
case 2: // metal
|
||||||
curScale[kDmgFall] = 16;
|
curScale[kDmgFall] = 16;
|
||||||
curScale[kDmgBullet] -= 64;
|
curScale[kDmgBullet] -= 128;
|
||||||
curScale[kDmgBurn] -= 45;
|
curScale[kDmgBurn] -= 90;
|
||||||
curScale[kDmgExplode] -= 35;
|
curScale[kDmgExplode] -= 55;
|
||||||
curScale[kDmgChoke] += 20;
|
curScale[kDmgChoke] += 20;
|
||||||
curScale[kDmgElectric] += 30;
|
curScale[kDmgElectric] += 30;
|
||||||
break;
|
break;
|
||||||
case 3: // wood
|
case 3: // wood
|
||||||
curScale[kDmgBullet] -= 5;
|
curScale[kDmgBullet] -= 10;
|
||||||
curScale[kDmgBurn] += 50;
|
curScale[kDmgBurn] += 50;
|
||||||
curScale[kDmgExplode] += 40;
|
curScale[kDmgExplode] += 40;
|
||||||
curScale[kDmgChoke] += 10;
|
curScale[kDmgChoke] += 10;
|
||||||
curScale[kDmgElectric] -= 30;
|
curScale[kDmgElectric] -= 60;
|
||||||
break;
|
break;
|
||||||
case 5: // water
|
case 5: // water
|
||||||
case 6: // dirt
|
case 6: // dirt
|
||||||
case 7: // clay
|
case 7: // clay
|
||||||
case 13: // goo
|
case 13: // goo
|
||||||
curScale[kDmgFall] = 8;
|
curScale[kDmgFall] = 8;
|
||||||
curScale[kDmgBullet] -= 10;
|
curScale[kDmgBullet] -= 20;
|
||||||
curScale[kDmgBurn] -= 128;
|
curScale[kDmgBurn] -= 200;
|
||||||
curScale[kDmgExplode] -= 30;
|
curScale[kDmgExplode] -= 60;
|
||||||
curScale[kDmgChoke] = 0;
|
curScale[kDmgChoke] = 0;
|
||||||
curScale[kDmgElectric] += 40;
|
curScale[kDmgElectric] += 40;
|
||||||
break;
|
break;
|
||||||
case 8: // snow
|
case 8: // snow
|
||||||
case 9: // ice
|
case 9: // ice
|
||||||
curScale[kDmgFall] = 8;
|
curScale[kDmgFall] = 8;
|
||||||
curScale[kDmgBullet] -= 10;
|
curScale[kDmgBullet] -= 20;
|
||||||
curScale[kDmgBurn] -= 60;
|
curScale[kDmgBurn] -= 100;
|
||||||
curScale[kDmgExplode] -= 40;
|
curScale[kDmgExplode] -= 50;
|
||||||
curScale[kDmgChoke] = 0;
|
curScale[kDmgChoke] = 0;
|
||||||
curScale[kDmgElectric] += 40;
|
curScale[kDmgElectric] += 40;
|
||||||
break;
|
break;
|
||||||
case 10: // leaves
|
case 10: // leaves
|
||||||
case 12: // plant
|
case 12: // plant
|
||||||
curScale[kDmgFall] = 0;
|
curScale[kDmgFall] = 0;
|
||||||
curScale[kDmgBullet] -= 5;
|
curScale[kDmgBullet] -= 10;
|
||||||
curScale[kDmgBurn] += 70;
|
curScale[kDmgBurn] += 70;
|
||||||
curScale[kDmgExplode] += 50;
|
curScale[kDmgExplode] += 50;
|
||||||
break;
|
break;
|
||||||
case 11: // cloth
|
case 11: // cloth
|
||||||
curScale[kDmgFall] = 8;
|
curScale[kDmgFall] = 8;
|
||||||
curScale[kDmgBullet] -= 5;
|
curScale[kDmgBullet] -= 10;
|
||||||
curScale[kDmgBurn] += 30;
|
curScale[kDmgBurn] += 30;
|
||||||
curScale[kDmgExplode] += 20;
|
curScale[kDmgExplode] += 20;
|
||||||
break;
|
break;
|
||||||
|
@ -2116,7 +2119,7 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
|
||||||
pExtra->nLifeLeech = -1;
|
pExtra->nLifeLeech = -1;
|
||||||
if (pSprite->owner != kMaxSprites - 1) {
|
if (pSprite->owner != kMaxSprites - 1) {
|
||||||
for (int nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
for (int nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
||||||
if (sprite[nSprite].owner == pSprite->index && pSprite->type == kModernThingEnemyLifeLeech) {
|
if (sprite[nSprite].owner == pSprite->index && sprite[nSprite].type == kModernThingEnemyLifeLeech) {
|
||||||
pExtra->nLifeLeech = nSprite;
|
pExtra->nLifeLeech = nSprite;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
|
bool gModernMap = false;
|
||||||
unsigned short gStatCount[kMaxStatus + 1];
|
unsigned short gStatCount[kMaxStatus + 1];
|
||||||
|
|
||||||
XSPRITE xsprite[kMaxXSprites];
|
XSPRITE xsprite[kMaxXSprites];
|
||||||
|
|
|
@ -49,7 +49,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
bool gModernMap = false;
|
|
||||||
bool gAllowTrueRandom = false;
|
bool gAllowTrueRandom = false;
|
||||||
bool gEventRedirectsUsed = false;
|
bool gEventRedirectsUsed = false;
|
||||||
SPRITEMASS gSpriteMass[]; // cache for getSpriteMassBySize();
|
SPRITEMASS gSpriteMass[]; // cache for getSpriteMassBySize();
|
||||||
|
@ -113,20 +112,20 @@ THINGINFO_EXTRA gThingInfoExtra[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
DUDEINFO_EXTRA gDudeInfoExtra[] = {
|
DUDEINFO_EXTRA gDudeInfoExtra[] = {
|
||||||
false, false, false, false, false, false, false, false, false, false, true, false,
|
false, false, false, false, false, false, false, true,
|
||||||
false, false, false, false, true, false, true, true, false, true, false, false,
|
false, false, false, true, true, true, true, false,
|
||||||
true, false, false, false, false, false, false, true, true, false, true, true,
|
true, false, false, false, false, true, false, true,
|
||||||
false, true, true, false, true, true, false, true, true, false, true, false,
|
false, true, false, true, false, true, false, true,
|
||||||
false, true, true, true, true, true, false, true, true, false, false, true,
|
false, true, true, true, false, true, false, false,
|
||||||
false, true, true, false, false, true, false, true, true, false, false, false,
|
false, true, false, false, false, true, false, false,
|
||||||
false, false, false, false, false, false, false, false, false, false, false, false,
|
false, false, false, false, false, false, false, false,
|
||||||
false, false, false, false, false, false, false, false, false, false, false, false,
|
false, false, false, false, false, false, false, false,
|
||||||
false, false, false, false, false, false, false, false, false, false, false, false,
|
false, false, false, false, false, false, false, false,
|
||||||
false, false, false, false, false, false, false, false, false, false, false, false,
|
false, false, false, false, false, false, false, false,
|
||||||
false, false, false, false, false, false, false, true, false, false, true, false,
|
false, false, false, false, false, true, false, true,
|
||||||
false, false, false, false, false, false, false, false, false, false, false, false,
|
false, false, false, false, false, false, false, false,
|
||||||
false, true, false, false, true, false, false, false, false, false, false, false,
|
false, true, false, true, false, false, false, false,
|
||||||
false, false, false, false, false, false,
|
false, false, false, false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// for actor.cpp
|
// for actor.cpp
|
||||||
|
@ -294,78 +293,11 @@ void nnExtInitModernStuff(bool bSaveLoad) {
|
||||||
break;
|
break;
|
||||||
case kModernCondition:
|
case kModernCondition:
|
||||||
case kModernConditionFalse:
|
case kModernConditionFalse:
|
||||||
if (!bSaveLoad) {
|
if (bSaveLoad) break;
|
||||||
|
else if (!pXSprite->rxID) condError(pXSprite,"\nThe condition must have RX ID!\nSPRITE #%d", pSprite->index);
|
||||||
pSprite->yvel = pSprite->type; // store it here, because inittype gets cleared later.
|
else if (!pXSprite->txID && !pSprite->hitag) {
|
||||||
pSprite->type = kModernCondition;
|
consoleSysMsg("The condition must have TX ID or hitag to be set: RX ID %d, SPRITE #%d", pXSprite->rxID, pSprite->index);
|
||||||
|
|
||||||
if (!pXSprite->rxID) {
|
|
||||||
ThrowError("\nThe condition must have RX ID!\nSPRITE #%d", pSprite->index);
|
|
||||||
} else if (!pXSprite->txID && !pSprite->hitag) {
|
|
||||||
consoleSysMsg("Inactive condition: RX ID %d, SPRITE #%d", pXSprite->rxID, pSprite->index);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect objects for tracking conditions
|
|
||||||
if (pXSprite->busyTime <= 0) break;
|
|
||||||
else if (gTrackingCondsCount >= kMaxTrackingConditions)
|
|
||||||
ThrowError("\nMax (%d) tracking conditions reached!", kMaxTrackingConditions);
|
|
||||||
|
|
||||||
int tracedObjects = 0; TRCONDITION* pCond = &gCondition[gTrackingCondsCount];
|
|
||||||
for (int i = 0; i < kMaxXSprites; i++) {
|
|
||||||
if (!spriRangeIsFine(xsprite[i].reference) || xsprite[i].txID != pXSprite->rxID || xsprite[i].reference == pSprite->index)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
XSPRITE* pXSpr = &xsprite[i]; spritetype* pSpr = &sprite[pXSpr->reference];
|
|
||||||
int index = pXSpr->reference; int cmd = pXSpr->command;
|
|
||||||
if (pSpr->statnum == kStatModernPlayerLinker && pXSpr->isTriggered && bSaveLoad) {
|
|
||||||
|
|
||||||
// assign player sprite after savegame loading
|
|
||||||
index = pXSpr->sysData1;
|
|
||||||
cmd = xsprite[sprite[index].extra].command;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pSpr->type == kModernCondition)
|
|
||||||
ThrowError("\nTracking condition always must be first in condition sequence!\nRX ID: %d, SPRITE #%d", pXSpr->rxID, pXSpr->reference);
|
|
||||||
|
|
||||||
if (tracedObjects >= kMaxTracedObjects)
|
|
||||||
ThrowError("\nMax (%d) objects to track reached for condition #%d, rx id: %d!", pSprite->index, pXSprite->rxID);
|
|
||||||
|
|
||||||
pCond->obj[tracedObjects].type = OBJ_SPRITE;
|
|
||||||
pCond->obj[tracedObjects].index = index;
|
|
||||||
pCond->obj[tracedObjects++].cmd = cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < kMaxXSectors; i++) {
|
|
||||||
if (!sectRangeIsFine(xsector[i].reference) || xsector[i].txID != pXSprite->rxID) continue;
|
|
||||||
else if (tracedObjects < kMaxTracedObjects) {
|
|
||||||
pCond->obj[tracedObjects].type = OBJ_SECTOR;
|
|
||||||
pCond->obj[tracedObjects].index = xsector[i].reference;
|
|
||||||
pCond->obj[tracedObjects++].cmd = xsector[i].command;
|
|
||||||
} else {
|
|
||||||
ThrowError("\nMax (%d) objects to track reached for condition #%d, rx id: %d!", pSprite->index, pXSprite->rxID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < kMaxXWalls; i++) {
|
|
||||||
if (!sectRangeIsFine(xwall[i].reference) || xwall[i].txID != pXSprite->rxID) continue;
|
|
||||||
else if (tracedObjects < kMaxTracedObjects) {
|
|
||||||
pCond->obj[tracedObjects].type = OBJ_WALL;
|
|
||||||
pCond->obj[tracedObjects].index = xwall[i].reference;
|
|
||||||
pCond->obj[tracedObjects++].cmd = xwall[i].command;
|
|
||||||
} else {
|
|
||||||
ThrowError("\nMax (%d) objects to track reached for condition #%d, rx id: %d!", pSprite->index, pXSprite->rxID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pCond->length = tracedObjects;
|
|
||||||
if (tracedObjects == 0)
|
|
||||||
consoleSysMsg("No objects to track found for condition #%d, rx id: %d!", pSprite->index, pXSprite->rxID);
|
|
||||||
|
|
||||||
pXSprite->sysData1 = gTrackingCondsCount++;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,6 +327,10 @@ void nnExtInitModernStuff(bool bSaveLoad) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// auto set going On and going Off if both are empty
|
||||||
|
if (pXSprite->txID && !pXSprite->triggerOn && !pXSprite->triggerOff)
|
||||||
|
pXSprite->triggerOn = pXSprite->triggerOff = true;
|
||||||
|
|
||||||
// copy custom start health to avoid overwrite by kThingBloodChunks
|
// copy custom start health to avoid overwrite by kThingBloodChunks
|
||||||
if (IsDudeSprite(pSprite))
|
if (IsDudeSprite(pSprite))
|
||||||
pXSprite->sysData2 = pXSprite->data4;
|
pXSprite->sysData2 = pXSprite->data4;
|
||||||
|
@ -404,20 +340,17 @@ void nnExtInitModernStuff(bool bSaveLoad) {
|
||||||
bool sysStat = true;
|
bool sysStat = true;
|
||||||
switch (pSprite->statnum) {
|
switch (pSprite->statnum) {
|
||||||
case kStatModernDudeTargetChanger:
|
case kStatModernDudeTargetChanger:
|
||||||
sysStat = (pSprite->type == kModernDudeTargetChanger);
|
sysStat = (pSprite->type != kModernDudeTargetChanger);
|
||||||
break;
|
break;
|
||||||
case kStatModernCondition:
|
case kStatModernCondition:
|
||||||
sysStat = (pSprite->type == kModernCondition || pSprite->type == kModernConditionFalse);
|
sysStat = (pSprite->type != kModernCondition && pSprite->type != kModernConditionFalse);
|
||||||
break;
|
break;
|
||||||
case kStatModernEventRedirector:
|
case kStatModernEventRedirector:
|
||||||
sysStat = (pSprite->type == kModernRandomTX || pSprite->type == kModernSequentialTX);
|
sysStat = (pSprite->type != kModernRandomTX && pSprite->type != kModernSequentialTX);
|
||||||
break;
|
|
||||||
case kStatModernSeqSpawner:
|
|
||||||
sysStat = (pSprite->type == kModernSeqSpawner);
|
|
||||||
break;
|
break;
|
||||||
case kStatModernPlayerLinker:
|
case kStatModernPlayerLinker:
|
||||||
case kStatModernQavScene:
|
case kStatModernQavScene:
|
||||||
sysStat = (pSprite->type == kModernPlayerControl);
|
sysStat = (pSprite->type != kModernPlayerControl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,9 +388,6 @@ void nnExtInitModernStuff(bool bSaveLoad) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kModernSeqSpawner:
|
|
||||||
changespritestat(pSprite->index, kStatModernSeqSpawner);
|
|
||||||
break;
|
|
||||||
case kModernThingTNTProx:
|
case kModernThingTNTProx:
|
||||||
pXSprite->Proximity = true;
|
pXSprite->Proximity = true;
|
||||||
break;
|
break;
|
||||||
|
@ -472,6 +402,10 @@ void nnExtInitModernStuff(bool bSaveLoad) {
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kDudePodMother:
|
||||||
|
case kDudeTentacleMother:
|
||||||
|
pXSprite->state = 1;
|
||||||
|
break;
|
||||||
case kModernPlayerControl:
|
case kModernPlayerControl:
|
||||||
switch (pXSprite->command) {
|
switch (pXSprite->command) {
|
||||||
case kCmdLink:
|
case kCmdLink:
|
||||||
|
@ -504,18 +438,35 @@ void nnExtInitModernStuff(bool bSaveLoad) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kModernCondition:
|
case kModernCondition:
|
||||||
if (pXSprite->waitTime > 0 && pXSprite->busyTime > 0) {
|
case kModernConditionFalse:
|
||||||
|
if (pXSprite->busyTime > 0) {
|
||||||
|
|
||||||
|
if (pXSprite->waitTime > 0) {
|
||||||
pXSprite->busyTime += ClipHigh(((pXSprite->waitTime * 120) / 10), 4095); pXSprite->waitTime = 0;
|
pXSprite->busyTime += ClipHigh(((pXSprite->waitTime * 120) / 10), 4095); pXSprite->waitTime = 0;
|
||||||
consoleSysMsg("Summing busyTime and waitTime for tracking condition #%d, RX ID %d. Result = %d ticks", pSprite->index, pXSprite->rxID, pXSprite->busyTime);
|
consoleSysMsg("Summing busyTime and waitTime for tracking condition #%d, RX ID %d. Result = %d ticks", pSprite->index, pXSprite->rxID, pXSprite->busyTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pXSprite->busy = pXSprite->busyTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pXSprite->waitTime && pXSprite->command >= kCmdNumberic)
|
||||||
|
condError(pXSprite, "Delay is not available when using numberic commands (%d - %d)", kCmdNumberic, 255);
|
||||||
|
|
||||||
pXSprite->Decoupled = false; // must go through operateSprite always
|
pXSprite->Decoupled = false; // must go through operateSprite always
|
||||||
pXSprite->Sight = pXSprite->Impact = pXSprite->Touch = pXSprite->triggerOff = false;
|
pXSprite->Sight = pXSprite->Impact = pXSprite->Touch = pXSprite->triggerOff = false;
|
||||||
pXSprite->Proximity = pXSprite->Push = pXSprite->Vector = pXSprite->triggerOn = false;
|
pXSprite->Proximity = pXSprite->Push = pXSprite->Vector = pXSprite->triggerOn = false;
|
||||||
pXSprite->state = pXSprite->restState = 0;
|
pXSprite->state = pXSprite->restState = 0;
|
||||||
|
|
||||||
pXSprite->targetX = pXSprite->targetY = pXSprite->targetZ = pXSprite->target = -1;
|
pXSprite->targetX = pXSprite->targetY = pXSprite->targetZ = pXSprite->target = pXSprite->sysData2 = -1;
|
||||||
changespritestat(pSprite->index, kStatModernCondition);
|
changespritestat(pSprite->index, kStatModernCondition);
|
||||||
|
int oldStat = pSprite->cstat; pSprite->cstat = 0x30;
|
||||||
|
|
||||||
|
if (oldStat & CSTAT_SPRITE_BLOCK)
|
||||||
|
pSprite->cstat |= CSTAT_SPRITE_BLOCK;
|
||||||
|
|
||||||
|
if (oldStat & 0x2000) pSprite->cstat |= 0x2000;
|
||||||
|
else if (oldStat & 0x4000) pSprite->cstat |= 0x4000;
|
||||||
|
|
||||||
pSprite->cstat |= CSTAT_SPRITE_INVISIBLE;
|
pSprite->cstat |= CSTAT_SPRITE_INVISIBLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -705,14 +656,14 @@ int nnExtRandom(int a, int b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetDataVal(spritetype* pSprite, int data) {
|
int GetDataVal(spritetype* pSprite, int data) {
|
||||||
if (pSprite->extra >= 0) {
|
dassert(xspriRangeIsFine(pSprite->extra));
|
||||||
|
|
||||||
switch (data) {
|
switch (data) {
|
||||||
case 0: return xsprite[pSprite->extra].data1;
|
case 0: return xsprite[pSprite->extra].data1;
|
||||||
case 1: return xsprite[pSprite->extra].data2;
|
case 1: return xsprite[pSprite->extra].data2;
|
||||||
case 2: return xsprite[pSprite->extra].data3;
|
case 2: return xsprite[pSprite->extra].data3;
|
||||||
case 3: return xsprite[pSprite->extra].data4;
|
case 3: return xsprite[pSprite->extra].data4;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -807,6 +758,27 @@ spritetype* randomSpawnDude(spritetype* pSource) {
|
||||||
|
|
||||||
void nnExtProcessSuperSprites() {
|
void nnExtProcessSuperSprites() {
|
||||||
|
|
||||||
|
// process tracking conditions
|
||||||
|
if (gTrackingCondsCount > 0) {
|
||||||
|
for (int i = 0; i < gTrackingCondsCount; i++) {
|
||||||
|
|
||||||
|
TRCONDITION* pCond = &gCondition[i]; XSPRITE* pXCond = &xsprite[pCond->xindex];
|
||||||
|
if (pCond->length > 0 && !pXCond->locked && !pXCond->isTriggered && ++pXCond->busy >= pXCond->busyTime) {
|
||||||
|
|
||||||
|
pXCond->busy = 0;
|
||||||
|
for (int k = 0; k < pCond->length; k++) {
|
||||||
|
|
||||||
|
EVENT evn;
|
||||||
|
evn.index = pCond->obj[k].index; evn.cmd = pCond->obj[k].cmd;
|
||||||
|
evn.type = pCond->obj[k].type; evn.funcID = kCallbackMax;
|
||||||
|
useCondition(&sprite[pXCond->reference], pXCond, evn);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// process additional proximity sprites
|
// process additional proximity sprites
|
||||||
if (gProxySpritesCount > 0) {
|
if (gProxySpritesCount > 0) {
|
||||||
for (int i = 0; i < gProxySpritesCount; i++) {
|
for (int i = 0; i < gProxySpritesCount; i++) {
|
||||||
|
@ -1326,25 +1298,13 @@ void windGenStopWindOnSectors(XSPRITE* pXSource) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*XSPRITE* trPlayerCtrlFindNextScene(XSPRITE* pXScene) {
|
|
||||||
|
|
||||||
int curIndex = pXScene->reference; bool oldFound = false;
|
void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force) {
|
||||||
for (int i = bucketHead[pXScene->txID]; i < bucketHead[pXScene->txID + 1]; i++) {
|
|
||||||
if (sprite[rxBucket[i].index].type != kModernPlayerControl) continue;
|
|
||||||
else if (rxBucket[i].index == curIndex) {
|
|
||||||
oldFound = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
XSPRITE* pXSpr = &xsprite[sprite[rxBucket[i].index].extra];
|
int nSource = pXSource->reference; TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer];
|
||||||
if (oldFound && pXSpr->command == 67 && pXSpr->data1 == pXScene->data1 && !pXSpr->locked)
|
|
||||||
return pXSpr;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer) {
|
if (pCtrl->qavScene.index >= 0 && !force) return;
|
||||||
|
|
||||||
int nSource = sprite[pXSource->reference].index; TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer];
|
|
||||||
QAV* pQav = playerQavSceneLoad(pXSource->data2);
|
QAV* pQav = playerQavSceneLoad(pXSource->data2);
|
||||||
if (pQav != NULL) {
|
if (pQav != NULL) {
|
||||||
|
|
||||||
|
@ -1433,13 +1393,12 @@ void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition) {
|
||||||
|
|
||||||
// let's check if there is tracking condition expecting objects with this TX id
|
// let's check if there is tracking condition expecting objects with this TX id
|
||||||
if (checkCondition && pXSource->txID >= kChannelUser) {
|
if (checkCondition && pXSource->txID >= kChannelUser) {
|
||||||
for (int i = bucketHead[pXSource->txID]; i < bucketHead[pXSource->txID + 1]; i++) {
|
for (int i = 0; i < gTrackingCondsCount; i++) {
|
||||||
if (sprite[rxBucket[i].index].type != kModernCondition) continue;
|
|
||||||
|
|
||||||
XSPRITE* pXCond = &xsprite[sprite[rxBucket[i].index].extra];
|
TRCONDITION* pCond = &gCondition[i];
|
||||||
if (pXCond->busyTime <= 0) continue;
|
if (xsprite[pCond->xindex].rxID != pXSource->txID)
|
||||||
|
continue;
|
||||||
|
|
||||||
TRCONDITION* pCond = &gCondition[pXCond->sysData1];
|
|
||||||
// search for player control sprite and replace it with actual player sprite
|
// search for player control sprite and replace it with actual player sprite
|
||||||
for (int k = 0; k < pCond->length; k++) {
|
for (int k = 0; k < pCond->length; k++) {
|
||||||
if (pCond->obj[k].type != OBJ_SPRITE || pCond->obj[k].index != pXSource->reference) continue;
|
if (pCond->obj[k].type != OBJ_SPRITE || pCond->obj[k].index != pXSource->reference) continue;
|
||||||
|
@ -1447,6 +1406,7 @@ void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition) {
|
||||||
pCond->obj[k].cmd = pPlayer->pXSprite->command;
|
pCond->obj[k].cmd = pPlayer->pXSprite->command;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1473,9 +1433,9 @@ void trPlayerCtrlSetMoveSpeed(XSPRITE* pXSource, PLAYER* pPlayer) {
|
||||||
for (int i = 0; i < kModeMax; i++) {
|
for (int i = 0; i < kModeMax; i++) {
|
||||||
for (int a = 0; a < kPostureMax; a++) {
|
for (int a = 0; a < kPostureMax; a++) {
|
||||||
POSTURE* curPosture = &pPlayer->pPosture[i][a]; POSTURE* defPosture = &gPostureDefaults[i][a];
|
POSTURE* curPosture = &pPlayer->pPosture[i][a]; POSTURE* defPosture = &gPostureDefaults[i][a];
|
||||||
curPosture->frontAccel = (defPosture->frontAccel * speed) / kPercentFull;
|
curPosture->frontAccel = (defPosture->frontAccel * speed) / kPercFull;
|
||||||
curPosture->sideAccel = (defPosture->sideAccel * speed) / kPercentFull;
|
curPosture->sideAccel = (defPosture->sideAccel * speed) / kPercFull;
|
||||||
curPosture->backAccel = (defPosture->backAccel * speed) / kPercentFull;
|
curPosture->backAccel = (defPosture->backAccel * speed) / kPercFull;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1485,8 +1445,8 @@ void trPlayerCtrlSetJumpHeight(XSPRITE* pXSource, PLAYER* pPlayer) {
|
||||||
int jump = ClipRange(pXSource->data3, 0, 500);
|
int jump = ClipRange(pXSource->data3, 0, 500);
|
||||||
for (int i = 0; i < kModeMax; i++) {
|
for (int i = 0; i < kModeMax; i++) {
|
||||||
POSTURE* curPosture = &pPlayer->pPosture[i][kPostureStand]; POSTURE* defPosture = &gPostureDefaults[i][kPostureStand];
|
POSTURE* curPosture = &pPlayer->pPosture[i][kPostureStand]; POSTURE* defPosture = &gPostureDefaults[i][kPostureStand];
|
||||||
curPosture->normalJumpZ = (defPosture->normalJumpZ * jump) / kPercentFull;
|
curPosture->normalJumpZ = (defPosture->normalJumpZ * jump) / kPercFull;
|
||||||
curPosture->pwupJumpZ = (defPosture->pwupJumpZ * jump) / kPercentFull;
|
curPosture->pwupJumpZ = (defPosture->pwupJumpZ * jump) / kPercFull;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1528,13 +1488,13 @@ void trPlayerCtrlSetScreenEffect(XSPRITE* pXSource, PLAYER* pPlayer) {
|
||||||
|
|
||||||
void trPlayerCtrlSetLookAngle(XSPRITE* pXSource, PLAYER* pPlayer) {
|
void trPlayerCtrlSetLookAngle(XSPRITE* pXSource, PLAYER* pPlayer) {
|
||||||
|
|
||||||
int upAngle = 289; int downAngle = -347;
|
CONSTEXPR int upAngle = 289; CONSTEXPR int downAngle = -347;
|
||||||
double lookStepUp = 4.0 * upAngle / 60.0;
|
CONSTEXPR double lookStepUp = 4.0 * upAngle / 60.0;
|
||||||
double lookStepDown = -4.0 * downAngle / 60.0;
|
CONSTEXPR double lookStepDown = -4.0 * downAngle / 60.0;
|
||||||
|
|
||||||
int look = pXSource->data2 << 5;
|
int look = pXSource->data2 << 5;
|
||||||
if (look > 0) pPlayer->q16look = fix16_min(mulscale8(fix16_from_dbl(lookStepUp), look), fix16_from_int(upAngle));
|
if (look > 0) pPlayer->q16look = fix16_min(mulscale8(F16(lookStepUp), look), F16(upAngle));
|
||||||
else if (look < 0) pPlayer->q16look = -fix16_max(mulscale8(fix16_from_dbl(lookStepDown), abs(look)), fix16_from_int(downAngle));
|
else if (look < 0) pPlayer->q16look = -fix16_max(mulscale8(F16(lookStepDown), abs(look)), F16(downAngle));
|
||||||
else pPlayer->q16look = 0;
|
else pPlayer->q16look = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1575,6 +1535,11 @@ void trPlayerCtrlEraseStuff(XSPRITE* pXSource, PLAYER* pPlayer) {
|
||||||
case 4: // erase all keys
|
case 4: // erase all keys
|
||||||
for (int i = 0; i < 8; i++) pPlayer->hasKey[i] = false;
|
for (int i = 0; i < 8; i++) pPlayer->hasKey[i] = false;
|
||||||
if (pXSource->data2) break;
|
if (pXSource->data2) break;
|
||||||
|
fallthrough__;
|
||||||
|
case 5: // erase powerups
|
||||||
|
for (int i = 0; i < kMaxPowerUps; i++) pPlayer->pwUpTime[i] = 0;
|
||||||
|
if (pXSource->data2) break;
|
||||||
|
fallthrough__;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1604,7 +1569,7 @@ void trPlayerCtrlGiveStuff(XSPRITE* pXSource, PLAYER* pPlayer, TRPLAYERCTRL* pCt
|
||||||
for (int i = 0; i < 11; i++) {
|
for (int i = 0; i < 11; i++) {
|
||||||
if (gWeaponItemData[i].type != weapon) continue;
|
if (gWeaponItemData[i].type != weapon) continue;
|
||||||
|
|
||||||
const WEAPONITEMDATA* pWeaponData = &gWeaponItemData[i]; int nAmmoType = pWeaponData->ammoType;
|
WEAPONITEMDATA* pWeaponData = &gWeaponItemData[i]; int nAmmoType = pWeaponData->ammoType;
|
||||||
switch (pXSource->data2) {
|
switch (pXSource->data2) {
|
||||||
case 1:
|
case 1:
|
||||||
pPlayer->hasWeapon[weapon] = true;
|
pPlayer->hasWeapon[weapon] = true;
|
||||||
|
@ -2313,6 +2278,7 @@ void useSpriteDamager(XSPRITE* pXSource, spritetype* pSprite) {
|
||||||
if (!IsDudeSprite(pSprite) || !xspriRangeIsFine(pSprite->extra) || xsprite[pSprite->extra].health <= 0 || pXSource->data3 < 0)
|
if (!IsDudeSprite(pSprite) || !xspriRangeIsFine(pSprite->extra) || xsprite[pSprite->extra].health <= 0 || pXSource->data3 < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
XSPRITE* pXSprite = &xsprite[pSprite->extra]; PLAYER* pPlayer = getPlayerById(pSprite->type);
|
XSPRITE* pXSprite = &xsprite[pSprite->extra]; PLAYER* pPlayer = getPlayerById(pSprite->type);
|
||||||
int dmgType = (pXSource->data2 >= kDmgFall) ? ClipHigh(pXSource->data2, kDmgElectric) : -1;
|
int dmgType = (pXSource->data2 >= kDmgFall) ? ClipHigh(pXSource->data2, kDmgElectric) : -1;
|
||||||
int dmg = pXSprite->health << 4; int armor[3];
|
int dmg = pXSprite->health << 4; int armor[3];
|
||||||
|
@ -2323,8 +2289,8 @@ void useSpriteDamager(XSPRITE* pXSource, spritetype* pSprite) {
|
||||||
if (godMode || pXSprite->locked) return;
|
if (godMode || pXSprite->locked) return;
|
||||||
else if (pXSource->data3) {
|
else if (pXSource->data3) {
|
||||||
if (pSource->flags & kModernTypeFlag1) dmg = ClipHigh(pXSource->data3 << 1, 65535);
|
if (pSource->flags & kModernTypeFlag1) dmg = ClipHigh(pXSource->data3 << 1, 65535);
|
||||||
else if (pXSprite->sysData2 > 0) dmg = (ClipHigh(pXSprite->sysData2 << 4, 65535) * pXSource->data3) / kPercentFull;
|
else if (pXSprite->sysData2 > 0) dmg = (ClipHigh(pXSprite->sysData2 << 4, 65535) * pXSource->data3) / kPercFull;
|
||||||
else dmg = ((getDudeInfo(pSprite->type)->startHealth << 4) * pXSource->data3) / kPercentFull;
|
else dmg = ((getDudeInfo(pSprite->type)->startHealth << 4) * pXSource->data3) / kPercFull;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dmgType >= kDmgFall) {
|
if (dmgType >= kDmgFall) {
|
||||||
|
@ -2498,7 +2464,11 @@ bool condRestore(XSPRITE* pXSprite) {
|
||||||
bool condCmp(int val, int arg1, int arg2, int comOp) {
|
bool condCmp(int val, int arg1, int arg2, int comOp) {
|
||||||
if (comOp & 0x2000) return (comOp & CSTAT_SPRITE_BLOCK) ? (val > arg1) : (val >= arg1); // blue sprite
|
if (comOp & 0x2000) return (comOp & CSTAT_SPRITE_BLOCK) ? (val > arg1) : (val >= arg1); // blue sprite
|
||||||
else if (comOp & 0x4000) return (comOp & CSTAT_SPRITE_BLOCK) ? (val < arg1) : (val <= arg1); // green sprite
|
else if (comOp & 0x4000) return (comOp & CSTAT_SPRITE_BLOCK) ? (val < arg1) : (val <= arg1); // green sprite
|
||||||
else return (comOp & CSTAT_SPRITE_BLOCK) ? (val >= arg1 && val <= arg2) : (val == arg1);
|
else if (comOp & CSTAT_SPRITE_BLOCK) {
|
||||||
|
if (arg1 > arg2) ThrowError("Value of argument #1 (%d) must be less than value of argument #2 (%d)", arg1, arg2);
|
||||||
|
return (val >= arg1 && val <= arg2);
|
||||||
|
}
|
||||||
|
else return (val == arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no extra comparison (val always = 0)?
|
// no extra comparison (val always = 0)?
|
||||||
|
@ -2506,7 +2476,11 @@ bool condCmpne(int arg1, int arg2, int comOp) {
|
||||||
|
|
||||||
if (comOp & 0x2000) return (comOp & CSTAT_SPRITE_BLOCK) ? (0 > arg1) : (0 >= arg1); // blue sprite
|
if (comOp & 0x2000) return (comOp & CSTAT_SPRITE_BLOCK) ? (0 > arg1) : (0 >= arg1); // blue sprite
|
||||||
else if (comOp & 0x4000) return (comOp & CSTAT_SPRITE_BLOCK) ? (0 < arg1) : (0 <= arg1); // green sprite
|
else if (comOp & 0x4000) return (comOp & CSTAT_SPRITE_BLOCK) ? (0 < arg1) : (0 <= arg1); // green sprite
|
||||||
else return (comOp & CSTAT_SPRITE_BLOCK) ? (0 >= arg1 && 0 <= arg2) : (0 == arg1);
|
else if (comOp & CSTAT_SPRITE_BLOCK) {
|
||||||
|
if (arg1 > arg2) ThrowError("Value of argument #1 (%d) must be less than value of argument #2 (%d)", arg1, arg2);
|
||||||
|
return (0 >= arg1 && 0 <= arg2);
|
||||||
|
}
|
||||||
|
else return (0 == arg1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2516,20 +2490,25 @@ bool condCmpb(int val, int arg1, int arg2, int comOp) {
|
||||||
arg1 = ClipRange(arg1, 0, 1); arg2 = ClipRange(arg2, 0, 1);
|
arg1 = ClipRange(arg1, 0, 1); arg2 = ClipRange(arg2, 0, 1);
|
||||||
if (comOp & 0x2000) return (comOp & CSTAT_SPRITE_BLOCK) ? (val > 0) : (val >= 0); // blue sprite
|
if (comOp & 0x2000) return (comOp & CSTAT_SPRITE_BLOCK) ? (val > 0) : (val >= 0); // blue sprite
|
||||||
else if (comOp & 0x4000) return (comOp & CSTAT_SPRITE_BLOCK) ? (val < arg1) : (val <= arg1); // green sprite
|
else if (comOp & 0x4000) return (comOp & CSTAT_SPRITE_BLOCK) ? (val < arg1) : (val <= arg1); // green sprite
|
||||||
else return (comOp & CSTAT_SPRITE_BLOCK) ? (val >= arg1 && val <= arg2) : (val == arg1);
|
else if (comOp & CSTAT_SPRITE_BLOCK) {
|
||||||
|
if (arg1 > arg2) ThrowError("Value of argument #1 (%d) must be less than value of argument #2 (%d)", arg1, arg2);
|
||||||
|
return (val >= arg1 && val <= arg2);
|
||||||
|
}
|
||||||
|
else return (val == arg1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void condError(XSPRITE* pXCond, const char* pzFormat, ...) {
|
void condError(XSPRITE* pXCond, const char* pzFormat, ...) {
|
||||||
|
|
||||||
char buffer[256]; char buffer2[512];
|
char buffer[256]; char buffer2[512];
|
||||||
Bsprintf(buffer, "\nCONDITION RX: %d, TX: %d, SPRITE: #%d RETURNS:\n", pXCond->rxID, pXCond->txID, pXCond->reference);
|
Bsprintf(buffer, "\nCONDITION RX: %d, TX: %d, SPRITE: #%d RETURNS:\n----------\n\n", pXCond->rxID, pXCond->txID, pXCond->reference);
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, pzFormat);
|
va_start(args, pzFormat);
|
||||||
vsprintf(buffer2, pzFormat, args);
|
vsprintf(buffer2, pzFormat, args);
|
||||||
ThrowError(Bstrcat(buffer, buffer2));
|
ThrowError(Bstrcat(buffer, buffer2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool condCheckMixed(XSPRITE* pXCond, EVENT event, int cmpOp, bool PUSH) {
|
bool condCheckMixed(XSPRITE* pXCond, EVENT event, int cmpOp, bool PUSH) {
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(PUSH);
|
UNREFERENCED_PARAMETER(PUSH);
|
||||||
|
@ -2657,9 +2636,8 @@ bool condCheckMixed(XSPRITE* pXCond, EVENT event, int cmpOp, bool PUSH) {
|
||||||
case 54: return condCmpb(pXObj->triggerOff, arg1, arg2, cmpOp);
|
case 54: return condCmpb(pXObj->triggerOff, arg1, arg2, cmpOp);
|
||||||
case 55: return condCmpb(pXObj->triggerOnce, arg1, arg2, cmpOp);
|
case 55: return condCmpb(pXObj->triggerOnce, arg1, arg2, cmpOp);
|
||||||
case 56: return condCmpb(pXObj->isTriggered, arg1, arg2, cmpOp);
|
case 56: return condCmpb(pXObj->isTriggered, arg1, arg2, cmpOp);
|
||||||
case 57:
|
case 57: return condCmpb(pXObj->state, arg1, arg2, cmpOp);
|
||||||
return condCmpb(pXObj->state, arg1, arg2, cmpOp);
|
case 58: return condCmp((kPercFull * pXObj->busy) / 65536, arg1, arg2, cmpOp);
|
||||||
case 58: return condCmp((kPercentFull * pXObj->busy) / 65536, arg1, arg2, cmpOp);
|
|
||||||
case 59: return condCmpb(pXObj->dudeLockout, arg1, arg2, cmpOp);
|
case 59: return condCmpb(pXObj->dudeLockout, arg1, arg2, cmpOp);
|
||||||
case 70:
|
case 70:
|
||||||
switch (arg3) {
|
switch (arg3) {
|
||||||
|
@ -2693,7 +2671,7 @@ bool condCheckMixed(XSPRITE* pXCond, EVENT event, int cmpOp, bool PUSH) {
|
||||||
case 55: return condCmpb(pXObj->triggerOnce, arg1, arg2, cmpOp);
|
case 55: return condCmpb(pXObj->triggerOnce, arg1, arg2, cmpOp);
|
||||||
case 56: return condCmpb(pXObj->isTriggered, arg1, arg2, cmpOp);
|
case 56: return condCmpb(pXObj->isTriggered, arg1, arg2, cmpOp);
|
||||||
case 57: return condCmpb(pXObj->state, arg1, arg2, cmpOp);
|
case 57: return condCmpb(pXObj->state, arg1, arg2, cmpOp);
|
||||||
case 58: return condCmp((kPercentFull * pXObj->busy) / 65536, arg1, arg2, cmpOp);
|
case 58: return condCmp((kPercFull * pXObj->busy) / 65536, arg1, arg2, cmpOp);
|
||||||
case 59: return condCmpb(pXObj->DudeLockout, arg1, arg2, cmpOp);
|
case 59: return condCmpb(pXObj->DudeLockout, arg1, arg2, cmpOp);
|
||||||
case 70: return condCmp(seqGetID(3, sprite[objIndex].extra), arg1, arg2, cmpOp);
|
case 70: return condCmp(seqGetID(3, sprite[objIndex].extra), arg1, arg2, cmpOp);
|
||||||
case 71: return condCmp(seqGetStatus(3, sprite[objIndex].extra), arg1, arg2, cmpOp);
|
case 71: return condCmp(seqGetStatus(3, sprite[objIndex].extra), arg1, arg2, cmpOp);
|
||||||
|
@ -2713,7 +2691,7 @@ bool condCheckMixed(XSPRITE* pXCond, EVENT event, int cmpOp, bool PUSH) {
|
||||||
case 55: return condCmpb(pXObj->triggerOnce, arg1, arg2, cmpOp);
|
case 55: return condCmpb(pXObj->triggerOnce, arg1, arg2, cmpOp);
|
||||||
case 56: return condCmpb(pXObj->isTriggered, arg1, arg2, cmpOp);
|
case 56: return condCmpb(pXObj->isTriggered, arg1, arg2, cmpOp);
|
||||||
case 57: return condCmpb(pXObj->state, arg1, arg2, cmpOp);
|
case 57: return condCmpb(pXObj->state, arg1, arg2, cmpOp);
|
||||||
case 58: return condCmp((kPercentFull * pXObj->busy) / 65536, arg1, arg2, cmpOp);
|
case 58: return condCmp((kPercFull * pXObj->busy) / 65536, arg1, arg2, cmpOp);
|
||||||
case 59: return condCmpb(pXObj->dudeLockout, arg1, arg2, cmpOp);
|
case 59: return condCmpb(pXObj->dudeLockout, arg1, arg2, cmpOp);
|
||||||
case 70:
|
case 70:
|
||||||
switch (arg3) {
|
switch (arg3) {
|
||||||
|
@ -2788,7 +2766,7 @@ bool condCheckSector(XSPRITE* pXCond, int cmpOp, bool PUSH) {
|
||||||
h = ClipLow(abs(pXSect->onCeilZ - pXSect->offCeilZ), 1);
|
h = ClipLow(abs(pXSect->onCeilZ - pXSect->offCeilZ), 1);
|
||||||
curH = abs(pSect->ceilingz - pXSect->offCeilZ);
|
curH = abs(pSect->ceilingz - pXSect->offCeilZ);
|
||||||
}
|
}
|
||||||
return condCmp((kPercentFull * curH) / h, arg1, arg2, cmpOp);
|
return condCmp((kPercFull * curH) / h, arg1, arg2, cmpOp);
|
||||||
default:
|
default:
|
||||||
condError(pXCond, "Sector conditions:\nUsupported sector type %d", pSect->type);
|
condError(pXCond, "Sector conditions:\nUsupported sector type %d", pSect->type);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2901,7 +2879,7 @@ bool condCheckPlayer(XSPRITE* pXCond, int cmpOp, bool PUSH) {
|
||||||
case 8: // check for powerup amount in %
|
case 8: // check for powerup amount in %
|
||||||
if (arg3 > 0 && arg3 < 30) var = (12 + arg3) - 1; // allowable powerups
|
if (arg3 > 0 && arg3 < 30) var = (12 + arg3) - 1; // allowable powerups
|
||||||
else condError(pXCond, "Unexpected powerup #%d", arg3);
|
else condError(pXCond, "Unexpected powerup #%d", arg3);
|
||||||
return condCmp((kPercentFull * pPlayer->pwUpTime[var]) / gPowerUpInfo[var].bonusTime, arg1, arg2, cmpOp);
|
return condCmp((kPercFull * pPlayer->pwUpTime[var]) / gPowerUpInfo[var].bonusTime, arg1, arg2, cmpOp);
|
||||||
case 9:
|
case 9:
|
||||||
if (!spriRangeIsFine(pPlayer->fraggerId)) return false;
|
if (!spriRangeIsFine(pPlayer->fraggerId)) return false;
|
||||||
else if (PUSH) condPush(pXCond, OBJ_SPRITE, pPlayer->fraggerId);
|
else if (PUSH) condPush(pXCond, OBJ_SPRITE, pPlayer->fraggerId);
|
||||||
|
@ -2939,9 +2917,9 @@ bool condCheckDude(XSPRITE* pXCond, int cmpOp, bool PUSH) {
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(cmpOp);
|
UNREFERENCED_PARAMETER(cmpOp);
|
||||||
|
|
||||||
//int var = -1; PLAYER* pPlayer = NULL;
|
int var = -1; //PLAYER* pPlayer = NULL;
|
||||||
int cond = pXCond->data1 - kCondDudeBase; //int arg1 = pXCond->data2;
|
int cond = pXCond->data1 - kCondDudeBase; int arg1 = pXCond->data2;
|
||||||
//int arg2 = pXCond->data3; int arg3 = pXCond->data4;
|
int arg2 = pXCond->data3; //int arg3 = pXCond->data4;
|
||||||
|
|
||||||
int objType = -1; int objIndex = -1;
|
int objType = -1; int objIndex = -1;
|
||||||
condUnserialize(pXCond->targetX, &objType, &objIndex);
|
condUnserialize(pXCond->targetX, &objType, &objIndex);
|
||||||
|
@ -2967,10 +2945,63 @@ bool condCheckDude(XSPRITE* pXCond, int cmpOp, bool PUSH) {
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
default: break;
|
default: break;
|
||||||
case 0: // dude have any targets?
|
case 0: // dude have any targets?
|
||||||
if (!spriRangeIsFine(pXSpr->target)) return false;
|
if (!spriRangeIsFine(pXSpr->target) || !IsDudeSprite(&sprite[pXSpr->target])) return false;
|
||||||
else if (PUSH) condPush(pXCond, OBJ_SPRITE, pXSpr->target);
|
else if (PUSH) condPush(pXCond, OBJ_SPRITE, pXSpr->target);
|
||||||
return true;
|
return true;
|
||||||
case 1: return aiFightDudeIsAffected(pXSpr); // dude affected by ai fight?
|
case 1: return aiFightDudeIsAffected(pXSpr); // dude affected by ai fight?
|
||||||
|
case 2: // distance to the target in a range?
|
||||||
|
case 3: // is the target visible?
|
||||||
|
case 4: // is the target visible with periphery?
|
||||||
|
{
|
||||||
|
DUDEINFO* pInfo = getDudeInfo(pSpr->type);
|
||||||
|
int eyeAboveZ = pInfo->eyeHeight * pSpr->yrepeat << 2;
|
||||||
|
if (!spriRangeIsFine(pXSpr->target))
|
||||||
|
condError(pXCond, "Dude #%d have no target!", objIndex);
|
||||||
|
|
||||||
|
spritetype* pTrgt = &sprite[pXSpr->target];
|
||||||
|
int dx = pTrgt->x - pSpr->x; int dy = pTrgt->y - pSpr->y;
|
||||||
|
|
||||||
|
switch (cond) {
|
||||||
|
case 2:
|
||||||
|
var = condCmp(approxDist(dx, dy), arg1 * 512, arg2 * 512, cmpOp);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
var = cansee(pSpr->x, pSpr->y, pSpr->z, pSpr->sectnum, pTrgt->x, pTrgt->y, pTrgt->z - eyeAboveZ, pTrgt->sectnum);
|
||||||
|
if (cond == 4 && var > 0) {
|
||||||
|
var = ((1024 + getangle(dx, dy) - pSpr->ang) & 2047) - 1024;
|
||||||
|
var = (klabs(var) < ((arg1 <= 0) ? pInfo->periphery : ClipHigh(arg1, 2048)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var <= 0) return false;
|
||||||
|
else if (PUSH) condPush(pXCond, OBJ_SPRITE, pXSpr->target);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
case 20: // kDudeModernCustom conditions
|
||||||
|
case 21:
|
||||||
|
switch (pSpr->type) {
|
||||||
|
case kDudeModernCustom:
|
||||||
|
case kDudeModernCustomBurning:
|
||||||
|
switch (cond) {
|
||||||
|
case 20: // life leech is thrown?
|
||||||
|
var = genDudeExtra(pSpr)->nLifeLeech;
|
||||||
|
if (!spriRangeIsFine(var)) return false;
|
||||||
|
else if (PUSH) condPush(pXCond, OBJ_SPRITE, var);
|
||||||
|
return true;
|
||||||
|
case 21: // life leech is destroyed?
|
||||||
|
var = genDudeExtra(pSpr)->nLifeLeech;
|
||||||
|
if (!spriRangeIsFine(var) && pSpr->owner == kMaxSprites - 1) return true;
|
||||||
|
else if (PUSH) condPush(pXCond, OBJ_SPRITE, var);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fallthrough__;
|
||||||
|
default:
|
||||||
|
condError(pXCond, "Dude #%d is not a Custom Dude!", objIndex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3084,7 +3115,7 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) {
|
||||||
if (IsDudeSprite(pSpr)) var = (pXSpr->sysData2 > 0) ? ClipRange(pXSpr->sysData2 << 4, 1, 65535) : getDudeInfo(pSpr->type)->startHealth << 4;
|
if (IsDudeSprite(pSpr)) var = (pXSpr->sysData2 > 0) ? ClipRange(pXSpr->sysData2 << 4, 1, 65535) : getDudeInfo(pSpr->type)->startHealth << 4;
|
||||||
else if (pSpr->type == kThingBloodChunks) return condCmpne(arg1, arg2, cmpOp);
|
else if (pSpr->type == kThingBloodChunks) return condCmpne(arg1, arg2, cmpOp);
|
||||||
else if (pSpr->type >= kThingBase && pSpr->type < kThingMax) var = thingInfo[pSpr->type - kThingBase].startHealth << 4;
|
else if (pSpr->type >= kThingBase && pSpr->type < kThingMax) var = thingInfo[pSpr->type - kThingBase].startHealth << 4;
|
||||||
return condCmp((kPercentFull * pXSpr->health) / ClipLow(var, 1), arg1, arg2, cmpOp);
|
return condCmp((kPercFull * pXSpr->health) / ClipLow(var, 1), arg1, arg2, cmpOp);
|
||||||
case 55: // touching ceil of sector?
|
case 55: // touching ceil of sector?
|
||||||
if ((gSpriteHit[pSpr->extra].ceilhit & 0xc000) != 0x4000) return false;
|
if ((gSpriteHit[pSpr->extra].ceilhit & 0xc000) != 0x4000) return false;
|
||||||
else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].ceilhit & 0x3fff);
|
else if (PUSH) condPush(pXCond, OBJ_SECTOR, gSpriteHit[pSpr->extra].ceilhit & 0x3fff);
|
||||||
|
@ -3117,9 +3148,21 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) {
|
||||||
return true;
|
return true;
|
||||||
case 65: // compare burn time (in %)
|
case 65: // compare burn time (in %)
|
||||||
var = (IsDudeSprite(pSpr)) ? 2400 : 1200;
|
var = (IsDudeSprite(pSpr)) ? 2400 : 1200;
|
||||||
if (!condCmp((kPercentFull * pXSpr->burnTime) / var, arg1, arg2, cmpOp)) return false;
|
if (!condCmp((kPercFull * pXSpr->burnTime) / var, arg1, arg2, cmpOp)) return false;
|
||||||
else if (PUSH) condPush(pXCond, OBJ_SPRITE, pXSpr->burnSource);
|
else if (PUSH && spriRangeIsFine(pXSpr->burnSource)) condPush(pXCond, OBJ_SPRITE, pXSpr->burnSource);
|
||||||
return true;
|
return true;
|
||||||
|
case 66: // any flares stuck in this sprite?
|
||||||
|
for (int nSprite = headspritestat[kStatFlare]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
||||||
|
spritetype* pFlare = &sprite[nSprite];
|
||||||
|
if (!xspriRangeIsFine(pFlare->extra) || (pFlare->flags & kHitagFree))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
XSPRITE* pXFlare = &xsprite[pFlare->extra];
|
||||||
|
if (!spriRangeIsFine(pXFlare->target) || pXFlare->target != objIndex) continue;
|
||||||
|
else if (PUSH) condPush(pXCond, OBJ_SPRITE, nSprite);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
case 70:
|
case 70:
|
||||||
return condCmp(getSpriteMassBySize(pSpr), arg1, arg2, cmpOp); // mass of the sprite in a range?
|
return condCmp(getSpriteMassBySize(pSpr), arg1, arg2, cmpOp); // mass of the sprite in a range?
|
||||||
}
|
}
|
||||||
|
@ -3140,15 +3183,10 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH) {
|
||||||
// this updates index of object in all conditions
|
// this updates index of object in all conditions
|
||||||
void condUpdateObjectIndex(int objType, int oldIndex, int newIndex) {
|
void condUpdateObjectIndex(int objType, int oldIndex, int newIndex) {
|
||||||
|
|
||||||
int oldSerial = condSerialize(objType, oldIndex);
|
// update index in tracking conditions first
|
||||||
int newSerial = condSerialize(objType, newIndex);
|
for (int i = 0; i < gTrackingCondsCount; i++) {
|
||||||
|
|
||||||
for (int nSpr = headspritestat[kStatModernCondition]; nSpr >= 0; nSpr = nextspritestat[nSpr]) {
|
TRCONDITION* pCond = &gCondition[i];
|
||||||
|
|
||||||
XSPRITE* pXCond = &xsprite[sprite[nSpr].extra];
|
|
||||||
if (pXCond->busyTime > 0) {
|
|
||||||
|
|
||||||
TRCONDITION* pCond = &gCondition[pXCond->sysData1];
|
|
||||||
for (int k = 0; k < pCond->length; k++) {
|
for (int k = 0; k < pCond->length; k++) {
|
||||||
if (pCond->obj[k].type != objType || pCond->obj[k].index != oldIndex) continue;
|
if (pCond->obj[k].type != objType || pCond->obj[k].index != oldIndex) continue;
|
||||||
pCond->obj[k].index = newIndex;
|
pCond->obj[k].index = newIndex;
|
||||||
|
@ -3157,6 +3195,13 @@ void condUpdateObjectIndex(int objType, int oldIndex, int newIndex) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int oldSerial = condSerialize(objType, oldIndex);
|
||||||
|
int newSerial = condSerialize(objType, newIndex);
|
||||||
|
|
||||||
|
// then update serials
|
||||||
|
for (int nSpr = headspritestat[kStatModernCondition]; nSpr >= 0; nSpr = nextspritestat[nSpr]) {
|
||||||
|
|
||||||
|
XSPRITE* pXCond = &xsprite[sprite[nSpr].extra];
|
||||||
if (pXCond->targetX == oldSerial) pXCond->targetX = newSerial;
|
if (pXCond->targetX == oldSerial) pXCond->targetX = newSerial;
|
||||||
if (pXCond->targetY == oldSerial) pXCond->targetY = newSerial;
|
if (pXCond->targetY == oldSerial) pXCond->targetY = newSerial;
|
||||||
|
|
||||||
|
@ -3527,10 +3572,6 @@ void aiFightAlarmDudesInSight(spritetype* pSprite, int max) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool aiFightIsAnnoyingUnit(spritetype* pDude) {
|
|
||||||
return (IsDudeSprite(pDude) && gDudeInfoExtra[pDude->type - kDudeBase].annoying);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool aiFightUnitCanFly(spritetype* pDude) {
|
bool aiFightUnitCanFly(spritetype* pDude) {
|
||||||
return (IsDudeSprite(pDude) && gDudeInfoExtra[pDude->type - kDudeBase].flying);
|
return (IsDudeSprite(pDude) && gDudeInfoExtra[pDude->type - kDudeBase].flying);
|
||||||
}
|
}
|
||||||
|
@ -3586,13 +3627,10 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
|
||||||
|
|
||||||
switch (pSprite->type) {
|
switch (pSprite->type) {
|
||||||
case kModernCondition:
|
case kModernCondition:
|
||||||
if (!pXSprite->locked) {
|
case kModernConditionFalse:
|
||||||
if (pXSprite->busyTime > 0)
|
pXSprite->restState = 0;
|
||||||
evPost(pSprite->index, OBJ_SPRITE, 0, kCallbackCondition);
|
if (pXSprite->busyTime <= 0) break;
|
||||||
} else {
|
else if (!pXSprite->locked) pXSprite->busy = 0;
|
||||||
pXSprite->state = 0;
|
|
||||||
evKill(pSprite->index, OBJ_SPRITE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3627,7 +3665,8 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
|
||||||
switch (pSprite->type) {
|
switch (pSprite->type) {
|
||||||
default:
|
default:
|
||||||
return false; // no modern type found to work with, go normal OperateSprite();
|
return false; // no modern type found to work with, go normal OperateSprite();
|
||||||
case kModernCondition: // WIP
|
case kModernCondition:
|
||||||
|
case kModernConditionFalse:
|
||||||
if (!pXSprite->isTriggered) useCondition(pSprite, pXSprite, event);
|
if (!pXSprite->isTriggered) useCondition(pSprite, pXSprite, event);
|
||||||
return true;
|
return true;
|
||||||
// add spawn random dude feature - works only if at least 2 data fields are not empty.
|
// add spawn random dude feature - works only if at least 2 data fields are not empty.
|
||||||
|
@ -3663,11 +3702,11 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
|
||||||
if (pXSprite->command == kCmdLink) return true; // work as event redirector
|
if (pXSprite->command == kCmdLink) return true; // work as event redirector
|
||||||
switch (pSprite->type) {
|
switch (pSprite->type) {
|
||||||
case kModernRandomTX:
|
case kModernRandomTX:
|
||||||
useRandomTx(pXSprite, (COMMAND_ID)event.cmd, true);
|
useRandomTx(pXSprite, (COMMAND_ID)pXSprite->command, true);
|
||||||
break;
|
break;
|
||||||
case kModernSequentialTX:
|
case kModernSequentialTX:
|
||||||
if (!(pSprite->flags & kModernTypeFlag1)) useSequentialTx(pXSprite, (COMMAND_ID)event.cmd, true);
|
if (!(pSprite->flags & kModernTypeFlag1)) useSequentialTx(pXSprite, (COMMAND_ID)pXSprite->command, true);
|
||||||
else seqTxSendCmdAll(pXSprite, pSprite->index, (COMMAND_ID)event.cmd, false);
|
else seqTxSendCmdAll(pXSprite, pSprite->index, (COMMAND_ID)pXSprite->command, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -3856,7 +3895,7 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
|
||||||
case kModernPlayerControl: { // WIP
|
case kModernPlayerControl: { // WIP
|
||||||
PLAYER* pPlayer = NULL; int cmd = (event.cmd >= kCmdNumberic) ? event.cmd : pXSprite->command;
|
PLAYER* pPlayer = NULL; int cmd = (event.cmd >= kCmdNumberic) ? event.cmd : pXSprite->command;
|
||||||
if ((pPlayer = getPlayerById(pXSprite->data1)) == NULL
|
if ((pPlayer = getPlayerById(pXSprite->data1)) == NULL
|
||||||
|| ((cmd < 3 || cmd > 4) && !modernTypeSetSpriteState(nSprite, pXSprite, pXSprite->state ^ 1)))
|
|| ((cmd < 67 || cmd > 68) && !modernTypeSetSpriteState(nSprite, pXSprite, pXSprite->state ^ 1)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer];
|
TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer];
|
||||||
|
@ -3895,11 +3934,11 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
|
||||||
else trPlayerCtrlSetScreenEffect(pXSprite, pPlayer);
|
else trPlayerCtrlSetScreenEffect(pXSprite, pPlayer);
|
||||||
break;
|
break;
|
||||||
case 3: // 67 (start playing qav scene)
|
case 3: // 67 (start playing qav scene)
|
||||||
if (pCtrl->qavScene.index == nSprite && !pXSprite->Interrutable) break;
|
trPlayerCtrlStartScene(pXSprite, pPlayer, (pXSprite->data4 == 1) ? true : false);
|
||||||
else trPlayerCtrlStartScene(pXSprite, pPlayer);
|
|
||||||
break;
|
break;
|
||||||
case 4: // 68 (stop playing qav scene)
|
case 4: // 68 (stop playing qav scene)
|
||||||
trPlayerCtrlStopScene(pPlayer);
|
if (pXSprite->data2 > 0 && pXSprite->data2 != pPlayer->sceneQav) break;
|
||||||
|
else trPlayerCtrlStopScene(pPlayer);
|
||||||
break;
|
break;
|
||||||
case 5: // 69 (set player look angle, TO-DO: if tx > 0, take a look on TX ID sprite)
|
case 5: // 69 (set player look angle, TO-DO: if tx > 0, take a look on TX ID sprite)
|
||||||
//data4 is reserved
|
//data4 is reserved
|
||||||
|
@ -3998,14 +4037,14 @@ void seqTxSendCmdAll(XSPRITE* pXSource, int nIndex, COMMAND_ID cmd, bool modernS
|
||||||
bool ranged = txIsRanged(pXSource);
|
bool ranged = txIsRanged(pXSource);
|
||||||
if (ranged) {
|
if (ranged) {
|
||||||
for (pXSource->txID = pXSource->data1; pXSource->txID <= pXSource->data4; pXSource->txID++) {
|
for (pXSource->txID = pXSource->data1; pXSource->txID <= pXSource->data4; pXSource->txID++) {
|
||||||
if (pXSource->txID < 0 || pXSource->txID >= kChannelUserMax) continue;
|
if (pXSource->txID <= 0 || pXSource->txID >= kChannelUserMax) continue;
|
||||||
else if (!modernSend) evSend(nIndex, 3, pXSource->txID, cmd);
|
else if (!modernSend) evSend(nIndex, 3, pXSource->txID, cmd);
|
||||||
else modernTypeSendCommand(nIndex, pXSource->txID, cmd);
|
else modernTypeSendCommand(nIndex, pXSource->txID, cmd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i <= 3; i++) {
|
for (int i = 0; i <= 3; i++) {
|
||||||
pXSource->txID = GetDataVal(&sprite[pXSource->reference], i);
|
pXSource->txID = GetDataVal(&sprite[pXSource->reference], i);
|
||||||
if (pXSource->txID < 0 || pXSource->txID >= kChannelUserMax) continue;
|
if (pXSource->txID <= 0 || pXSource->txID >= kChannelUserMax) continue;
|
||||||
else if (!modernSend) evSend(nIndex, 3, pXSource->txID, cmd);
|
else if (!modernSend) evSend(nIndex, 3, pXSource->txID, cmd);
|
||||||
else modernTypeSendCommand(nIndex, pXSource->txID, cmd);
|
else modernTypeSendCommand(nIndex, pXSource->txID, cmd);
|
||||||
}
|
}
|
||||||
|
@ -4099,10 +4138,12 @@ void useSequentialTx(XSPRITE* pXSource, COMMAND_ID cmd, bool setState) {
|
||||||
int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) {
|
int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) {
|
||||||
|
|
||||||
int objType = event.type; int objIndex = event.index;
|
int objType = event.type; int objIndex = event.index;
|
||||||
bool srcIsCondition = (objType == OBJ_SPRITE && sprite[objIndex].type == kModernCondition && objIndex != pSource->index);
|
bool srcIsCondition = false;
|
||||||
|
if (objType == OBJ_SPRITE && objIndex != pSource->index)
|
||||||
|
srcIsCondition = (sprite[objIndex].type == kModernCondition || sprite[objIndex].type == kModernConditionFalse);
|
||||||
|
|
||||||
// if it's a tracking condition, it must ignore all the commands sent from objects
|
// if it's a tracking condition, it must ignore all the commands sent from objects
|
||||||
if (pXSource->busyTime > 0 && event.funcID != kCallbackCondition) return -1;
|
if (pXSource->busyTime > 0 && event.funcID != kCallbackMax) return -1;
|
||||||
else if (!srcIsCondition) { // save object serials in the stack and make copy of initial object
|
else if (!srcIsCondition) { // save object serials in the stack and make copy of initial object
|
||||||
|
|
||||||
pXSource->targetX = pXSource->targetY = condSerialize(objType, objIndex);
|
pXSource->targetX = pXSource->targetY = condSerialize(objType, objIndex);
|
||||||
|
@ -4114,14 +4155,12 @@ int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cond = pXSource->data1; bool ok = false; bool RVRS = (pSource->yvel == kModernConditionFalse);
|
int cond = pXSource->data1; bool ok = false; bool RVRS = (pSource->type == kModernConditionFalse);
|
||||||
bool RSET = (pXSource->command == kCmdNumberic + 36);
|
bool RSET = (pXSource->command == kCmdNumberic + 36); bool PUSH = (pXSource->command == kCmdNumberic);
|
||||||
|
int comOp = pSource->cstat; // comparison operator
|
||||||
|
|
||||||
if (pXSource->restState == 0) {
|
if (pXSource->restState == 0) {
|
||||||
|
|
||||||
bool PUSH = (pXSource->command == kCmdNumberic);
|
|
||||||
int comOp = pSource->cstat; // comparison operator
|
|
||||||
|
|
||||||
if (cond == 0) ok = true; // dummy
|
if (cond == 0) ok = true; // dummy
|
||||||
else if (cond >= kCondMixedBase && cond < kCondMixedMax) ok = condCheckMixed(pXSource, event, comOp, PUSH);
|
else if (cond >= kCondMixedBase && cond < kCondMixedMax) ok = condCheckMixed(pXSource, event, comOp, PUSH);
|
||||||
else if (cond >= kCondWallBase && cond < kCondWallMax) ok = condCheckWall(pXSource, comOp, PUSH);
|
else if (cond >= kCondWallBase && cond < kCondWallMax) ok = condCheckWall(pXSource, comOp, PUSH);
|
||||||
|
@ -4152,6 +4191,7 @@ int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IF
|
||||||
if (pXSource->state) {
|
if (pXSource->state) {
|
||||||
|
|
||||||
pXSource->isTriggered = (pXSource->triggerOnce) ? true : false;
|
pXSource->isTriggered = (pXSource->triggerOnce) ? true : false;
|
||||||
|
@ -4165,8 +4205,10 @@ int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) {
|
||||||
if (pSource->hitag) {
|
if (pSource->hitag) {
|
||||||
|
|
||||||
// send it for object currently in the focus
|
// send it for object currently in the focus
|
||||||
if (pSource->hitag & kModernTypeFlag1)
|
if (pSource->hitag & kModernTypeFlag1) {
|
||||||
|
condUnserialize(pXSource->targetX, &objType, &objIndex);
|
||||||
nnExtTriggerObject(objType, objIndex, pXSource->command);
|
nnExtTriggerObject(objType, objIndex, pXSource->command);
|
||||||
|
}
|
||||||
|
|
||||||
// send it for initial object
|
// send it for initial object
|
||||||
if ((pSource->hitag & kModernTypeFlag2) && (pXSource->targetX != pXSource->targetY || !(pSource->hitag & kModernTypeFlag1))) {
|
if ((pSource->hitag & kModernTypeFlag2) && (pXSource->targetX != pXSource->targetY || !(pSource->hitag & kModernTypeFlag1))) {
|
||||||
|
@ -4176,6 +4218,14 @@ int useCondition(spritetype* pSource, XSPRITE* pXSource, EVENT event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ELSE
|
||||||
|
} else if (pXSource->sysData2 >= 0) {
|
||||||
|
|
||||||
|
pSource = &sprite[pXSource->sysData2]; pXSource = &xsprite[pSource->extra];
|
||||||
|
useCondition(pSource, pXSource, event);
|
||||||
|
|
||||||
|
if (pXSource->isTriggered) pXSource->sysData2 = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pXSource->state;
|
return pXSource->state;
|
||||||
|
@ -4422,7 +4472,9 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
spritetype* pSource = &sprite[pXSource->reference]; XSPRITE* pXSprite = &xsprite[pSprite->extra];
|
//spritetype* pSource = &sprite[pXSource->reference];
|
||||||
|
|
||||||
|
XSPRITE* pXSprite = &xsprite[pSprite->extra];
|
||||||
spritetype* pTarget = NULL; XSPRITE* pXTarget = NULL; int receiveHp = 33 + Random(33);
|
spritetype* pTarget = NULL; XSPRITE* pXTarget = NULL; int receiveHp = 33 + Random(33);
|
||||||
DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); int matesPerEnemy = 1;
|
DUDEINFO* pDudeInfo = getDudeInfo(pSprite->type); int matesPerEnemy = 1;
|
||||||
|
|
||||||
|
@ -4493,14 +4545,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// instantly kill annoying spiders, rats, hands etc if dude is big enough
|
else if (pXSource->data2 == 1 && aiFightIsMateOf(pXSprite, pXTarget)) {
|
||||||
else if (aiFightIsAnnoyingUnit(pTarget) && !aiFightIsAnnoyingUnit(pSprite) && tilesiz[pSprite->picnum].y >= 60 &&
|
|
||||||
aiFightGetTargetDist(pSprite, pDudeInfo, pTarget) < 2) {
|
|
||||||
|
|
||||||
actKillDude(pSource->index, pTarget, DAMAGE_TYPE_0, 65535);
|
|
||||||
aiSetTarget(pXSprite, pSprite->x, pSprite->y, pSprite->z);
|
|
||||||
|
|
||||||
} else if (pXSource->data2 == 1 && aiFightIsMateOf(pXSprite, pXTarget)) {
|
|
||||||
spritetype* pMate = pTarget; XSPRITE* pXMate = pXTarget;
|
spritetype* pMate = pTarget; XSPRITE* pXMate = pXTarget;
|
||||||
|
|
||||||
// heal dude
|
// heal dude
|
||||||
|
@ -4568,6 +4613,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
||||||
if (!isActive(pTarget->index))
|
if (!isActive(pTarget->index))
|
||||||
aiActivateDude(pTarget, pXTarget);
|
aiActivateDude(pTarget, pXTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4604,7 +4650,7 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
||||||
// ...and change target of target to dude to force it fight
|
// ...and change target of target to dude to force it fight
|
||||||
if (pXSource->data3 > 0 && pXTarget->target != pSprite->index) {
|
if (pXSource->data3 > 0 && pXTarget->target != pSprite->index) {
|
||||||
aiSetTarget(pXTarget, pSprite->index);
|
aiSetTarget(pXTarget, pSprite->index);
|
||||||
if (!isActive(pTarget->index))
|
if (pPlayer == NULL && !isActive(pTarget->index))
|
||||||
aiActivateDude(pTarget, pXTarget);
|
aiActivateDude(pTarget, pXTarget);
|
||||||
|
|
||||||
if (pXSource->data3 == 2)
|
if (pXSource->data3 == 2)
|
||||||
|
@ -4706,13 +4752,42 @@ QAV* playerQavSceneLoad(int qavId) {
|
||||||
void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) {
|
void playerQavSceneProcess(PLAYER* pPlayer, QAVSCENE* pQavScene) {
|
||||||
int nIndex = pQavScene->index;
|
int nIndex = pQavScene->index;
|
||||||
if (xspriRangeIsFine(sprite[nIndex].extra)) {
|
if (xspriRangeIsFine(sprite[nIndex].extra)) {
|
||||||
|
|
||||||
XSPRITE* pXSprite = &xsprite[sprite[nIndex].extra];
|
XSPRITE* pXSprite = &xsprite[sprite[nIndex].extra];
|
||||||
if (pXSprite->waitTime > 0 && --pXSprite->sysData1 <= 0) {
|
if (pXSprite->waitTime > 0 && --pXSprite->sysData1 <= 0) {
|
||||||
if (pXSprite->txID > 0) evSend(nIndex, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command);
|
if (pXSprite->txID >= kChannelUser) {
|
||||||
else trPlayerCtrlStopScene(pPlayer);
|
|
||||||
|
XSPRITE* pXSpr = NULL;
|
||||||
|
for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) {
|
||||||
|
if (rxBucket[i].type == OBJ_SPRITE) {
|
||||||
|
|
||||||
|
spritetype* pSpr = &sprite[rxBucket[i].index];
|
||||||
|
if (pSpr->index == nIndex || !xspriRangeIsFine(pSpr->extra))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pXSpr = &xsprite[pSpr->extra];
|
||||||
|
if (pSpr->type == kModernPlayerControl && pXSpr->command == 67) {
|
||||||
|
if (pXSpr->data2 == pXSprite->data2 || pXSpr->locked) continue;
|
||||||
|
else trPlayerCtrlStartScene(pXSpr, pPlayer, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
nnExtTriggerObject(rxBucket[i].type, rxBucket[i].index, pXSprite->command);
|
||||||
|
|
||||||
|
}
|
||||||
|
} //else {
|
||||||
|
|
||||||
|
trPlayerCtrlStopScene(pPlayer);
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
playerQavScenePlay(pPlayer);
|
playerQavScenePlay(pPlayer);
|
||||||
pPlayer->weaponTimer = ClipLow(pPlayer->weaponTimer -= 4, 0);
|
pPlayer->weaponTimer = ClipLow(pPlayer->weaponTimer -= 4, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -5088,11 +5163,14 @@ bool incDecGoalValueIsReached(XSPRITE* pXSprite) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void seqSpawnerOffSameTx(XSPRITE* pXSource) {
|
void seqSpawnerOffSameTx(XSPRITE* pXSource) {
|
||||||
for (int nSprite = headspritestat[kStatModernSeqSpawner]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
|
||||||
if (nSprite != pXSource->reference) {
|
for (int i = 0; i < kMaxXSprites; i++) {
|
||||||
XSPRITE* pXSprite = &xsprite[sprite[nSprite].extra];
|
|
||||||
if (pXSprite->txID == pXSource->txID && pXSprite->state == 1) {
|
XSPRITE* pXSprite = &xsprite[i];
|
||||||
evKill(nSprite, OBJ_SPRITE);
|
if (pXSprite->reference != pXSource->reference && spriRangeIsFine(pXSprite->reference)) {
|
||||||
|
if (sprite[pXSprite->reference].type != kModernSeqSpawner) continue;
|
||||||
|
else if (pXSprite->txID == pXSource->txID && pXSprite->state == 1) {
|
||||||
|
evKill(pXSprite->reference, OBJ_SPRITE);
|
||||||
pXSprite->state = 0;
|
pXSprite->state = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,6 +195,7 @@ struct OBJECTS_TO_TRACK {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TRCONDITION {
|
struct TRCONDITION {
|
||||||
|
signed int xindex: 16;
|
||||||
unsigned int length: 8;
|
unsigned int length: 8;
|
||||||
OBJECTS_TO_TRACK obj[kMaxTracedObjects];
|
OBJECTS_TO_TRACK obj[kMaxTracedObjects];
|
||||||
};
|
};
|
||||||
|
@ -289,7 +290,7 @@ void seqTxSendCmdAll(XSPRITE* pXSource, int nIndex, COMMAND_ID cmd, bool modernS
|
||||||
// ------------------------------------------------------------------------- //
|
// ------------------------------------------------------------------------- //
|
||||||
void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition);
|
void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer, bool checkCondition);
|
||||||
void trPlayerCtrlSetRace(XSPRITE* pXSource, PLAYER* pPlayer);
|
void trPlayerCtrlSetRace(XSPRITE* pXSource, PLAYER* pPlayer);
|
||||||
void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer);
|
void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer, bool force);
|
||||||
void trPlayerCtrlStopScene(PLAYER* pPlayer);
|
void trPlayerCtrlStopScene(PLAYER* pPlayer);
|
||||||
void trPlayerCtrlSetMoveSpeed(XSPRITE* pXSource, PLAYER* pPlayer);
|
void trPlayerCtrlSetMoveSpeed(XSPRITE* pXSource, PLAYER* pPlayer);
|
||||||
void trPlayerCtrlSetJumpHeight(XSPRITE* pXSource, PLAYER* pPlayer);
|
void trPlayerCtrlSetJumpHeight(XSPRITE* pXSource, PLAYER* pPlayer);
|
||||||
|
|
|
@ -569,20 +569,6 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*if (pSprite->statnum != kStatRespawn) {
|
|
||||||
switch (event.cmd) {
|
|
||||||
case kCmdOn:
|
|
||||||
actExplodeSprite(pSprite);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sfxPlay3DSound(pSprite, 454, 0, 0);
|
|
||||||
evPost(nSprite, 3, 18, kCmdOff);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kThingArmedProxBomb:
|
case kThingArmedProxBomb:
|
||||||
if (pSprite->statnum != kStatRespawn) {
|
if (pSprite->statnum != kStatRespawn) {
|
||||||
switch (event.cmd) {
|
switch (event.cmd) {
|
||||||
|
@ -2157,10 +2143,6 @@ void trInit(void)
|
||||||
if (pXSprite->waitTime > 0)
|
if (pXSprite->waitTime > 0)
|
||||||
evPost(i, 3, (pXSprite->waitTime * 120) / 10, pXSprite->restState ? kCmdOn : kCmdOff);
|
evPost(i, 3, (pXSprite->waitTime * 120) / 10, pXSprite->restState ? kCmdOn : kCmdOff);
|
||||||
break;
|
break;
|
||||||
case kModernCondition:
|
|
||||||
if (pXSprite->busyTime <= 0 || pXSprite->locked) break;
|
|
||||||
evPost(i, 3, ClipLow(pXSprite->busyTime, 5), kCallbackCondition);
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
case kGenTrigger:
|
case kGenTrigger:
|
||||||
case kGenDripWater:
|
case kGenDripWater:
|
||||||
|
|
|
@ -2419,12 +2419,12 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t
|
||||||
pTSprite->ang = (pTSprite->ang+((int)totalclock<<3))&2047;
|
pTSprite->ang = (pTSprite->ang+((int)totalclock<<3))&2047;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pTSprite->cstat&48) != 48 && usemodels && !(spriteext[nSprite].flags&SPREXT_NOTMD))
|
if ((pTSprite->cstat&48) != 48 && hw_models && !(spriteext[nSprite].flags&SPREXT_NOTMD))
|
||||||
{
|
{
|
||||||
int const nRootTile = pTSprite->picnum;
|
int const nRootTile = pTSprite->picnum;
|
||||||
int nAnimTile = pTSprite->picnum + animateoffs_replace(pTSprite->picnum, 32768+pTSprite->owner);
|
int nAnimTile = pTSprite->picnum + animateoffs_replace(pTSprite->picnum, 32768+pTSprite->owner);
|
||||||
|
|
||||||
if (usemodels && tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].modelid >= 0 &&
|
if (tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].modelid >= 0 &&
|
||||||
tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].framenum >= 0)
|
tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].framenum >= 0)
|
||||||
{
|
{
|
||||||
pTSprite->yoffset += picanm[nAnimTile].yofs;
|
pTSprite->yoffset += picanm[nAnimTile].yofs;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
#include "inputstate.h"
|
#include "inputstate.h"
|
||||||
|
|
|
@ -95,7 +95,7 @@ int32_t FileStream::Seek(int32_t offset, SeekDirection direction)
|
||||||
nStatus = file.Seek(offset, FileReader::SeekCur);
|
nStatus = file.Seek(offset, FileReader::SeekCur);
|
||||||
}
|
}
|
||||||
else if (kSeekEnd == direction) {
|
else if (kSeekEnd == direction) {
|
||||||
nStatus = klseek(file, offset, SEEK_END);
|
nStatus = file.Seek(offset, FileReader::SeekEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nStatus;
|
return nStatus;
|
||||||
|
|
|
@ -47,13 +47,9 @@
|
||||||
#ifndef playmve_h_
|
#ifndef playmve_h_
|
||||||
#define playmve_h_
|
#define playmve_h_
|
||||||
|
|
||||||
#include "a.h"
|
|
||||||
#include "baselayer.h"
|
#include "baselayer.h"
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include "cache1d.h"
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "fx_man.h"
|
|
||||||
#include "keyboard.h"
|
|
||||||
#include "pragmas.h"
|
#include "pragmas.h"
|
||||||
|
|
||||||
bool playmve(const char* filename);
|
bool playmve(const char* filename);
|
||||||
|
|
Loading…
Reference in a new issue