- Added ifdefs for NOONE_EXTENSIONS that provides modern features for mappers

and changes that was required to minimize their amount in code.

# Conflicts:
#	source/blood/src/actor.cpp
#	source/blood/src/ai.h
#	source/blood/src/aiunicult.cpp
#	source/blood/src/aiunicult.h
#	source/blood/src/db.cpp
#	source/blood/src/db.h
#	source/blood/src/dude.h
#	source/blood/src/gameutil.cpp
#	source/blood/src/loadsave.cpp
#	source/blood/src/player.h
#	source/blood/src/sfx.cpp
#	source/blood/src/triggers.h
#	source/blood/src/view.cpp
#	source/blood/src/weapon.cpp
This commit is contained in:
NoOneBlood 2020-01-26 14:19:01 +03:00 committed by Christoph Oelckers
parent 5db1f95b29
commit 0693b0efc8
27 changed files with 1564 additions and 1350 deletions

File diff suppressed because it is too large Load diff

View file

@ -64,16 +64,12 @@ enum VECTOR_TYPE {
VECTOR_TYPE_19, VECTOR_TYPE_19,
VECTOR_TYPE_20, VECTOR_TYPE_20,
VECTOR_TYPE_21, VECTOR_TYPE_21,
VECTOR_TYPE_22, #ifdef NOONE_EXTENSIONS
kVectorGenDudePunch,
#endif
kVectorMax, kVectorMax,
}; };
enum {
kRandomizeItem = 0,
kRandomizeDude = 1,
kRandomizeTX = 2,
};
struct THINGINFO struct THINGINFO
{ {
short startHealth; short startHealth;
@ -89,7 +85,6 @@ struct THINGINFO
unsigned char xrepeat; // xrepeat unsigned char xrepeat; // xrepeat
unsigned char yrepeat; // yrepeat unsigned char yrepeat; // yrepeat
int dmgControl[kDamageMax]; // damage int dmgControl[kDamageMax]; // damage
bool allowThrow; // By NoOne: indicates if kDudeModernCustom can throw it
}; };
struct AMMOITEMDATA struct AMMOITEMDATA
@ -138,8 +133,6 @@ struct MissileType
unsigned char yrepeat; unsigned char yrepeat;
char shade; char shade;
unsigned char clipDist; unsigned char clipDist;
int fireSound[2]; // By NoOne: predefined fire sounds. used by kDudeModernCustom, but can be used for something else.
bool dmgType[kDamageMax]; // By NoOne: list of damages types missile can use
}; };
struct EXPLOSION struct EXPLOSION
@ -147,7 +140,7 @@ struct EXPLOSION
unsigned char repeat; unsigned char repeat;
char dmg; char dmg;
char dmgRng; char dmgRng;
int radius; // radius int radius;
int dmgType; int dmgType;
int burnTime; int burnTime;
int ticks; int ticks;
@ -172,22 +165,8 @@ struct VECTORDATA {
int bloodSplats; // blood splats int bloodSplats; // blood splats
int splatChance; // blood splat chance int splatChance; // blood splat chance
SURFHIT surfHit[15]; SURFHIT surfHit[15];
int fireSound[2]; // By NoOne: predefined fire sounds. used by kDudeModernCustom, but can be used for something else.
}; };
// by NoOne: sprite mass info for getSpriteMassBySize();
struct SPRITEMASS {
int seqId;
short picnum; // mainly needs for moving debris
short xrepeat;
short yrepeat;
short clipdist; // mass multiplier
int mass;
short airVel; // mainly needs for moving debris
int fraction; // mainly needs for moving debris
};
extern AMMOITEMDATA gAmmoItemData[]; extern AMMOITEMDATA gAmmoItemData[];
extern WEAPONITEMDATA gWeaponItemData[]; extern WEAPONITEMDATA gWeaponItemData[];
extern ITEMDATA gItemData[]; extern ITEMDATA gItemData[];
@ -281,6 +260,9 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6,
void actPostSprite(int nSprite, int nStatus); void actPostSprite(int nSprite, int nStatus);
void actPostProcess(void); void actPostProcess(void);
void MakeSplash(spritetype *pSprite, XSPRITE *pXSprite); void MakeSplash(spritetype *pSprite, XSPRITE *pXSprite);
void actBuildMissile(spritetype* pMissile, int nXSprite, int nSprite);
#ifdef NOONE_EXTENSIONS
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);
@ -290,13 +272,46 @@ bool sfxPlayVectorSound(spritetype* pSprite, int vectorId);
spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist); spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist);
int getSpriteMassBySize(spritetype* pSprite); int getSpriteMassBySize(spritetype* pSprite);
bool ceilIsTooLow(spritetype* pSprite); bool ceilIsTooLow(spritetype* pSprite);
void actBuildMissile(spritetype* pMissile, int nXSprite, int nSprite);
int isDebris(int nSprite); int isDebris(int nSprite);
int debrisGetFreeIndex(void); int debrisGetFreeIndex(void);
void debrisMove(int listIndex); void debrisMove(int listIndex);
void debrisConcuss(int nOwner, int listIndex, int x, int y, int z, int dmg); void debrisConcuss(int nOwner, int listIndex, int x, int y, int z, int dmg);
bool isImmune(spritetype* pSprite, int dmgType, int minScale = 16); bool isImmune(spritetype* pSprite, int dmgType, int minScale = 16);
enum {
kRandomizeItem = 0,
kRandomizeDude = 1,
kRandomizeTX = 2,
};
// sprite mass info for getSpriteMassBySize();
struct SPRITEMASS {
int seqId;
short picnum; // mainly needs for moving debris
short xrepeat;
short yrepeat;
short clipdist; // mass multiplier
int mass;
short airVel; // mainly needs for moving debris
int fraction; // mainly needs for moving debris
};
struct THINGINFO_EXTRA {
bool allowThrow; // indicates if kDudeModernCustom can throw it
};
struct VECTORINFO_EXTRA {
int fireSound[2]; // predefined fire sounds. used by kDudeModernCustom, but can be used for something else.
};
struct MISSILEINFO_EXTRA {
int fireSound[2]; // predefined fire sounds. used by kDudeModernCustom, but can be used for something else.
bool dmgType[kDamageMax]; // list of damages types missile can use
};
extern THINGINFO_EXTRA gThingInfoExtra[kThingMax];
extern VECTORINFO_EXTRA gVectorInfoExtra[kVectorMax];
extern MISSILEINFO_EXTRA gMissileInfoExtra[kMissileMax];
extern SPRITEMASS gSpriteMass[kMaxXSprites]; extern SPRITEMASS gSpriteMass[kMaxXSprites];
extern short gProxySpritesList[kMaxSuperXSprites]; extern short gProxySpritesList[kMaxSuperXSprites];
extern short gSightSpritesList[kMaxSuperXSprites]; extern short gSightSpritesList[kMaxSuperXSprites];
@ -304,6 +319,8 @@ extern short gPhysSpritesList[kMaxSuperXSprites];
extern short gProxySpritesCount; extern short gProxySpritesCount;
extern short gSightSpritesCount; extern short gSightSpritesCount;
extern short gPhysSpritesCount; extern short gPhysSpritesCount;
#endif
extern int DudeDifficulty[]; extern int DudeDifficulty[];
END_BLD_NS END_BLD_NS

View file

@ -48,7 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "aitchern.h" #include "aitchern.h"
#include "aizomba.h" #include "aizomba.h"
#include "aizombf.h" #include "aizombf.h"
#include "aiunicult.h" // By NoOne: add custom dude #include "aiunicult.h"
#include "blood.h" #include "blood.h"
#include "db.h" #include "db.h"
#include "dude.h" #include "dude.h"
@ -77,7 +77,7 @@ AISTATE genIdle = {kAiStateGenIdle, 0, -1, 0, NULL, NULL, NULL, NULL };
AISTATE genRecoil = {kAiStateRecoil, 5, -1, 20, NULL, NULL, NULL, &genIdle }; 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};
#ifdef NOONE_EXTENSIONS
void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) { void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) {
switch (pSprite->type) { switch (pSprite->type) {
case kDudeModernCustom: case kDudeModernCustom:
@ -89,6 +89,7 @@ void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) {
break; break;
} }
} }
#endif
bool sub_5BDA8(spritetype *pSprite, int nSeq) bool sub_5BDA8(spritetype *pSprite, int nSeq)
{ {
@ -166,7 +167,8 @@ bool CanMove(spritetype *pSprite, int a2, int nAngle, int nRange)
if (pXSector->Depth) if (pXSector->Depth)
Depth = 1; Depth = 1;
if (sector[nSector].type == kSectorDamage || pXSector->damageType > 0) { if (sector[nSector].type == kSectorDamage || pXSector->damageType > 0) {
// By NoOne: a quick fix for Cerberus spinning in E3M7-like maps, where damage sectors is used. #ifdef NOONE_EXTENSIONS
// a quick fix for Cerberus spinning in E3M7-like maps, where damage sectors is used.
// It makes ignore danger if enemy immune to N damageType. As result Cerberus start acting like // It makes ignore danger if enemy immune to N damageType. As result Cerberus start acting like
// in Blood 1.0 so it can move normally to player. It's up to you for adding rest of enemies here as // in Blood 1.0 so it can move normally to player. It's up to you for adding rest of enemies here as
// i don't think it will broke something in game. // i don't think it will broke something in game.
@ -180,6 +182,9 @@ bool CanMove(spritetype *pSprite, int a2, int nAngle, int nRange)
Crusher = 1; Crusher = 1;
break; break;
} }
#else
Crusher = 1;
#endif
} }
} }
int nUpper = gUpperLink[nSector]; int nUpper = gUpperLink[nSector];
@ -233,11 +238,13 @@ bool CanMove(spritetype *pSprite, int a2, int nAngle, int nRange)
if (floorZ - bottom > 0x2000) if (floorZ - bottom > 0x2000)
return false; return false;
break; break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustom: case kDudeModernCustom:
case kDudeModernCustomBurning: case kDudeModernCustomBurning:
if ((Crusher && !isImmune(pSprite, pXSector->damageType)) || ((Water || Underwater) && !canSwim(pSprite))) return false; if ((Crusher && !isImmune(pSprite, pXSector->damageType)) || ((Water || Underwater) && !canSwim(pSprite))) return false;
return true; return true;
fallthrough__; fallthrough__;
#endif
case kDudeZombieAxeNormal: case kDudeZombieAxeNormal:
case kDudePhantasm: case kDudePhantasm:
case kDudeGillBeast: case kDudeGillBeast:
@ -407,7 +414,7 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
} }
break; break;
} }
#ifdef NOONE_EXTENSIONS
case kDudeModernCustom: case kDudeModernCustom:
{ {
DUDEEXTRA_at6_u1* pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1; DUDEEXTRA_at6_u1* pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
@ -427,6 +434,7 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
if (pXSprite->target == -1) aiGenDudeNewState(pSprite, &genDudeBurnSearch); if (pXSprite->target == -1) aiGenDudeNewState(pSprite, &genDudeBurnSearch);
else aiGenDudeNewState(pSprite, &genDudeBurnChase); else aiGenDudeNewState(pSprite, &genDudeBurnChase);
break; break;
#endif
case kDudeCultistTommyProne: { case kDudeCultistTommyProne: {
DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1; DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1;
pDudeExtraE->at8 = 1; pDudeExtraE->at0 = 0; pDudeExtraE->at8 = 1; pDudeExtraE->at0 = 0;
@ -679,7 +687,9 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
} }
case kDudeGargoyleStatueFlesh: case kDudeGargoyleStatueFlesh:
case kDudeGargoyleStatueStone: case kDudeGargoyleStatueStone:
// By NoOne: play gargoyle statue breaking animation if data1 = 1.
#ifdef NOONE_EXTENSIONS
// play gargoyle statue breaking animation if data1 = 1.
if (gModernMap && pXSprite->data1 == 1) { if (gModernMap && pXSprite->data1 == 1) {
if (pSprite->type == kDudeGargoyleStatueFlesh) aiNewState(pSprite, pXSprite, &statueFBreakSEQ); if (pSprite->type == kDudeGargoyleStatueFlesh) aiNewState(pSprite, pXSprite, &statueFBreakSEQ);
else aiNewState(pSprite, pXSprite, &statueSBreakSEQ); else aiNewState(pSprite, pXSprite, &statueSBreakSEQ);
@ -690,6 +700,13 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite)
if (pSprite->type == kDudeGargoyleStatueFlesh) aiNewState(pSprite, pXSprite, &gargoyleFMorph); if (pSprite->type == kDudeGargoyleStatueFlesh) aiNewState(pSprite, pXSprite, &gargoyleFMorph);
else aiNewState(pSprite, pXSprite, &gargoyleSMorph); else aiNewState(pSprite, pXSprite, &gargoyleSMorph);
} }
#else
if (Chance(0x4000)) aiPlay3DSound(pSprite, 1401, AI_SFX_PRIORITY_1, -1);
else aiPlay3DSound(pSprite, 1400, AI_SFX_PRIORITY_1, -1);
if (pSprite->type == kDudeGargoyleStatueFlesh) aiNewState(pSprite, pXSprite, &gargoyleFMorph);
else aiNewState(pSprite, pXSprite, &gargoyleSMorph);
#endif
break; break;
case kDudeCerberusTwoHead: case kDudeCerberusTwoHead:
if (pXSprite->target == -1) if (pXSprite->target == -1)
@ -1006,6 +1023,7 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
evKill(nSprite, 3, kCallbackFXFlameLick); evKill(nSprite, 3, kCallbackFXFlameLick);
} }
break; break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustomBurning: case kDudeModernCustomBurning:
if (Chance(0x2000) && gDudeExtra[pSprite->extra].at0 < (int)gFrameClock) { if (Chance(0x2000) && gDudeExtra[pSprite->extra].at0 < (int)gFrameClock) {
playGenDudeSound(pSprite, kGenDudeSndBurning); playGenDudeSound(pSprite, kGenDudeSndBurning);
@ -1077,6 +1095,7 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T
} }
break; break;
} }
#endif
case kDudeCultistBeast: case kDudeCultistBeast:
if (pXSprite->health <= (unsigned int)pDudeInfo->fleeHealth) if (pXSprite->health <= (unsigned int)pDudeInfo->fleeHealth)
{ {
@ -1110,6 +1129,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
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]; DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase];
switch (pSprite->type) { switch (pSprite->type) {
#ifdef NOONE_EXTENSIONS
case kDudeModernCustom: { case kDudeModernCustom: {
GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); int rChance = getRecoilChance(pSprite); GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); int rChance = getRecoilChance(pSprite);
if (pExtra->canElectrocute && pDudeExtra->at4 && !spriteIsUnderwater(pSprite, false)) { if (pExtra->canElectrocute && pDudeExtra->at4 && !spriteIsUnderwater(pSprite, false)) {
@ -1156,6 +1176,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
pDudeExtra->at4 = 0; pDudeExtra->at4 = 0;
break; break;
} }
#endif
case kDudeCultistTommy: case kDudeCultistTommy:
case kDudeCultistShotgun: case kDudeCultistShotgun:
case kDudeCultistTesla: case kDudeCultistTesla:
@ -1186,9 +1207,11 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBurningCultist: case kDudeBurningCultist:
aiNewState(pSprite, pXSprite, &cultistBurnGoto); aiNewState(pSprite, pXSprite, &cultistBurnGoto);
break; break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustomBurning: case kDudeModernCustomBurning:
aiGenDudeNewState(pSprite, &genDudeBurnGoto); aiGenDudeNewState(pSprite, &genDudeBurnGoto);
break; break;
#endif
case kDudeZombieButcher: case kDudeZombieButcher:
aiPlay3DSound(pSprite, 1202, AI_SFX_PRIORITY_2, -1); aiPlay3DSound(pSprite, 1202, AI_SFX_PRIORITY_2, -1);
if (pDudeExtra->at4) if (pDudeExtra->at4)
@ -1454,31 +1477,33 @@ void aiProcessDudes(void) {
int nXSprite = pSprite->extra; 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; if (IsPlayerSprite(pSprite) || pXSprite->health == 0) continue;
pXSprite->stateTimer = ClipLow(pXSprite->stateTimer-4, 0); pXSprite->stateTimer = ClipLow(pXSprite->stateTimer-4, 0);
if (pSprite->type >= kDudeVanillaMax && pSprite->type < kDudeMax) switch (pSprite->type){
genDudeProcess(pSprite, pXSprite); #ifdef NOONE_EXTENSIONS
case kDudeModernCustom:
case kDudeModernCustomBurning:
genDudeProcess(pSprite, pXSprite);
break;
#endif
default:
if (pXSprite->aiState->moveFunc)
pXSprite->aiState->moveFunc(pSprite, pXSprite);
else { if (pXSprite->aiState->thinkFunc && (gFrame & 3) == (nSprite & 3))
pXSprite->aiState->thinkFunc(pSprite, pXSprite);
if (pXSprite->aiState->moveFunc)
pXSprite->aiState->moveFunc(pSprite, pXSprite);
if (pXSprite->aiState->thinkFunc && (gFrame & 3) == (nSprite & 3)) if (pXSprite->stateTimer == 0 && pXSprite->aiState->nextState) {
pXSprite->aiState->thinkFunc(pSprite, pXSprite); if (pXSprite->aiState->stateTicks > 0)
aiNewState(pSprite, pXSprite, pXSprite->aiState->nextState);
if (pXSprite->stateTimer == 0 && pXSprite->aiState->nextState) { else if (seqGetStatus(3, nXSprite) < 0)
if (pXSprite->aiState->stateTicks > 0) aiNewState(pSprite, pXSprite, pXSprite->aiState->nextState);
aiNewState(pSprite, pXSprite, pXSprite->aiState->nextState); }
else if (seqGetStatus(3, nXSprite) < 0)
aiNewState(pSprite, pXSprite, pXSprite->aiState->nextState);
}
if (pXSprite->health > 0 && ((pDudeInfo->hinderDamage << 4) <= cumulDamage[nXSprite])) {
pXSprite->data3 = cumulDamage[nXSprite];
RecoilDude(pSprite, pXSprite);
}
if (pXSprite->health > 0 && ((pDudeInfo->hinderDamage << 4) <= cumulDamage[nXSprite])) {
pXSprite->data3 = cumulDamage[nXSprite];
RecoilDude(pSprite, pXSprite);
}
break;
} }
} }
memset(cumulDamage, 0, sizeof(cumulDamage)); memset(cumulDamage, 0, sizeof(cumulDamage));
@ -1505,6 +1530,7 @@ void aiInitSprite(spritetype *pSprite)
pDudeExtra->at4 = 0; pDudeExtra->at4 = 0;
pDudeExtra->at0 = 0; pDudeExtra->at0 = 0;
switch (pSprite->type) { switch (pSprite->type) {
#ifdef NOONE_EXTENSIONS
case kDudeModernCustom: { case kDudeModernCustom: {
DUDEEXTRA_at6_u1* pDudeExtraE = &gDudeExtra[nXSprite].at6.u1; DUDEEXTRA_at6_u1* pDudeExtraE = &gDudeExtra[nXSprite].at6.u1;
pDudeExtraE->at8 = pDudeExtraE->at0 = 0; pDudeExtraE->at8 = pDudeExtraE->at0 = 0;
@ -1516,6 +1542,7 @@ void aiInitSprite(spritetype *pSprite)
aiGenDudeNewState(pSprite, &genDudeBurnGoto); aiGenDudeNewState(pSprite, &genDudeBurnGoto);
pXSprite->burnTime = 1200; pXSprite->burnTime = 1200;
break; break;
#endif
case kDudeCultistTommy: case kDudeCultistTommy:
case kDudeCultistShotgun: case kDudeCultistShotgun:
case kDudeCultistTesla: case kDudeCultistTesla:
@ -1707,10 +1734,11 @@ void aiInitSprite(spritetype *pSprite)
case kDudeZombieAxeLaying: case kDudeZombieAxeLaying:
pSprite->flags = 7; pSprite->flags = 7;
break; break;
case kDudePodMother: // by NoOne: FakeDude type #ifdef NOONE_EXTENSIONS
case kDudePodMother: // FakeDude type
if (gModernMap) break; if (gModernMap) break;
fallthrough__; fallthrough__;
// By NoOne: Allow put pods and tentacles on ceilings if sprite is y-flipped. // Allow put pods and tentacles on ceilings if sprite is y-flipped.
case kDudePodGreen: case kDudePodGreen:
case kDudeTentacleGreen: case kDudeTentacleGreen:
case kDudePodFire: case kDudePodFire:
@ -1723,6 +1751,7 @@ void aiInitSprite(spritetype *pSprite)
} }
fallthrough__; fallthrough__;
// go default // go default
#endif
default: default:
pSprite->flags = 15; pSprite->flags = 15;
break; break;

View file

@ -106,8 +106,9 @@ void aiInit(void);
void aiInitSprite(spritetype *pSprite); void aiInitSprite(spritetype *pSprite);
bool CanMove(spritetype* pSprite, int a2, int nAngle, int nRange); bool CanMove(spritetype* pSprite, int a2, int nAngle, int nRange);
void RecoilDude(spritetype* pSprite, XSPRITE* pXSprite); void RecoilDude(spritetype* pSprite, XSPRITE* pXSprite);
#ifdef NOONE_EXTENSIONS
// By NoOne: this function required for kModernDudeTargetChanger // this function required for kModernDudeTargetChanger
void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite); void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite);
#endif
END_BLD_NS END_BLD_NS

View file

@ -128,9 +128,11 @@ static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBurningTinyCaleb: case kDudeBurningTinyCaleb:
aiNewState(pSprite, pXSprite, &tinycalebBurnSearch); aiNewState(pSprite, pXSprite, &tinycalebBurnSearch);
break; break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustomBurning: case kDudeModernCustomBurning:
aiNewState(pSprite, pXSprite, &genDudeBurnSearch); aiNewState(pSprite, pXSprite, &genDudeBurnSearch);
break; break;
#endif
} }
} }
aiThinkTarget(pSprite, pXSprite); aiThinkTarget(pSprite, pXSprite);
@ -160,9 +162,11 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBurningTinyCaleb: case kDudeBurningTinyCaleb:
aiNewState(pSprite, pXSprite, &tinycalebBurnGoto); aiNewState(pSprite, pXSprite, &tinycalebBurnGoto);
break; break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustomBurning: case kDudeModernCustomBurning:
aiNewState(pSprite, pXSprite, &genDudeBurnGoto); aiNewState(pSprite, pXSprite, &genDudeBurnGoto);
break; break;
#endif
} }
return; return;
} }
@ -196,9 +200,11 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBurningTinyCaleb: case kDudeBurningTinyCaleb:
aiNewState(pSprite, pXSprite, &tinycalebBurnSearch); aiNewState(pSprite, pXSprite, &tinycalebBurnSearch);
break; break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustomBurning: case kDudeModernCustomBurning:
aiNewState(pSprite, pXSprite, &genDudeBurnSearch); aiNewState(pSprite, pXSprite, &genDudeBurnSearch);
break; break;
#endif
} }
return; return;
} }
@ -234,9 +240,11 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBurningTinyCaleb: case kDudeBurningTinyCaleb:
aiNewState(pSprite, pXSprite, &tinycalebBurnAttack); aiNewState(pSprite, pXSprite, &tinycalebBurnAttack);
break; break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustomBurning: case kDudeModernCustomBurning:
aiNewState(pSprite, pXSprite, &genDudeBurnSearch); aiNewState(pSprite, pXSprite, &genDudeBurnSearch);
break; break;
#endif
} }
} }
return; return;
@ -264,9 +272,11 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite)
case kDudeBurningTinyCaleb: case kDudeBurningTinyCaleb:
aiNewState(pSprite, pXSprite, &tinycalebBurnGoto); aiNewState(pSprite, pXSprite, &tinycalebBurnGoto);
break; break;
#ifdef NOONE_EXTENSIONS
case kDudeModernCustomBurning: case kDudeModernCustomBurning:
aiNewState(pSprite, pXSprite, &genDudeBurnSearch); aiNewState(pSprite, pXSprite, &genDudeBurnSearch);
break; break;
#endif
} }
pXSprite->target = -1; pXSprite->target = -1;
} }

View file

@ -24,11 +24,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "ns.h" // Must come before everything else! #include "ns.h" // Must come before everything else!
#include "common_game.h"
#ifdef NOONE_EXTENSIONS
#include "compat.h" #include "compat.h"
#include "build.h" #include "build.h"
#include "pragmas.h" #include "pragmas.h"
#include "mmulti.h" #include "mmulti.h"
#include "common_game.h"
#include "actor.h" #include "actor.h"
#include "ai.h" #include "ai.h"
#include "aiunicult.h" #include "aiunicult.h"
@ -222,7 +224,7 @@ static void punchCallback(int, int nXIndex) {
if (!playGenDudeSound(pSprite, kGenDudeSndAttackMelee)) if (!playGenDudeSound(pSprite, kGenDudeSndAttackMelee))
sfxPlay3DSound(pSprite, 530, 1, 0); sfxPlay3DSound(pSprite, 530, 1, 0);
actFireVector(pSprite, 0, 0, dx, dy, dz,VECTOR_TYPE_22); actFireVector(pSprite, 0, 0, dx, dy, dz,kVectorGenDudePunch);
} }
} }
@ -315,7 +317,7 @@ static void ThrowThing(int nXIndex, bool impact) {
if (weaponType != kGenDudeWeaponThrow) return; if (weaponType != kGenDudeWeaponThrow) return;
const THINGINFO* pThinkInfo = &thingInfo[curWeapon - kThingBase]; const THINGINFO* pThinkInfo = &thingInfo[curWeapon - kThingBase];
if (!pThinkInfo->allowThrow) return; if (!gThingInfoExtra[curWeapon - kThingBase].allowThrow) return;
else if (!playGenDudeSound(pSprite, kGenDudeSndAttackThrow)) else if (!playGenDudeSound(pSprite, kGenDudeSndAttackThrow))
sfxPlay3DSound(pSprite, 455, -1, 0); sfxPlay3DSound(pSprite, 455, -1, 0);
@ -521,7 +523,7 @@ static void thinkChase( spritetype* pSprite, XSPRITE* pXSprite ) {
spritetype* pLeech = leechIsDropped(pSprite); VECTORDATA* meleeVector = &gVectorData[22]; spritetype* pLeech = leechIsDropped(pSprite); VECTORDATA* meleeVector = &gVectorData[22];
if (weaponType == kGenDudeWeaponThrow) { if (weaponType == kGenDudeWeaponThrow) {
if (klabs(losAngle) < kAng15) { if (klabs(losAngle) < kAng15) {
if (!thingInfo[curWeapon - kThingBase].allowThrow) { if (!gThingInfoExtra[curWeapon - kThingBase].allowThrow) {
if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeChaseW); if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeChaseW);
else aiGenDudeNewState(pSprite, &genDudeChaseL); else aiGenDudeNewState(pSprite, &genDudeChaseL);
return; return;
@ -870,7 +872,7 @@ static void thinkChase( spritetype* pSprite, XSPRITE* pXSprite ) {
else if (hit == 3 && (failed = (pHSprite->statnum != kStatThing || pXHSprite == NULL || pXHSprite->locked)) == false) { else if (hit == 3 && (failed = (pHSprite->statnum != kStatThing || pXHSprite == NULL || pXHSprite->locked)) == false) {
// check also for damage resistance (all possible damages missile can use) // check also for damage resistance (all possible damages missile can use)
for (int i = 0; i < kDmgMax; i++) { for (int i = 0; i < kDmgMax; i++) {
if (missileInfo[curWeapon - kMissileBase].dmgType[i] && (failed = isImmune(pHSprite, i)) == false) if (gMissileInfoExtra[curWeapon - kMissileBase].dmgType[i] && (failed = isImmune(pHSprite, i)) == false)
break; break;
} }
} }
@ -1993,4 +1995,4 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
return true; return true;
} }
END_BLD_NS #endifEND_BLD_NS

View file

@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
#pragma once #pragma once
#ifdef NOONE_EXTENSIONS
#include "ai.h" #include "ai.h"
#include "eventq.h" #include "eventq.h"
@ -220,4 +221,4 @@ bool genDudePrepare(spritetype* pSprite, int propId = kGenDudePropertyAll);
void genDudeUpdate(spritetype* pSprite); void genDudeUpdate(spritetype* pSprite);
void genDudeProcess(spritetype* pSprite, XSPRITE* pXSprite); void genDudeProcess(spritetype* pSprite, XSPRITE* pXSprite);
bool genDudeAdjustSlope(spritetype* pSprite, XSPRITE* pXSprite, int dist, int weaponType, int by = 64); bool genDudeAdjustSlope(spritetype* pSprite, XSPRITE* pXSprite, int dist, int weaponType, int by = 64);
END_BLD_NS #endifEND_BLD_NS

View file

@ -593,6 +593,7 @@ void StartLevel(GAMEOPTIONS *gameOptions)
} }
#ifdef NOONE_EXTENSIONS
if (gModernMap) { if (gModernMap) {
switch (pSprite->type) { switch (pSprite->type) {
@ -664,6 +665,7 @@ void StartLevel(GAMEOPTIONS *gameOptions)
} }
} }
} }
#endif
} }
} }
scrLoadPLUs(); scrLoadPLUs();
@ -675,7 +677,8 @@ void StartLevel(GAMEOPTIONS *gameOptions)
gStartZone[i].sectnum = startsectnum; gStartZone[i].sectnum = startsectnum;
gStartZone[i].ang = startang; gStartZone[i].ang = startang;
// By NoOne: Create spawn zones for players in teams mode. #ifdef NOONE_EXTENSIONS
// Create spawn zones for players in teams mode.
if (gModernMap && i <= kMaxPlayers / 2) { if (gModernMap && i <= kMaxPlayers / 2) {
gStartZoneTeam1[i].x = startpos.x; gStartZoneTeam1[i].x = startpos.x;
gStartZoneTeam1[i].y = startpos.y; gStartZoneTeam1[i].y = startpos.y;
@ -689,6 +692,7 @@ void StartLevel(GAMEOPTIONS *gameOptions)
gStartZoneTeam2[i].sectnum = startsectnum; gStartZoneTeam2[i].sectnum = startsectnum;
gStartZoneTeam2[i].ang = startang; gStartZoneTeam2[i].ang = startang;
} }
#endif
} }
InitSectorFX(); InitSectorFX();
warpInit(); warpInit();

View file

@ -343,9 +343,11 @@ void EnemyBubble(int nSprite) // 11
void CounterCheck(int nSector) // 12 void CounterCheck(int nSector) // 12
{ {
dassert(nSector >= 0 && nSector < kMaxSectors); dassert(nSector >= 0 && nSector < kMaxSectors);
// By NoOne: remove check below, so every sector can be counter if command 12 (this callback) received. // remove check below, so every sector can be counter if command 12 (this callback) received.
//if (pSector->type != kSectorCounter) return; #ifndef NOONE_EXTENSIONS
if (sector[nSector].type != kSectorCounter) return;
#endif
if (sector[nSector].extra <= 0) return; if (sector[nSector].extra <= 0) return;
XSECTOR *pXSector = &xsector[sector[nSector].extra]; XSECTOR *pXSector = &xsector[sector[nSector].extra];
@ -566,7 +568,9 @@ void LeechStateTimer(int nSprite) // 20
if (pSprite->statnum == kStatThing && !(pSprite->flags & 32)) { if (pSprite->statnum == kStatThing && !(pSprite->flags & 32)) {
switch (pSprite->type) { switch (pSprite->type) {
case kThingDroppedLifeLeech: case kThingDroppedLifeLeech:
#ifdef NOONE_EXTENSIONS
case kModernThingEnemyLifeLeech: case kModernThingEnemyLifeLeech:
#endif
xsprite[pSprite->extra].stateTimer = 0; xsprite[pSprite->extra].stateTimer = 0;
break; break;
} }
@ -708,6 +712,7 @@ void DropVoodoo(int nSprite) // unused
} }
} }
#ifdef NOONE_EXTENSIONS
void UniMissileBurst(int nSprite) // 22 void UniMissileBurst(int nSprite) // 22
{ {
dassert(nSprite >= 0 && nSprite < kMaxSprites); dassert(nSprite >= 0 && nSprite < kMaxSprites);
@ -766,12 +771,13 @@ void makeMissileBlocking(int nSprite) // 23
sprite[nSprite].cstat |= CSTAT_SPRITE_BLOCK; sprite[nSprite].cstat |= CSTAT_SPRITE_BLOCK;
} }
void genDudeUpdateCallback(int nSprite) // 24
{
if (spriRangeIsFine(nSprite))
genDudeUpdate(&sprite[nSprite]);
}
void genDudeUpdateCallback(int nSprite) // 24
{
if (spriRangeIsFine(nSprite))
genDudeUpdate(&sprite[nSprite]);
}
#endif
void(*gCallback[kCallbackMax])(int) = void(*gCallback[kCallbackMax])(int) =
{ {
fxFlameLick, fxFlameLick,
@ -796,9 +802,11 @@ void(*gCallback[kCallbackMax])(int) =
fxPodBloodSplat, fxPodBloodSplat,
LeechStateTimer, LeechStateTimer,
DropVoodoo, // unused DropVoodoo, // unused
#ifdef NOONE_EXTENSIONS
UniMissileBurst, UniMissileBurst,
makeMissileBlocking, makeMissileBlocking,
genDudeUpdateCallback, genDudeUpdateCallback,
#endif
}; };
END_BLD_NS END_BLD_NS

View file

@ -49,9 +49,11 @@ enum CALLBACK_ID {
kCallbackFXPodBloodSplat = 19, kCallbackFXPodBloodSplat = 19,
kCallbackLeechStateTimer = 20, kCallbackLeechStateTimer = 20,
kCallbackDropVoodoo = 21, // unused kCallbackDropVoodoo = 21, // unused
#ifdef NOONE_EXTENSIONS
kCallbackMissileBurst = 22, // by NoOne kCallbackMissileBurst = 22, // by NoOne
kCallbackMissileSpriteBlock = 23, // by NoOne kCallbackMissileSpriteBlock = 23, // by NoOne
kCallbackGenDudeUpdate = 24, // by NoOne kCallbackGenDudeUpdate = 24, // by NoOne
#endif
kCallbackMax, kCallbackMax,
}; };

