mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-18 23:21:43 +00:00
- Rewrite true random once again
- Fix Custom Dude genIdle aistate - Fix grown and shrink races - Fix qav scene was not able to stop if sprite is locked - Fix stupid error in gDefaultJump array # Conflicts: # source/blood/src/actor.cpp # source/blood/src/view.cpp
This commit is contained in:
parent
1eb50414ab
commit
ec782a28de
12 changed files with 144 additions and 178 deletions
|
@ -3109,24 +3109,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
||||||
int nXSprite = pSprite->extra;
|
int nXSprite = pSprite->extra;
|
||||||
dassert(nXSprite > 0);
|
dassert(nXSprite > 0);
|
||||||
XSPRITE *pXSprite = &xsprite[pSprite->extra];
|
XSPRITE *pXSprite = &xsprite[pSprite->extra];
|
||||||
|
|
||||||
// kMaxSprites - 1 = custom dude had once life leech
|
|
||||||
if (pSprite->owner >= 0 && pSprite->owner != (kMaxSprites - 1)) {
|
|
||||||
switch (sprite[pSprite->owner].type) {
|
|
||||||
case kDudeModernCustom:
|
|
||||||
case kDudeModernCustomBurning:
|
|
||||||
for (int i = 0; i <= gGameOptions.nDifficulty; i++) {
|
|
||||||
if (!IsDudeSprite(pSprite) || gGenDudeExtra[pSprite->owner].slave[i] == pSprite->index || pXSprite->health <= 0) {
|
|
||||||
gGenDudeExtra[pSprite->owner].slave[i] = -1;
|
|
||||||
gGenDudeExtra[pSprite->owner].slaveCount = ClipRange(gGenDudeExtra[pSprite->owner].slaveCount - 1, 0, gGameOptions.nDifficulty + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
switch (pSprite->type) {
|
switch (pSprite->type) {
|
||||||
case kDudeModernCustom: {
|
case kDudeModernCustom: {
|
||||||
|
|
||||||
|
@ -7355,43 +7338,55 @@ int GetDataVal(spritetype* pSprite, int data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// tries to get random data field of sprite
|
// tries to get random data field of sprite
|
||||||
int GetRandDataVal(int *rData) {
|
int GetRandDataVal(XSPRITE* pXSprite, int randType) {
|
||||||
dassert(rData != NULL);
|
if (pXSprite == NULL) return -1;
|
||||||
int random = 0, a = 0; int first = -1; int maxRetries = 10;
|
int random = 0; int bad = 0; int maxRetries = 10;
|
||||||
|
|
||||||
// randomize only in case if at least 2 data fields are not empty
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
if (rData[i] <= 0 && a++ > 1) return -1;
|
|
||||||
else if (first == -1) first = rData[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int rData[4];
|
||||||
|
rData[0] = pXSprite->data1; rData[2] = pXSprite->data3;
|
||||||
|
rData[1] = pXSprite->data2; rData[3] = pXSprite->data4;
|
||||||
|
// randomize only in case if at least 2 data fields fits.
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
switch (randType) {
|
||||||
|
case kRandomizeItem:
|
||||||
|
if (rData[i] >= kItemWeaponBase && rData[i] < kItemMax) break;
|
||||||
|
else bad++;
|
||||||
|
break;
|
||||||
|
case kRandomizeDude:
|
||||||
|
if (rData[i] >= kDudeBase && rData[i] < kDudeMax) break;
|
||||||
|
else bad++;
|
||||||
|
break;
|
||||||
|
case kRandomizeTX:
|
||||||
|
if (rData[i] > kChannelZero && rData[i] < kChannelUserMax) break;
|
||||||
|
else bad++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bad++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bad < 3) {
|
||||||
// try randomize few times
|
// try randomize few times
|
||||||
while (maxRetries > 0) {
|
while (maxRetries > 0) {
|
||||||
// use true random only for single player mode, otherwise use Blood's default one.
|
// use true random only for single player mode, otherwise use Blood's default one.
|
||||||
random = (gGameOptions.nGameType == 0 && !VanillaMode() && !DemoRecordStatus()) ? STD_Random(0, 3) : Random(3);
|
random = (gGameOptions.nGameType == 0 && !VanillaMode() && !DemoRecordStatus()) ? STD_Random(0, 3) : Random(3);
|
||||||
if (rData[random] > 0) return rData[random];
|
if (rData[random] > 0) return rData[random];
|
||||||
else maxRetries--;
|
maxRetries--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if nothing, get first found data value from top
|
return -1;
|
||||||
return first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function drops random item using random pickup generator(s)
|
// this function drops random item using random pickup generator(s)
|
||||||
spritetype* DropRandomPickupObject(spritetype* pSprite, short prevItem) {
|
spritetype* DropRandomPickupObject(spritetype* pSource, short prevItem) {
|
||||||
spritetype* pSprite2 = NULL; int rData[4]; int selected = -1;
|
spritetype* pSprite2 = NULL; int selected = -1; int maxRetries = 9;
|
||||||
if (xspriData2Array(pSprite->extra,rData)) {
|
if (xspriRangeIsFine(pSource->extra)) {
|
||||||
|
XSPRITE* pXSource = &xsprite[pSource->extra];
|
||||||
// randomize only in case if at least 2 data fields fits.
|
while ((selected = GetRandDataVal(pXSource, kRandomizeItem)) == prevItem) if (maxRetries-- <= 0) break;
|
||||||
for (int i = 0; i <= 3; i++)
|
|
||||||
if (rData[i] < kItemWeaponBase || rData[i] >= kItemMax)
|
|
||||||
rData[i] = 0;
|
|
||||||
|
|
||||||
int maxRetries = 9;
|
|
||||||
while ((selected = GetRandDataVal(rData)) == prevItem) if (maxRetries-- <= 0) break;
|
|
||||||
if (selected > 0) {
|
if (selected > 0) {
|
||||||
spritetype* pSource = pSprite; XSPRITE* pXSource = &xsprite[pSource->extra];
|
pSprite2 = actDropObject(pSource, selected);
|
||||||
pSprite2 = actDropObject(pSprite, selected);
|
|
||||||
if (pSprite2 != NULL) {
|
if (pSprite2 != NULL) {
|
||||||
|
|
||||||
pXSource->dropMsg = pSprite2->type; // store dropped item type in dropMsg
|
pXSource->dropMsg = pSprite2->type; // store dropped item type in dropMsg
|
||||||
|
@ -7415,23 +7410,17 @@ spritetype* DropRandomPickupObject(spritetype* pSprite, short prevItem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pSprite2;
|
return pSprite2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function spawns random dude using dudeSpawn
|
// this function spawns random dude using dudeSpawn
|
||||||
spritetype* spawnRandomDude(spritetype* pSprite) {
|
spritetype* spawnRandomDude(spritetype* pSource) {
|
||||||
spritetype* pSprite2 = NULL; int rData[4]; int selected = -1;
|
spritetype* pSprite2 = NULL; int selected = -1;
|
||||||
if (xspriData2Array(pSprite->extra, rData)) {
|
if (xspriRangeIsFine(pSource->extra)) {
|
||||||
// randomize only in case if at least 2 data fields fits.
|
XSPRITE* pXSource = &xsprite[pSource->extra];
|
||||||
for (int i = 0; i <= 3; i++)
|
if ((selected = GetRandDataVal(pXSource, kRandomizeDude)) > 0)
|
||||||
if (rData[i] < kDudeBase || rData[i] >= kDudeMax)
|
pSprite2 = actSpawnDude(pSource, selected, -1, 0);
|
||||||
rData[i] = 0;
|
|
||||||
|
|
||||||
if ((selected = GetRandDataVal(rData)) > 0)
|
|
||||||
pSprite2 = actSpawnDude(pSprite, selected, -1, 0);
|
|
||||||
}
|
}
|
||||||
return pSprite2;
|
return pSprite2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,12 @@ enum VECTOR_TYPE {
|
||||||
kVectorMax,
|
kVectorMax,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kRandomizeItem = 0,
|
||||||
|
kRandomizeDude = 1,
|
||||||
|
kRandomizeTX = 2,
|
||||||
|
};
|
||||||
|
|
||||||
struct THINGINFO
|
struct THINGINFO
|
||||||
{
|
{
|
||||||
short startHealth;
|
short startHealth;
|
||||||
|
@ -269,7 +275,7 @@ void MakeSplash(spritetype *pSprite, XSPRITE *pXSprite);
|
||||||
spritetype* DropRandomPickupObject(spritetype* pSprite, short prevItem);
|
spritetype* DropRandomPickupObject(spritetype* pSprite, short prevItem);
|
||||||
spritetype* spawnRandomDude(spritetype* pSprite);
|
spritetype* spawnRandomDude(spritetype* pSprite);
|
||||||
int GetDataVal(spritetype* pSprite, int data);
|
int GetDataVal(spritetype* pSprite, int data);
|
||||||
int GetRandDataVal(int *rData);
|
int GetRandDataVal(XSPRITE* pXSprite, int randType);
|
||||||
bool sfxPlayMissileSound(spritetype* pSprite, int missileId);
|
bool sfxPlayMissileSound(spritetype* pSprite, int missileId);
|
||||||
bool sfxPlayVectorSound(spritetype* pSprite, int vectorId);
|
bool sfxPlayVectorSound(spritetype* pSprite, int vectorId);
|
||||||
spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist);
|
spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist);
|
||||||
|
|
|
@ -79,7 +79,15 @@ AISTATE genRecoil = {kAiStateRecoil, 5, -1, 20, NULL, NULL, NULL, &genIdle };
|
||||||
int dword_138BB0[5] = {0x2000, 0x4000, 0x8000, 0xa000, 0xe000};
|
int dword_138BB0[5] = {0x2000, 0x4000, 0x8000, 0xa000, 0xe000};
|
||||||
|
|
||||||
void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) {
|
void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) {
|
||||||
aiNewState(pSprite, pXSprite, &genIdle);
|
switch (pSprite->type) {
|
||||||
|
case kDudeModernCustom:
|
||||||
|
case kDudeModernCustomBurning:
|
||||||
|
aiGenDudeNewState(pSprite, &genIdle);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
aiNewState(pSprite, pXSprite, &genIdle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sub_5BDA8(spritetype *pSprite, int nSeq)
|
bool sub_5BDA8(spritetype *pSprite, int nSeq)
|
||||||
|
|
|
@ -237,18 +237,16 @@ static void genDudeAttack1(int, int nXIndex) {
|
||||||
consoleSysMsg("nIndex >= 0 && nIndex < kMaxSprites");
|
consoleSysMsg("nIndex >= 0 && nIndex < kMaxSprites");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dx, dy, dz; spritetype* pSprite = &sprite[nSprite];
|
int dx, dy, dz; spritetype* pSprite = &sprite[nSprite];
|
||||||
xvel[pSprite->index] = yvel[pSprite->index] = 0;
|
xvel[pSprite->index] = yvel[pSprite->index] = 0;
|
||||||
|
|
||||||
short dispersion = gGenDudeExtra[nSprite].baseDispersion;
|
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
|
||||||
|
short dispersion = pExtra->baseDispersion;
|
||||||
if (inDuck(pXSprite->aiState))
|
if (inDuck(pXSprite->aiState))
|
||||||
dispersion = ClipLow(dispersion >> 1, kGenDudeMinDispesion);
|
dispersion = ClipLow(dispersion >> 1, kGenDudeMinDispesion);
|
||||||
|
|
||||||
//short dispersion = 1;
|
if (pExtra->weaponType == kGenDudeWeaponHitscan) {
|
||||||
|
|
||||||
short curWeapon = gGenDudeExtra[nSprite].curWeapon; short weaponType = gGenDudeExtra[nSprite].weaponType;
|
|
||||||
if (weaponType == kGenDudeWeaponHitscan) {
|
|
||||||
|
|
||||||
dx = Cos(pSprite->ang) >> 16; dy = Sin(pSprite->ang) >> 16; dz = gDudeSlope[nXIndex];
|
dx = Cos(pSprite->ang) >> 16; dy = Sin(pSprite->ang) >> 16; dz = gDudeSlope[nXIndex];
|
||||||
// dispersal modifiers here in case if non-melee enemy
|
// dispersal modifiers here in case if non-melee enemy
|
||||||
|
@ -256,42 +254,40 @@ static void genDudeAttack1(int, int nXIndex) {
|
||||||
dx += Random3(dispersion); dy += Random3(dispersion); dz += Random3(dispersion);
|
dx += Random3(dispersion); dy += Random3(dispersion); dz += Random3(dispersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
actFireVector(pSprite, 0, 0, dx, dy, dz,(VECTOR_TYPE)curWeapon);
|
actFireVector(pSprite, 0, 0, dx, dy, dz,(VECTOR_TYPE)pExtra->curWeapon);
|
||||||
if (!playGenDudeSound(pSprite, kGenDudeSndAttackNormal))
|
if (!playGenDudeSound(pSprite, kGenDudeSndAttackNormal))
|
||||||
sfxPlayVectorSound(pSprite, curWeapon);
|
sfxPlayVectorSound(pSprite, pExtra->curWeapon);
|
||||||
|
|
||||||
} else if (weaponType == kGenDudeWeaponSummon) {
|
} else if (pExtra->weaponType == kGenDudeWeaponSummon) {
|
||||||
|
|
||||||
spritetype* pSpawned = NULL; int dist = pSprite->clipdist << 4;
|
spritetype* pSpawned = NULL; int dist = pSprite->clipdist << 4;
|
||||||
short slaveCnt = gGenDudeExtra[pSprite->index].slaveCount;
|
if (pExtra->slaveCount <= gGameOptions.nDifficulty) {
|
||||||
if (slaveCnt <= gGameOptions.nDifficulty && (pSpawned = actSpawnDude(pSprite, curWeapon, dist + Random(dist), 0)) != NULL) {
|
if ((pSpawned = actSpawnDude(pSprite, pExtra->curWeapon, dist + Random(dist), 0)) != NULL) {
|
||||||
|
pSpawned->owner = nSprite;
|
||||||
pSpawned->owner = nSprite;
|
|
||||||
|
|
||||||
if (pSpawned->extra > -1) {
|
|
||||||
xsprite[pSpawned->extra].target = pXSprite->target;
|
|
||||||
if (pXSprite->target > -1)
|
|
||||||
aiActivateDude(pSpawned, &xsprite[pSpawned->extra]);
|
|
||||||
}
|
|
||||||
|
|
||||||
gKillMgr.sub_263E0(1);
|
|
||||||
gGenDudeExtra[pSprite->index].slave[slaveCnt] = pSpawned->index;
|
|
||||||
gGenDudeExtra[pSprite->index].slaveCount++;
|
|
||||||
|
|
||||||
if (!playGenDudeSound(pSprite, kGenDudeSndAttackNormal))
|
if (xspriRangeIsFine(pSpawned->extra)) {
|
||||||
sfxPlay3DSoundCP(pSprite, 379, 1, 0, 0x10000 - Random3(0x3000));
|
xsprite[pSpawned->extra].target = pXSprite->target;
|
||||||
|
if (pXSprite->target > -1)
|
||||||
|
aiActivateDude(pSpawned, &xsprite[pSpawned->extra]);
|
||||||
|
}
|
||||||
|
|
||||||
|
gKillMgr.sub_263E0(1);
|
||||||
|
pExtra->slave[pExtra->slaveCount++] = pSpawned->index;
|
||||||
|
if (!playGenDudeSound(pSprite, kGenDudeSndAttackNormal))
|
||||||
|
sfxPlay3DSoundCP(pSprite, 379, 1, 0, 0x10000 - Random3(0x3000));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (weaponType == kGenDudeWeaponMissile) {
|
} else if (pExtra->weaponType == kGenDudeWeaponMissile) {
|
||||||
|
|
||||||
dx = Cos(pSprite->ang) >> 16; dy = Sin(pSprite->ang) >> 16; dz = gDudeSlope[nXIndex];
|
dx = Cos(pSprite->ang) >> 16; dy = Sin(pSprite->ang) >> 16; dz = gDudeSlope[nXIndex];
|
||||||
|
|
||||||
// dispersal modifiers here
|
// dispersal modifiers here
|
||||||
dx += Random3(dispersion); dy += Random3(dispersion); dz += Random3(dispersion >> 1);
|
dx += Random3(dispersion); dy += Random3(dispersion); dz += Random3(dispersion >> 1);
|
||||||
|
|
||||||
actFireMissile(pSprite, 0, 0, dx, dy, dz, curWeapon);
|
actFireMissile(pSprite, 0, 0, dx, dy, dz, pExtra->curWeapon);
|
||||||
if (!playGenDudeSound(pSprite, kGenDudeSndAttackNormal))
|
if (!playGenDudeSound(pSprite, kGenDudeSndAttackNormal))
|
||||||
sfxPlayMissileSound(pSprite, curWeapon);
|
sfxPlayMissileSound(pSprite, pExtra->curWeapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1124,14 +1120,14 @@ void aiGenDudeNewState(spritetype* pSprite, AISTATE* pAIState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pXSprite->stateTimer = pAIState->stateTicks; pXSprite->aiState = pAIState;
|
pXSprite->stateTimer = pAIState->stateTicks; pXSprite->aiState = pAIState;
|
||||||
int seqStartId = pXSprite->data2;
|
|
||||||
|
int stateSeq = pXSprite->data2 + pAIState->seqId;
|
||||||
if (pAIState->seqId >= 0 && gSysRes.Lookup((seqStartId += pAIState->seqId), "SEQ"))
|
if (pAIState->seqId >= 0 && gSysRes.Lookup(stateSeq, "SEQ")) {
|
||||||
seqSpawn(seqStartId, 3, pSprite->extra, pAIState->funcId);
|
seqSpawn(stateSeq, 3, pSprite->extra, pAIState->funcId);
|
||||||
|
}
|
||||||
|
|
||||||
if (pAIState->enterFunc)
|
if (pAIState->enterFunc)
|
||||||
pAIState->enterFunc(pSprite, pXSprite);
|
pAIState->enterFunc(pSprite, pXSprite);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1665,41 +1661,38 @@ void updateTargetOfLeech(spritetype* pSprite) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTargetOfSlaves(spritetype* pSprite) {
|
void updateTargetOfSlaves(spritetype* pSprite) {
|
||||||
if (!(pSprite->extra >= 0 && pSprite->extra < kMaxXSprites)) {
|
if (!xspriRangeIsFine(pSprite->extra)) {
|
||||||
consoleSysMsg("pSprite->extra >= 0 && pSprite->extra < kMaxXSprites");
|
consoleSysMsg("!xspriRangeIsFine(pSprite->extra)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
XSPRITE* pXSprite = &xsprite[pSprite->extra];
|
|
||||||
|
|
||||||
short* slave = gGenDudeExtra[pSprite->index].slave;
|
XSPRITE* pXSprite = &xsprite[pSprite->extra];
|
||||||
|
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); short* slave = pExtra->slave;
|
||||||
spritetype* pTarget = (pXSprite->target >= 0 && IsDudeSprite(&sprite[pXSprite->target])) ? &sprite[pXSprite->target] : NULL;
|
spritetype* pTarget = (pXSprite->target >= 0 && IsDudeSprite(&sprite[pXSprite->target])) ? &sprite[pXSprite->target] : NULL;
|
||||||
XSPRITE* pXTarget = (pTarget != NULL && pTarget->extra >= 0 && xsprite[pTarget->extra].health > 0) ? &xsprite[pTarget->extra] : NULL;
|
XSPRITE* pXTarget = (pTarget != NULL && xspriRangeIsFine(pTarget->extra) && xsprite[pTarget->extra].health > 0) ? &xsprite[pTarget->extra] : NULL;
|
||||||
|
|
||||||
|
int newCnt = pExtra->slaveCount;
|
||||||
for (int i = 0; i <= gGameOptions.nDifficulty; i++) {
|
for (int i = 0; i <= gGameOptions.nDifficulty; i++) {
|
||||||
if (slave[i] >= 0) {
|
if (spriRangeIsFine(slave[i])) {
|
||||||
spritetype* pSlave = &sprite[slave[i]];
|
spritetype* pSlave = &sprite[slave[i]];
|
||||||
if (!IsDudeSprite(pSlave) || pSlave->extra < 0 || xsprite[pSlave->extra].health < 0) {
|
if (!IsDudeSprite(pSlave) || !xspriRangeIsFine(pSlave->extra) || xsprite[pSlave->extra].health < 0) {
|
||||||
slave[i] = -1;
|
slave[i] = pSlave->owner = -1; newCnt--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
XSPRITE* pXSlave = &xsprite[pSlave->index];
|
XSPRITE* pXSlave = &xsprite[pSlave->index];
|
||||||
if (pXTarget == NULL) aiSetTarget(pXSlave, pSprite->x, pSprite->y, pSprite->z); // try return to master
|
if (pXTarget != NULL) {
|
||||||
else if (pXSprite->target != pXSlave->target)
|
if (pXSprite->target != pXSlave->target) aiSetTarget(pXSlave, pXSprite->target);
|
||||||
aiSetTarget(pXSlave, pXSprite->target);
|
// check if slave have proper target
|
||||||
|
if (!spriRangeIsFine(pXSlave->target) || sprite[pXSlave->target].owner == pSprite->index)
|
||||||
// check if slave attacking another slave
|
aiSetTarget(pXSlave, pSprite->x, pSprite->y, pSprite->z);
|
||||||
if (pXSlave->target >= 0) {
|
|
||||||
if (sprite[pXSlave->target].owner == pSprite->index)
|
|
||||||
aiSetTarget(pXSlave, pSprite->x, pSprite->y, pSprite->z); // try return to master
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// try return to master
|
aiSetTarget(pXSlave, pSprite->x, pSprite->y, pSprite->z); // try return to master
|
||||||
aiSetTarget(pXSlave, pSprite->x, pSprite->y, pSprite->z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pExtra->slaveCount = newCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
short inDodge(AISTATE* aiState) {
|
short inDodge(AISTATE* aiState) {
|
||||||
|
@ -1933,7 +1926,7 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
|
||||||
case kGenDudeSeqMoveD:
|
case kGenDudeSeqMoveD:
|
||||||
case kGenDudeSeqDeathBurn2:
|
case kGenDudeSeqDeathBurn2:
|
||||||
case kGenDudeSeqIdleW:
|
case kGenDudeSeqIdleW:
|
||||||
continue;
|
break;
|
||||||
case kGenDudeSeqReserved3:
|
case kGenDudeSeqReserved3:
|
||||||
case kGenDudeSeqReserved4:
|
case kGenDudeSeqReserved4:
|
||||||
case kGenDudeSeqReserved5:
|
case kGenDudeSeqReserved5:
|
||||||
|
@ -1967,8 +1960,8 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
|
||||||
case kGenDudePropertySlaves:
|
case kGenDudePropertySlaves:
|
||||||
pExtra->slaveCount = 0; memset(pExtra->slave, -1, sizeof(pExtra->slave));
|
pExtra->slaveCount = 0; memset(pExtra->slave, -1, sizeof(pExtra->slave));
|
||||||
for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
||||||
if (sprite[nSprite].owner != pSprite->xvel) continue;
|
if (sprite[nSprite].owner != pSprite->index) continue;
|
||||||
else if (!IsDudeSprite(&sprite[nSprite]) || sprite[nSprite].extra < 0 || xsprite[sprite[nSprite].extra].health <= 0) {
|
else if (!IsDudeSprite(&sprite[nSprite]) || !xspriRangeIsFine(sprite[nSprite].extra) || xsprite[sprite[nSprite].extra].health <= 0) {
|
||||||
sprite[nSprite].owner = -1;
|
sprite[nSprite].owner = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,8 +178,9 @@ struct GENDUDEEXTRA {
|
||||||
|
|
||||||
extern GENDUDEEXTRA gGenDudeExtra[];
|
extern GENDUDEEXTRA gGenDudeExtra[];
|
||||||
|
|
||||||
inline GENDUDEEXTRA* genDudeExtra(spritetype* pSprite) {
|
inline GENDUDEEXTRA* genDudeExtra(spritetype* pGenDude) {
|
||||||
return &gGenDudeExtra[pSprite->index];
|
dassert(spriRangeIsFine(pGenDude->index));
|
||||||
|
return &gGenDudeExtra[pGenDude->index];
|
||||||
}
|
}
|
||||||
|
|
||||||
XSPRITE* getNextIncarnation(XSPRITE* pXSprite);
|
XSPRITE* getNextIncarnation(XSPRITE* pXSprite);
|
||||||
|
|
|
@ -67,6 +67,7 @@ kChannelRemoteBomb5,
|
||||||
kChannelRemoteBomb6,
|
kChannelRemoteBomb6,
|
||||||
kChannelRemoteBomb7,
|
kChannelRemoteBomb7,
|
||||||
kChannelUser = 100,
|
kChannelUser = 100,
|
||||||
|
kChannelUserMax = 1024,
|
||||||
kChannelMax = 4096,
|
kChannelMax = 4096,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -917,23 +917,12 @@ int picHeight(short nPic, short repeat) {
|
||||||
return ClipLow((tilesiz[nPic].y * repeat) << 2, 0);
|
return ClipLow((tilesiz[nPic].y * repeat) << 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool xspriData2Array(int nXSprite, int* rData) {
|
|
||||||
if (xspriRangeIsFine(nXSprite) && rData) {
|
|
||||||
rData[0] = xsprite[nXSprite].data1; rData[2] = xsprite[nXSprite].data3;
|
|
||||||
rData[1] = xsprite[nXSprite].data2; rData[3] = xsprite[nXSprite].data4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// by NoOne: used for better randomness in single player
|
// by NoOne: used for better randomness in single player
|
||||||
int STD_Random(int a, int b) {
|
int STD_Random(int a, int b) {
|
||||||
|
std::default_random_engine stdRandom;
|
||||||
std::default_random_engine rng;
|
stdRandom.seed(std::random_device()());
|
||||||
rng.seed(std::random_device()());
|
|
||||||
std::uniform_int_distribution<int> dist_a_b(a, b);
|
std::uniform_int_distribution<int> dist_a_b(a, b);
|
||||||
return dist_a_b(rng);
|
return dist_a_b(stdRandom);
|
||||||
}
|
}
|
||||||
|
|
||||||
END_BLD_NS
|
END_BLD_NS
|
||||||
|
|
|
@ -85,7 +85,6 @@ int GetClosestSectors(int nSector, int x, int y, int nDist, short *pSectors, cha
|
||||||
int GetClosestSpriteSectors(int nSector, int x, int y, int nDist, short *pSectors, char *pSectBit, short *a8);
|
int GetClosestSpriteSectors(int nSector, int x, int y, int nDist, short *pSectors, char *pSectBit, short *a8);
|
||||||
int picWidth(short nPic, short repeat);
|
int picWidth(short nPic, short repeat);
|
||||||
int picHeight(short nPic, short repeat);
|
int picHeight(short nPic, short repeat);
|
||||||
bool xspriData2Array(int nXSprite, int* rData);
|
|
||||||
int STD_Random(int a, int b);
|
int STD_Random(int a, int b);
|
||||||
|
|
||||||
END_BLD_NS
|
END_BLD_NS
|
||||||
|
|
|
@ -133,20 +133,20 @@ int gDefaultAccel[] = {
|
||||||
// shrink human
|
// shrink human
|
||||||
10384, 2108, 2192, // stand (front, side, back) / swim (front, side, back) / crouch (front, side, back)
|
10384, 2108, 2192, // stand (front, side, back) / swim (front, side, back) / crouch (front, side, back)
|
||||||
// grown human
|
// grown human
|
||||||
19384, 5608, 11192 // stand (front, side, back) / swim (front, side, back) / crouch (front, side, back)
|
19384, 5608, 11192, // stand (front, side, back) / swim (front, side, back) / crouch (front, side, back)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int gDefaultJumpZ[] = {
|
int gDefaultJumpZ[] = {
|
||||||
|
|
||||||
// normal human
|
// normal human
|
||||||
-0xbaaaa, -0x175555, 0x5b05, 0, 0, 0 // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
|
-0xbaaaa, -0x175555, 0x5b05, 0, 0, 0, // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
|
||||||
// normal beast
|
// normal beast
|
||||||
-0xbaaaa, -0x175555, 0x5b05, 0, 0, 0 // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
|
-0xbaaaa, -0x175555, 0x5b05, 0, 0, 0, // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
|
||||||
// shrink human
|
// shrink human
|
||||||
-200000, -0x175555, 0x5b05, 0, 0, 0 // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
|
-564586, -1329173, 0x5b05, 0, 0, 0, // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
|
||||||
// grown human
|
// grown human
|
||||||
-250000, -0x175555, 0x5b05, 0, 0, 0 // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
|
-1014586, -1779173, 0x5b05, 0, 0, 0, // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1183,17 +1183,19 @@ void playerReset(PLAYER *pPlayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerResetMoveSpeed(PLAYER* pPlayer) {
|
void playerResetMoveSpeed(PLAYER* pPlayer) {
|
||||||
for (int i = 0, k = 0; i < 4; i++) {
|
for (int i = kModeHuman, k = 0; i < kModeMax; i++) {
|
||||||
for (int a = 0; a < 3; a++, k++)
|
for (int a = kPostureStand; a < kPostureMax; a++, k++)
|
||||||
gPosture[i][a].frontAccel = gPosture[i][a].sideAccel = gPosture[i][a].backAccel = gDefaultAccel[k];
|
gPosture[i][a].frontAccel = gPosture[i][a].sideAccel = gPosture[i][a].backAccel = gDefaultAccel[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerResetJumpHeight(PLAYER* pPlayer) {
|
void playerResetJumpHeight(PLAYER* pPlayer) {
|
||||||
for (int i = 0, k = 0; i < 4; i++) {
|
for (int i = kModeHuman, k = 0; i < kModeMax; i++) {
|
||||||
for (int a = 0; a < 3; a++) {
|
for (int a = kPostureStand; a < kPostureMax; a++) {
|
||||||
|
|
||||||
gPosture[i][a].normalJumpZ = gDefaultJumpZ[k++];
|
gPosture[i][a].normalJumpZ = gDefaultJumpZ[k++];
|
||||||
gPosture[i][a].pwupJumpZ = gDefaultJumpZ[k++];
|
gPosture[i][a].pwupJumpZ = gDefaultJumpZ[k++];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1787,17 +1789,11 @@ void ProcessInput(PLAYER *pPlayer)
|
||||||
default:
|
default:
|
||||||
if (!pPlayer->cantJump && pInput->buttonFlags.jump && pXSprite->height == 0) {
|
if (!pPlayer->cantJump && pInput->buttonFlags.jump && pXSprite->height == 0) {
|
||||||
sfxPlay3DSound(pSprite, 700, 0, 0);
|
sfxPlay3DSound(pSprite, 700, 0, 0);
|
||||||
if (packItemActive(pPlayer, 4)) zvel[nSprite] = pPosture->pwupJumpZ;// -0x175555;
|
if (packItemActive(pPlayer, 4)) zvel[nSprite] = pPosture->pwupJumpZ; //-0x175555;
|
||||||
else zvel[nSprite] = pPosture->normalJumpZ;//-0xbaaaa;
|
else zvel[nSprite] = pPosture->normalJumpZ; //-0xbaaaa;
|
||||||
|
|
||||||
|
|
||||||
if (isShrinked(pPlayer->pSprite)) zvel[nSprite] -= gPosture[kModeHumanShrink][pPlayer->posture].normalJumpZ;//-200000;
|
|
||||||
else if (isGrown(pPlayer->pSprite)) zvel[nSprite] += gPosture[kModeHumanGrown][pPlayer->posture].normalJumpZ; //-250000;
|
|
||||||
|
|
||||||
pPlayer->cantJump = 1;
|
pPlayer->cantJump = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pInput->buttonFlags.crouch)
|
if (pInput->buttonFlags.crouch)
|
||||||
pPlayer->posture = 2;
|
pPlayer->posture = 2;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -462,21 +462,14 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
while (maxRetries > 0) {
|
||||||
int rData[4];
|
if ((tx = GetRandDataVal(pXSprite, kRandomizeTX)) > 0 && tx != pXSprite->txID) break;
|
||||||
if (xspriData2Array(pSprite->extra, rData)) {
|
maxRetries--;
|
||||||
while (maxRetries > 0) {
|
|
||||||
if ((tx = GetRandDataVal(rData)) > 0 && tx != pXSprite->txID) break;
|
|
||||||
maxRetries--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx > 0) {
|
pXSprite->txID = (tx > 0 && tx < kChannelUserMax) ? tx : 0;
|
||||||
pXSprite->txID = tx;
|
SetSpriteState(nSprite, pXSprite, pXSprite->state ^ 1, event.causedBy);
|
||||||
SetSpriteState(nSprite, pXSprite, pXSprite->state ^ 1, event.causedBy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -569,7 +562,7 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pXSprite->txID = tx;
|
pXSprite->txID = (tx > 0 && tx < kChannelUserMax) ? tx : 0;
|
||||||
SetSpriteState(nSprite, pXSprite, pXSprite->state ^ 1, event.causedBy);
|
SetSpriteState(nSprite, pXSprite, pXSprite->state ^ 1, event.causedBy);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -3695,12 +3688,11 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
|
||||||
/* 4: follow player(s) when no targets in sight, attack targets if any in sight - */
|
/* 4: follow player(s) when no targets in sight, attack targets if any in sight - */
|
||||||
|
|
||||||
if (type != 3) return;
|
if (type != 3) return;
|
||||||
else if (!IsDudeSprite(&sprite[nDest]) && sprite[nDest].statnum != kStatDude && xsprite[sprite[nDest].extra].data3 != 0) {
|
else if (!IsDudeSprite(&sprite[nDest]) && sprite[nDest].statnum != kStatDude) {
|
||||||
switch (sprite[nDest].type) { // can be dead dude turned in gib
|
switch (sprite[nDest].type) { // can be dead dude turned in gib
|
||||||
// make current target and all other dudes not attack this dude anymore
|
// make current target and all other dudes not attack this dude anymore
|
||||||
case kThingBloodBits:
|
case kThingBloodBits:
|
||||||
case kThingBloodChunks:
|
case kThingBloodChunks:
|
||||||
xsprite[sprite[nDest].extra].data3 = 0;
|
|
||||||
freeTargets(nDest);
|
freeTargets(nDest);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
@ -3713,8 +3705,9 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
|
||||||
DUDEINFO* pDudeInfo = &dudeInfo[pSprite->type - kDudeBase]; int matesPerEnemy = 1;
|
DUDEINFO* pDudeInfo = &dudeInfo[pSprite->type - kDudeBase]; int matesPerEnemy = 1;
|
||||||
|
|
||||||
// dude is burning?
|
// dude is burning?
|
||||||
if (pXSprite->burnTime > 0 && pXSprite->burnSource >= 0 && pXSprite->burnSource < kMaxSprites) {
|
if (pXSprite->burnTime > 0 && spriRangeIsFine(pXSprite->burnSource)) {
|
||||||
if (IsBurningDude(pSprite)) actKillDude(pSource->xvel, pSprite, DAMAGE_TYPE_0, 65535);
|
|
||||||
|
if (IsBurningDude(pSprite)) return;
|
||||||
else {
|
else {
|
||||||
spritetype* pBurnSource = &sprite[pXSprite->burnSource];
|
spritetype* pBurnSource = &sprite[pXSprite->burnSource];
|
||||||
if (pBurnSource->extra >= 0) {
|
if (pBurnSource->extra >= 0) {
|
||||||
|
@ -3734,12 +3727,6 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dude is dead?
|
|
||||||
if (pXSprite->health <= 0) {
|
|
||||||
pSprite->type = kThingBloodChunks; actPostSprite(pSprite->xvel, kStatThing); // turn it in gib
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
spritetype* pPlayer = targetIsPlayer(pXSprite);
|
spritetype* pPlayer = targetIsPlayer(pXSprite);
|
||||||
// special handling for player(s) if target changer data4 > 2.
|
// special handling for player(s) if target changer data4 > 2.
|
||||||
if (pPlayer != NULL) {
|
if (pPlayer != NULL) {
|
||||||
|
|
|
@ -402,10 +402,6 @@ void fakeProcessInput(PLAYER *pPlayer, GINPUT *pInput)
|
||||||
if (!predict.at6f && predict.at71 && predict.at6a == 0) {
|
if (!predict.at6f && predict.at71 && predict.at6a == 0) {
|
||||||
if (packItemActive(pPlayer, 4)) predict.at64 = pPosture->pwupJumpZ;//-0x175555;
|
if (packItemActive(pPlayer, 4)) predict.at64 = pPosture->pwupJumpZ;//-0x175555;
|
||||||
else predict.at64 = pPosture->normalJumpZ;//-0xbaaaa;
|
else predict.at64 = pPosture->normalJumpZ;//-0xbaaaa;
|
||||||
|
|
||||||
if (isShrinked(pPlayer->pSprite)) zvel[pPlayer->nSprite] -= gPosture[kModeHumanShrink][pPlayer->posture].normalJumpZ;//-200000;
|
|
||||||
else if (isGrown(pPlayer->pSprite)) zvel[pPlayer->nSprite] += gPosture[kModeHumanGrown][pPlayer->posture].normalJumpZ; //-250000;
|
|
||||||
|
|
||||||
predict.at6f = 1;
|
predict.at6f = 1;
|
||||||
}
|
}
|
||||||
if (pInput->buttonFlags.crouch)
|
if (pInput->buttonFlags.crouch)
|
||||||
|
@ -2769,7 +2765,7 @@ void viewSetSystemMessage(const char* pMessage, ...) {
|
||||||
vsprintf(buffer, pMessage, args);
|
vsprintf(buffer, pMessage, args);
|
||||||
|
|
||||||
Printf(PRINT_HIGH | PRINT_NOTIFY, "%s\n", buffer); // print it also in console
|
Printf(PRINT_HIGH | PRINT_NOTIFY, "%s\n", buffer); // print it also in console
|
||||||
gGameMessageMgr.Add(buffer, 15, 7, MESSAGE_PRIORITY_SYSTEM);
|
gGameMessageMgr.Add(buffer, 15, 7, MESSAGE_PRIORITY_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void viewSetMessage(const char *pMessage, const int pal, const MESSAGE_PRIORITY priority)
|
void viewSetMessage(const char *pMessage, const int pal, const MESSAGE_PRIORITY priority)
|
||||||
|
|
|
@ -1938,7 +1938,8 @@ void WeaponProcess(PLAYER *pPlayer) {
|
||||||
if (pXSprite->waitTime > 0 && --pXSprite->sysData1 <= 0) {
|
if (pXSprite->waitTime > 0 && --pXSprite->sysData1 <= 0) {
|
||||||
if (pXSprite->txID > 0)
|
if (pXSprite->txID > 0)
|
||||||
evSend(nIndex, 3, pXSprite->txID, (COMMAND_ID) pXSprite->command, pQavScene->causedBy);
|
evSend(nIndex, 3, pXSprite->txID, (COMMAND_ID) pXSprite->command, pQavScene->causedBy);
|
||||||
evPost(nIndex, 3, 0, (COMMAND_ID) (kCmdNumberic + 4), pQavScene->causedBy);
|
if (pXSprite->locked) trPlayerCtrlStopScene(pXSprite, pPlayer);
|
||||||
|
else evPost(nIndex, 3, 0, (COMMAND_ID) (kCmdNumberic + 4), pQavScene->causedBy);
|
||||||
} else {
|
} else {
|
||||||
qavScenePlay(pPlayer);
|
qavScenePlay(pPlayer);
|
||||||
pPlayer->weaponTimer = ClipLow(pPlayer->weaponTimer -= 4, 0);
|
pPlayer->weaponTimer = ClipLow(pPlayer->weaponTimer -= 4, 0);
|
||||||
|
|
Loading…
Reference in a new issue