mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-26 03:30:46 +00:00
Merge branch 'master' into menu_for_real
This commit is contained in:
commit
f2cfad8d9b
23 changed files with 1185 additions and 825 deletions
|
@ -2737,7 +2737,7 @@ void actInit(bool bSaveLoad) {
|
|||
case kDudeModernCustom:
|
||||
case kDudeModernCustomBurning:
|
||||
pSprite->cstat |= 4096 + CSTAT_SPRITE_BLOCK_HITSCAN + CSTAT_SPRITE_BLOCK;
|
||||
seqStartId = getSeqStartId(pXSprite); // by NoOne: Custom Dude stores it's SEQ in data2
|
||||
seqStartId = genDudeSeqStartId(pXSprite); // by NoOne: Custom Dude stores it's SEQ in data2
|
||||
pXSprite->sysData1 = pXSprite->data3; // by NoOne move sndStartId to sysData1, because data3 used by the game;
|
||||
pXSprite->data3 = 0;
|
||||
break;
|
||||
|
@ -3127,10 +3127,10 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
if ((gSysRes.Lookup(pXSprite->data2 + 15, "SEQ") || gSysRes.Lookup(pXSprite->data2 + 16, "SEQ")) && pXSprite->medium == kMediumNormal) {
|
||||
if (gSysRes.Lookup(pXSprite->data2 + 3, "SEQ")) {
|
||||
pSprite->type = kDudeModernCustomBurning;
|
||||
if (pXSprite->data2 == kDefaultAnimationBase) // don't inherit palette for burning if using default animation
|
||||
if (pXSprite->data2 == kGenDudeDefaultSeq) // don't inherit palette for burning if using default animation
|
||||
pSprite->pal = 0;
|
||||
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnGoto);
|
||||
aiGenDudeNewState(pSprite, &genDudeBurnGoto);
|
||||
actHealDude(pXSprite, dudeInfo[55].startHealth, dudeInfo[55].startHealth);
|
||||
if (pXSprite->burnTime <= 0) pXSprite->burnTime = 1200;
|
||||
gDudeExtra[pSprite->extra].at0 = (int)gFrameClock + 360;
|
||||
|
@ -3162,7 +3162,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
int seqId = pXSprite->data2 + 18;
|
||||
if (!gSysRes.Lookup(seqId, "SEQ")) {
|
||||
seqKill(3, nXSprite);
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndTransforming);
|
||||
playGenDudeSound(pSprite, kGenDudeSndTransforming);
|
||||
spritetype* pEffect = gFX.fxSpawn((FX_ID)52, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, pSprite->ang);
|
||||
if (pEffect != NULL) {
|
||||
pEffect->cstat = CSTAT_SPRITE_ALIGNMENT_FACING;
|
||||
|
@ -3187,7 +3187,10 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
return;
|
||||
}
|
||||
seqSpawn(seqId, 3, nXSprite, -1);
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndTransforming);
|
||||
playGenDudeSound(pSprite, kGenDudeSndTransforming);
|
||||
|
||||
pXSprite->sysData1 = kGenDudeTransformStatus; // in transform
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -3287,7 +3290,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
switch (pSprite->type) {
|
||||
case kDudeModernCustom:
|
||||
case kDudeModernCustomBurning:
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndDeathExplode);
|
||||
playGenDudeSound(pSprite, kGenDudeSndDeathExplode);
|
||||
break;
|
||||
case kDudeCultistTommy:
|
||||
case kDudeCultistShotgun:
|
||||
|
@ -3406,15 +3409,15 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
seqSpawn(dudeInfo[nType].seqStartID+15, 3, nXSprite, nDudeToGibClient2);
|
||||
break;
|
||||
case kDudeModernCustom:
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndDeathNormal);
|
||||
playGenDudeSound(pSprite, kGenDudeSndDeathNormal);
|
||||
if (nSeq == 3) {
|
||||
|
||||
bool seq15 = gSysRes.Lookup(pXSprite->data2 + 15, "SEQ"); bool seq16 = gSysRes.Lookup(pXSprite->data2 + 16, "SEQ");
|
||||
if (seq15 && seq16) seqSpawn((15 + Random(2)) + pXSprite->data2, 3, nXSprite, nDudeToGibClient2);
|
||||
else if (seq16) seqSpawn(16 + pXSprite->data2, 3, nXSprite, nDudeToGibClient2);
|
||||
else if (seq15) seqSpawn(15 + pXSprite->data2, 3, nXSprite, nDudeToGibClient2);
|
||||
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
|
||||
if (pExtra->availDeaths[kDmgBurn] == 3) seqSpawn((15 + Random(2)) + pXSprite->data2, 3, nXSprite, nDudeToGibClient2);
|
||||
else if (pExtra->availDeaths[kDmgBurn] == 2) seqSpawn(16 + pXSprite->data2, 3, nXSprite, nDudeToGibClient2);
|
||||
else if (pExtra->availDeaths[kDmgBurn] == 1) seqSpawn(15 + pXSprite->data2, 3, nXSprite, nDudeToGibClient2);
|
||||
else if (gSysRes.Lookup(pXSprite->data2 + nSeq, "SEQ"))seqSpawn(nSeq + pXSprite->data2, 3, nXSprite, nDudeToGibClient2);
|
||||
else seqKill(3, nXSprite);
|
||||
else seqSpawn(1 + pXSprite->data2, 3, nXSprite, nDudeToGibClient2);
|
||||
|
||||
} else {
|
||||
seqSpawn(nSeq + pXSprite->data2, 3, nXSprite, nDudeToGibClient1);
|
||||
|
@ -3423,9 +3426,8 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
pXSprite->txID = 0; // to avoid second trigger.
|
||||
break;
|
||||
|
||||
case kDudeModernCustomBurning:
|
||||
{
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndDeathExplode);
|
||||
case kDudeModernCustomBurning: {
|
||||
playGenDudeSound(pSprite, kGenDudeSndDeathExplode);
|
||||
damageType = DAMAGE_TYPE_3;
|
||||
|
||||
if (Chance(0x4000)) {
|
||||
|
@ -3436,14 +3438,11 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
GibSprite(pSprite, GIBTYPE_7, &gibPos, &gibVel);
|
||||
}
|
||||
|
||||
int seqId = pXSprite->data2;
|
||||
bool seq15 = gSysRes.Lookup(pXSprite->data2 + 15, "SEQ"); bool seq16 = gSysRes.Lookup(pXSprite->data2 + 16, "SEQ");
|
||||
|
||||
if (seq15 && seq16) seqId += (15 + Random(2));
|
||||
else if (seq16) seqId += 16;
|
||||
else seqId += 15;
|
||||
|
||||
seqSpawn(seqId, 3, nXSprite, nDudeToGibClient1);
|
||||
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
|
||||
if (pExtra->availDeaths[kDmgBurn] == 3) seqSpawn((15 + Random(2)) + pXSprite->data2, 3, nXSprite, nDudeToGibClient1);
|
||||
else if (pExtra->availDeaths[kDmgBurn] == 2) seqSpawn(16 + pXSprite->data2, 3, nXSprite, nDudeToGibClient1);
|
||||
else if (pExtra->availDeaths[kDmgBurn] == 1) seqSpawn(15 + pXSprite->data2, 3, nXSprite, nDudeToGibClient1);
|
||||
else seqSpawn(1 + pXSprite->data2, 3, nXSprite, nDudeToGibClient1);
|
||||
break;
|
||||
}
|
||||
case kDudeBurningZombieAxe:
|
||||
|
@ -3570,6 +3569,12 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
sfxPlay3DSound(pSprite, 2103+Random(2), -1, 0);
|
||||
seqSpawn(dudeInfo[nType].seqStartID+nSeq, 3, nXSprite, -1);
|
||||
break;
|
||||
case kDudePodGreen:
|
||||
case kDudeTentacleGreen:
|
||||
case kDudePodFire:
|
||||
case kDudeTentacleFire:
|
||||
if ((pSprite->cstat & CSTAT_SPRITE_YFLIP)) pSprite->cstat &= ~CSTAT_SPRITE_YFLIP;
|
||||
switch (pSprite->type) {
|
||||
case kDudePodGreen:
|
||||
if (Chance(0x4000) && nSeq == 3)
|
||||
sfxPlay3DSound(pSprite, 2205, -1, 0);
|
||||
|
@ -3595,6 +3600,8 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
sfxPlay3DSound(pSprite, 2501, -1, 0);
|
||||
seqSpawn(dudeInfo[nType].seqStartID + nSeq, 3, nXSprite, -1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kDudePodMother:
|
||||
if (Chance(0x4000) && nSeq == 3)
|
||||
sfxPlay3DSound(pSprite, 2205, -1, 0);
|
||||
|
@ -4717,7 +4724,10 @@ void MoveDude(spritetype *pSprite)
|
|||
PLAYER *pPlayer = NULL;
|
||||
if (IsPlayerSprite(pSprite))
|
||||
pPlayer = &gPlayer[pSprite->type-kDudePlayer1];
|
||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||
if (!(pSprite->type >= kDudeBase && pSprite->type < kDudeMax)) {
|
||||
consoleSysMsg("pSprite->type >= kDudeBase && pSprite->type < kDudeMax");
|
||||
return;
|
||||
}
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
int top, bottom;
|
||||
GetSpriteExtents(pSprite, &top, &bottom);
|
||||
|
@ -6141,9 +6151,10 @@ void actProcessSprites(void)
|
|||
}
|
||||
|
||||
// By NoOne: handle incarnations of custom dude
|
||||
if (pSprite->type == kDudeModernCustom && pXSprite->txID > 0 && pXSprite->health <= 0 && seqGetStatus(3, nXSprite) < 0) {
|
||||
if (pSprite->type == kDudeModernCustom && pXSprite->txID > 0 && pXSprite->health <= 0 && pXSprite->sysData1 == kGenDudeTransformStatus) {
|
||||
xvel[pSprite->index] = ClipLow(xvel[pSprite->index] >> 4, 0); yvel[pSprite->index] = ClipLow(yvel[pSprite->index] >> 4, 0);
|
||||
XSPRITE* pXIncarnation = getNextIncarnation(pXSprite);
|
||||
if (pXIncarnation != NULL) {
|
||||
if (seqGetStatus(3, nXSprite) < 0 && pXIncarnation != NULL) {
|
||||
spritetype* pIncarnation = &sprite[pXIncarnation->reference];
|
||||
pXSprite->key = pXSprite->dropMsg = pXSprite->locked = 0;
|
||||
|
||||
|
@ -6158,7 +6169,6 @@ void actProcessSprites(void)
|
|||
// trigger dude death before transform
|
||||
trTriggerSprite(nSprite, pXSprite, kCmdOff, pSprite->owner);
|
||||
|
||||
|
||||
pSprite->type = pIncarnation->type;
|
||||
pSprite->flags = pIncarnation->flags;
|
||||
pSprite->pal = pIncarnation->pal;
|
||||
|
@ -6211,8 +6221,8 @@ void actProcessSprites(void)
|
|||
break;
|
||||
case kDudeModernCustom:
|
||||
case kDudeModernCustomBurning:
|
||||
seqId = getSeqStartId(pXSprite);
|
||||
getSpriteMassBySize(pSprite); // create or refresh mass cache
|
||||
seqId = genDudeSeqStartId(pXSprite);
|
||||
genDudePrepare(pSprite, kGenDudePropertyMass);
|
||||
fallthrough__; // go below
|
||||
default:
|
||||
seqSpawn(seqId, 3, nXSprite, -1);
|
||||
|
@ -7510,7 +7520,7 @@ spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist) {
|
|||
pXDude->data3 = 0;
|
||||
|
||||
// spawn seq
|
||||
seqSpawn(getSeqStartId(pXDude), 3, pDude->extra, -1);
|
||||
seqSpawn(genDudeSeqStartId(pXDude), 3, pDude->extra, -1);
|
||||
|
||||
// inherit movement speed.
|
||||
pXDude->busyTime = pXSource->busyTime;
|
||||
|
@ -7550,6 +7560,12 @@ spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist) {
|
|||
}
|
||||
}
|
||||
|
||||
// inherit sprite size (useful for seqs with zero repeats)
|
||||
if (pSource->flags & kModernTypeFlag2) {
|
||||
pDude->xrepeat = pSource->xrepeat;
|
||||
pDude->yrepeat = pSource->yrepeat;
|
||||
}
|
||||
|
||||
aiInitSprite(pDude);
|
||||
return pDude;
|
||||
}
|
||||
|
@ -7650,7 +7666,7 @@ int getSpriteMassBySize(spritetype* pSprite) {
|
|||
cached->picnum = pSprite->picnum; cached->seqId = seqId;
|
||||
cached->clipdist = pSprite->clipdist;
|
||||
|
||||
viewSetSystemMessage("MASS: %d", cached->mass);
|
||||
//viewSetSystemMessage("MASS: %d", cached->mass);
|
||||
return cached->mass;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,25 +110,20 @@ void aiPlay3DSound(spritetype *pSprite, int a2, AI_SFX_PRIORITY a3, int a4)
|
|||
void aiNewState(spritetype *pSprite, XSPRITE *pXSprite, AISTATE *pAIState)
|
||||
{
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
pXSprite->stateTimer = pAIState->at8;
|
||||
pXSprite->stateTimer = pAIState->stateTicks;
|
||||
pXSprite->aiState = pAIState;
|
||||
int seqStartId = pDudeInfo->seqStartID;
|
||||
|
||||
if (pAIState->at0 >= 0) {
|
||||
// By NoOne: Custom dude uses data2 to keep it's seqStartId
|
||||
switch (pSprite->type) {
|
||||
case kDudeModernCustom:
|
||||
case kDudeModernCustomBurning:
|
||||
seqStartId = pXSprite->data2;
|
||||
break;
|
||||
}
|
||||
seqStartId += pAIState->at0;
|
||||
if (pAIState->seqId >= 0) {
|
||||
seqStartId += pAIState->seqId;
|
||||
if (gSysRes.Lookup(seqStartId, "SEQ"))
|
||||
seqSpawn(seqStartId, 3, pSprite->extra, pAIState->at4);
|
||||
seqSpawn(seqStartId, 3, pSprite->extra, pAIState->funcId);
|
||||
}
|
||||
|
||||
if (pAIState->atc) pAIState->atc(pSprite, pXSprite); // entry function
|
||||
if (pAIState->enterFunc)
|
||||
pAIState->enterFunc(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
bool dudeIsImmune(spritetype* pSprite, int dmgType) {
|
||||
if (dmgType < 0 || dmgType > 6) return true;
|
||||
else if (dudeInfo[pSprite->type - kDudeBase].startDamage[dmgType] == 0) return true;
|
||||
|
@ -417,31 +412,18 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
pDudeExtraE->at8 = 1;
|
||||
pDudeExtraE->at0 = 0;
|
||||
if (pXSprite->target == -1) {
|
||||
if (spriteIsUnderwater(pSprite, false))
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeSearchW);
|
||||
else {
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeSearchL);
|
||||
if (Chance(0x4000))
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndTargetSpot);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Chance(0x4000))
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndTargetSpot);
|
||||
|
||||
if (spriteIsUnderwater(pSprite, false))
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeChaseW);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeChaseL);
|
||||
|
||||
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeSearchW);
|
||||
else aiGenDudeNewState(pSprite, &genDudeSearchL);
|
||||
} else {
|
||||
if (Chance(0x4000)) playGenDudeSound(pSprite, kGenDudeSndTargetSpot);
|
||||
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeChaseW);
|
||||
else aiGenDudeNewState(pSprite, &genDudeChaseL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kDudeModernCustomBurning:
|
||||
if (pXSprite->target == -1)
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
else
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnChase);
|
||||
if (pXSprite->target == -1) aiGenDudeNewState(pSprite, &genDudeBurnSearch);
|
||||
else aiGenDudeNewState(pSprite, &genDudeBurnChase);
|
||||
break;
|
||||
case kDudeCultistTommyProne: {
|
||||
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
|
||||
|
@ -1026,7 +1008,7 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
|
|||
break;
|
||||
case kDudeModernCustomBurning:
|
||||
if (Chance(0x2000) && gDudeExtra[pSprite->extra].at0 < (int)gFrameClock) {
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndBurning);
|
||||
playGenDudeSound(pSprite, kGenDudeSndBurning);
|
||||
gDudeExtra[pSprite->extra].at0 = (int)gFrameClock + 360;
|
||||
}
|
||||
if (pXSprite->burnTime == 0) pXSprite->burnTime = 2400;
|
||||
|
@ -1034,17 +1016,18 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
|
|||
pSprite->type = kDudeModernCustom;
|
||||
pXSprite->burnTime = 0;
|
||||
pXSprite->health = 1; // so it can be killed with flame weapons while underwater and if already was burning dude before.
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeGotoW);
|
||||
aiGenDudeNewState(pSprite, &genDudeGotoW);
|
||||
}
|
||||
break;
|
||||
case kDudeModernCustom:
|
||||
{
|
||||
case kDudeModernCustom: {
|
||||
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite);
|
||||
|
||||
if (nDmgType == DAMAGE_TYPE_1) {
|
||||
if (pXSprite->health <= pDudeInfo->fleeHealth) {
|
||||
if (pXSprite->txID <= 0 || getNextIncarnation(pXSprite) == NULL) {
|
||||
if (pXSprite->health > pDudeInfo->fleeHealth) break;
|
||||
else if (pXSprite->txID <= 0 || getNextIncarnation(pXSprite) == NULL) {
|
||||
removeDudeStuff(pSprite);
|
||||
|
||||
if (pXSprite->data1 >= kTrapExploder && pXSprite->data1 < (kTrapExploder + kExplodeMax) - 1)
|
||||
if (pExtra->curWeapon >= kTrapExploder && pExtra->curWeapon < (kTrapExploder + kExplodeMax) - 1)
|
||||
doExplosion(pSprite, pXSprite->data1 - kTrapExploder);
|
||||
|
||||
if (spriteIsUnderwater(pSprite, false)) {
|
||||
|
@ -1055,17 +1038,16 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
|
|||
if (pXSprite->burnTime <= 0)
|
||||
pXSprite->burnTime = 1200;
|
||||
|
||||
if ((gSysRes.Lookup(pXSprite->data2 + 15, "SEQ") || gSysRes.Lookup(pXSprite->data2 + 16, "SEQ"))
|
||||
&& gSysRes.Lookup(pXSprite->data2 + 3, "SEQ")) {
|
||||
if (pExtra->canBurn && pExtra->availDeaths[DAMAGE_TYPE_1] > 0) {
|
||||
|
||||
aiPlay3DSound(pSprite, 361, AI_SFX_PRIORITY_0, -1);
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndBurning);
|
||||
playGenDudeSound(pSprite, kGenDudeSndBurning);
|
||||
pSprite->type = kDudeModernCustomBurning;
|
||||
|
||||
if (pXSprite->data2 == kDefaultAnimationBase) // don't inherit palette for burning if using default animation
|
||||
if (pXSprite->data2 == kGenDudeDefaultSeq) // don't inherit palette for burning if using default animation
|
||||
pSprite->pal = 0;
|
||||
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnGoto);
|
||||
aiGenDudeNewState(pSprite, &genDudeBurnGoto);
|
||||
actHealDude(pXSprite, dudeInfo[55].startHealth, dudeInfo[55].startHealth);
|
||||
gDudeExtra[pSprite->extra].at0 = (int)gFrameClock + 360;
|
||||
evKill(nSprite, 3, kCallbackFXFlameLick);
|
||||
|
@ -1075,22 +1057,20 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
|
|||
} else {
|
||||
actKillDude(nSource, pSprite, DAMAGE_TYPE_0, 65535);
|
||||
}
|
||||
}
|
||||
} else if (!inDodge(pXSprite->aiState)) {
|
||||
|
||||
if (Chance(getDodgeChance(pSprite)) || inIdle(pXSprite->aiState)) {
|
||||
} else if (canWalk(pSprite) && !inDodge(pXSprite->aiState) && !inRecoil(pXSprite->aiState)) {
|
||||
if (inIdle(pXSprite->aiState) || inSearch(pXSprite->aiState) || Chance(getDodgeChance(pSprite))) {
|
||||
if (!spriteIsUnderwater(pSprite, false)) {
|
||||
if (!canDuck(pSprite) || !sub_5BDA8(pSprite, 14)) aiNewState(pSprite, pXSprite, &GDXGenDudeDodgeDmgL);
|
||||
else aiNewState(pSprite, pXSprite, &GDXGenDudeDodgeDmgD);
|
||||
if (!canDuck(pSprite) || !sub_5BDA8(pSprite, 14)) aiGenDudeNewState(pSprite, &genDudeDodgeShortL);
|
||||
else aiGenDudeNewState(pSprite, &genDudeDodgeShortD);
|
||||
|
||||
if (Chance(0x0200))
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndGotHit);
|
||||
}
|
||||
else if (sub_5BDA8(pSprite, 13))
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeDodgeDmgW);
|
||||
}
|
||||
}
|
||||
playGenDudeSound(pSprite, kGenDudeSndGotHit);
|
||||
|
||||
} else if (sub_5BDA8(pSprite, 13)) {
|
||||
aiGenDudeNewState(pSprite, &genDudeDodgeShortW);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kDudeCultistBeast:
|
||||
|
@ -1123,43 +1103,53 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
{
|
||||
char v4 = Chance(0x8000);
|
||||
DUDEEXTRA *pDudeExtra = &gDudeExtra[pSprite->extra];
|
||||
if (pSprite->statnum == kStatDude && (pSprite->type >= kDudeBase && pSprite->type < kDudeMax))
|
||||
{
|
||||
if (pSprite->statnum == kStatDude && (pSprite->type >= kDudeBase && pSprite->type < kDudeMax)) {
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
|
||||
switch (pSprite->type)
|
||||
{
|
||||
case kDudeModernCustom:
|
||||
{
|
||||
int mass = getSpriteMassBySize(pSprite); int chance4 = getRecoilChance(pSprite); bool chance3 = Chance(chance4);
|
||||
if (pDudeExtra->at4 && (inIdle(pXSprite->aiState) || mass < 155 || (mass >= 155 && chance3)) && !spriteIsUnderwater(pSprite, false))
|
||||
{
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndGotHit);
|
||||
switch (pSprite->type) {
|
||||
case kDudeModernCustom: {
|
||||
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); int rChance = getRecoilChance(pSprite);
|
||||
if (pExtra->canElectrocute && pDudeExtra->at4 && !spriteIsUnderwater(pSprite, false)) {
|
||||
|
||||
if (gSysRes.Lookup(pXSprite->data2 + 4, "SEQ")) {
|
||||
GDXGenDudeRTesla.at18 = (Chance(chance4 * 2) ? &GDXGenDudeDodgeL : &GDXGenDudeDodgeDmgL);
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeRTesla);
|
||||
}
|
||||
else if (canDuck(pSprite) && (Chance(chance4) || gGameOptions.nDifficulty == 0)) aiNewState(pSprite, pXSprite, &GDXGenDudeRecoilD);
|
||||
else if (canSwim(pSprite) && spriteIsUnderwater(pSprite, false)) aiNewState(pSprite, pXSprite, &GDXGenDudeRecoilW);
|
||||
else aiNewState(pSprite, pXSprite, &GDXGenDudeRecoilL);
|
||||
break;
|
||||
}
|
||||
if (Chance(rChance << 3) || (dudeIsMelee(pXSprite) && Chance(rChance << 4))) aiGenDudeNewState(pSprite, &genDudeRecoilTesla);
|
||||
else if (pExtra->canRecoil && Chance(rChance)) aiGenDudeNewState(pSprite, &genDudeRecoilL);
|
||||
else if (canWalk(pSprite)) {
|
||||
|
||||
if (inDodge(pXSprite->aiState)) {
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndGotHit);
|
||||
break;
|
||||
}
|
||||
|
||||
if (inIdle(pXSprite->aiState) || chance3 || Chance(getRecoilChance(pSprite)) || (!dudeIsMelee(pXSprite) && mass < 155)) {
|
||||
|
||||
sfxPlayGDXGenDudeSound(pSprite, kGenDudeSndGotHit);
|
||||
|
||||
if (canDuck(pSprite) && (Chance(chance4) || gGameOptions.nDifficulty == 0)) aiNewState(pSprite, pXSprite, &GDXGenDudeRecoilD);
|
||||
else if (canSwim(pSprite) && spriteIsUnderwater(pSprite, false)) aiNewState(pSprite, pXSprite, &GDXGenDudeRecoilW);
|
||||
else aiNewState(pSprite, pXSprite, &GDXGenDudeRecoilL);
|
||||
if (Chance(rChance >> 2)) aiGenDudeNewState(pSprite, &genDudeDodgeL);
|
||||
else if (Chance(rChance >> 1)) aiGenDudeNewState(pSprite, &genDudeDodgeShortL);
|
||||
|
||||
}
|
||||
|
||||
} else if (pExtra->canRecoil && Chance(rChance)) {
|
||||
|
||||
if (inDuck(pXSprite->aiState) && Chance(rChance >> 2)) aiGenDudeNewState(pSprite, &genDudeRecoilD);
|
||||
else if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeRecoilW);
|
||||
else aiGenDudeNewState(pSprite, &genDudeRecoilL);
|
||||
|
||||
}
|
||||
|
||||
short rState = inRecoil(pXSprite->aiState);
|
||||
if (rState > 0) {
|
||||
|
||||
if (!canWalk(pSprite)) {
|
||||
if (rState == 1) pXSprite->aiState->nextState = &genDudeChaseNoWalkL;
|
||||
else if (rState == 2) pXSprite->aiState->nextState = &genDudeChaseNoWalkD;
|
||||
else pXSprite->aiState->nextState = &genDudeChaseNoWalkW;
|
||||
|
||||
} else if (!dudeIsMelee(pXSprite) || Chance(rChance >> 2)) {
|
||||
if (rState == 1) pXSprite->aiState->nextState = (Chance(rChance) ? &genDudeDodgeL : &genDudeDodgeShortL);
|
||||
else if (rState == 2) pXSprite->aiState->nextState = (Chance(rChance) ? &genDudeDodgeD : &genDudeDodgeShortD);
|
||||
else if (rState == 1) pXSprite->aiState->nextState = (Chance(rChance) ? &genDudeDodgeW : &genDudeDodgeShortW);
|
||||
|
||||
}
|
||||
else if (rState == 1) pXSprite->aiState->nextState = &genDudeChaseL;
|
||||
else if (rState == 2) pXSprite->aiState->nextState = &genDudeChaseD;
|
||||
else pXSprite->aiState->nextState = &genDudeChaseW;
|
||||
|
||||
playGenDudeSound(pSprite, kGenDudeSndGotHit);
|
||||
|
||||
}
|
||||
|
||||
pDudeExtra->at4 = 0;
|
||||
break;
|
||||
}
|
||||
case kDudeCultistTommy:
|
||||
|
@ -1193,7 +1183,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
aiNewState(pSprite, pXSprite, &cultistBurnGoto);
|
||||
break;
|
||||
case kDudeModernCustomBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnGoto);
|
||||
aiGenDudeNewState(pSprite, &genDudeBurnGoto);
|
||||
break;
|
||||
case kDudeZombieButcher:
|
||||
aiPlay3DSound(pSprite, 1202, AI_SFX_PRIORITY_2, -1);
|
||||
|
@ -1453,26 +1443,31 @@ void sub_5F15C(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
}
|
||||
}
|
||||
|
||||
void aiProcessDudes(void)
|
||||
{
|
||||
void aiProcessDudes(void) {
|
||||
for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (pSprite->flags & 32) continue;
|
||||
int nXSprite = pSprite->extra;
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite];
|
||||
DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
XSPRITE *pXSprite = &xsprite[nXSprite]; DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
|
||||
if (IsPlayerSprite(pSprite) || pXSprite->health == 0) continue;
|
||||
|
||||
pXSprite->stateTimer = ClipLow(pXSprite->stateTimer-4, 0);
|
||||
if (pXSprite->aiState->at10)
|
||||
pXSprite->aiState->at10(pSprite, pXSprite);
|
||||
if (pXSprite->aiState->at14 && (gFrame&3) == (nSprite&3))
|
||||
pXSprite->aiState->at14(pSprite, pXSprite);
|
||||
if (pXSprite->stateTimer == 0 && pXSprite->aiState->at18) {
|
||||
if (pXSprite->aiState->at8 > 0)
|
||||
aiNewState(pSprite, pXSprite, pXSprite->aiState->at18);
|
||||
if (pSprite->type >= kDudeVanillaMax && pSprite->type < kDudeMax)
|
||||
genDudeProcess(pSprite, pXSprite);
|
||||
|
||||
else {
|
||||
|
||||
if (pXSprite->aiState->moveFunc)
|
||||
pXSprite->aiState->moveFunc(pSprite, pXSprite);
|
||||
|
||||
if (pXSprite->aiState->thinkFunc && (gFrame & 3) == (nSprite & 3))
|
||||
pXSprite->aiState->thinkFunc(pSprite, pXSprite);
|
||||
|
||||
if (pXSprite->stateTimer == 0 && pXSprite->aiState->nextState) {
|
||||
if (pXSprite->aiState->stateTicks > 0)
|
||||
aiNewState(pSprite, pXSprite, pXSprite->aiState->nextState);
|
||||
else if (seqGetStatus(3, nXSprite) < 0)
|
||||
aiNewState(pSprite, pXSprite, pXSprite->aiState->at18);
|
||||
aiNewState(pSprite, pXSprite, pXSprite->aiState->nextState);
|
||||
}
|
||||
|
||||
if (pXSprite->health > 0 && ((pDudeInfo->hinderDamage << 4) <= cumulDamage[nXSprite])) {
|
||||
|
@ -1480,19 +1475,8 @@ void aiProcessDudes(void)
|
|||
RecoilDude(pSprite, pXSprite);
|
||||
}
|
||||
|
||||
if (pSprite->type >= kDudeVanillaMax) {
|
||||
switch (pSprite->type) {
|
||||
case kDudeModernCustom:
|
||||
case kDudeModernCustomBurning:
|
||||
GENDUDEEXTRA* pExtra = &gGenDudeExtra[pSprite->index];
|
||||
if (pExtra->slaveCount > 0) updateTargetOfSlaves(pSprite);
|
||||
if (pExtra->nLifeLeech >= 0) updateTargetOfLeech(pSprite);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
memset(cumulDamage, 0, sizeof(cumulDamage));
|
||||
}
|
||||
|
||||
|
@ -1520,12 +1504,12 @@ void aiInitSprite(spritetype *pSprite)
|
|||
case kDudeModernCustom: {
|
||||
DUDEEXTRA_at6_u1* pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
|
||||
pDudeExtraE->at8 = pDudeExtraE->at0 = 0;
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeIdleL);
|
||||
aiGenDudeNewState(pSprite, &genDudeIdleL);
|
||||
genDudePrepare(pSprite);
|
||||
break;
|
||||
}
|
||||
case kDudeModernCustomBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnGoto);
|
||||
aiGenDudeNewState(pSprite, &genDudeBurnGoto);
|
||||
pXSprite->burnTime = 1200;
|
||||
break;
|
||||
case kDudeCultistTommy:
|
||||
|
|
|
@ -32,13 +32,13 @@ BEGIN_BLD_NS
|
|||
|
||||
struct AISTATE {
|
||||
int stateType; // By NoOne: current type of state. Basically required for kModernDudeTargetChanger, but can be used for something else.
|
||||
int at0; // seq
|
||||
int at4; // seq callback
|
||||
int at8;
|
||||
void(*atc)(spritetype *, XSPRITE *);
|
||||
void(*at10)(spritetype *, XSPRITE *);
|
||||
void(*at14)(spritetype *, XSPRITE *);
|
||||
AISTATE *at18; // next state ?
|
||||
int seqId;
|
||||
int funcId; // seq callback
|
||||
int stateTicks;
|
||||
void(*enterFunc)(spritetype *, XSPRITE *);
|
||||
void(*moveFunc)(spritetype *, XSPRITE *);
|
||||
void(*thinkFunc)(spritetype *, XSPRITE *);
|
||||
AISTATE *nextState;
|
||||
};
|
||||
extern AISTATE aiState[];
|
||||
|
||||
|
@ -86,6 +86,7 @@ struct TARGETTRACK {
|
|||
extern int dword_138BB0[5];
|
||||
extern DUDEEXTRA gDudeExtra[];
|
||||
extern int gDudeSlope[];
|
||||
extern int cumulDamage[];
|
||||
|
||||
bool sub_5BDA8(spritetype *pSprite, int nSeq);
|
||||
void aiPlay3DSound(spritetype *pSprite, int a2, AI_SFX_PRIORITY a3, int a4);
|
||||
|
@ -104,6 +105,7 @@ void aiProcessDudes(void);
|
|||
void aiInit(void);
|
||||
void aiInitSprite(spritetype *pSprite);
|
||||
bool CanMove(spritetype* pSprite, int a2, int nAngle, int nRange);
|
||||
void RecoilDude(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
|
||||
// By NoOne: this function required for kModernDudeTargetChanger
|
||||
void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
|
|
|
@ -81,11 +81,11 @@ AISTATE tinycalebBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, th
|
|||
AISTATE tinycalebBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, &tinycalebBurnSearch };
|
||||
AISTATE tinycalebBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &tinycalebBurnChase };
|
||||
|
||||
AISTATE GDXGenDudeBurnIdle = { kAiStateIdle, 3, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE GDXGenDudeBurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE GDXGenDudeBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &GDXGenDudeBurnSearch };
|
||||
AISTATE GDXGenDudeBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, &GDXGenDudeBurnSearch };
|
||||
AISTATE GDXGenDudeBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &GDXGenDudeBurnChase };
|
||||
AISTATE genDudeBurnIdle = { kAiStateIdle, 3, -1, 0, NULL, NULL, aiThinkTarget, NULL };
|
||||
AISTATE genDudeBurnChase = { kAiStateChase, 3, -1, 0, NULL, aiMoveForward, thinkChase, NULL };
|
||||
AISTATE genDudeBurnGoto = { kAiStateMove, 3, -1, 3600, NULL, aiMoveForward, thinkGoto, &genDudeBurnSearch };
|
||||
AISTATE genDudeBurnSearch = { kAiStateSearch, 3, -1, 3600, NULL, aiMoveForward, thinkSearch, &genDudeBurnSearch };
|
||||
AISTATE genDudeBurnAttack = { kAiStateChase, 3, nBurnClient, 120, NULL, NULL, NULL, &genDudeBurnChase };
|
||||
|
||||
static void BurnSeqCallback(int, int)
|
||||
{
|
||||
|
@ -129,7 +129,7 @@ static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
aiNewState(pSprite, pXSprite, &tinycalebBurnSearch);
|
||||
break;
|
||||
case kDudeModernCustomBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
aiNewState(pSprite, pXSprite, &genDudeBurnSearch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
aiNewState(pSprite, pXSprite, &tinycalebBurnGoto);
|
||||
break;
|
||||
case kDudeModernCustomBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnGoto);
|
||||
aiNewState(pSprite, pXSprite, &genDudeBurnGoto);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
@ -197,7 +197,7 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
aiNewState(pSprite, pXSprite, &tinycalebBurnSearch);
|
||||
break;
|
||||
case kDudeModernCustomBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
aiNewState(pSprite, pXSprite, &genDudeBurnSearch);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
@ -235,7 +235,7 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
aiNewState(pSprite, pXSprite, &tinycalebBurnAttack);
|
||||
break;
|
||||
case kDudeModernCustomBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
aiNewState(pSprite, pXSprite, &genDudeBurnSearch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
|
|||
aiNewState(pSprite, pXSprite, &tinycalebBurnGoto);
|
||||
break;
|
||||
case kDudeModernCustomBurning:
|
||||
aiNewState(pSprite, pXSprite, &GDXGenDudeBurnSearch);
|
||||
aiNewState(pSprite, pXSprite, &genDudeBurnSearch);
|
||||
break;
|
||||
}
|
||||
pXSprite->target = -1;
|
||||
|
|
|
@ -50,10 +50,10 @@ extern AISTATE tinycalebBurnChase;
|
|||
extern AISTATE tinycalebBurnGoto;
|
||||
extern AISTATE tinycalebBurnSearch;
|
||||
extern AISTATE tinycalebBurnAttack;
|
||||
extern AISTATE GDXGenDudeBurnIdle;
|
||||
extern AISTATE GDXGenDudeBurnChase;
|
||||
extern AISTATE GDXGenDudeBurnGoto;
|
||||
extern AISTATE GDXGenDudeBurnSearch;
|
||||
extern AISTATE GDXGenDudeBurnAttack;
|
||||
extern AISTATE genDudeBurnIdle;
|
||||
extern AISTATE genDudeBurnChase;
|
||||
extern AISTATE genDudeBurnGoto;
|
||||
extern AISTATE genDudeBurnSearch;
|
||||
extern AISTATE genDudeBurnAttack;
|
||||
|
||||
END_BLD_NS
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -26,9 +26,40 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "eventq.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
#define kDefaultAnimationBase 11520
|
||||
#define kGenDudeDefaultSeq 11520
|
||||
#define kGenDudeMaxSlaves 7
|
||||
#define kGenDudeTransformStatus -222
|
||||
#define kGenDudeUpdTimeRate 10
|
||||
#define kGenDudeMaxMeleeDist 2048
|
||||
|
||||
enum {
|
||||
kGenDudeSeqIdleL = 0,
|
||||
kGenDudeSeqDeathDefault = 1,
|
||||
kGenDudeSeqDeathExplode = 2,
|
||||
kGenDudeSeqBurning = 3,
|
||||
kGenDudeSeqElectocuted = 4,
|
||||
kGenDudeSeqRecoil = 5,
|
||||
kGenDudeSeqAttackNormalL = 6,
|
||||
kGenDudeSeqAttackThrow = 7,
|
||||
kGenDudeSeqAttackNormalDW = 8,
|
||||
kGenDudeSeqMoveL = 9,
|
||||
kGenDudeSeqAttackPunch = 10,
|
||||
kGenDudeSeqReserved1 = 11,
|
||||
kGenDudeSeqReserved2 = 12,
|
||||
kGenDudeSeqMoveW = 13,
|
||||
kGenDudeSeqMoveD = 14,
|
||||
kGenDudeSeqDeathBurn1 = 15,
|
||||
kGenDudeSeqDeathBurn2 = 16,
|
||||
kGenDudeSeqIdleW = 17,
|
||||
kGenDudeSeqTransform = 18,
|
||||
kGenDudeSeqReserved3 = 19,
|
||||
kGenDudeSeqReserved4 = 20,
|
||||
kGenDudeSeqReserved5 = 21,
|
||||
kGenDudeSeqReserved6 = 22,
|
||||
kGenDudeSeqReserved7 = 23,
|
||||
kGenDudeSeqReserved8 = 24,
|
||||
kGenDudeSeqMax ,
|
||||
};
|
||||
|
||||
enum {
|
||||
kGenDudeSndTargetSpot = 0,
|
||||
|
@ -48,44 +79,47 @@ kGenDudeSndMax ,
|
|||
enum {
|
||||
kGenDudePropertyAll = 0,
|
||||
kGenDudePropertyWeapon = 1,
|
||||
kGenDudePropertyDamage = 2,
|
||||
kGenDudePropertyDmgScale = 2,
|
||||
kGenDudePropertyMass = 3,
|
||||
kGenDudePropertyAttack = 4,
|
||||
kGenDudePropertyStates = 5,
|
||||
kGenDudePropertyLeech = 6,
|
||||
kGenDudePropertySlaves = 7,
|
||||
kGenDudePropertyMelee = 8,
|
||||
kGenDudePropertyClipdist = 9,
|
||||
kGenDudePropertySpriteSize = 8,
|
||||
kGenDudePropertyInitVals = 9,
|
||||
kGenDudePropertyMax ,
|
||||
};
|
||||
|
||||
|
||||
extern AISTATE GDXGenDudeIdleL;
|
||||
extern AISTATE GDXGenDudeIdleW;
|
||||
extern AISTATE GDXGenDudeSearchL;
|
||||
extern AISTATE GDXGenDudeSearchW;
|
||||
extern AISTATE GDXGenDudeGotoL;
|
||||
extern AISTATE GDXGenDudeGotoW;
|
||||
extern AISTATE GDXGenDudeDodgeL;
|
||||
extern AISTATE GDXGenDudeDodgeD;
|
||||
extern AISTATE GDXGenDudeDodgeW;
|
||||
extern AISTATE GDXGenDudeDodgeDmgL;
|
||||
extern AISTATE GDXGenDudeDodgeDmgD;
|
||||
extern AISTATE GDXGenDudeDodgeDmgW;
|
||||
extern AISTATE GDXGenDudeChaseL;
|
||||
extern AISTATE GDXGenDudeChaseD;
|
||||
extern AISTATE GDXGenDudeChaseW;
|
||||
extern AISTATE GDXGenDudeFireL;
|
||||
extern AISTATE GDXGenDudeFireD;
|
||||
extern AISTATE GDXGenDudeFireW;
|
||||
extern AISTATE GDXGenDudeRecoilL;
|
||||
extern AISTATE GDXGenDudeRecoilD;
|
||||
extern AISTATE GDXGenDudeRecoilW;
|
||||
extern AISTATE GDXGenDudeThrow;
|
||||
extern AISTATE GDXGenDudeThrow2;
|
||||
extern AISTATE GDXGenDudePunch;
|
||||
extern AISTATE GDXGenDudeRTesla;
|
||||
extern AISTATE GDXGenDudeTransform;
|
||||
extern AISTATE genDudeIdleL;
|
||||
extern AISTATE genDudeIdleW;
|
||||
extern AISTATE genDudeSearchL;
|
||||
extern AISTATE genDudeSearchW;
|
||||
extern AISTATE genDudeGotoL;
|
||||
extern AISTATE genDudeGotoW;
|
||||
extern AISTATE genDudeDodgeL;
|
||||
extern AISTATE genDudeDodgeD;
|
||||
extern AISTATE genDudeDodgeW;
|
||||
extern AISTATE genDudeDodgeShortL;
|
||||
extern AISTATE genDudeDodgeShortD;
|
||||
extern AISTATE genDudeDodgeShortW;
|
||||
extern AISTATE genDudeChaseL;
|
||||
extern AISTATE genDudeChaseD;
|
||||
extern AISTATE genDudeChaseW;
|
||||
extern AISTATE genDudeFireL;
|
||||
extern AISTATE genDudeFireD;
|
||||
extern AISTATE genDudeFireW;
|
||||
extern AISTATE genDudeRecoilL;
|
||||
extern AISTATE genDudeRecoilD;
|
||||
extern AISTATE genDudeRecoilW;
|
||||
extern AISTATE genDudeThrow;
|
||||
extern AISTATE genDudeThrow2;
|
||||
extern AISTATE genDudePunch;
|
||||
extern AISTATE genDudeRecoilTesla;
|
||||
extern AISTATE genDudeSearchNoWalkL;
|
||||
extern AISTATE genDudeSearchNoWalkW;
|
||||
extern AISTATE genDudeChaseNoWalkL;
|
||||
extern AISTATE genDudeChaseNoWalkD;
|
||||
extern AISTATE genDudeChaseNoWalkW;
|
||||
|
||||
struct GENDUDESND
|
||||
{
|
||||
|
@ -93,6 +127,7 @@ struct GENDUDESND
|
|||
int randomRange;
|
||||
int sndIdOffset; // relative to data3
|
||||
bool aiPlaySound; // false = sfxStart3DSound();
|
||||
bool interruptable;
|
||||
};
|
||||
|
||||
extern GENDUDESND gCustomDudeSnd[];
|
||||
|
@ -105,29 +140,41 @@ struct GENDUDEEXTRA {
|
|||
unsigned short curWeapon; // data1 duplicate to avoid potential problems when changing data dynamically
|
||||
unsigned short baseDispersion;
|
||||
signed short nLifeLeech; // spritenum of dropped dude's leech
|
||||
short dmgControl[kDamageMax]; // depends of current weapon, drop armor item and sprite yrepeat
|
||||
short slave[kGenDudeMaxSlaves]; // index of the ones dude is summon
|
||||
short slaveCount;
|
||||
short slave[kGenDudeMaxSlaves]; // index of the ones dude is summon
|
||||
short dmgControl[kDamageMax]; // depends of current weapon, drop armor item, sprite yrepeat and surface type
|
||||
short availDeaths[kDamageMax]; // list of seqs with deaths for each damage type
|
||||
short initVals[3]; // xrepeat, yrepeat, clipdist
|
||||
bool forcePunch; // indicate if there is no fire trigger in punch state seq
|
||||
bool updReq[kGenDudePropertyMax]; // update requests
|
||||
bool sndPlaying; // indicate if sound of AISTATE currently playing
|
||||
bool isMelee;
|
||||
bool canBurn; // can turn in Burning dude or not
|
||||
bool canElectrocute;
|
||||
bool canAttack;
|
||||
bool canRecoil;
|
||||
bool canWalk;
|
||||
bool canDuck;
|
||||
bool canSwim;
|
||||
bool canFly;
|
||||
|
||||
};
|
||||
|
||||
extern GENDUDEEXTRA gGenDudeExtra[];
|
||||
|
||||
inline GENDUDEEXTRA* genDudeExtra(spritetype* pSprite) {
|
||||
return &gGenDudeExtra[pSprite->index];
|
||||
}
|
||||
|
||||
XSPRITE* getNextIncarnation(XSPRITE* pXSprite);
|
||||
void killDudeLeech(spritetype* pLeech);
|
||||
void removeLeech(spritetype* pLeech, bool delSprite = true);
|
||||
void removeDudeStuff(spritetype* pSprite);
|
||||
spritetype* leechIsDropped(spritetype* pSprite);
|
||||
bool spriteIsUnderwater(spritetype* pSprite, bool oldWay);
|
||||
bool sfxPlayGDXGenDudeSound(spritetype* pSprite, int mode);
|
||||
bool spriteIsUnderwater(spritetype* pSprite, bool oldWay = false);
|
||||
bool playGenDudeSound(spritetype* pSprite, int mode, bool forceInterrupt = false);
|
||||
void aiGenDudeMoveForward(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
void aiGenDudeChooseDirection(spritetype* pSprite, XSPRITE* pXSprite, int a3, int aXvel = -1, int aYvel = -1);
|
||||
void aiGenDudeNewState(spritetype* pSprite, AISTATE* pAIState);
|
||||
int getGenDudeMoveSpeed(spritetype* pSprite, int which, bool mul, bool shift);
|
||||
bool TargetNearThing(spritetype* pSprite, int thingType);
|
||||
int checkAttackState(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
|
@ -143,12 +190,16 @@ bool canDuck(spritetype* pSprite);
|
|||
bool canWalk(spritetype* pSprite);
|
||||
bool inDodge(AISTATE* aiState);
|
||||
bool inIdle(AISTATE* aiState);
|
||||
int getSeqStartId(XSPRITE* pXSprite);
|
||||
int getSeeDist(spritetype* pSprite, int startDist, int minDist, int maxDist);
|
||||
bool inAttack(AISTATE* aiState);
|
||||
short inRecoil(AISTATE* aiState);
|
||||
short inSearch(AISTATE* aiState);
|
||||
short inDuck(AISTATE* aiState);
|
||||
int genDudeSeqStartId(XSPRITE* pXSprite);
|
||||
int getRangeAttackDist(spritetype* pSprite, int minDist = 1200, int maxDist = 80000);
|
||||
int getDispersionModifier(spritetype* pSprite, int minDisp, int maxDisp);
|
||||
void scaleDamage(XSPRITE* pXSprite);
|
||||
void genDudePrepare(spritetype* pSprite, int propId = kGenDudePropertyAll);
|
||||
bool genDudePrepare(spritetype* pSprite, int propId = kGenDudePropertyAll);
|
||||
void genDudeUpdate(spritetype* pSprite);
|
||||
void genDudeProcess(spritetype* pSprite, XSPRITE* pXSprite);
|
||||
|
||||
END_BLD_NS
|
||||
|
|
|
@ -608,6 +608,7 @@ void StartLevel(GAMEOPTIONS *gameOptions)
|
|||
case kModernObjDataAccumulator:
|
||||
case kModernEffectSpawner:
|
||||
case kModernWindGenerator:
|
||||
case kModernPlayerControl:
|
||||
pSprite->type = kSpriteDecoration;
|
||||
break;
|
||||
case kItemModernMapLevel:
|
||||
|
|
|
@ -45,6 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "trig.h"
|
||||
#include "triggers.h"
|
||||
#include "view.h"
|
||||
#include "aiunicult.h"
|
||||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
|
@ -763,6 +764,12 @@ void makeMissileBlocking(int nSprite) // 23
|
|||
sprite[nSprite].cstat |= CSTAT_SPRITE_BLOCK;
|
||||
}
|
||||
|
||||
void genDudeUpdateCallback(int nSprite) // 24
|
||||
{
|
||||
if (spriRangeIsFine(nSprite))
|
||||
genDudeUpdate(&sprite[nSprite]);
|
||||
}
|
||||
|
||||
void(*gCallback[kCallbackMax])(int) =
|
||||
{
|
||||
fxFlameLick,
|
||||
|
@ -789,6 +796,7 @@ void(*gCallback[kCallbackMax])(int) =
|
|||
DropVoodoo, // unused
|
||||
UniMissileBurst,
|
||||
makeMissileBlocking,
|
||||
genDudeUpdateCallback,
|
||||
};
|
||||
|
||||
END_BLD_NS
|
||||
|
|
|
@ -51,6 +51,7 @@ enum CALLBACK_ID {
|
|||
kCallbackDropVoodoo = 21, // unused
|
||||
kCallbackMissileBurst = 22, // by NoOne
|
||||
kCallbackMissileSpriteBlock = 23, // by NoOne
|
||||
kCallbackGenDudeUpdate = 24, // by NoOne
|
||||
kCallbackMax,
|
||||
};
|
||||
|
||||
|
|
|
@ -436,6 +436,17 @@ enum {
|
|||
kSectorMax = 620,
|
||||
};
|
||||
|
||||
// ai state types
|
||||
enum {
|
||||
kAiStateOther = -1,
|
||||
kAiStateIdle = 0,
|
||||
kAiStateGenIdle = 1,
|
||||
kAiStateMove = 2,
|
||||
kAiStateSearch = 3,
|
||||
kAiStateChase = 4,
|
||||
kAiStateRecoil = 5,
|
||||
kAiStateAttack = 6,
|
||||
};
|
||||
|
||||
// sprite attributes
|
||||
#define kHitagAutoAim 0x0008
|
||||
|
@ -472,16 +483,6 @@ enum {
|
|||
#define kSecCFloorShade 0x8000
|
||||
|
||||
|
||||
// ai state types
|
||||
#define kAiStateOther -1
|
||||
#define kAiStateIdle 0
|
||||
#define kAiStateGenIdle 1
|
||||
#define kAiStateMove 2
|
||||
#define kAiStateSearch 3
|
||||
#define kAiStateChase 4
|
||||
#define kAiStateRecoil 5
|
||||
|
||||
|
||||
#define kAng5 28
|
||||
#define kAng15 85
|
||||
#define kAng30 170
|
||||
|
|
|
@ -32,7 +32,7 @@ BEGIN_BLD_NS
|
|||
#define kMaxSuperXSprites 128
|
||||
|
||||
// by NoOne: functions to quckly check range of specifical arrays
|
||||
inline bool xsprRangeIsFine(int nXindex) {
|
||||
inline bool xspriRangeIsFine(int nXindex) {
|
||||
return (nXindex >= 0 && nXindex < kMaxXSprites);
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,10 @@ inline bool xwallRangeIsFine(int nXindex) {
|
|||
return (nXindex >= 0 && nXindex < kMaxXWalls);
|
||||
}
|
||||
|
||||
inline bool xspriIsFine(int nIndex) {
|
||||
return (nIndex >= 0 && nIndex < kMaxSprites && !(sprite[nIndex].flags & 32) && sprite[nIndex].statnum != kStatFree);
|
||||
}
|
||||
|
||||
extern bool gModernMap;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
|
|
@ -1544,7 +1544,7 @@ DUDEINFO dudeInfo[kDudeMax-kDudeBase] =
|
|||
0,
|
||||
0
|
||||
},
|
||||
//254 - kGDXUniversalCultist
|
||||
//254 - kDudeModernCustom
|
||||
{
|
||||
11520, // start sequence ID
|
||||
85, // start health
|
||||
|
@ -1570,12 +1570,12 @@ DUDEINFO dudeInfo[kDudeMax-kDudeBase] =
|
|||
256, // angSpeed
|
||||
// 0,
|
||||
7, -1, 18, // nGibType
|
||||
128, 128, 128, 128, 128, 128, 128,
|
||||
128, 150, 128, 256, 128, 128, 128,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0
|
||||
},
|
||||
//255 - kGDXGenDudeBurning
|
||||
//255 - kDudeModernCustomBurning
|
||||
{
|
||||
4096, // start sequence ID
|
||||
25, // start health
|
||||
|
|
|
@ -158,45 +158,6 @@ void CKillMgr::sub_2641C(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void CKillMgr::AddKill(spritetype *pSprite) {
|
||||
if (pSprite->statnum == kStatDude) {
|
||||
switch (pSprite->type) {
|
||||
case kDudeBat:
|
||||
case kDudeRat:
|
||||
case kDudeBurningInnocent:
|
||||
case kDudeInnocent:
|
||||
return;
|
||||
}
|
||||
|
||||
at4++;
|
||||
}
|
||||
}
|
||||
|
||||
void CKillMgr::sub_2641C(void)
|
||||
{
|
||||
at0 = 0;
|
||||
for (int nSprite = headspritestat[kStatDude]; nSprite >= 0; nSprite = nextspritestat[nSprite]) {
|
||||
|
||||
spritetype *pSprite = &sprite[nSprite];
|
||||
if (IsDudeSprite(pSprite)) {
|
||||
if (pSprite->statnum == kStatDude) {
|
||||
switch (pSprite->type) {
|
||||
case kDudeBat:
|
||||
case kDudeRat:
|
||||
case kDudeBurningInnocent:
|
||||
case kDudeInnocent:
|
||||
return;
|
||||
}
|
||||
|
||||
at0++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void CKillMgr::Draw(void)
|
||||
{
|
||||
char pBuffer[40];
|
||||
|
|
|
@ -427,11 +427,12 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command, short causedBy)
|
|||
break;
|
||||
}
|
||||
|
||||
//by NoOne: allow to send commands on player sprites
|
||||
|
||||
if (gModernMap) {
|
||||
|
||||
// allow to send commands on player sprites
|
||||
PLAYER* pPlayer = NULL;
|
||||
if (rxId >= kChannelPlayer0 && rxId <= kChannelPlayer7) {
|
||||
if (playerRXRngIsFine(rxId)) {
|
||||
if ((pPlayer = getPlayerById((kChannelPlayer0 - kChannelPlayer7) + kMaxPlayers)) != NULL)
|
||||
trMessageSprite(pPlayer->nSprite, event);
|
||||
} else if (rxId == kChannelAllPlayers) {
|
||||
|
@ -439,6 +440,9 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command, short causedBy)
|
|||
if ((pPlayer = getPlayerById(i)) != NULL)
|
||||
trMessageSprite(pPlayer->nSprite, event);
|
||||
}
|
||||
// send command on sprite which create the event sequence
|
||||
} else if (rxId == kChannelEventCauser && spriRangeIsFine(event.causedBy)) {
|
||||
trMessageSprite(event.causedBy, event);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,9 +40,8 @@ kChannelLevelStartCoop,
|
|||
kChannelLevelStartTeamsOnly,
|
||||
kChannelPlayerDeathTeamA = 15,
|
||||
kChannelPlayerDeathTeamB,
|
||||
|
||||
// by NoOne: RX channels of players to send commands on
|
||||
/////////////////////////////
|
||||
// channels of players to send commands on
|
||||
kChannelPlayer0 = 30,
|
||||
kChannelPlayer1,
|
||||
kChannelPlayer2,
|
||||
|
@ -52,10 +51,11 @@ kChannelPlayer5,
|
|||
kChannelPlayer6,
|
||||
kChannelPlayer7,
|
||||
kChannelAllPlayers = kChannelPlayer0 + kMaxPlayers,
|
||||
// channel of event causer
|
||||
kChannelEventCauser = 50,
|
||||
// map requires modern features to work properly
|
||||
kChannelMapModernize = 60,
|
||||
/////////////////////////////
|
||||
|
||||
kChannelMapModernize = 60, // map requires modern features to work properly
|
||||
|
||||
kChannelTeamAFlagCaptured = 80,
|
||||
kChannelTeamBFlagCaptured,
|
||||
kChannelRemoteBomb0 = 90,
|
||||
|
|
|
@ -360,7 +360,7 @@ void levelEndLevel(int arg)
|
|||
}
|
||||
}
|
||||
|
||||
// By NoOne: this function can be called via sending numbered command to TX kGDXChannelEndLevel
|
||||
// By NoOne: this function can be called via sending numbered command to TX kChannelModernEndLevelCustom
|
||||
// This allows to set custom next level instead of taking it from INI file.
|
||||
void levelEndLevelCustom(int nLevel) {
|
||||
|
||||
|
|
|
@ -483,23 +483,45 @@ QAV* qavSceneLoad(int qavId) {
|
|||
return pQav;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void qavSceneDraw(PLAYER* pPlayer, int a2, int a3, int a4, int a5) {
|
||||
if (pPlayer == NULL || pPlayer->sceneQav == -1) return;
|
||||
|
||||
QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene;
|
||||
spritetype* pSprite = &sprite[pQavScene->index];
|
||||
|
||||
if (pQavScene->qavResrc != NULL) {
|
||||
|
||||
QAV* pQAV = pQavScene->qavResrc;
|
||||
int v4 = (pPlayer->weaponTimer == 0) ? (int)totalclock % pQAV->at10 : pQAV->at10 - pPlayer->weaponTimer;
|
||||
|
||||
pQAV->x = a3; pQAV->y = a4; int flags = 2;
|
||||
int nInv = powerupCheck(pPlayer, kPwUpShadowCloak);
|
||||
int flags = 2; int nInv = powerupCheck(pPlayer, kPwUpShadowCloak);
|
||||
if (nInv >= 120 * 8 || (nInv != 0 && ((int)totalclock & 32))) {
|
||||
a2 = -128;
|
||||
flags |= 1;
|
||||
a2 = -128; flags |= 1;
|
||||
}
|
||||
|
||||
// draw as weapon
|
||||
if (!(pSprite->flags & kModernTypeFlag1)) {
|
||||
|
||||
pQAV->x = a3; pQAV->y = a4;
|
||||
pQAV->Draw(v4, flags, a2, a5);
|
||||
|
||||
// draw fullscreen (currently 4:3 only)
|
||||
} else {
|
||||
|
||||
int wx1 = windowxy1.x, wy1 = windowxy1.y, wx2 = windowxy2.x, wy2 = windowxy2.y;
|
||||
|
||||
windowxy2.x = xdim - 1; windowxy2.y = ydim - 1;
|
||||
windowxy1.x = windowxy1.y = 0;
|
||||
|
||||
pQAV->Draw(v4, flags, a2, a5);
|
||||
|
||||
windowxy1.x = wx1; windowxy1.y = wy1;
|
||||
windowxy2.x = wx2; windowxy2.y = wy2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ struct PLAYER {
|
|||
DUDEINFO *pDudeInfo;
|
||||
GINPUT input;
|
||||
//short input; // INPUT
|
||||
//char at10; // forward
|
||||
//char moveFunc; // forward
|
||||
//short at11; // turn
|
||||
//char hearDist; // strafe
|
||||
//int bobV; // buttonFlags
|
||||
|
@ -216,11 +216,15 @@ struct POWERUPINFO {
|
|||
int maxTime;
|
||||
};
|
||||
|
||||
|
||||
#define kQavSceneStackSize 16
|
||||
// by NoOne: this one stores qavs anims that can be played by trigger
|
||||
struct QAVSCENE {
|
||||
short index = -1; // index of sprite which triggered qav scene
|
||||
QAV* qavResrc = NULL;
|
||||
short causedBy = -1;
|
||||
|
||||
// TO-DO: Stack of animations which allows to pop and push (restoring previous animation instead of weapon once current animation is played)
|
||||
};
|
||||
|
||||
// by NoOne: this one for controlling the player using triggers (movement speed, jumps and other stuff)
|
||||
|
|
|
@ -56,7 +56,7 @@ struct Seq {
|
|||
short at8;
|
||||
short ata;
|
||||
int atc;
|
||||
SEQFRAME frames[1]; // at10
|
||||
SEQFRAME frames[1];
|
||||
void Preload(void);
|
||||
void Precache(void);
|
||||
};
|
||||
|
|
|
@ -42,28 +42,6 @@ POINT2D earL, earR, earL0, earR0; // Ear position
|
|||
VECTOR2D earVL, earVR; // Ear velocity ?
|
||||
int lPhase, rPhase, lVol, rVol, lPitch, rPitch;
|
||||
|
||||
struct BONKLE
|
||||
{
|
||||
int at0;
|
||||
int at4;
|
||||
DICTNODE *at8;
|
||||
int atc;
|
||||
spritetype *at10;
|
||||
int at14;
|
||||
int at18;
|
||||
int at1c;
|
||||
POINT3D at20;
|
||||
POINT3D at2c;
|
||||
//int at20;
|
||||
//int at24;
|
||||
//int at28;
|
||||
//int at2c;
|
||||
//int at30;
|
||||
//int at34;
|
||||
int at38;
|
||||
int at3c;
|
||||
};
|
||||
|
||||
BONKLE Bonkle[256];
|
||||
BONKLE *BonkleCache[256];
|
||||
|
||||
|
|
|
@ -25,6 +25,31 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
struct BONKLE
|
||||
{
|
||||
int at0;
|
||||
int at4;
|
||||
DICTNODE* at8;
|
||||
int atc;
|
||||
spritetype* at10;
|
||||
int at14;
|
||||
int at18;
|
||||
int at1c;
|
||||
POINT3D at20;
|
||||
POINT3D at2c;
|
||||
//int at20;
|
||||
//int at24;
|
||||
//int at28;
|
||||
//int at2c;
|
||||
//int at30;
|
||||
//int at34;
|
||||
int at38;
|
||||
int at3c;
|
||||
};
|
||||
|
||||
extern BONKLE Bonkle[256];
|
||||
extern BONKLE* BonkleCache[256];
|
||||
|
||||
void sfxInit(void);
|
||||
void sfxTerm(void);
|
||||
void sfxPlay3DSound(int x, int y, int z, int soundId, int nSector);
|
||||
|
|
|
@ -863,29 +863,30 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
}
|
||||
return;
|
||||
case kModernPlayerControl: // WIP
|
||||
PLAYER* pPlayer = NULL; int nPlayer = pXSprite->data1;
|
||||
PLAYER* pPlayer = NULL; int nPlayer = pXSprite->data1; int oldCmd = -1;
|
||||
if (pXSprite->data1 == 0 && spriRangeIsFine(event.causedBy))
|
||||
nPlayer = sprite[event.causedBy].type;
|
||||
|
||||
if ((pPlayer = getPlayerById(nPlayer)) == NULL || pPlayer->pXSprite->health <= 0)
|
||||
return;
|
||||
if ((pPlayer = getPlayerById(nPlayer)) == NULL || pPlayer->pXSprite->health <= 0) return;
|
||||
else if (pXSprite->command < kCmdNumberic + 3 && pXSprite->command > kCmdNumberic + 4
|
||||
&& !modernTypeSetSpriteState(nSprite, pXSprite, pXSprite->state ^ 1, event.causedBy)) return;
|
||||
|
||||
TRPLAYERCTRL* pCtrl = pCtrl = &gPlayerCtrl[pPlayer->nPlayer];
|
||||
if (event.cmd >= kCmdNumberic) {
|
||||
switch (event.cmd) {
|
||||
case kCmdNumberic + 3:// start playing qav scene
|
||||
viewSetSystemMessage("START QAV %d, %d", pXSprite->rxID, pXSprite->txID);
|
||||
if (pCtrl->qavScene.index != nSprite || pXSprite->Interrutable)
|
||||
trPlayerCtrlStartScene(pXSprite, pPlayer, event.causedBy);
|
||||
break;
|
||||
return;
|
||||
case kCmdNumberic + 4: // stop playing qav scene
|
||||
viewSetSystemMessage("STOP QAV", gPlayerCtrl[pPlayer->nPlayer].qavScene.index);
|
||||
if (pCtrl->qavScene.index == nSprite)
|
||||
if (pCtrl->qavScene.index == nSprite || event.type != 3 || sprite[event.index].type != kModernPlayerControl)
|
||||
trPlayerCtrlStopScene(pXSprite, pPlayer);
|
||||
return;
|
||||
default:
|
||||
oldCmd = pXSprite->command;
|
||||
pXSprite->command = event.cmd; // convert event command to current sprite command
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// !!! COMMANDS OF THE CURRENT SPRITE, NOT OF THE EVENT !!! ///
|
||||
|
@ -923,7 +924,8 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
gPosture[i][a].frontAccel = gPosture[i][a].sideAccel = gPosture[i][a].backAccel = ClipRange(mulscale8(defSpeed, speed), 0, 65535);
|
||||
}
|
||||
}
|
||||
viewSetSystemMessage("MOVEMENT: %d %d %d", pXSprite->rxID,pSprite->index, gPosture[0][0].frontAccel);
|
||||
|
||||
//viewSetSystemMessage("MOVEMENT: %d %d %d", pXSprite->rxID,pSprite->index, gPosture[0][0].frontAccel);
|
||||
}
|
||||
|
||||
// player jump height (for all players ATM)
|
||||
|
@ -941,7 +943,7 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
}
|
||||
}
|
||||
}
|
||||
viewSetSystemMessage("JUMPING: %d", gPosture[0][0].normalJumpZ);
|
||||
//viewSetSystemMessage("JUMPING: %d", gPosture[0][0].normalJumpZ);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -950,7 +952,7 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
if (pXSprite->data3 < 0) break;
|
||||
switch (pXSprite->data2) {
|
||||
case 1: // tilting
|
||||
pPlayer->tiltEffect = pXSprite->data3;
|
||||
pPlayer->tiltEffect = ClipRange(pXSprite->data3, 0, 220);
|
||||
break;
|
||||
case 2: // pain
|
||||
pPlayer->painEffect = pXSprite->data3;
|
||||
|
@ -987,27 +989,25 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
|
||||
case kCmdNumberic + 5: // 69
|
||||
// set player sprite and look angles
|
||||
if (pXSprite->data2 == 0) {
|
||||
if (pXSprite->data4 == 0) {
|
||||
|
||||
// look angle
|
||||
if (valueIsBetween(pXSprite->data3, -128, 128)) {
|
||||
if (valueIsBetween(pXSprite->data2, -128, 128)) {
|
||||
CONSTEXPR int upAngle = 289; CONSTEXPR int downAngle = -347;
|
||||
CONSTEXPR double lookStepUp = 4.0 * upAngle / 60.0;
|
||||
CONSTEXPR double lookStepDown = -4.0 * downAngle / 60.0;
|
||||
|
||||
int look = pXSprite->data3 << 5;
|
||||
int look = pXSprite->data2 << 5;
|
||||
if (look > 0) pPlayer->q16look = fix16_min(mulscale8(F16(lookStepUp), look), F16(upAngle));
|
||||
else if (look < 0) pPlayer->q16look = -fix16_max(mulscale8(F16(lookStepDown), abs(look)), F16(downAngle));
|
||||
else pPlayer->q16look = 0;
|
||||
}
|
||||
|
||||
// angle
|
||||
if ((pSprite->flags & kModernTypeFlag1) && valueIsBetween(pXSprite->data4, 0, kAng180))
|
||||
pPlayer->pSprite->ang = pXSprite->data4;
|
||||
else if (pXSprite->data4 == 1)
|
||||
pPlayer->pSprite->ang = pSprite->ang;
|
||||
|
||||
|
||||
// TO-DO: if tx > 0, take a look on TX ID sprite
|
||||
if (pXSprite->data3 == 1) pPlayer->pSprite->ang = pXSprite->data3;
|
||||
else if (valueIsBetween(pXSprite->data3, 0, kAng180))
|
||||
pPlayer->pSprite->ang = pXSprite->data3;
|
||||
}
|
||||
//viewSetSystemMessage("ANGLE: %d, SLOPE: %d", pPlayer->pSprite->ang, pPlayer->q16look);
|
||||
break;
|
||||
|
@ -1017,15 +1017,16 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
switch (pXSprite->data2) {
|
||||
// erase all
|
||||
case 0:
|
||||
// erase all weapons except pitchfork
|
||||
// erase weapons
|
||||
case 1:
|
||||
// erase all
|
||||
if (pXSprite->data3 <= 0) {
|
||||
WeaponLower(pPlayer);
|
||||
|
||||
for (int i = 0; i < 14; i++) {
|
||||
pPlayer->hasWeapon[i] = false;
|
||||
// also erase ammo
|
||||
if (i < 12 && pXSprite->data3 == 1)
|
||||
pPlayer->ammoCount[i] = 0;
|
||||
if (i < 12) pPlayer->ammoCount[i] = 0;
|
||||
}
|
||||
|
||||
pPlayer->hasWeapon[1] = true;
|
||||
|
@ -1033,6 +1034,11 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
pPlayer->nextWeapon = 1;
|
||||
|
||||
WeaponRaise(pPlayer);
|
||||
|
||||
// erase just specified
|
||||
} else {
|
||||
|
||||
}
|
||||
if (pXSprite->data2) break;
|
||||
// erase all armor
|
||||
case 2:
|
||||
|
@ -1065,11 +1071,11 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
if (pXSprite->data2 == 1) {
|
||||
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + pWeaponData->count, gAmmoInfo[nAmmoType].max);
|
||||
} else {
|
||||
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + pXSprite->data3, gAmmoInfo[nAmmoType].max);
|
||||
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + pXSprite->data4, gAmmoInfo[nAmmoType].max);
|
||||
break;
|
||||
}
|
||||
|
||||
pPlayer->hasWeapon[pXSprite->data2] = true;
|
||||
pPlayer->hasWeapon[pXSprite->data3] = true;
|
||||
|
||||
if (pXSprite->data4 == 0) { // switch on it
|
||||
if (pPlayer->sceneQav >= 0) {
|
||||
|
@ -1085,7 +1091,19 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case kCmdNumberic + 8: // 72
|
||||
// use inventory item
|
||||
if (pXSprite->data2 > 0 && pXSprite->data2 <= 5) {
|
||||
packUseItem(pPlayer, pXSprite->data2 - 1);
|
||||
|
||||
// force remove after use
|
||||
if (pXSprite->data4 == 1)
|
||||
pPlayer->packSlots[0].curAmount = pPlayer->packSlots[0].curAmount = 0;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (oldCmd > -1) pXSprite->command = oldCmd;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1549,10 +1567,6 @@ void useObjResizer(XSPRITE* pXSource, short objType, int objIndex) {
|
|||
// for sprites
|
||||
case 3:
|
||||
|
||||
/*PLAYER* pPlayer = NULL;
|
||||
if (playerRXRngIsFine(pXSource->txID) && (pPlayer = getPlayerById((kChannelPlayer0 - kChannelPlayer7) + kMaxPlayers)) != NULL)
|
||||
objIndex = pPlayer->nSprite;*/
|
||||
|
||||
// resize by seq scaling
|
||||
if (sprite[pXSource->reference].flags & kModernTypeFlag1) {
|
||||
if (valueIsBetween(pXSource->data1, -255, 32767)) {
|
||||
|
@ -1565,9 +1579,11 @@ void useObjResizer(XSPRITE* pXSource, short objType, int objIndex) {
|
|||
switch (sprite[objIndex].type) {
|
||||
case kDudeModernCustom:
|
||||
case kDudeModernCustomBurning:
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertySpriteSize] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyAttack] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyMass] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyDamage] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyDmgScale] = true;
|
||||
evPost(objIndex, 3, kGenDudeUpdTimeRate, kCallbackGenDudeUpdate, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1583,7 +1599,6 @@ void useObjResizer(XSPRITE* pXSource, short objType, int objIndex) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
if (valueIsBetween(pXSource->data3, -1, 32767))
|
||||
sprite[objIndex].xoffset = ClipRange(pXSource->data3, 0, 255);
|
||||
|
||||
|
@ -1876,7 +1891,12 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
if (pXSector != NULL && pXSector->Underwater) xsprite[pSprite->extra].medium = kMediumWater;
|
||||
else xsprite[pSprite->extra].medium = kMediumNormal;
|
||||
|
||||
if (pXSource->data2 == 1) pSprite->ang = pSource->ang;
|
||||
if (pXSource->data2 == 1) {
|
||||
pSprite->ang = pSource->ang;
|
||||
if (IsDudeSprite(pSprite) && xspriRangeIsFine(pSprite->index))
|
||||
xsprite[pSprite->extra].goalAng = pSprite->ang;
|
||||
}
|
||||
|
||||
if (pXSource->data3 == 1)
|
||||
xvel[pSprite->xvel] = yvel[pSprite->xvel] = zvel[pSprite->xvel] = 0;
|
||||
|
||||
|
@ -2006,11 +2026,21 @@ void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void useSpriteDamager(XSPRITE* pXSource, spritetype* pSprite) {
|
||||
if (pSprite != NULL) {
|
||||
int dmgType = (pXSource->data2 == 7) ? Random(6) : ClipRange(pXSource->data2, 0, 6);
|
||||
|
||||
spritetype* pSource = &sprite[pXSource->reference];
|
||||
if (pSprite != NULL && xspriIsFine(pSprite->index)) {
|
||||
int dmg = (pXSource->data3 == 0) ? 65535 : ClipRange(pXSource->data3, 1, 65535);
|
||||
actDamageSprite(pSprite->index, pSprite, (DAMAGE_TYPE)dmgType, dmg);
|
||||
int dmgType = ClipRange(pXSource->data2, 0, 6);
|
||||
|
||||
if (pXSource->data2 == -1 && IsDudeSprite(pSprite)) {
|
||||
xsprite[pSprite->extra].health = ClipLow(xsprite[pSprite->extra].health - dmg, 0);
|
||||
if (xsprite[pSprite->extra].health == 0)
|
||||
actKillDude(pSource->index, pSprite, (DAMAGE_TYPE)0, 65535);
|
||||
}
|
||||
else actDamageSprite(pSource->index, pSprite, (DAMAGE_TYPE)dmgType, dmg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4206,7 +4236,22 @@ int getDataFieldOfObject(int objType, int objIndex, int dataIndex) {
|
|||
|
||||
bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value, int causedBy) {
|
||||
switch (objType) {
|
||||
case 3:
|
||||
case 3: {
|
||||
|
||||
XSPRITE* pXSprite = &xsprite[sprite[objIndex].extra];
|
||||
|
||||
// exceptions
|
||||
if (IsDudeSprite(&sprite[objIndex]) && pXSprite->health <= 0) return true;
|
||||
/*switch (sprite[objIndex].type) {
|
||||
case kThingBloodBits:
|
||||
case kThingBloodChunks:
|
||||
case kThingZombieHead:
|
||||
case kThingObjectGib:
|
||||
case kThingObjectExplode:
|
||||
if (pXSprite->data1 > 0 || pXSprite->data2 > 0 || pXSprite->data3 > 0 || pXSprite->data4 > 0) return true;
|
||||
break;
|
||||
}*/
|
||||
|
||||
switch (dataIndex) {
|
||||
case 1:
|
||||
xsprite[sprite[objIndex].extra].data1 = value;
|
||||
|
@ -4218,8 +4263,8 @@ bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value, i
|
|||
case kDudeModernCustom:
|
||||
case kDudeModernCustomBurning:
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyWeapon] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyMelee] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyDamage] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyDmgScale] = true;
|
||||
evPost(objIndex, 3, kGenDudeUpdTimeRate, kCallbackGenDudeUpdate, causedBy);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
@ -4228,10 +4273,12 @@ bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value, i
|
|||
switch (sprite[objIndex].type) {
|
||||
case kDudeModernCustom:
|
||||
case kDudeModernCustomBurning:
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertySpriteSize] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyMass] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyDamage] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyDmgScale] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyStates] = true;
|
||||
gGenDudeExtra[objIndex].updReq[kGenDudePropertyAttack] = true;
|
||||
evPost(objIndex, 3, kGenDudeUpdTimeRate, kCallbackGenDudeUpdate, causedBy);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
@ -4250,6 +4297,7 @@ bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value, i
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
xsector[sector[objIndex].extra].data = value;
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue