mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-18 23:21:43 +00:00
- More compact code for event redirection
- Fix demo desync - Fix MINGW compile warnings - Move custom start health from data4 to sysData2 in gModern maps - Proper respawn for custom dude # Conflicts: # source/blood/src/dude.cpp # source/blood/src/dude.h
This commit is contained in:
parent
64de30209b
commit
e3e805b24c
8 changed files with 172 additions and 162 deletions
|
@ -2469,7 +2469,7 @@ void actInit(bool bSaveLoad) {
|
||||||
nnExtInitModernStuff(bSaveLoad);
|
nnExtInitModernStuff(bSaveLoad);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
||||||
switch (sprite[nSprite].type) {
|
switch (sprite[nSprite].type) {
|
||||||
case kItemWeaponVoodooDoll:
|
case kItemWeaponVoodooDoll:
|
||||||
|
@ -2587,7 +2587,15 @@ void actInit(bool bSaveLoad) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0;
|
xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0;
|
||||||
pXSprite->health = dudeGetStartHp(pSprite);
|
|
||||||
|
#ifdef NOONE_EXTENSIONS
|
||||||
|
// add a way to set custom hp for every enemy - should work only if map just started and not loaded.
|
||||||
|
if (!gModernMap || pXSprite->sysData2 <= 0) pXSprite->health = dudeInfo[nType].startHealth << 4;
|
||||||
|
else pXSprite->health = ClipRange(pXSprite->sysData2 << 4, 1, 65535);
|
||||||
|
#else
|
||||||
|
pXSprite->health = dudeInfo[nType].startHealth << 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gSysRes.Lookup(seqStartId, "SEQ")) seqSpawn(seqStartId, 3, pSprite->extra);
|
if (gSysRes.Lookup(seqStartId, "SEQ")) seqSpawn(seqStartId, 3, pSprite->extra);
|
||||||
|
|
|
@ -1647,7 +1647,9 @@ spritetype* genDudeSpawn(spritetype* pSprite, int nDist) {
|
||||||
if (pSource->clipdist > 0) pDude->clipdist = pSource->clipdist;
|
if (pSource->clipdist > 0) pDude->clipdist = pSource->clipdist;
|
||||||
|
|
||||||
// inherit custom hp settings
|
// inherit custom hp settings
|
||||||
pXDude->health = dudeGetStartHp(pDude);
|
if (pXSource->data4 <= 0) pXDude->health = dudeInfo[nType - kDudeBase].startHealth << 4;
|
||||||
|
else pXDude->health = ClipRange(pXSource->data4 << 4, 1, 65535);
|
||||||
|
|
||||||
|
|
||||||
if (pSource->flags & kModernTypeFlag1) {
|
if (pSource->flags & kModernTypeFlag1) {
|
||||||
switch (pSource->type) {
|
switch (pSource->type) {
|
||||||
|
@ -1740,8 +1742,8 @@ void genDudeTransform(spritetype* pSprite) {
|
||||||
pXSprite->data1 = pXIncarnation->data1;
|
pXSprite->data1 = pXIncarnation->data1;
|
||||||
pXSprite->data2 = pXIncarnation->data2;
|
pXSprite->data2 = pXIncarnation->data2;
|
||||||
|
|
||||||
pXSprite->sysData1 = pXIncarnation->data3;
|
pXSprite->sysData1 = pXIncarnation->data3; // soundBase id
|
||||||
pXSprite->sysData2 = pXIncarnation->data4;
|
pXSprite->sysData2 = pXIncarnation->data4; // start hp
|
||||||
|
|
||||||
pXSprite->dudeGuard = pXIncarnation->dudeGuard;
|
pXSprite->dudeGuard = pXIncarnation->dudeGuard;
|
||||||
pXSprite->dudeDeaf = pXIncarnation->dudeDeaf;
|
pXSprite->dudeDeaf = pXIncarnation->dudeDeaf;
|
||||||
|
@ -1758,7 +1760,8 @@ void genDudeTransform(spritetype* pSprite) {
|
||||||
pXIncarnation->key = pXIncarnation->dropMsg = 0;
|
pXIncarnation->key = pXIncarnation->dropMsg = 0;
|
||||||
|
|
||||||
// set hp
|
// set hp
|
||||||
pXSprite->health = dudeGetStartHp(pSprite);
|
if (pXSprite->sysData2 <= 0) pXSprite->health = dudeInfo[pSprite->type - kDudeBase].startHealth << 4;
|
||||||
|
else pXSprite->health = ClipRange(pXSprite->sysData2 << 4, 1, 65535);
|
||||||
|
|
||||||
int seqId = dudeInfo[pSprite->type - kDudeBase].seqStartID;
|
int seqId = dudeInfo[pSprite->type - kDudeBase].seqStartID;
|
||||||
switch (pSprite->type) {
|
switch (pSprite->type) {
|
||||||
|
|
|
@ -270,7 +270,9 @@ void Respawn(int nSprite) // 9
|
||||||
pSprite->y = baseSprite[nSprite].y;
|
pSprite->y = baseSprite[nSprite].y;
|
||||||
pSprite->z = baseSprite[nSprite].z;
|
pSprite->z = baseSprite[nSprite].z;
|
||||||
pSprite->cstat |= 0x1101;
|
pSprite->cstat |= 0x1101;
|
||||||
pXSprite->health = dudeGetStartHp(pSprite);
|
#ifdef NOONE_EXTENSIONS
|
||||||
|
if (!gModernMap || pXSprite->sysData2 <= 0) pXSprite->health = dudeInfo[pSprite->type - kDudeBase].startHealth << 4;
|
||||||
|
else pXSprite->health = ClipRange(pXSprite->sysData2 << 4, 1, 65535);
|
||||||
switch (pSprite->type) {
|
switch (pSprite->type) {
|
||||||
default:
|
default:
|
||||||
pSprite->clipdist = getDudeInfo(nType + kDudeBase)->clipdist;
|
pSprite->clipdist = getDudeInfo(nType + kDudeBase)->clipdist;
|
||||||
|
@ -281,6 +283,12 @@ void Respawn(int nSprite) // 9
|
||||||
seqSpawn(genDudeSeqStartId(pXSprite), 3, pSprite->extra, -1);
|
seqSpawn(genDudeSeqStartId(pXSprite), 3, pSprite->extra, -1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
pSprite->clipdist = getDudeInfo(nType + kDudeBase)->clipdist;
|
||||||
|
pXSprite->health = getDudeInfo(nType + kDudeBase)->startHealth << 4;
|
||||||
|
if (gSysRes.Lookup(getDudeInfo(nType + kDudeBase)->seqStartID, "SEQ"))
|
||||||
|
seqSpawn(getDudeInfo(nType + kDudeBase)->seqStartID, 3, pSprite->extra, -1);
|
||||||
|
#endif
|
||||||
aiInitSprite(pSprite);
|
aiInitSprite(pSprite);
|
||||||
pXSprite->key = 0;
|
pXSprite->key = 0;
|
||||||
} else if (pSprite->type == kThingTNTBarrel) {
|
} else if (pSprite->type == kThingTNTBarrel) {
|
||||||
|
|
|
@ -1570,7 +1570,7 @@ DUDEINFO dudeInfo[kDudeMax-kDudeBase] =
|
||||||
256, // angSpeed
|
256, // angSpeed
|
||||||
// 0,
|
// 0,
|
||||||
7, -1, 18, // nGibType
|
7, -1, 18, // nGibType
|
||||||
64, 256, 256, 256, 256, 256, 256,
|
128, 150, 128, 256, 128, 128, 128,
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
|
@ -1732,20 +1732,4 @@ DUDEINFO gPlayerTemplate[4] =
|
||||||
};
|
};
|
||||||
|
|
||||||
DUDEINFO fakeDudeInfo = {};
|
DUDEINFO fakeDudeInfo = {};
|
||||||
|
|
||||||
int dudeGetStartHp(spritetype* pDude) {
|
|
||||||
|
|
||||||
int hp = getDudeInfo(pDude->type)->startHealth << 4;
|
|
||||||
if (!hp) {
|
|
||||||
consoleSysMsg("Sprite #%d (type %d) is not a dude!", pDude->index, pDude->type);
|
|
||||||
return hp;
|
|
||||||
}
|
|
||||||
#ifdef NOONE_EXTENSIONS
|
|
||||||
// add a way to set custom hp for every enemy (data4 moved to sysData2)
|
|
||||||
else if (gModernMap && xsprite[pDude->extra].sysData2 > 0)
|
|
||||||
hp = ClipRange(xsprite[pDude->extra].sysData2 << 4, 1, 65535);
|
|
||||||
#endif
|
|
||||||
return hp;
|
|
||||||
}
|
|
||||||
|
|
||||||
END_BLD_NS
|
END_BLD_NS
|
||||||
|
|
|
@ -66,6 +66,4 @@ inline DUDEINFO *getDudeInfo(int const nType)
|
||||||
return &fakeDudeInfo;
|
return &fakeDudeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dudeGetStartHp(spritetype* pDude);
|
|
||||||
|
|
||||||
END_BLD_NS
|
END_BLD_NS
|
||||||
|
|
|
@ -407,6 +407,7 @@ void nnExtInitModernStuff(bool bSaveLoad) {
|
||||||
if (sysStat)
|
if (sysStat)
|
||||||
ThrowError("Sprite #%d: System status list number %d detected!", pSprite->index, pSprite->statnum);
|
ThrowError("Sprite #%d: System status list number %d detected!", pSprite->index, pSprite->statnum);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (pSprite->type) {
|
switch (pSprite->type) {
|
||||||
case kModernRandomTX:
|
case kModernRandomTX:
|
||||||
case kModernSequentialTX:
|
case kModernSequentialTX:
|
||||||
|
@ -729,7 +730,6 @@ void nnExtProcessSuperSprites() {
|
||||||
|
|
||||||
// process Debris sprites for movement
|
// process Debris sprites for movement
|
||||||
if (gPhysSpritesCount > 0) {
|
if (gPhysSpritesCount > 0) {
|
||||||
//viewSetSystemMessage("PHYS COUNT: %d", gPhysSpritesCount);
|
|
||||||
for (int i = 0; i < gPhysSpritesCount; i++) {
|
for (int i = 0; i < gPhysSpritesCount; i++) {
|
||||||
if (gPhysSpritesList[i] == -1) continue;
|
if (gPhysSpritesList[i] == -1) continue;
|
||||||
else if (sprite[gPhysSpritesList[i]].statnum == kStatFree || (sprite[gPhysSpritesList[i]].flags & kHitagFree) != 0) {
|
else if (sprite[gPhysSpritesList[i]].statnum == kStatFree || (sprite[gPhysSpritesList[i]].flags & kHitagFree) != 0) {
|
||||||
|
@ -1174,30 +1174,15 @@ void windGenStopWindOnSectors(XSPRITE* pXSource) {
|
||||||
pXSector->windVel = 0;
|
pXSector->windVel = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gEventRedirectsUsed) {
|
// check redirected TX buckets
|
||||||
int rx = 0; XSPRITE* pXRedir = eventRedirected(OBJ_SPRITE, pSource->extra, false);
|
int rx = -1; XSPRITE* pXRedir = NULL;
|
||||||
if (pXRedir == NULL) return;
|
while ((pXRedir = evrListRedirectors(OBJ_SPRITE, sprite[pXSource->reference].extra, pXRedir, &rx)) != NULL) {
|
||||||
else if (txIsRanged(pXRedir)) {
|
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
||||||
if (!channelRangeIsFine(pXRedir->data4 - pXRedir->data1)) return;
|
if (rxBucket[i].type != OBJ_SECTOR) continue;
|
||||||
for (rx = pXRedir->data1; rx <= pXRedir->data4; rx++) {
|
XSECTOR* pXSector = &xsector[sector[rxBucket[i].index].extra];
|
||||||
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
if ((pXSector->state == 1 && !pXSector->windAlways) || (pSource->flags & kModernTypeFlag2))
|
||||||
if (rxBucket[i].type != OBJ_SECTOR) continue;
|
pXSector->windVel = 0;
|
||||||
XSECTOR* pXSector = &xsector[sector[rxBucket[i].index].extra];
|
|
||||||
if ((pXSector->state == 1 && !pXSector->windAlways) || (pSource->flags & kModernTypeFlag2))
|
|
||||||
pXSector->windVel = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i <= 3; i++) {
|
|
||||||
if (!channelRangeIsFine((rx = GetDataVal(&sprite[pXRedir->reference], i)))) continue;
|
|
||||||
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
|
||||||
if (rxBucket[i].type != OBJ_SECTOR) continue;
|
|
||||||
XSECTOR* pXSector = &xsector[sector[rxBucket[i].index].extra];
|
|
||||||
if ((pXSector->state == 1 && !pXSector->windAlways) || (pSource->flags & kModernTypeFlag2))
|
|
||||||
pXSector->windVel = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1238,7 +1223,6 @@ void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer) {
|
||||||
void trPlayerCtrlStopScene(XSPRITE* pXSource, PLAYER* pPlayer) {
|
void trPlayerCtrlStopScene(XSPRITE* pXSource, PLAYER* pPlayer) {
|
||||||
|
|
||||||
TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer];
|
TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer];
|
||||||
//viewSetSystemMessage("OFF %d", pCtrl->qavScene.index);
|
|
||||||
|
|
||||||
pXSource->sysData1 = 0;
|
pXSource->sysData1 = 0;
|
||||||
pCtrl->qavScene.index = -1;
|
pCtrl->qavScene.index = -1;
|
||||||
|
@ -2204,6 +2188,9 @@ bool condCmp(int val, int arg1, int arg2, int comOp) {
|
||||||
|
|
||||||
// no extra comparison (val always = 0)?
|
// no extra comparison (val always = 0)?
|
||||||
bool condCmpne(int arg1, int arg2, int comOp) {
|
bool condCmpne(int arg1, int arg2, int comOp) {
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(arg2);
|
||||||
|
|
||||||
if (comOp & 0x2000) return (comOp & CSTAT_SPRITE_BLOCK) ? false : (!arg1); // blue sprite
|
if (comOp & 0x2000) return (comOp & CSTAT_SPRITE_BLOCK) ? false : (!arg1); // blue sprite
|
||||||
else if (comOp & 0x4000) return (comOp & CSTAT_SPRITE_BLOCK) ? false : (!arg1); // green sprite
|
else if (comOp & 0x4000) return (comOp & CSTAT_SPRITE_BLOCK) ? false : (!arg1); // green sprite
|
||||||
else return (!arg1);
|
else return (!arg1);
|
||||||
|
@ -2299,6 +2286,7 @@ bool condCheckMixed(XSPRITE* pXCond, EVENT event, int cmpOp, bool PUSH, bool RVR
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case 41:
|
case 41:
|
||||||
case 42:
|
case 42:
|
||||||
case 43:
|
case 43:
|
||||||
|
@ -2376,7 +2364,7 @@ bool condCheckSector(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
|
|
||||||
int var = -1;
|
int var = -1;
|
||||||
int cond = pXCond->data1 - kCondSectorBase; int arg1 = pXCond->data2;
|
int cond = pXCond->data1 - kCondSectorBase; 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);
|
||||||
|
@ -2445,7 +2433,7 @@ bool condCheckWall(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
|
|
||||||
int var = -1;
|
int var = -1;
|
||||||
int cond = pXCond->data1 - kCondWallBase; int arg1 = pXCond->data2;
|
int cond = pXCond->data1 - kCondWallBase; 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);
|
||||||
|
@ -2454,7 +2442,7 @@ bool condCheckWall(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
ThrowError("\nWall conditions:\nObject #%d (objType: %d) is not a wall!", objIndex, objType);
|
ThrowError("\nWall conditions:\nObject #%d (objType: %d) is not a wall!", objIndex, objType);
|
||||||
|
|
||||||
walltype* pWall = &wall[objIndex];
|
walltype* pWall = &wall[objIndex];
|
||||||
XWALL* pXWall = (xwallRangeIsFine(pWall->extra)) ? &xwall[pWall->extra] : NULL;
|
//XWALL* pXWall = (xwallRangeIsFine(pWall->extra)) ? &xwall[pWall->extra] : NULL;
|
||||||
|
|
||||||
if (cond < (kCondRange >> 1)) {
|
if (cond < (kCondRange >> 1)) {
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
|
@ -2488,6 +2476,8 @@ bool condCheckWall(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
|
|
||||||
bool condCheckDude(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
bool condCheckDude(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(RVRS);
|
||||||
|
|
||||||
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;
|
||||||
|
@ -2569,6 +2559,8 @@ bool condCheckDude(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
|
|
||||||
bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(RVRS);
|
||||||
|
|
||||||
int var = -1; PLAYER* pPlayer = NULL; bool retn = false;
|
int var = -1; PLAYER* pPlayer = NULL; bool retn = false;
|
||||||
int cond = pXCond->data1 - kCondSpriteBase; int arg1 = pXCond->data2;
|
int cond = pXCond->data1 - kCondSpriteBase; int arg1 = pXCond->data2;
|
||||||
int arg2 = pXCond->data3; int arg3 = pXCond->data4;
|
int arg2 = pXCond->data3; int arg3 = pXCond->data4;
|
||||||
|
@ -2666,7 +2658,7 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
default: break;
|
default: break;
|
||||||
case 50: // compare hp (in %)
|
case 50: // compare hp (in %)
|
||||||
if (IsDudeSprite(pSpr)) var = dudeGetStartHp(pSpr);
|
if (IsDudeSprite(pSpr)) var = (pXSpr->sysData2 > 0) ? ClipRange(pXSpr->sysData2 << 4, 1, 65535) : getDudeInfo(pSpr->type)->startHealth << 4;
|
||||||
else if (condCmpne(arg1, arg2, cmpOp) && pSpr->type == kThingBloodChunks) return true;
|
else if (condCmpne(arg1, arg2, cmpOp) && pSpr->type == kThingBloodChunks) return true;
|
||||||
else if (pSpr->type >= kThingBase && pSpr->type < kThingMax)
|
else if (pSpr->type >= kThingBase && pSpr->type < kThingMax)
|
||||||
var = thingInfo[pSpr->type - kThingBase].startHealth << 4;
|
var = thingInfo[pSpr->type - kThingBase].startHealth << 4;
|
||||||
|
@ -2711,7 +2703,6 @@ bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS) {
|
||||||
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?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
viewSetSystemMessage("!!!!!!!! %d", pSpr->type);
|
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
default: return false;
|
default: return false;
|
||||||
case 50:
|
case 50:
|
||||||
|
@ -2832,6 +2823,7 @@ void modernTypeTrigger(int destObjType, int destObjIndex, EVENT event) {
|
||||||
modernTypeSendCommand(pSource->index, pXSpr->txID, (COMMAND_ID)pXSource->command);
|
modernTypeSendCommand(pSource->index, pXSpr->txID, (COMMAND_ID)pXSource->command);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2896,55 +2888,6 @@ void modernTypeTrigger(int destObjType, int destObjIndex, EVENT event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XSPRITE* eventRedirected(int objType, int objXIndex, bool byRx) {
|
|
||||||
unsigned short id = 0;
|
|
||||||
switch (objType) {
|
|
||||||
case OBJ_SECTOR:
|
|
||||||
if (!xsectRangeIsFine(objXIndex)) return NULL;
|
|
||||||
id = (byRx) ? xsector[objXIndex].rxID : xsector[objXIndex].txID;
|
|
||||||
break;
|
|
||||||
case OBJ_SPRITE:
|
|
||||||
if (!xspriRangeIsFine(objXIndex)) return NULL;
|
|
||||||
id = (byRx) ? xsprite[objXIndex].rxID : xsprite[objXIndex].txID;
|
|
||||||
break;
|
|
||||||
case OBJ_WALL:
|
|
||||||
if (!xwallRangeIsFine(objXIndex)) return NULL;
|
|
||||||
id = (byRx) ? xwall[objXIndex].rxID : xwall[objXIndex].txID;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!byRx) {
|
|
||||||
for (int i = bucketHead[id]; i < bucketHead[id + 1]; i++) {
|
|
||||||
if (rxBucket[i].type != OBJ_SPRITE) continue;
|
|
||||||
spritetype* pSpr = &sprite[rxBucket[i].index];
|
|
||||||
if (!xspriRangeIsFine(pSpr->extra)) continue;
|
|
||||||
switch (pSpr->type) {
|
|
||||||
case kModernRandomTX:
|
|
||||||
case kModernSequentialTX:
|
|
||||||
XSPRITE* pXSpr = &xsprite[pSpr->extra];
|
|
||||||
if (!(pSpr->flags & kModernTypeFlag2) || pXSpr->locked) continue;
|
|
||||||
return pXSpr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int nSprite = headspritestat[kStatModernEventRedirector]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
|
||||||
if (xspriRangeIsFine(sprite[nSprite].extra)) {
|
|
||||||
XSPRITE* pXRedir = &xsprite[sprite[nSprite].extra];
|
|
||||||
if (txIsRanged(pXRedir)) {
|
|
||||||
if (id >= pXRedir->data1 && id <= pXRedir->data4) return pXRedir;
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i <= 3; i++)
|
|
||||||
if (id == GetDataVal(&sprite[pXRedir->reference], i)) return pXRedir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// the following functions required for kModernDudeTargetChanger
|
// the following functions required for kModernDudeTargetChanger
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
spritetype* aiFightGetTargetInRange(spritetype* pSprite, int minDist, int maxDist, short data, short teamMode) {
|
spritetype* aiFightGetTargetInRange(spritetype* pSprite, int minDist, int maxDist, short data, short teamMode) {
|
||||||
|
@ -3031,7 +2974,6 @@ bool aiFightDudeCanSeeTarget(XSPRITE* pXDude, DUDEINFO* pDudeInfo, spritetype* p
|
||||||
spritetype* pDude = &sprite[pXDude->reference];
|
spritetype* pDude = &sprite[pXDude->reference];
|
||||||
int dx = pTarget->x - pDude->x; int dy = pTarget->y - pDude->y;
|
int dx = pTarget->x - pDude->x; int dy = pTarget->y - pDude->y;
|
||||||
|
|
||||||
//viewSetSystemMessage("zzzz");
|
|
||||||
// check target
|
// check target
|
||||||
if (approxDist(dx, dy) < pDudeInfo->seeDist) {
|
if (approxDist(dx, dy) < pDudeInfo->seeDist) {
|
||||||
int eyeAboveZ = pDudeInfo->eyeHeight * pDude->yrepeat << 2;
|
int eyeAboveZ = pDudeInfo->eyeHeight * pDude->yrepeat << 2;
|
||||||
|
@ -3116,27 +3058,13 @@ bool aiFightGetDudesForBattle(XSPRITE* pXSprite) {
|
||||||
xsprite[sprite[rxBucket[i].index].extra].health > 0) return true;
|
xsprite[sprite[rxBucket[i].index].extra].health > 0) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gEventRedirectsUsed) {
|
// check redirected TX buckets
|
||||||
int rx = 0; XSPRITE* pXRedir = eventRedirected(OBJ_SPRITE, sprite[pXSprite->reference].extra, false);
|
int rx = -1; XSPRITE* pXRedir = NULL;
|
||||||
if (pXRedir == NULL) return false;
|
while ((pXRedir = evrListRedirectors(OBJ_SPRITE, sprite[pXSprite->reference].extra, pXRedir, &rx)) != NULL) {
|
||||||
else if (txIsRanged(pXRedir)) {
|
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
||||||
if (!channelRangeIsFine(pXRedir->data4 - pXRedir->data1)) return false;
|
if (rxBucket[i].type != OBJ_SPRITE) continue;
|
||||||
for (rx = pXRedir->data1; rx <= pXRedir->data4; rx++) {
|
else if (IsDudeSprite(&sprite[rxBucket[i].index]) &&
|
||||||
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
xsprite[sprite[rxBucket[i].index].extra].health > 0) return true;
|
||||||
if (rxBucket[i].type != OBJ_SPRITE) continue;
|
|
||||||
else if (IsDudeSprite(&sprite[rxBucket[i].index]) &&
|
|
||||||
xsprite[sprite[rxBucket[i].index].extra].health > 0) return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i <= 3; i++) {
|
|
||||||
if (!channelRangeIsFine((rx = GetDataVal(&sprite[pXRedir->reference], i)))) continue;
|
|
||||||
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
|
||||||
if (rxBucket[i].type != OBJ_SPRITE) continue;
|
|
||||||
else if (IsDudeSprite(&sprite[rxBucket[i].index]) &&
|
|
||||||
xsprite[sprite[rxBucket[i].index].extra].health > 0) return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -3442,11 +3370,9 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite
|
||||||
evPost(nSprite, 3, 0, kCmdOff);
|
evPost(nSprite, 3, 0, kCmdOff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pXSprite->txID > 0 /*&& pXSprite->data1 > 0 && pXSprite->data1 <= 4*/) {
|
modernTypeSendCommand(nSprite, pXSprite->txID, (COMMAND_ID)pXSprite->command);
|
||||||
modernTypeSendCommand(nSprite, pXSprite->txID, (COMMAND_ID)pXSprite->command);
|
if (pXSprite->busyTime > 0) evPost(nSprite, 3, pXSprite->busyTime, kCmdRepeat);
|
||||||
if (pXSprite->busyTime > 0) evPost(nSprite, 3, pXSprite->busyTime, kCmdRepeat);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (pXSprite->state == 0) evPost(nSprite, 3, 0, kCmdOn);
|
if (pXSprite->state == 0) evPost(nSprite, 3, 0, kCmdOn);
|
||||||
|
@ -4099,6 +4025,7 @@ void useIncDecGen(XSPRITE* pXSource, short objType, int objIndex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pXSource->sysData1 = data;
|
||||||
setDataValueOfObject(objType, objIndex, dataIndex, data);
|
setDataValueOfObject(objType, objIndex, dataIndex, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4196,11 +4123,10 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
||||||
if (pBurnSource->extra >= 0) {
|
if (pBurnSource->extra >= 0) {
|
||||||
if (pXSource->data2 == 1 && aiFightIsMateOf(pXSprite, &xsprite[pBurnSource->extra])) {
|
if (pXSource->data2 == 1 && aiFightIsMateOf(pXSprite, &xsprite[pBurnSource->extra])) {
|
||||||
pXSprite->burnTime = 0;
|
pXSprite->burnTime = 0;
|
||||||
|
|
||||||
// heal dude a bit in case of friendly fire
|
// heal dude a bit in case of friendly fire
|
||||||
int startHp = dudeGetStartHp(pSprite);
|
int startHp = (pXSprite->sysData2 > 0) ? ClipRange(pXSprite->sysData2 << 4, 1, 65535) : pDudeInfo->startHealth << 4;
|
||||||
if (pXSprite->health < startHp) actHealDude(pXSprite, receiveHp, startHp);
|
if (pXSprite->health < startHp) actHealDude(pXSprite, receiveHp, startHp);
|
||||||
|
|
||||||
} else if (xsprite[pBurnSource->extra].health <= 0) {
|
} else if (xsprite[pBurnSource->extra].health <= 0) {
|
||||||
pXSprite->burnTime = 0;
|
pXSprite->burnTime = 0;
|
||||||
}
|
}
|
||||||
|
@ -4266,11 +4192,11 @@ void useTargetChanger(XSPRITE* pXSource, spritetype* pSprite) {
|
||||||
spritetype* pMate = pTarget; XSPRITE* pXMate = pXTarget;
|
spritetype* pMate = pTarget; XSPRITE* pXMate = pXTarget;
|
||||||
|
|
||||||
// heal dude
|
// heal dude
|
||||||
int startHp = dudeGetStartHp(pSprite);
|
int startHp = (pXSprite->sysData2 > 0) ? ClipRange(pXSprite->sysData2 << 4, 1, 65535) : pDudeInfo->startHealth << 4;
|
||||||
if (pXSprite->health < startHp) actHealDude(pXSprite, receiveHp, startHp);
|
if (pXSprite->health < startHp) actHealDude(pXSprite, receiveHp, startHp);
|
||||||
|
|
||||||
// heal mate
|
// heal mate
|
||||||
startHp = dudeGetStartHp(pMate);
|
startHp = (pXMate->sysData2 > 0) ? ClipRange(pXMate->sysData2 << 4, 1, 65535) : getDudeInfo(pMate->type)->startHealth << 4;
|
||||||
if (pXMate->health < startHp) actHealDude(pXMate, receiveHp, startHp);
|
if (pXMate->health < startHp) actHealDude(pXMate, receiveHp, startHp);
|
||||||
|
|
||||||
if (pXMate->target > -1 && sprite[pXMate->target].extra >= 0) {
|
if (pXMate->target > -1 && sprite[pXMate->target].extra >= 0) {
|
||||||
|
@ -4750,44 +4676,114 @@ bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int listTx(XSPRITE* pXRedir, int tx) {
|
||||||
|
if (txIsRanged(pXRedir)) {
|
||||||
|
if (tx == -1) tx = pXRedir->data1;
|
||||||
|
else if (tx < pXRedir->data4) tx++;
|
||||||
|
else tx = -1;
|
||||||
|
} else {
|
||||||
|
if (tx == -1) {
|
||||||
|
for (int i = 0; i <= 3; i++) {
|
||||||
|
if ((tx = GetDataVal(&sprite[pXRedir->reference], i)) <= 0) continue;
|
||||||
|
else return tx;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int saved = tx; bool savedFound = false;
|
||||||
|
for (int i = 0; i <= 3; i++) {
|
||||||
|
tx = GetDataVal(&sprite[pXRedir->reference], i);
|
||||||
|
if (savedFound && tx > 0) return tx;
|
||||||
|
else if (tx != saved) continue;
|
||||||
|
else savedFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSPRITE* evrIsRedirector(int nSprite) {
|
||||||
|
if (spriRangeIsFine(nSprite)) {
|
||||||
|
switch (sprite[nSprite].type) {
|
||||||
|
case kModernRandomTX:
|
||||||
|
case kModernSequentialTX:
|
||||||
|
if ((sprite[nSprite].flags & kModernTypeFlag2)
|
||||||
|
&& xspriRangeIsFine(sprite[nSprite].extra) && !xsprite[sprite[nSprite].extra].locked) {
|
||||||
|
return &xsprite[sprite[nSprite].extra];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSPRITE* evrListRedirectors(int objType, int objXIndex, XSPRITE* pXRedir, int* tx) {
|
||||||
|
if (!gEventRedirectsUsed) return NULL;
|
||||||
|
else if (pXRedir && (*tx = listTx(pXRedir, *tx)) != -1)
|
||||||
|
return pXRedir;
|
||||||
|
|
||||||
|
int id = 0;
|
||||||
|
switch (objType) {
|
||||||
|
case OBJ_SECTOR:
|
||||||
|
if (!xsectRangeIsFine(objXIndex)) return NULL;
|
||||||
|
id = xsector[objXIndex].txID;
|
||||||
|
break;
|
||||||
|
case OBJ_SPRITE:
|
||||||
|
if (!xspriRangeIsFine(objXIndex)) return NULL;
|
||||||
|
id = xsprite[objXIndex].txID;
|
||||||
|
break;
|
||||||
|
case OBJ_WALL:
|
||||||
|
if (!xwallRangeIsFine(objXIndex)) return NULL;
|
||||||
|
id = xwall[objXIndex].txID;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nIndex = (pXRedir) ? pXRedir->reference : -1; bool prevFound = false;
|
||||||
|
for (int i = bucketHead[id]; i < bucketHead[id + 1]; i++) {
|
||||||
|
if (rxBucket[i].type != OBJ_SPRITE) continue;
|
||||||
|
XSPRITE* pXSpr = evrIsRedirector(rxBucket[i].index);
|
||||||
|
if (!pXSpr) continue;
|
||||||
|
else if (prevFound || nIndex == -1) { *tx = listTx(pXSpr, *tx); return pXSpr; }
|
||||||
|
else if (nIndex != pXSpr->reference) continue;
|
||||||
|
else prevFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
*tx = -1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// this function checks if all TX objects have the same value
|
// this function checks if all TX objects have the same value
|
||||||
bool incDecGoalValueIsReached(XSPRITE* pXSprite) {
|
bool incDecGoalValueIsReached(XSPRITE* pXSprite) {
|
||||||
|
|
||||||
char buffer[5]; sprintf(buffer, "%d", abs(pXSprite->data1)); int len = strlen(buffer); int rx = 0;
|
if (pXSprite->data3 != pXSprite->sysData1) return false;
|
||||||
XSPRITE* pXRedir = (gEventRedirectsUsed) ? eventRedirected(OBJ_SPRITE, sprite[pXSprite->reference].extra, false) : NULL;
|
char buffer[5]; sprintf(buffer, "%d", abs(pXSprite->data1)); int len = strlen(buffer); int rx = -1;
|
||||||
for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) {
|
for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) {
|
||||||
if (pXRedir && sprite[pXRedir->reference].index == (int) rxBucket[i].index) continue;
|
if (rxBucket[i].type == OBJ_SPRITE && evrIsRedirector(rxBucket[i].index)) continue;
|
||||||
for (int a = 0; a < len; a++) {
|
for (int a = 0; a < len; a++) {
|
||||||
if (getDataFieldOfObject(rxBucket[i].type, rxBucket[i].index, (buffer[a] - 52) + 4) != pXSprite->data3)
|
if (getDataFieldOfObject(rxBucket[i].type, rxBucket[i].index, (buffer[a] - 52) + 4) != pXSprite->data3)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pXRedir == NULL) return true;
|
XSPRITE* pXRedir = NULL; // check redirected TX buckets
|
||||||
else if (txIsRanged(pXRedir)) {
|
while ((pXRedir = evrListRedirectors(OBJ_SPRITE, sprite[pXSprite->reference].extra, pXRedir, &rx)) != NULL) {
|
||||||
if (!channelRangeIsFine(pXRedir->data4 - pXRedir->data1)) return false;
|
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
||||||
for (rx = pXRedir->data1; rx <= pXRedir->data4; rx++) {
|
for (int a = 0; a < len; a++) {
|
||||||
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
if (getDataFieldOfObject(rxBucket[i].type, rxBucket[i].index, (buffer[a] - 52) + 4) != pXSprite->data3)
|
||||||
for (int a = 0; a < len; i++) {
|
return false;
|
||||||
if (getDataFieldOfObject(rxBucket[i].type, rxBucket[i].index, (buffer[a] - 52) + 4) != pXSprite->data3)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i <= 3; i++) {
|
|
||||||
if (!channelRangeIsFine((rx = GetDataVal(&sprite[pXRedir->reference], i)))) continue;
|
|
||||||
for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) {
|
|
||||||
for (int a = 0; a < len; a++) {
|
|
||||||
if (getDataFieldOfObject(rxBucket[i].type, rxBucket[i].index, (buffer[a] - 52) + 4) != pXSprite->data3)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// this function can be called via sending numbered command to TX kChannelModernEndLevelCustom
|
// this function can be called via sending numbered command to TX kChannelModernEndLevelCustom
|
||||||
// it allows to set custom next level instead of taking it from INI file.
|
// it allows to set custom next level instead of taking it from INI file.
|
||||||
void levelEndLevelCustom(int nLevel) {
|
void levelEndLevelCustom(int nLevel) {
|
||||||
|
|
|
@ -328,7 +328,6 @@ void windGenStopWindOnSectors(XSPRITE* pXSource);
|
||||||
int getSpriteMassBySize(spritetype* pSprite);
|
int getSpriteMassBySize(spritetype* pSprite);
|
||||||
bool ceilIsTooLow(spritetype* pSprite);
|
bool ceilIsTooLow(spritetype* pSprite);
|
||||||
void levelEndLevelCustom(int nLevel);
|
void levelEndLevelCustom(int nLevel);
|
||||||
XSPRITE* eventRedirected(int objType, int objXIndex, bool byRx);
|
|
||||||
bool useCondition(XSPRITE* pXSource, EVENT event);
|
bool useCondition(XSPRITE* pXSource, EVENT event);
|
||||||
bool condPush(XSPRITE* pXSprite, int objType, int objIndex);
|
bool condPush(XSPRITE* pXSprite, int objType, int objIndex);
|
||||||
bool condRestore(XSPRITE* pXSprite);
|
bool condRestore(XSPRITE* pXSprite);
|
||||||
|
@ -339,6 +338,9 @@ bool condCheckSector(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS);
|
||||||
bool condCheckWall(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS);
|
bool condCheckWall(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS);
|
||||||
bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS);
|
bool condCheckSprite(XSPRITE* pXCond, int cmpOp, bool PUSH, bool RVRS);
|
||||||
void condUpdateObjectIndex(int objType, int oldIndex, int newIndex);
|
void condUpdateObjectIndex(int objType, int oldIndex, int newIndex);
|
||||||
|
XSPRITE* evrListRedirectors(int objType, int objXIndex, XSPRITE* pXRedir, int* tx);
|
||||||
|
XSPRITE* evrIsRedirector(int nSprite);
|
||||||
|
int listTx(XSPRITE* pXRedir, int tx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -332,8 +332,19 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
||||||
spritetype *pSprite = &sprite[nSprite];
|
spritetype *pSprite = &sprite[nSprite];
|
||||||
|
|
||||||
#ifdef NOONE_EXTENSIONS
|
#ifdef NOONE_EXTENSIONS
|
||||||
if (gModernMap && modernTypeOperateSprite(nSprite, pSprite, pXSprite, event))
|
if (gModernMap && modernTypeOperateSprite(nSprite, pSprite, pXSprite, event))
|
||||||
|
return;
|
||||||
|
switch (event.cmd) {
|
||||||
|
case kCmdLock:
|
||||||
|
pXSprite->locked = 1;
|
||||||
return;
|
return;
|
||||||
|
case kCmdUnlock:
|
||||||
|
pXSprite->locked = 0;
|
||||||
|
return;
|
||||||
|
case kCmdToggleLock:
|
||||||
|
pXSprite->locked = pXSprite->locked ^ 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
switch (event.cmd) {
|
switch (event.cmd) {
|
||||||
case kCmdLock:
|
case kCmdLock:
|
||||||
|
|
Loading…
Reference in a new issue