View file

@ -85,9 +85,12 @@ void _consoleSysMsg(const char* pMessage, ...);
// defined by NoOne: // defined by NoOne:
// ------------------------------- // -------------------------------
#define kMaxPAL 5
#define kFreeQAVEntry 108
/////////////////////////////////////////////////////////////
#define NOONE_EXTENSIONS 1
////////////////////////////////////////////////////////////
#define kMaxPAL 5
#define kUserPLUStart 15 #define kUserPLUStart 15
#define kDmgFall 0 #define kDmgFall 0
@ -126,11 +129,9 @@ kStatSpares = 13,
kStatFlare = 14, kStatFlare = 14,
kStatDebris = 15, kStatDebris = 15,
kStatPathMarker = 16, kStatPathMarker = 16,
kStatModernDudeTargetChanger = 20, // gModernMap only
kStatFree = 1024, kStatFree = 1024,
}; };
// POWERUPS ///////////////////////////////////////////////////// // POWERUPS /////////////////////////////////////////////////////
enum { enum {
kPwUpFeatherFall = 12, kPwUpFeatherFall = 12,
@ -196,30 +197,12 @@ enum {
kSwitchPadlock = 23, kSwitchPadlock = 23,
kSwitchMax = 24, kSwitchMax = 24,
// modern types (gModernMap only)
kModernCustomDudeSpawn = 24,
kModernRandomTX = 25,
kModernSequentialTX = 26,
kModernSeqSpawner = 27,
kModernObjPropertiesChanger = 28,
kModernObjPicnumChanger = 29,
kModernObjSizeChanger = 31,
kModernDudeTargetChanger = 33,
kModernSectorFXChanger = 34,
kModernObjDataChanger = 35,
kModernSpriteDamager = 36,
kModernObjDataAccumulator = 37,
kModernEffectSpawner = 38,
kModernWindGenerator = 39,
kModernPlayerControl = 500, /// WIP
// decorations // decorations
kDecorationTorch = 30, kDecorationTorch = 30,
kDecorationCandle = 32, kDecorationCandle = 32,
// (weapons) // (weapons)
kItemWeaponBase = 40, kItemWeaponBase = 40,
kModernRandom = 40, // gModernMap only
kItemWeaponSawedoff = 41, kItemWeaponSawedoff = 41,
kItemWeaponTommygun = 42, kItemWeaponTommygun = 42,
kItemWeaponVoodooDoll = 44, kItemWeaponVoodooDoll = 44,
@ -231,7 +214,6 @@ enum {
kItemAmmoSawedoffFew = 67, kItemAmmoSawedoffFew = 67,
kItemAmmoTommygunFew = 69, kItemAmmoTommygunFew = 69,
kAmmoItemVoodooDoll = 70, kAmmoItemVoodooDoll = 70,
kModernRandom2 = 80, // gModernMap Only
kItemAmmoMax = 81, kItemAmmoMax = 81,
kItemBase = 100, kItemBase = 100,
@ -266,8 +248,6 @@ enum {
kItemReflectShots = 124, kItemReflectShots = 124,
kItemBeastVision = 125, kItemBeastVision = 125,
kItemShroomDelirium = 128, kItemShroomDelirium = 128,
kItemShroomGrow = 129, // gModernMap only
kItemShroomShrink = 130, // gModernMap only
kItemArmorAsbest = 139, kItemArmorAsbest = 139,
kItemArmorBasic = 140, kItemArmorBasic = 140,
@ -280,7 +260,6 @@ enum {
kItemFlagBBase = 146, kItemFlagBBase = 146,
kItemFlagA = 147, kItemFlagA = 147,
kItemFlagB = 148, kItemFlagB = 148,
kItemModernMapLevel = 150, // once picked up, draws whole minimap
kItemMax = 151, kItemMax = 151,
// dudes // dudes
@ -339,8 +318,6 @@ enum {
kDudeBurningTinyCaleb = 252, kDudeBurningTinyCaleb = 252,
kDudeBurningBeast = 253, kDudeBurningBeast = 253,
kDudeVanillaMax = 254, kDudeVanillaMax = 254,
kDudeModernCustom = kDudeVanillaMax, // gModern map only
kDudeModernCustomBurning = 255, // gModern map only
kDudeMax = 256, kDudeMax = 256,
kMissileBase = 300, kMissileBase = 300,
@ -394,9 +371,6 @@ enum {
kThingPodGreenBall = 430, kThingPodGreenBall = 430,
kThingDroppedLifeLeech = 431, kThingDroppedLifeLeech = 431,
kThingVoodooHead = 432, // unused kThingVoodooHead = 432, // unused
kModernThingTNTProx = 433, // gModernMap only - detects only players
kModernThingThrowableRock = 434, // gModernMap only - does small damage if hits target
kModernThingEnemyLifeLeech = 435, // gModernMap only - the same as normal, except it aims in specified target only
kThingMax = 436, kThingMax = 436,
// traps // traps
@ -410,8 +384,7 @@ enum {
kGenDripWater = 701, kGenDripWater = 701,
kGenDripBlood = 702, kGenDripBlood = 702,
kGenMissileFireball = 703, kGenMissileFireball = 703,
kGenMissileEctoSkull = 704, // does not work in vanilla kGenMissileEctoSkull = 704,
kGenModernMissileUniversal = 704, // gModernMap only
kGenDart = 705, kGenDart = 705,
kGenBubble = 706, kGenBubble = 706,
kGenBubbleMulti = 707, kGenBubbleMulti = 707,
@ -422,6 +395,54 @@ enum {
kSoundPlayer = 711, kSoundPlayer = 711,
}; };
#ifdef NOONE_EXTENSIONS
// modern types (gModernMap only)
enum {
kModernCustomDudeSpawn = 24,
kModernRandomTX = 25,
kModernSequentialTX = 26,
kModernSeqSpawner = 27,
kModernObjPropertiesChanger = 28,
kModernObjPicnumChanger = 29,
kModernObjSizeChanger = 31,
kModernDudeTargetChanger = 33,
kModernSectorFXChanger = 34,
kModernObjDataChanger = 35,
kModernSpriteDamager = 36,
kModernObjDataAccumulator = 37,
kModernEffectSpawner = 38,
kModernWindGenerator = 39,
kModernRandom = 40,
kModernRandom2 = 80,
kItemShroomGrow = 129,
kItemShroomShrink = 130,
kItemModernMapLevel = 150, // once picked up, draws whole minimap
kDudeModernCustom = kDudeVanillaMax,
kDudeModernCustomBurning = 255,
kModernThingTNTProx = 433, // detects only players
kModernThingThrowableRock = 434, // does small damage if hits target
kModernThingEnemyLifeLeech = 435, // the same as normal, except it aims in specified target only
kModernPlayerControl = 500, /// WIP
kGenModernMissileUniversal = 704,
};
// modern statnums (gModernMap only)
enum {
kStatModernDudeTargetChanger = 20,
};
// additional physics attributes for debris sprites
#define kPhysDebrisFly 0x0008 // *debris* affected by negative gravity (fly instead of falling, DO NOT mess with kHitagAutoAim)
#define kPhysDebrisSwim 0x0016 // *debris* can swim underwater (instead of drowning)
#define kPhysDebrisVector 0x0400 // *debris* can be affected by vector weapons
#define kPhysDebrisExplode 0x0800 // *debris* can be affected by explosions
// *modern types only hitag*
#define kModernTypeFlag0 0x0
#define kModernTypeFlag1 0x1
#define kModernTypeFlag2 0x2
#define kModernTypeFlag3 0x3
#endif
// WALL TYPES ///////////////////////////////////////////////// // WALL TYPES /////////////////////////////////////////////////
enum { enum {
@ -471,18 +492,6 @@ kAiStateAttack = 6,
#define kPhysMove 0x0001 // affected by movement physics #define kPhysMove 0x0001 // affected by movement physics
#define kPhysGravity 0x0002 // affected by gravity #define kPhysGravity 0x0002 // affected by gravity
#define kPhysFalling 0x0004 // currently in z-motion #define kPhysFalling 0x0004 // currently in z-motion
// additional physics attributes for debris sprites
#define kPhysDebrisFly 0x0008 // *debris* affected by negative gravity (fly instead of falling, DO NOT mess with kHitagAutoAim)
#define kPhysDebrisSwim 0x0016 // *debris* can swim underwater (instead of drowning)
#define kPhysDebrisVector 0x0400 // *debris* can be affected by vector weapons
#define kPhysDebrisExplode 0x0800 // *debris* can be affected by explosions
// *modern types only hitag*
#define kModernTypeFlag0 0x0
#define kModernTypeFlag1 0x1
#define kModernTypeFlag2 0x2
#define kModernTypeFlag3 0x3
// sector cstat // sector cstat
#define kSecCParallax 0x01 #define kSecCParallax 0x01
@ -495,7 +504,6 @@ kAiStateAttack = 6,
#define kSecCRelAlign 0x40 #define kSecCRelAlign 0x40
#define kSecCFloorShade 0x8000 #define kSecCFloorShade 0x8000
#define kAng5 28 #define kAng5 28
#define kAng15 85 #define kAng15 85
#define kAng30 170 #define kAng30 170

View file

@ -54,7 +54,9 @@ PolymerLight_t gPolymerLight[kMaxSprites];
char qsprite_filler[kMaxSprites], qsector_filler[kMaxSectors]; char qsprite_filler[kMaxSprites], qsector_filler[kMaxSectors];
int gVisibility; int gVisibility;
#ifdef NOONE_EXTENSIONS
bool gModernMap = false; bool gModernMap = false;
#endif
void dbCrypt(char *pPtr, int nLength, int nKey) void dbCrypt(char *pPtr, int nLength, int nKey)
{ {
@ -639,8 +641,9 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
memset(show2dsector, 0, sizeof(show2dsector)); memset(show2dsector, 0, sizeof(show2dsector));
memset(show2dwall, 0, sizeof(show2dwall)); memset(show2dwall, 0, sizeof(show2dwall));
memset(show2dsprite, 0, sizeof(show2dsprite)); memset(show2dsprite, 0, sizeof(show2dsprite));
#ifdef NOONE_EXTENSIONS
gModernMap = false; gModernMap = false;
#endif
#ifdef USE_OPENGL #ifdef USE_OPENGL
Polymost_prepare_loadboard(); Polymost_prepare_loadboard();
@ -680,10 +683,12 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
if ((header.version & 0xff00) == 0x700) { if ((header.version & 0xff00) == 0x700) {
byte_1A76C8 = 1; byte_1A76C8 = 1;
// by NoOne: indicate if the map requires modern features to work properly #ifdef NOONE_EXTENSIONS
// indicate if the map requires modern features to work properly
// for maps wich created in PMAPEDIT BETA13 or higher versions. Since only minor version changed, // for maps wich created in PMAPEDIT BETA13 or higher versions. Since only minor version changed,
// the map is still can be loaded with vanilla BLOOD / MAPEDIT and should work in other ports too. // the map is still can be loaded with vanilla BLOOD / MAPEDIT and should work in other ports too.
if ((header.version & 0x00ff) == 0x001) gModernMap = true; if ((header.version & 0x00ff) == 0x001) gModernMap = true;
#endif
} else { } else {
initprintf("Map file is wrong version"); initprintf("Map file is wrong version");
@ -1094,10 +1099,12 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
xsprite[sprite[i].extra].lT |= xsprite[sprite[i].extra].lB; xsprite[sprite[i].extra].lT |= xsprite[sprite[i].extra].lB;
} }
// by NoOne: indicate if the map requires modern features to work properly #ifdef NOONE_EXTENSIONS
// indicate if the map requires modern features to work properly
// for maps wich created in different editors (include vanilla MAPEDIT) or in PMAPEDIT version below than BETA13 // for maps wich created in different editors (include vanilla MAPEDIT) or in PMAPEDIT version below than BETA13
if (!gModernMap && pXSprite->rxID == kChannelMapModernize && pXSprite->rxID == pXSprite->txID && pXSprite->command == kCmdModernFeaturesEnable) if (!gModernMap && pXSprite->rxID == kChannelMapModernize && pXSprite->rxID == pXSprite->txID && pXSprite->command == kCmdModernFeaturesEnable)
gModernMap = true; gModernMap = true;
#endif
} }
if ((sprite[i].cstat & 0x30) == 0x30) if ((sprite[i].cstat & 0x30) == 0x30)
{ {

View file

@ -28,8 +28,12 @@ BEGIN_BLD_NS
#define kMaxXWalls 512 #define kMaxXWalls 512
#define kMaxXSectors 512 #define kMaxXSectors 512
// by NoOne additional non-thing proximity, sight and physics sprites
#ifdef NOONE_EXTENSIONS
// additional non-thing proximity, sight and physics sprites
#define kMaxSuperXSprites 128 #define kMaxSuperXSprites 128
extern bool gModernMap;
#endif
// by NoOne: functions to quckly check range of specifical arrays // by NoOne: functions to quckly check range of specifical arrays
inline bool xspriRangeIsFine(int nXindex) { inline bool xspriRangeIsFine(int nXindex) {
@ -43,9 +47,6 @@ inline bool xsectRangeIsFine(int nXindex) {
inline bool xwallRangeIsFine(int nXindex) { inline bool xwallRangeIsFine(int nXindex) {
return (nXindex >= 0 && nXindex < kMaxXWalls); return (nXindex >= 0 && nXindex < kMaxXWalls);
} }
extern bool gModernMap;
#pragma pack(push, 1) #pragma pack(push, 1)
struct AISTATE; struct AISTATE;
@ -115,9 +116,12 @@ struct XSPRITE {
unsigned int height : 16; unsigned int height : 16;
unsigned int stateTimer : 16; // ai timer unsigned int stateTimer : 16; // ai timer
AISTATE* aiState; // ai AISTATE* aiState; // ai
#ifdef NOONE_EXTENSIONS
signed int sysData1 : 16; // used to keep here various system data, so user can't change it in map editor signed int sysData1 : 16; // used to keep here various system data, so user can't change it in map editor
unsigned int physAttr : 12; // currently used by additional physics sprites to keep it's attributes. unsigned int physAttr : 12; // currently used by additional physics sprites to keep it's attributes.
#endif
signed int scale; // used for scaling SEQ size on sprites signed int scale; // used for scaling SEQ size on sprites
}; };
struct XSECTOR { struct XSECTOR {
@ -189,7 +193,11 @@ struct XSECTOR {
unsigned int floorpal : 4; // Floor pal2 unsigned int floorpal : 4; // Floor pal2
unsigned int floorYPanFrac : 8; // Floor y panning frac unsigned int floorYPanFrac : 8; // Floor y panning frac
unsigned int locked : 1; // Locked unsigned int locked : 1; // Locked
unsigned int windVel : 32; // Wind vel (by NoOne: changed from 10 bit to use higher velocity values) #ifdef NOONE_EXTENSIONS
unsigned int windVel : 32; // Wind vel (changed from 10 bit to use higher velocity values)
#else
unsigned int windVel : 10;
#endif
unsigned int windAng : 11; // Wind ang unsigned int windAng : 11; // Wind ang
unsigned int windAlways : 1; // Wind always unsigned int windAlways : 1; // Wind always
unsigned int dudeLockout : 1; unsigned int dudeLockout : 1;

View file

@ -380,11 +380,13 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command)
case kChannelLevelExitSecret: case kChannelLevelExitSecret:
levelEndLevel(1); levelEndLevel(1);
return; return;
// By NoOne: finished level and load custom level ¹ via numbered command. #ifdef NOONE_EXTENSIONS
// finished level and load custom level ¹ via numbered command.
case kChannelModernEndLevelCustom: case kChannelModernEndLevelCustom:
if (command >= kCmdNumberic) levelEndLevelCustom(command - kCmdNumberic); if (command >= kCmdNumberic) levelEndLevelCustom(command - kCmdNumberic);
else viewSetSystemMessage("Invalid Level-Exit# command by xobject #%d (object type %d)", nIndex, nType); else viewSetSystemMessage("Invalid Level-Exit# command by xobject #%d (object type %d)", nIndex, nType);
return; return;
#endif
case kChannelSetTotalSecrets: case kChannelSetTotalSecrets:
if (command >= kCmdNumberic) levelSetupSecret(command - kCmdNumberic); if (command >= kCmdNumberic) levelSetupSecret(command - kCmdNumberic);
else viewSetSystemMessage("Invalid Total-Secrets command by xobject #%d (object type %d)", nIndex, nType); else viewSetSystemMessage("Invalid Total-Secrets command by xobject #%d (object type %d)", nIndex, nType);
@ -436,7 +438,7 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command)
break; break;
} }
#ifdef NOONE_EXTENSIONS
if (gModernMap) { if (gModernMap) {
// allow to send commands on player sprites // allow to send commands on player sprites
@ -452,7 +454,7 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command)
} }
} }
#endif
for (int i = bucketHead[rxId]; i < bucketHead[rxId+1]; i++) { for (int i = bucketHead[rxId]; i < bucketHead[rxId+1]; i++) {
if (event.type != rxBucket[i].type || event.index != rxBucket[i].index) { if (event.type != rxBucket[i].type || event.index != rxBucket[i].index) {
switch (rxBucket[i].type) { switch (rxBucket[i].type) {

View file

@ -917,12 +917,14 @@ int picHeight(short nPic, short repeat) {
return ClipLow((tilesiz[nPic].y * repeat) << 2, 0); return ClipLow((tilesiz[nPic].y * repeat) << 2, 0);
} }
// by NoOne: used for better randomness in single player #ifdef NOONE_EXTENSIONS
// 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 stdRandom;
stdRandom.seed(std::random_device()()); stdRandom.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(stdRandom); return dist_a_b(stdRandom);
} }
#endif
END_BLD_NS END_BLD_NS

View file

@ -358,7 +358,8 @@ void levelEndLevel(int arg)
} }
} }
// By NoOne: this function can be called via sending numbered command to TX kChannelModernEndLevelCustom #ifdef NOONE_EXTENSIONS
// 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. // This allows to set custom next level instead of taking it from INI file.
void levelEndLevelCustom(int nLevel) { void levelEndLevelCustom(int nLevel) {
@ -374,6 +375,7 @@ void levelEndLevelCustom(int nLevel) {
gNextLevel = nLevel; gNextLevel = nLevel;
} }
#endif
void levelRestart(void) void levelRestart(void)
{ {

View file

@ -118,8 +118,10 @@ void levelGetNextLevels(int nEpisode, int nLevel, int *pnEndingA, int *pnEndingB
// arg: 0 is normal exit, 1 is secret level // arg: 0 is normal exit, 1 is secret level
void levelEndLevel(int arg); void levelEndLevel(int arg);
// By NoOne: custom level selection via numbered command which sent to TX ID 6. #ifdef NOONE_EXTENSIONS
// custom level selection via numbered command which sent to TX ID 6.
void levelEndLevelCustom(int nLevel); void levelEndLevelCustom(int nLevel);
#endif
void levelRestart(void); void levelRestart(void);
int levelGetMusicIdx(const char *str); int levelGetMusicIdx(const char *str);

View file

@ -314,7 +314,9 @@ void MyLoadSave::Load(void)
Read(&gMapRev, sizeof(gMapRev)); Read(&gMapRev, sizeof(gMapRev));
Read(&gSongId, sizeof(gSkyCount)); Read(&gSongId, sizeof(gSkyCount));
Read(&gFogMode, sizeof(gFogMode)); Read(&gFogMode, sizeof(gFogMode));
#ifdef NOONE_EXTENSIONS
Read(&gModernMap, sizeof(gModernMap)); Read(&gModernMap, sizeof(gModernMap));
#endif
gCheatMgr.sub_5BCF4(); gCheatMgr.sub_5BCF4();
} }
@ -395,7 +397,9 @@ void MyLoadSave::Save(void)
Write(&gMapRev, sizeof(gMapRev)); Write(&gMapRev, sizeof(gMapRev));
Write(&gSongId, sizeof(gSkyCount)); Write(&gSongId, sizeof(gSkyCount));
Write(&gFogMode, sizeof(gFogMode)); Write(&gFogMode, sizeof(gFogMode));
#ifdef NOONE_EXTENSIONS
Write(&gModernMap, sizeof(gModernMap)); Write(&gModernMap, sizeof(gModernMap));
#endif
} }
void LoadSavedInfo(void) void LoadSavedInfo(void)

View file

@ -124,33 +124,6 @@ int Handicap[] = {
144, 208, 256, 304, 368 144, 208, 256, 304, 368
}; };
/*int gDefaultAccel[] = {
// normal human
0x4000, 0x1200, 0x2000, // stand (front, side, back) / swim (front, side, back) / crouch (front, side, back)
// normal beast
0x4000, 0x1200, 0x2000, // stand (front, side, back) / swim (front, side, back) / crouch (front, side, back)
// shrink human
10384, 2108, 2192, // stand (front, side, back) / swim (front, side, back) / crouch (front, side, back)
// grown human
19384, 5608, 11192, // stand (front, side, back) / swim (front, side, back) / crouch (front, side, back)
};
int gDefaultJumpZ[] = {
// normal human
-0xbaaaa, -0x175555, 0x5b05, 0, 0, 0, // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
// normal beast
-0xbaaaa, -0x175555, 0x5b05, 0, 0, 0, // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
// shrink human
-564586, -1329173, 0x5b05, 0, 0, 0, // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
// grown human
-1014586, -1779173, 0x5b05, 0, 0, 0, // stand (normal jump, pwup jump) / swim (normal jump, pwup jump) / crouch (normal jump, pwup jump)
};*/
POSTURE gPostureDefaults[kModeMax][kPostureMax] = { POSTURE gPostureDefaults[kModeMax][kPostureMax] = {
// normal human // normal human
@ -281,6 +254,7 @@ DAMAGEINFO damageInfo[7] = {
{ 0, 0, 0, 0, 0, 0, 0 } { 0, 0, 0, 0, 0, 0, 0 }
}; };
#ifdef NOONE_EXTENSIONS
TRPLAYERCTRL gPlayerCtrl[kMaxPlayers]; TRPLAYERCTRL gPlayerCtrl[kMaxPlayers];
QAV* qavSceneLoad(int qavId) { QAV* qavSceneLoad(int qavId) {
@ -292,8 +266,6 @@ QAV* qavSceneLoad(int qavId) {
return pQav; return pQav;
} }
void qavSceneDraw(PLAYER* pPlayer, int a2, int a3, int a4, int a5) { void qavSceneDraw(PLAYER* pPlayer, int a2, int a3, int a4, int a5) {
if (pPlayer == NULL || pPlayer->sceneQav == -1) return; if (pPlayer == NULL || pPlayer->sceneQav == -1) return;
@ -347,16 +319,6 @@ void qavScenePlay(PLAYER* pPlayer) {
} }
} }
int powerupCheck(PLAYER *pPlayer, int nPowerUp)
{
dassert(pPlayer != NULL);
dassert(nPowerUp >= 0 && nPowerUp < kMaxPowerUps);
int nPack = powerupToPackItem(nPowerUp);
if (nPack >= 0 && !packItemActive(pPlayer, nPack))
return 0;
return pPlayer->pwUpTime[nPowerUp];
}
bool isGrown(spritetype* pSprite) { bool isGrown(spritetype* pSprite) {
if (powerupCheck(&gPlayer[pSprite->type - kDudePlayer1], kPwUpGrowShroom) > 0) return true; if (powerupCheck(&gPlayer[pSprite->type - kDudePlayer1], kPwUpGrowShroom) > 0) return true;
else if (pSprite->extra >= 0 && xsprite[pSprite->extra].scale >= 512) return true; else if (pSprite->extra >= 0 && xsprite[pSprite->extra].scale >= 512) return true;
@ -386,6 +348,7 @@ bool resetPlayerSize(PLAYER* pPlayer) {
pPlayer->pXSprite->scale = 0; pPlayer->pXSprite->scale = 0;
return true; return true;
} }
#endif
void deactivateSizeShrooms(PLAYER* pPlayer) { void deactivateSizeShrooms(PLAYER* pPlayer) {
powerupDeactivate(pPlayer, kPwUpGrowShroom); powerupDeactivate(pPlayer, kPwUpGrowShroom);
@ -418,6 +381,16 @@ PLAYER* getPlayerById(short id) {
return NULL; return NULL;
} }
int powerupCheck(PLAYER *pPlayer, int nPowerUp)
{
dassert(pPlayer != NULL);
dassert(nPowerUp >= 0 && nPowerUp < kMaxPowerUps);
int nPack = powerupToPackItem(nPowerUp);
if (nPack >= 0 && !packItemActive(pPlayer, nPack))
return 0;
return pPlayer->pwUpTime[nPowerUp];
}
char powerupActivate(PLAYER *pPlayer, int nPowerUp) char powerupActivate(PLAYER *pPlayer, int nPowerUp)
{ {
@ -430,6 +403,7 @@ char powerupActivate(PLAYER *pPlayer, int nPowerUp)
pPlayer->packSlots[nPack].isActive = 1; pPlayer->packSlots[nPack].isActive = 1;
switch (nPowerUp + kItemBase) { switch (nPowerUp + kItemBase) {
#ifdef NOONE_EXTENSIONS
case kItemModernMapLevel: case kItemModernMapLevel:
if (gModernMap) gFullMap = true; if (gModernMap) gFullMap = true;
break; break;
@ -452,6 +426,7 @@ char powerupActivate(PLAYER *pPlayer, int nPowerUp)
actDamageSprite(pPlayer->pSprite->xvel, pPlayer->pSprite, DAMAGE_TYPE_3, 65535); actDamageSprite(pPlayer->pSprite->xvel, pPlayer->pSprite, DAMAGE_TYPE_3, 65535);
} }
break; break;
#endif
case kItemFeatherFall: case kItemFeatherFall:
case kItemJumpBoots: case kItemJumpBoots:
pPlayer->damageControl[0]++; pPlayer->damageControl[0]++;
@ -491,6 +466,7 @@ void powerupDeactivate(PLAYER *pPlayer, int nPowerUp)
pPlayer->packSlots[nPack].isActive = 0; pPlayer->packSlots[nPack].isActive = 0;
switch (nPowerUp + kItemBase) { switch (nPowerUp + kItemBase) {
#ifdef NOONE_EXTENSIONS
case kItemShroomShrink: case kItemShroomShrink:
if (gModernMap) { if (gModernMap) {
resetPlayerSize(pPlayer); resetPlayerSize(pPlayer);
@ -501,6 +477,7 @@ void powerupDeactivate(PLAYER *pPlayer, int nPowerUp)
case kItemShroomGrow: case kItemShroomGrow:
if (gModernMap) resetPlayerSize(pPlayer); if (gModernMap) resetPlayerSize(pPlayer);
break; break;
#endif
case kItemFeatherFall: case kItemFeatherFall:
case kItemJumpBoots: case kItemJumpBoots:
pPlayer->damageControl[0]--; pPlayer->damageControl[0]--;
@ -800,7 +777,8 @@ void playerStart(int nPlayer)
if (gGameOptions.nGameType <= 1) if (gGameOptions.nGameType <= 1)
pStartZone = &gStartZone[nPlayer]; pStartZone = &gStartZone[nPlayer];
// By NoOne: let's check if there is positions of teams is specified #ifdef NOONE_EXTENSIONS
// let's check if there is positions of teams is specified
// if no, pick position randomly, just like it works in vanilla. // if no, pick position randomly, just like it works in vanilla.
else if (gModernMap && gGameOptions.nGameType == 3 && gTeamsSpawnUsed == true) { else if (gModernMap && gGameOptions.nGameType == 3 && gTeamsSpawnUsed == true) {
int maxRetries = 5; int maxRetries = 5;
@ -822,7 +800,10 @@ void playerStart(int nPlayer)
if (pStartZone != NULL) if (pStartZone != NULL)
break; break;
} }
} else {
}
#endif
else {
pStartZone = &gStartZone[Random(8)]; pStartZone = &gStartZone[Random(8)];
} }
@ -914,7 +895,9 @@ void playerStart(int nPlayer)
pPlayer->weaponTimer = 0; pPlayer->weaponTimer = 0;
pPlayer->weaponState = 0; pPlayer->weaponState = 0;
pPlayer->weaponQav = -1; pPlayer->weaponQav = -1;
#ifdef NOONE_EXTENSIONS
playerResetQavScene(pPlayer); // reset qav scene playerResetQavScene(pPlayer); // reset qav scene
#endif
pPlayer->hand = 0; pPlayer->hand = 0;
pPlayer->nWaterPal = 0; pPlayer->nWaterPal = 0;
playerResetPowerUps(pPlayer); playerResetPowerUps(pPlayer);
@ -975,25 +958,29 @@ void playerReset(PLAYER *pPlayer)
pPlayer->packSlots[i].isActive = 0; pPlayer->packSlots[i].isActive = 0;
pPlayer->packSlots[i].curAmount = 0; pPlayer->packSlots[i].curAmount = 0;
} }
#ifdef NOONE_EXTENSIONS
///////////////// /////////////////
// reset qav scene // reset qav scene
playerResetQavScene(pPlayer); playerResetQavScene(pPlayer);
#endif
// reset posture (mainly required for resetting movement speed and jump height) // reset posture (mainly required for resetting movement speed and jump height)
playerResetPosture(pPlayer); playerResetPosture(pPlayer);
///////////////// /////////////////
} }
void playerResetPosture(PLAYER* pPlayer) { void playerResetPosture(PLAYER* pPlayer) {
memcpy(pPlayer->pPosture, gPostureDefaults, sizeof(gPostureDefaults)); memcpy(pPlayer->pPosture, gPostureDefaults, sizeof(gPostureDefaults));
} }
void playerResetQavScene(PLAYER* pPlayer) { #ifdef NOONE_EXTENSIONS
QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; void playerResetQavScene(PLAYER* pPlayer) {
pQavScene->index = pQavScene->dummy = pPlayer->sceneQav = -1; QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene;
pQavScene->qavResrc = NULL; pQavScene->index = pQavScene->dummy = pPlayer->sceneQav = -1;
} pQavScene->qavResrc = NULL;
}
#endif
int dword_21EFB0[8]; int dword_21EFB0[8];
ClockTicks dword_21EFD0[8]; ClockTicks dword_21EFD0[8];
@ -1036,10 +1023,16 @@ char PickupItem(PLAYER *pPlayer, spritetype *pItem) {
switch (pItem->type) { switch (pItem->type) {
case kItemShadowCloak: case kItemShadowCloak:
#ifdef NOONE_EXTENSIONS
if (isGrown(pPlayer->pSprite) || !powerupActivate(pPlayer, nType)) return false; if (isGrown(pPlayer->pSprite) || !powerupActivate(pPlayer, nType)) return false;
#else
if (!powerupActivate(pPlayer, nType)) return false;
#endif
break; break;
#ifdef NOONE_EXTENSIONS
case kItemShroomShrink: case kItemShroomShrink:
case kItemShroomGrow: case kItemShroomGrow:
if (gModernMap) { if (gModernMap) {
switch (pItem->type) { switch (pItem->type) {
case kItemShroomShrink: case kItemShroomShrink:
@ -1052,7 +1045,9 @@ char PickupItem(PLAYER *pPlayer, spritetype *pItem) {
powerupActivate(pPlayer, nType); powerupActivate(pPlayer, nType);
} }
break; break;
#endif
case kItemFlagABase: case kItemFlagABase:
case kItemFlagBBase: { case kItemFlagBBase: {
if (gGameOptions.nGameType != 3 || pItem->extra <= 0) return 0; if (gGameOptions.nGameType != 3 || pItem->extra <= 0) return 0;
@ -1203,9 +1198,11 @@ char PickupItem(PLAYER *pPlayer, spritetype *pItem) {
case kItemHealthLifeSeed: case kItemHealthLifeSeed:
case kItemHealthRedPotion: { case kItemHealthRedPotion: {
int addPower = gPowerUpInfo[nType].bonusTime; int addPower = gPowerUpInfo[nType].bonusTime;
// by NoOne: allow custom amount for item #ifdef NOONE_EXTENSIONS
// allow custom amount for item
if (gModernMap && sprite[pItem->xvel].extra >= 0 && xsprite[sprite[pItem->xvel].extra].data1 > 0) if (gModernMap && sprite[pItem->xvel].extra >= 0 && xsprite[sprite[pItem->xvel].extra].data1 > 0)
addPower = xsprite[sprite[pItem->xvel].extra].data1; addPower = xsprite[sprite[pItem->xvel].extra].data1;
#endif
if (!actHealDude(pXSprite, addPower, gPowerUpInfo[nType].maxTime)) return 0; if (!actHealDude(pXSprite, addPower, gPowerUpInfo[nType].maxTime)) return 0;
return 1; return 1;
@ -1230,11 +1227,12 @@ char PickupAmmo(PLAYER* pPlayer, spritetype* pAmmo) {
int nAmmoType = pAmmoItemData->type; int nAmmoType = pAmmoItemData->type;
if (pPlayer->ammoCount[nAmmoType] >= gAmmoInfo[nAmmoType].max) return 0; if (pPlayer->ammoCount[nAmmoType] >= gAmmoInfo[nAmmoType].max) return 0;
else if (!gModernMap || pAmmo->extra < 0 || xsprite[pAmmo->extra].data1 <= 0) #ifdef NOONE_EXTENSIONS
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType]+pAmmoItemData->count, gAmmoInfo[nAmmoType].max); else if (gModernMap && pAmmo->extra >= 0 && xsprite[pAmmo->extra].data1 > 0) // allow custom amount for item
// by NoOne: allow custom amount for item
else
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + xsprite[pAmmo->extra].data1, gAmmoInfo[nAmmoType].max); pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + xsprite[pAmmo->extra].data1, gAmmoInfo[nAmmoType].max);
#endif
else
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType]+pAmmoItemData->count, gAmmoInfo[nAmmoType].max);
if (pAmmoItemData->weaponType) pPlayer->hasWeapon[pAmmoItemData->weaponType] = 1; if (pAmmoItemData->weaponType) pPlayer->hasWeapon[pAmmoItemData->weaponType] = 1;
sfxPlay3DSound(pPlayer->pSprite, 782, -1, 0); sfxPlay3DSound(pPlayer->pSprite, 782, -1, 0);
@ -1250,11 +1248,13 @@ char PickupWeapon(PLAYER *pPlayer, spritetype *pWeapon) {
return 0; return 0;
pPlayer->hasWeapon[nWeaponType] = 1; pPlayer->hasWeapon[nWeaponType] = 1;
if (nAmmoType == -1) return 0; if (nAmmoType == -1) return 0;
// By NoOne: allow to set custom ammo count for weapon pickups // allow to set custom ammo count for weapon pickups
if (!gModernMap || pWeapon->extra < 0 || xsprite[pWeapon->extra].data1 <= 0) #ifdef NOONE_EXTENSIONS
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + pWeaponItemData->count, gAmmoInfo[nAmmoType].max); else if (gModernMap && pWeapon->extra >= 0 && xsprite[pWeapon->extra].data1 > 0)
else
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + xsprite[pWeapon->extra].data1, gAmmoInfo[nAmmoType].max); pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + xsprite[pWeapon->extra].data1, gAmmoInfo[nAmmoType].max);
#endif
else
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + pWeaponItemData->count, gAmmoInfo[nAmmoType].max);
int nNewWeapon = WeaponUpgrade(pPlayer, nWeaponType); int nNewWeapon = WeaponUpgrade(pPlayer, nWeaponType);
if (nNewWeapon != pPlayer->curWeapon) { if (nNewWeapon != pPlayer->curWeapon) {
@ -1266,10 +1266,12 @@ char PickupWeapon(PLAYER *pPlayer, spritetype *pWeapon) {
} }
if (!actGetRespawnTime(pWeapon) || nAmmoType == -1 || pPlayer->ammoCount[nAmmoType] >= gAmmoInfo[nAmmoType].max) return 0; if (!actGetRespawnTime(pWeapon) || nAmmoType == -1 || pPlayer->ammoCount[nAmmoType] >= gAmmoInfo[nAmmoType].max) return 0;
else if (!gModernMap || pWeapon->extra < 0 || xsprite[pWeapon->extra].data1 <= 0) #ifdef NOONE_EXTENSIONS
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType]+pWeaponItemData->count, gAmmoInfo[nAmmoType].max); else if (gModernMap && pWeapon->extra >= 0 && xsprite[pWeapon->extra].data1 > 0)
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + xsprite[pWeapon->extra].data1, gAmmoInfo[nAmmoType].max);
#endif
else else
pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + xsprite[pWeapon->extra].data1, gAmmoInfo[nAmmoType].max); pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType]+pWeaponItemData->count, gAmmoInfo[nAmmoType].max);
sfxPlay3DSound(pPlayer->pSprite, 777, -1, 0); sfxPlay3DSound(pPlayer->pSprite, 777, -1, 0);
return 1; return 1;
@ -1281,12 +1283,13 @@ void PickUp(PLAYER *pPlayer, spritetype *pSprite)
int nType = pSprite->type; int nType = pSprite->type;
char pickedUp = 0; char pickedUp = 0;
int customMsg = -1; int customMsg = -1;
#ifdef NOONE_EXTENSIONS
if (gModernMap) { // by NoOne: allow custom INI message instead "Picked up" if (gModernMap) { // allow custom INI message instead "Picked up"
XSPRITE* pXSprite = (pSprite->extra >= 0) ? &xsprite[pSprite->extra] : NULL; XSPRITE* pXSprite = (pSprite->extra >= 0) ? &xsprite[pSprite->extra] : NULL;
if (pXSprite != NULL && pXSprite->txID != 3 && pXSprite->lockMsg > 0) if (pXSprite != NULL && pXSprite->txID != 3 && pXSprite->lockMsg > 0)
customMsg = pXSprite->lockMsg; customMsg = pXSprite->lockMsg;
} }
#endif
if (nType >= kItemBase && nType <= kItemMax) { if (nType >= kItemBase && nType <= kItemMax) {
pickedUp = PickupItem(pPlayer, pSprite); pickedUp = PickupItem(pPlayer, pSprite);
@ -1578,7 +1581,9 @@ void ProcessInput(PLAYER *pPlayer)
break; break;
default: default:
if (!pPlayer->cantJump && pInput->buttonFlags.jump && pXSprite->height == 0) { if (!pPlayer->cantJump && pInput->buttonFlags.jump && pXSprite->height == 0) {
#ifdef NOONE_EXTENSIONS
if ((packItemActive(pPlayer, 4) && pPosture->pwupJumpZ != 0) || pPosture->normalJumpZ != 0) if ((packItemActive(pPlayer, 4) && pPosture->pwupJumpZ != 0) || pPosture->normalJumpZ != 0)
#endif
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;
@ -2332,17 +2337,18 @@ void PlayerLoadSave::Load(void)
Read(&gNetPlayers, sizeof(gNetPlayers)); Read(&gNetPlayers, sizeof(gNetPlayers));
Read(&gProfile, sizeof(gProfile)); Read(&gProfile, sizeof(gProfile));
Read(&gPlayer, sizeof(gPlayer)); Read(&gPlayer, sizeof(gPlayer));
#ifdef NOONE_EXTENSIONS
Read((void*)&buffer, sizeof(kPlayerCtrlSigStart)); Read((void*)&buffer, sizeof(kPlayerCtrlSigStart));
Read(&gPlayerCtrl, sizeof(gPlayerCtrl)); Read(&gPlayerCtrl, sizeof(gPlayerCtrl));
Read((void*)&buffer, sizeof(kPlayerCtrlSigEnd)); Read((void*)&buffer, sizeof(kPlayerCtrlSigEnd));
#endif
for (int i = 0; i < gNetPlayers; i++) { for (int i = 0; i < gNetPlayers; i++) {
gPlayer[i].pSprite = &sprite[gPlayer[i].nSprite]; gPlayer[i].pSprite = &sprite[gPlayer[i].nSprite];
gPlayer[i].pXSprite = &xsprite[gPlayer[i].pSprite->extra]; gPlayer[i].pXSprite = &xsprite[gPlayer[i].pSprite->extra];
gPlayer[i].pDudeInfo = &dudeInfo[gPlayer[i].pSprite->type-kDudeBase]; gPlayer[i].pDudeInfo = &dudeInfo[gPlayer[i].pSprite->type-kDudeBase];
// by NoOne: load qav scene #ifdef NOONE_EXTENSIONS
// load qav scene
if (gPlayer[i].sceneQav != -1) { if (gPlayer[i].sceneQav != -1) {
if (gPlayerCtrl[i].qavScene.qavResrc == NULL) if (gPlayerCtrl[i].qavScene.qavResrc == NULL)
gPlayer[i].sceneQav = -1; gPlayer[i].sceneQav = -1;
@ -2356,13 +2362,8 @@ void PlayerLoadSave::Load(void)
} }
} }
} }
#endif
// by NoOne: load posture info
/*for (int a = 0; a < kModeMax; a++) {
for (int b = 0; b < kPostureMax; b++) {
gPosture[a][b] = gPlayerCtrl[i].posture[a][b];
}
}*/
} }
} }
@ -2373,19 +2374,11 @@ void PlayerLoadSave::Save(void)
Write(&gProfile, sizeof(gProfile)); Write(&gProfile, sizeof(gProfile));
Write(&gPlayer, sizeof(gPlayer)); Write(&gPlayer, sizeof(gPlayer));
#ifdef NOONE_EXTENSIONS
////// by NoOne: copy posture to TRPLAYERCTRL before saving the game
/*for (int i = 0; i < gNetPlayers; i++) {
for (int a = 0; a < kModeMax; a++) {
for (int b = 0; b < kPostureMax; b++) {
gPlayerCtrl[i].posture[a][b] = gPosture[a][b];
}
}
}*/
Write((void*)kPlayerCtrlSigStart, sizeof(kPlayerCtrlSigStart)); Write((void*)kPlayerCtrlSigStart, sizeof(kPlayerCtrlSigStart));
Write(&gPlayerCtrl, sizeof(gPlayerCtrl)); Write(&gPlayerCtrl, sizeof(gPlayerCtrl));
Write((void*)kPlayerCtrlSigEnd, sizeof(kPlayerCtrlSigEnd)); Write((void*)kPlayerCtrlSigEnd, sizeof(kPlayerCtrlSigEnd));
////// #endif
} }
static PlayerLoadSave *myLoadSave; static PlayerLoadSave *myLoadSave;

View file

@ -61,11 +61,6 @@ struct PACKINFO
int curAmount = 0; // remaining percent int curAmount = 0; // remaining percent
}; };
// by NoOne: defaut player movement speeds of all move states for gPosture
extern int gDefaultAccel[12];
// by NoOne: defaut player jump heights of all move states for gPosture
extern int gDefaultJumpZ[24];
struct POSTURE struct POSTURE
{ {
int frontAccel; int frontAccel;
@ -224,19 +219,34 @@ struct POWERUPINFO
int maxTime; int maxTime;
}; };
// by NoOne: this one stores qavs anims that can be played by trigger #ifdef NOONE_EXTENSIONS
struct QAVSCENE { // this one stores qavs anims that can be played by trigger
struct QAVSCENE
{
short index = -1; // index of sprite which triggered qav scene short index = -1; // index of sprite which triggered qav scene
QAV * qavResrc = NULL; QAV * qavResrc = NULL;
short dummy = -1; short dummy = -1;
}; };
// by NoOne: this one for controlling the player using triggers (movement speed, jumps and other stuff) // this one for controlling the player using triggers (movement speed, jumps and other stuff)
struct TRPLAYERCTRL { struct TRPLAYERCTRL {
QAVSCENE qavScene; QAVSCENE qavScene;
}; };
extern TRPLAYERCTRL gPlayerCtrl[kMaxPlayers]; extern TRPLAYERCTRL gPlayerCtrl[kMaxPlayers];
bool isGrown(spritetype *pSprite);
bool isShrinked(spritetype *pSprite);
bool shrinkPlayerSize(PLAYER *pPlayer, int divider);
bool growPlayerSize(PLAYER *pPlayer, int multiplier);
bool resetPlayerSize(PLAYER *pPlayer);
void deactivateSizeShrooms(PLAYER *pPlayer);
PLAYER * getPlayerById(short id);
QAV * qavSceneLoad(int qavId);
void qavScenePlay(PLAYER *pPlayer);
void qavSceneDraw(PLAYER *pPlayer, int a2, int a3, int a4, int a5);
void playerResetQavScene(PLAYER *pPlayer);
#endif
void playerResetPosture(PLAYER* pPlayer);
extern PLAYER gPlayer[kMaxPlayers]; extern PLAYER gPlayer[kMaxPlayers];
extern PLAYER *gMe, *gView; extern PLAYER *gMe, *gView;
@ -324,17 +334,5 @@ void sub_41250(PLAYER *pPlayer);
void playerLandingSound(PLAYER *pPlayer); void playerLandingSound(PLAYER *pPlayer);
void PlayerSurvive(int, int nXSprite); void PlayerSurvive(int, int nXSprite);
void PlayerKneelsOver(int, int nXSprite); void PlayerKneelsOver(int, int nXSprite);
bool isGrown(spritetype *pSprite);
bool isShrinked(spritetype *pSprite);
bool shrinkPlayerSize(PLAYER *pPlayer, int divider);
bool growPlayerSize(PLAYER *pPlayer, int multiplier);
bool resetPlayerSize(PLAYER *pPlayer);
void deactivateSizeShrooms(PLAYER *pPlayer);
PLAYER * getPlayerById(short id);
QAV * qavSceneLoad(int qavId);
void qavScenePlay(PLAYER *pPlayer);
void qavSceneDraw(PLAYER *pPlayer, int a2, int a3, int a4, int a5);
void playerResetPosture(PLAYER* pPlayer);
void playerResetQavScene(PLAYER *pPlayer);
END_BLD_NS END_BLD_NS

View file

@ -302,10 +302,11 @@ void SEQINST::Update(ACTIVE *pActive)
sfxPlay3DSound(&sprite[xsprite[pActive->xindex].reference], sound, -1, 0); sfxPlay3DSound(&sprite[xsprite[pActive->xindex].reference], sound, -1, 0);
} }
// by NoOne: add surfaceSound trigger feature
spritetype* pSprite = &sprite[xsprite[pActive->xindex].reference]; spritetype* pSprite = &sprite[xsprite[pActive->xindex].reference];
if (!VanillaMode() && pSequence->frames[frameIndex].surfaceSound && zvel[pSprite->xvel] == 0 && xvel[pSprite->xvel] != 0) { if (!VanillaMode() && pSequence->frames[frameIndex].surfaceSound && zvel[pSprite->xvel] == 0 && xvel[pSprite->xvel] != 0) {
// by NoOne: add surfaceSound trigger feature
if (gUpperLink[pSprite->sectnum] >= 0) break; // don't play surface sound for stacked sectors if (gUpperLink[pSprite->sectnum] >= 0) break; // don't play surface sound for stacked sectors
int surf = tileGetSurfType(pSprite->sectnum + 0x4000); if (!surf) break; int surf = tileGetSurfType(pSprite->sectnum + 0x4000); if (!surf) break;
static int surfSfxMove[15][4] = { static int surfSfxMove[15][4] = {
@ -336,8 +337,6 @@ void SEQINST::Update(ACTIVE *pActive)
sfxPlay3DSoundCP(pSprite, sndId, -1, 0, 0, (surfSfxMove[surf][2] != relVol) ? relVol : surfSfxMove[surf][3]); sfxPlay3DSoundCP(pSprite, sndId, -1, 0, 0, (surfSfxMove[surf][2] != relVol) ? relVol : surfSfxMove[surf][3]);
} }
} }
break; break;
} }
case 4: case 4:

File diff suppressed because it is too large Load diff

View file

@ -32,9 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "player.h" #include "player.h"
BEGIN_BLD_NS BEGIN_BLD_NS
#define kPlayerCtrlSigStart "<<<<TRPLAYERCTRL{" // save game TRPLAYERCTRL block start
#define kPlayerCtrlSigEnd "}TRPLAYERCTRL>>>>" // save game TRPLAYERCTRL block end
void trTriggerSector(unsigned int nSector, XSECTOR *pXSector, int command); void trTriggerSector(unsigned int nSector, XSECTOR *pXSector, int command);
void trMessageSector(unsigned int nSector, EVENT event); void trMessageSector(unsigned int nSector, EVENT event);
void trTriggerWall(unsigned int nWall, XWALL *pXWall, int command); void trTriggerWall(unsigned int nWall, XWALL *pXWall, int command);
@ -45,8 +42,12 @@ void trProcessBusy(void);
void trInit(void); void trInit(void);
void trTextOver(int nId); void trTextOver(int nId);
// By NoOne: functions required for new features #ifdef NOONE_EXTENSIONS
// functions required for new features
// ------------------------------------------------------- // -------------------------------------------------------
#define kPlayerCtrlSigStart "<<<<TRPLAYERCTRL{" // save game TRPLAYERCTRL block start
#define kPlayerCtrlSigEnd "}TRPLAYERCTRL>>>>" // save game TRPLAYERCTRL block end
void pastePropertiesInObj(int type, int nDest, EVENT event); void pastePropertiesInObj(int type, int nDest, EVENT event);
spritetype* getTargetInRange(spritetype* pSprite, int minDist, int maxDist, short data, short teamMode); spritetype* getTargetInRange(spritetype* pSprite, int minDist, int maxDist, short data, short teamMode);
bool isMateOf(XSPRITE* pXDude, XSPRITE* pXSprite); bool isMateOf(XSPRITE* pXDude, XSPRITE* pXSprite);
@ -86,6 +87,8 @@ bool valueIsBetween(int val, int min, int max);
void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer); void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer);
void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer); void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer);
void trPlayerCtrlStopScene(XSPRITE* pXSource, PLAYER* pPlayer); void trPlayerCtrlStopScene(XSPRITE* pXSource, PLAYER* pPlayer);
char modernTypeSetSpriteState(int nSprite, XSPRITE* pXSprite, int nState);
// ------------------------------------------------------- // -------------------------------------------------------
#endif// -------------------------------------------------------
END_BLD_NS END_BLD_NS

View file

@ -3498,12 +3498,17 @@ void viewDrawScreen(bool sceneonly)
nPalette = pSector->floorpal; nPalette = pSector->floorpal;
} }
#ifdef NOONE_EXTENSIONS
if (gView->sceneQav < 0) WeaponDraw(gView, nShade, cX, cY, nPalette); if (gView->sceneQav < 0) WeaponDraw(gView, nShade, cX, cY, nPalette);
else if (gView->pXSprite->health > 0) qavSceneDraw(gView, nShade, cX, cY, nPalette); else if (gView->pXSprite->health > 0) qavSceneDraw(gView, nShade, cX, cY, nPalette);
else { else {
gView->sceneQav = gView->weaponQav = -1; gView->sceneQav = gView->weaponQav = -1;
gView->weaponTimer = gView->curWeapon = 0; gView->weaponTimer = gView->curWeapon = 0;
} }
#else
WeaponDraw(gView, nShade, cX, cY, nPalette);
#endif
} }

View file

@ -36,11 +36,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_BLD_NS BEGIN_BLD_NS
ZONE gStartZone[8]; ZONE gStartZone[8];
ZONE gStartZoneTeam1[8]; #ifdef NOONE_EXTENSIONS
ZONE gStartZoneTeam2[8]; ZONE gStartZoneTeam1[8];
ZONE gStartZoneTeam2[8];
bool gTeamsSpawnUsed = false; bool gTeamsSpawnUsed = false;
#endif
void warpInit(void) void warpInit(void)
{ {
for (int i = 0; i < kMaxSectors; i++) for (int i = 0; i < kMaxSectors; i++)
@ -48,7 +48,9 @@ void warpInit(void)
gUpperLink[i] = -1; gUpperLink[i] = -1;
gLowerLink[i] = -1; gLowerLink[i] = -1;
} }
#ifdef NOONE_EXTENSIONS
int team1 = 0; int team2 = 0; gTeamsSpawnUsed = false; // increment if team start positions specified. int team1 = 0; int team2 = 0; gTeamsSpawnUsed = false; // increment if team start positions specified.
#endif
for (int nSprite = 0; nSprite < kMaxSprites; nSprite++) for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
{ {
if (sprite[nSprite].statnum < kMaxStatus) { if (sprite[nSprite].statnum < kMaxStatus) {
@ -79,27 +81,30 @@ void warpInit(void)
pZone->sectnum = pSprite->sectnum; pZone->sectnum = pSprite->sectnum;
pZone->ang = pSprite->ang; pZone->ang = pSprite->ang;
// By NoOne: fill player spawn position according team of player in TEAMS mode. #ifdef NOONE_EXTENSIONS
if (gModernMap && gGameOptions.nGameType == 3) { // fill player spawn position according team of player in TEAMS mode.
if (pXSprite->data2 == 1) { if (gModernMap && gGameOptions.nGameType == 3) {
pZone = &gStartZoneTeam1[team1]; if (pXSprite->data2 == 1) {
pZone->x = pSprite->x; pZone = &gStartZoneTeam1[team1];
pZone->y = pSprite->y; pZone->x = pSprite->x;
pZone->z = pSprite->z; pZone->y = pSprite->y;
pZone->sectnum = pSprite->sectnum; pZone->z = pSprite->z;
pZone->ang = pSprite->ang; pZone->sectnum = pSprite->sectnum;
team1++; pZone->ang = pSprite->ang;
team1++;
} else if (pXSprite->data2 == 2) { } else if (pXSprite->data2 == 2) {
pZone = &gStartZoneTeam2[team2]; pZone = &gStartZoneTeam2[team2];
pZone->x = pSprite->x; pZone->x = pSprite->x;
pZone->y = pSprite->y; pZone->y = pSprite->y;
pZone->z = pSprite->z; pZone->z = pSprite->z;
pZone->sectnum = pSprite->sectnum; pZone->sectnum = pSprite->sectnum;
pZone->ang = pSprite->ang; pZone->ang = pSprite->ang;
team2++; team2++;
}
} }
} #endif
} }
DeleteSprite(nSprite); DeleteSprite(nSprite);
} }
@ -135,6 +140,7 @@ void warpInit(void)
} }
} }
#ifdef NOONE_EXTENSIONS
// check if there is enough start positions for teams, if any used // check if there is enough start positions for teams, if any used
if (team1 > 0 || team2 > 0) { if (team1 > 0 || team2 > 0) {
gTeamsSpawnUsed = true; gTeamsSpawnUsed = true;
@ -143,6 +149,7 @@ void warpInit(void)
viewSetSystemMessage("Team A positions: %d, Team B positions: %d.", team1, team2); viewSetSystemMessage("Team A positions: %d, Team B positions: %d.", team1, team2);
} }
} }
#endif
for (int i = 0; i < kMaxSectors; i++) for (int i = 0; i < kMaxSectors; i++)
{ {

View file

@ -30,9 +30,11 @@ struct ZONE {
short sectnum, ang; short sectnum, ang;
}; };
extern ZONE gStartZone[8]; extern ZONE gStartZone[8];
#ifdef NOONE_EXTENSIONS
extern ZONE gStartZoneTeam1[8]; extern ZONE gStartZoneTeam1[8];
extern ZONE gStartZoneTeam2[8]; extern ZONE gStartZoneTeam2[8];
extern bool gTeamsSpawnUsed; extern bool gTeamsSpawnUsed;
#endif
void warpInit(void); void warpInit(void);
int CheckLink(spritetype *pSprite); int CheckLink(spritetype *pSprite);

View file

@ -1936,7 +1936,7 @@ char sub_4F484(PLAYER *pPlayer)
void WeaponProcess(PLAYER *pPlayer) { void WeaponProcess(PLAYER *pPlayer) {
pPlayer->flashEffect = ClipLow(pPlayer->flashEffect - 1, 0); pPlayer->flashEffect = ClipLow(pPlayer->flashEffect - 1, 0);
#ifdef NOONE_EXTENSIONS
if (gPlayerCtrl[pPlayer->nPlayer].qavScene.index >= 0 && pPlayer->pXSprite->health > 0) { if (gPlayerCtrl[pPlayer->nPlayer].qavScene.index >= 0 && pPlayer->pXSprite->health > 0) {
QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene;
@ -1960,6 +1960,7 @@ void WeaponProcess(PLAYER *pPlayer) {
return; return;
} }
#endif
if (pPlayer->pXSprite->health == 0) if (pPlayer->pXSprite->health == 0)
{ {