From 0693b0efc85b4b21b6b02f751c294d994f61423d Mon Sep 17 00:00:00 2001 From: NoOneBlood Date: Sun, 26 Jan 2020 14:19:01 +0300 Subject: [PATCH] - 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 --- source/blood/src/actor.cpp | 403 +++---- source/blood/src/actor.h | 69 +- source/blood/src/ai.cpp | 85 +- source/blood/src/ai.h | 5 +- source/blood/src/aiburn.cpp | 10 + source/blood/src/aiunicult.cpp | 14 +- source/blood/src/aiunicult.h | 3 +- source/blood/src/blood.cpp | 6 +- source/blood/src/callback.cpp | 24 +- source/blood/src/callback.h | 2 + source/blood/src/common_game.h | 100 +- source/blood/src/db.cpp | 13 +- source/blood/src/db.h | 18 +- source/blood/src/eventq.cpp | 8 +- source/blood/src/gameutil.cpp | 4 +- source/blood/src/levels.cpp | 4 +- source/blood/src/levels.h | 4 +- source/blood/src/loadsave.cpp | 4 + source/blood/src/player.cpp | 171 ++- source/blood/src/player.h | 44 +- source/blood/src/seq.cpp | 7 +- source/blood/src/triggers.cpp | 1840 +++++++++++++++++--------------- source/blood/src/triggers.h | 11 +- source/blood/src/view.cpp | 5 + source/blood/src/warp.cpp | 55 +- source/blood/src/warp.h | 2 + source/blood/src/weapon.cpp | 3 +- 27 files changed, 1564 insertions(+), 1350 deletions(-) diff --git a/source/blood/src/actor.cpp b/source/blood/src/actor.cpp index 2c26951b4..3b77cd14f 100644 --- a/source/blood/src/actor.cpp +++ b/source/blood/src/actor.cpp @@ -79,6 +79,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS VECTORDATA gVectorData[] = { + // Tine { DAMAGE_TYPE_2, @@ -104,8 +105,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 1207, 1207, }, + // Shell { DAMAGE_TYPE_2, @@ -131,8 +132,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 1001, 1001, }, + // Bullet { DAMAGE_TYPE_2, @@ -158,8 +159,9 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, 513, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 4001, 4002, + }, + // Tommy AP { DAMAGE_TYPE_2, @@ -185,8 +187,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, 513, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 431, 431 }, + // Shell AP { DAMAGE_TYPE_2, @@ -212,8 +214,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 1002, 1002, }, + // Tommy regular { DAMAGE_TYPE_2, @@ -239,8 +241,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, 513, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 359, 359, }, + // Bat bite { DAMAGE_TYPE_2, @@ -266,8 +268,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 521, 521, }, + // Eel bite { DAMAGE_TYPE_2, @@ -293,8 +295,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 513, 513 }, + // Gill bite { DAMAGE_TYPE_2, @@ -320,8 +322,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 499, 499 }, + // Beast slash { DAMAGE_TYPE_3, @@ -347,8 +349,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 9012, 9014 }, + // Axe { DAMAGE_TYPE_2, @@ -374,8 +376,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 1101, 1101 }, + // Cleaver { DAMAGE_TYPE_2, @@ -401,8 +403,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 1207, 1207 }, + // Phantasm slash { DAMAGE_TYPE_2, @@ -428,8 +430,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 499, 495 }, + // Gargoyle Slash { DAMAGE_TYPE_2, @@ -455,8 +457,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_6, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_5, FX_NONE, -1, - 495, 496 }, + // Cerberus bite { DAMAGE_TYPE_2, @@ -482,8 +484,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 9013, 499 }, + // Hound bite { DAMAGE_TYPE_2, @@ -509,8 +511,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 1307, 1308 }, + // Rat bite { DAMAGE_TYPE_2, @@ -536,8 +538,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 499, 499 }, + // Spider bite { DAMAGE_TYPE_2, @@ -563,8 +565,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 499, 499 }, + // Unk { DAMAGE_TYPE_2, @@ -590,7 +592,6 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 502, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 499, 499 }, { @@ -617,8 +618,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 499, 499 }, + // Tchernobog burn vector { DAMAGE_TYPE_1, @@ -644,8 +645,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 351, 351 }, + // Vodoo 1.0 vector { DAMAGE_TYPE_5, @@ -671,8 +672,8 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, FX_NONE, FX_NONE, FX_NONE, -1, - 0,0 }, + // 22 kVectorGenDudePunch { DAMAGE_TYPE_0, @@ -698,7 +699,6 @@ VECTORDATA gVectorData[] = { FX_NONE, FX_NONE, FX_NONE, 357, FX_NONE, FX_NONE, FX_NONE, 357, FX_NONE, FX_NONE, FX_NONE, 357, - 357, 499 }, }; @@ -1514,9 +1514,6 @@ MissileType missileInfo[] = { 40, (char)-16, 16, - 1207, 1207, - false, false, false, false, false, true, false - }, // Regular flare { @@ -1527,8 +1524,6 @@ MissileType missileInfo[] = { 32, (char)-128, 32, - 420, 420, - false, true, true, false, false, false, false }, // Tesla alt { @@ -1539,8 +1534,6 @@ MissileType missileInfo[] = { 32, (char)-128, 32, - 471, 471, - false, false, false, false, false, false, true }, // Flare alt { @@ -1551,8 +1544,6 @@ MissileType missileInfo[] = { 32, (char)-128, 4, - 421, 421, - false, true, false, true, false, false, false }, // Spray flame { @@ -1563,8 +1554,6 @@ MissileType missileInfo[] = { 24, (char)-128, 16, - 1309, 351, - false, true, false, false, false, false, false }, // Fireball { @@ -1575,8 +1564,6 @@ MissileType missileInfo[] = { 32, (char)-128, 32, - 480, 480, - false, true, false, true, false, false, false }, // Tesla regular { @@ -1587,8 +1574,6 @@ MissileType missileInfo[] = { 32, (char)-128, 16, - 470, 470, - false, false, false, false, false, false, true }, // EctoSkull { @@ -1599,8 +1584,6 @@ MissileType missileInfo[] = { 32, (char)-24, 32, - 489, 490, - false, false, false, false, false, true, false }, // Hellhound flame { @@ -1611,8 +1594,6 @@ MissileType missileInfo[] = { 24, (char)-128, 16, - 462, 351, - false, true, false, false, false, false, false }, // Puke { @@ -1623,8 +1604,6 @@ MissileType missileInfo[] = { 16, (char)-16, 16, - 1203, 172, - false, false, true, false, false, false, false }, // Reserved { @@ -1635,8 +1614,6 @@ MissileType missileInfo[] = { 8, (char)0, 16, - 0,0, - false, false, true, false, false, false, false }, // Stone gargoyle projectile { @@ -1647,8 +1624,6 @@ MissileType missileInfo[] = { 32, (char)-128, 16, - 1457, 249, - false, false, false, false, false, true, false }, // Napalm launcher { @@ -1659,8 +1634,6 @@ MissileType missileInfo[] = { 30, (char)-128, 24, - 480, 489, - false, true, false, true, false, false, false }, // Cerberus fireball { @@ -1671,8 +1644,6 @@ MissileType missileInfo[] = { 30, (char)-128, 24, - 480, 489, - false, false, false, true, false, false, false }, // Tchernobog fireball { @@ -1683,8 +1654,6 @@ MissileType missileInfo[] = { 24, (char)-128, 16, - 480, 489, - false, false, false, true, false, false, false }, // Regular life leech { @@ -1695,8 +1664,6 @@ MissileType missileInfo[] = { 32, (char)-128, 16, - 491, 491, - true, true, true, true, true, true, true }, // Dropped life leech (enough ammo) { @@ -1707,8 +1674,6 @@ MissileType missileInfo[] = { 16, (char)-128, 16, - 520, 520, - false, false, false, false, false, true, false }, // Dropped life leech (no ammo) { @@ -1719,8 +1684,6 @@ MissileType missileInfo[] = { 32, (char)-128, 16, - 520, 520, - false, false, false, false, false, true, false } }; @@ -1740,8 +1703,8 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 256, 128, 64, 0, 0, 128, - 1 }, + // Armed Proxy Dynamite { 5, @@ -1757,7 +1720,6 @@ const THINGINFO thingInfo[] = { 32, 32, 256, 256, 256, 64, 0, 0, 512, - 1 }, // Armed Remote Dynamite { @@ -1774,7 +1736,6 @@ const THINGINFO thingInfo[] = { 32, 32, 256, 256, 256, 64, 0, 0, 512, - 1 }, // Vase1 { @@ -1791,7 +1752,6 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 0, 256, 128, 0, 0, 0, - 0 }, // Vase2 { @@ -1808,7 +1768,6 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 256, 256, 128, 0, 0, 0, - 0 }, // Crate face { @@ -1825,7 +1784,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 0, 0, 256, 0, 0, 0, - 0 }, // Glass window { @@ -1842,7 +1800,6 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 0, 256, 256, 0, 0, 0, - 0, }, // Flourescent Light { @@ -1859,7 +1816,6 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 0, 256, 256, 0, 0, 512, - 0, }, // Wall Crack { @@ -1876,7 +1832,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 0, 0, 256, 0, 0, 0, - 0, }, // Wood Beam { @@ -1893,7 +1848,6 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 0, 256, 128, 0, 0, 0, - 0, }, // Spider's Web { @@ -1910,7 +1864,6 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 256, 64, 256, 0, 0, 128, - 0, }, // Metal Grate { @@ -1927,7 +1880,6 @@ const THINGINFO thingInfo[] = { 0, 0, 64, 0, 128, 256, 0, 0, 0, - 0, }, // Flammable Tree { @@ -1944,7 +1896,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 256, 0, 256, 0, 0, 128, - 0, }, // MachineGun Trap { @@ -1961,7 +1912,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 0, 128, 256, 0, 0, 512, - 0, }, // Falling Rock { @@ -1978,7 +1928,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, }, // Kickable Pail { @@ -1995,7 +1944,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, }, // Gib Object { @@ -2012,7 +1960,6 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 0, 256, 256, 0, 0, 128, - 0, }, // Explode Object { @@ -2029,7 +1976,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 0, 0, 256, 0, 0, 128, - 0, }, // Armed stick Of TNT { @@ -2046,7 +1992,6 @@ const THINGINFO thingInfo[] = { 32, 32, 64, 256, 128, 64, 0, 0, 256, - 1 }, // Armed bundle Of TNT { @@ -2063,7 +2008,6 @@ const THINGINFO thingInfo[] = { 32, 32, 64, 256, 128, 64, 0, 0, 256, - 1 }, // Armed aerosol { @@ -2080,7 +2024,6 @@ const THINGINFO thingInfo[] = { 32, 32, 64, 256, 128, 64, 0, 0, 256, - 1 }, // Bone (Flesh Garg.) { @@ -2097,7 +2040,6 @@ const THINGINFO thingInfo[] = { 32, 32, 0, 0, 0, 0, 0, 0, 0, - 1 }, // Some alpha stuff { @@ -2114,7 +2056,6 @@ const THINGINFO thingInfo[] = { 0, 0, 256, 0, 256, 256, 0, 0, 0, - 0, }, // WaterDrip { @@ -2131,7 +2072,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 }, // BloodDrip { @@ -2148,7 +2088,6 @@ const THINGINFO thingInfo[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, }, // Blood chucks1 { @@ -2165,7 +2104,6 @@ const THINGINFO thingInfo[] = { 0, 0, 128, 64, 256, 256, 0, 0, 256, - 0, }, // Blood chucks2 { @@ -2182,7 +2120,6 @@ const THINGINFO thingInfo[] = { 0, 0, 128, 64, 256, 256, 0, 0, 64, - 0, }, // Axe Zombie Head { @@ -2199,7 +2136,6 @@ const THINGINFO thingInfo[] = { 40, 40, 128, 64, 256, 256, 0, 0, 64, - 1, }, // Napalm's Alt Fire explosion { @@ -2216,7 +2152,6 @@ const THINGINFO thingInfo[] = { 32, 32, 0, 0, 0, 0, 0, 0, 0, - 1, }, // Fire Pod Explosion { @@ -2233,7 +2168,6 @@ const THINGINFO thingInfo[] = { 32, 32, 256, 0, 256, 256, 0, 0, 0, - 1, }, // Green Pod Explosion { @@ -2250,7 +2184,6 @@ const THINGINFO thingInfo[] = { 32, 32, 256, 0, 256, 256, 0, 0, 0, - 1, }, // Life Leech { @@ -2267,7 +2200,6 @@ const THINGINFO thingInfo[] = { 48, 48, 64, 64, 112, 64, 0, 96, 96, - 1, }, // Voodoo Head { @@ -2284,7 +2216,6 @@ const THINGINFO thingInfo[] = { 16, 16, 0, 0, 0, 0, 0, 0, 0, - 1, }, // 433 - kModernThingTNTProx { @@ -2301,7 +2232,6 @@ const THINGINFO thingInfo[] = { 32, 32, 256, 256, 256, 64, 0, 0, 512, - 1 }, // 434 - kModernThingThrowableRock { @@ -2318,7 +2248,6 @@ const THINGINFO thingInfo[] = { 32, 32, 0, 0, 0, 0, 0, 0, 0, - 1 }, // 435 - kModernThingEnemyLifeLeech { @@ -2335,7 +2264,6 @@ const THINGINFO thingInfo[] = { 48, 48, 64, 64, 112, 64, 0, 96, 96, - 1, }, }; @@ -2463,7 +2391,50 @@ struct POSTPONE { POSTPONE gPost[kMaxSprites]; -//static char buffer[120]; +#ifdef NOONE_EXTENSIONS +VECTORINFO_EXTRA gVectorInfoExtra[] = { + 1207,1207, 1001,1001, 4001,4002, + 431,431, 1002,1002, 359,359, + 521,521, 513,513, 499,499, + 9012,9014, 1101,1101, 1207,1207, + 499,495, 495,496, 9013,499, + 1307,1308, 499,499, 499,499, + 499,499, 499,499, 351,351, + 0,0, 357,499 +}; + +MISSILEINFO_EXTRA gMissileInfoExtra[] = { + 1207, 1207, false, false, false, false, false, true, false, + 420, 420, false, true, true, false, false, false, false, + 471, 471, false, false, false, false, false, false, true, + 421, 421, false, true, false, true, false, false, false, + 1309, 351, false, true, false, false, false, false, false, + 480, 480, false, true, false, true, false, false, false, + 470, 470, false, false, false, false, false, false, true, + 489, 490, false, false, false, false, false, true, false, + 462, 351, false, true, false, false, false, false, false, + 1203, 172, false, false, true, false, false, false, false, + 0,0, false, false, true, false, false, false, false, + 1457, 249, false, false, false, false, false, true, false, + 480, 489, false, true, false, true, false, false, false, + 480, 489, false, false, false, true, false, false, false, + 480, 489, false, false, false, true, false, false, false, + 491, 491, true, true, true, true, true, true, true, + 520, 520, false, false, false, false, false, true, false, + 520, 520, false, false, false, false, false, true, false +}; + +THINGINFO_EXTRA gThingInfoExtra[] = { + true, true, true, false, false, + false, false, false, false, false, + false, false, false, false, false, + true, false, false, true, true, + true, true, false, false, false, + false, false, true, true, true, + true, true, true, true, true, + true, +}; +#endif bool IsItemSprite(spritetype *pSprite) { @@ -2546,20 +2517,23 @@ int DudeDifficulty[5] = { 512, 384, 256, 208, 160 }; -SPRITEMASS gSpriteMass[]; // by NoOne: cache for getSpriteMassBySize(); +#ifdef NOONE_EXTENSIONS +SPRITEMASS gSpriteMass[]; // cache for getSpriteMassBySize(); -short gProxySpritesList[]; // by NoOne: list of additional sprites which can be triggered by Proximity +short gProxySpritesList[]; // list of additional sprites which can be triggered by Proximity short gProxySpritesCount; // current count -short gSightSpritesList[]; // by NoOne: list of additional sprites which can be triggered by Sight +short gSightSpritesList[]; // list of additional sprites which can be triggered by Sight short gSightSpritesCount; // current count -short gPhysSpritesList[]; // by NoOne: list of additional sprites which can be affected by physics +short gPhysSpritesList[]; // list of additional sprites which can be affected by physics short gPhysSpritesCount; // current count +#endif void actInit(bool bSaveLoad) { - // by NoOne: init code for all my stuff + #ifdef NOONE_EXTENSIONS + // init code for all my stuff if (gModernMap) { // reset counters @@ -2663,6 +2637,7 @@ void actInit(bool bSaveLoad) { } } } + #endif for (int nSprite = headspritestat[kStatItem]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { switch (sprite[nSprite].type) { @@ -2690,10 +2665,13 @@ void actInit(bool bSaveLoad) { int nType = pSprite->type - kThingBase; pXSprite->health = thingInfo[nType].startHealth << 4; - // by NoOne: allow level designer to set custom clipdist. + #ifdef NOONE_EXTENSIONS + // allow level designer to set custom clipdist. // this is especially useful for various Gib and Explode objects which have clipdist 1 for some reason predefined, // but what if it have voxel model...? - if (!gModernMap) pSprite->clipdist = thingInfo[nType].clipdist; + if (!gModernMap) + #endif + pSprite->clipdist = thingInfo[nType].clipdist; pSprite->flags = thingInfo[nType].flags; if (pSprite->flags & kPhysGravity) pSprite->flags |= kPhysFalling; @@ -2702,7 +2680,9 @@ void actInit(bool bSaveLoad) { switch (pSprite->type) { case kThingArmedProxBomb: case kTrapMachinegun: + #ifdef NOONE_EXTENSIONS case kModernThingTNTProx: + #endif pXSprite->state = 0; break; case kThingBloodChunks: { @@ -2753,15 +2733,16 @@ void actInit(bool bSaveLoad) { int nType = pSprite->type - kDudeBase; int seqStartId = dudeInfo[nType].seqStartID; if (!IsPlayerSprite(pSprite)) { + #ifdef NOONE_EXTENSIONS switch (pSprite->type) { case kDudeModernCustom: case kDudeModernCustomBurning: pSprite->cstat |= 4096 + CSTAT_SPRITE_BLOCK_HITSCAN + CSTAT_SPRITE_BLOCK; - 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; + seqStartId = genDudeSeqStartId(pXSprite); // Custom Dude stores it's SEQ in data2 + pXSprite->sysData1 = pXSprite->data3; // move sndStartId to sysData1, because data3 used by the game; pXSprite->data3 = 0; break; - case kDudePodMother: // by NoOne: FakeDude type (no seq, custom flags, clipdist and cstat) + case kDudePodMother: // FakeDude type (no seq, custom flags, clipdist and cstat) if (gModernMap) break; fallthrough__; default: @@ -2769,12 +2750,21 @@ void actInit(bool bSaveLoad) { pSprite->cstat |= 4096 + CSTAT_SPRITE_BLOCK_HITSCAN + CSTAT_SPRITE_BLOCK; break; } + #else + pSprite->clipdist = dudeInfo[nType].clipdist; + pSprite->cstat |= 4096 + CSTAT_SPRITE_BLOCK_HITSCAN + CSTAT_SPRITE_BLOCK; + #endif xvel[nSprite] = yvel[nSprite] = zvel[nSprite] = 0; - // By NoOne: add a way to set custom hp for every enemy - should work only if map just started and not loaded. + #ifdef NOONE_EXTENSIONS + // add a way to set custom hp for every enemy - should work only if map just started and not loaded. if (!gModernMap || pXSprite->data4 <= 0) pXSprite->health = dudeInfo[nType].startHealth << 4; else pXSprite->health = ClipRange(pXSprite->data4 << 4, 1, 65535); + #else + pXSprite->health = dudeInfo[nType].startHealth << 4; + #endif + } if (gSysRes.Lookup(seqStartId, "SEQ")) seqSpawn(seqStartId, 3, pSprite->extra); @@ -2798,12 +2788,14 @@ void ConcussSprite(int a1, spritetype *pSprite, int x, int y, int z, int a6) if (IsDudeSprite(pSprite)) { mass = dudeInfo[pSprite->type - kDudeBase].mass; + #ifdef NOONE_EXTENSIONS switch (pSprite->type) { case kDudeModernCustom: case kDudeModernCustomBurning: mass = getSpriteMassBySize(pSprite); break; } + #endif } else if (pSprite->type >= kThingBase && pSprite->type < kThingMax) { mass = thingInfo[pSprite->type - kThingBase].mass; @@ -3114,6 +3106,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, XSPRITE *pXSprite = &xsprite[pSprite->extra]; switch (pSprite->type) { + #ifdef NOONE_EXTENSIONS case kDudeModernCustom: { GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); @@ -3193,6 +3186,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, } break; } + #endif case kDudeCerberusTwoHead: // Cerberus seqSpawn(dudeInfo[nType].seqStartID+1, 3, nXSprite, -1); return; @@ -3286,6 +3280,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, case DAMAGE_TYPE_3: nSeq = 2; switch (pSprite->type) { + #ifdef NOONE_EXTENSIONS case kDudeModernCustom: case kDudeModernCustomBurning: { playGenDudeSound(pSprite, kGenDudeSndDeathExplode); @@ -3295,6 +3290,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, } break; } + #endif case kDudeCultistTommy: case kDudeCultistShotgun: case kDudeCultistTommyProne: @@ -3411,6 +3407,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, else seqSpawn(dudeInfo[nType].seqStartID+15, 3, nXSprite, nDudeToGibClient2); break; +#ifdef NOONE_EXTENSIONS case kDudeModernCustom: playGenDudeSound(pSprite, kGenDudeSndDeathNormal); if (nSeq == 3) { @@ -3448,6 +3445,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType, else seqSpawn(1 + pXSprite->data2, 3, nXSprite, nDudeToGibClient1); break; } +#endif case kDudeBurningZombieAxe: if (Chance(0x8000) && nSeq == 3) sfxPlay3DSound(pSprite, 1109, -1, 0); @@ -3698,8 +3696,10 @@ int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE damageType, in } int nType = pSprite->type - kDudeBase; int nDamageFactor = dudeInfo[nType].at70[damageType]; + #ifdef NOONE_EXTENSIONS if (pSprite->type == kDudeModernCustom) nDamageFactor = gGenDudeExtra[pSprite->index].dmgControl[damageType]; + #endif if (!nDamageFactor) return 0; else if (nDamageFactor != 256) @@ -3733,14 +3733,19 @@ int actDamageSprite(int nSource, spritetype *pSprite, DAMAGE_TYPE damageType, in if (pXSprite->health <= 0) { switch (pSprite->type) { case kThingDroppedLifeLeech: + #ifdef NOONE_EXTENSIONS case kModernThingEnemyLifeLeech: + #endif GibSprite(pSprite, GIBTYPE_14, NULL, NULL); pXSprite->data1 = pXSprite->data2 = pXSprite->data3 = pXSprite->DudeLockout = 0; pXSprite->stateTimer = pXSprite->data4 = pXSprite->isTriggered = 0; + #ifdef NOONE_EXTENSIONS if (pSprite->owner >= 0 && sprite[pSprite->owner].type == kDudeModernCustom) - sprite[pSprite->owner].owner = kMaxSprites - 1; // By NoOne: indicates if custom dude had life leech. + sprite[pSprite->owner].owner = kMaxSprites - 1; // indicates if custom dude had life leech. + #endif break; + default: if (!(pSprite->flags & kHitagRespawn)) actPropagateSpriteOwner(pSprite, &sprite[nSource]); @@ -4232,7 +4237,8 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) xvel[pSprite2->index] += mulscale(4, pSprite2->x-sprite[nSprite].x, 2); yvel[pSprite2->index] += mulscale(4, pSprite2->y-sprite[nSprite].y, 2); - // by NoOne: add size shroom abilities + #ifdef NOONE_EXTENSIONS + // add size shroom abilities if ((IsPlayerSprite(pSprite) && isShrinked(pSprite)) || (IsPlayerSprite(pSprite2) && isGrown(pSprite2))) { int mass1 = dudeInfo[pSprite2->type - kDudeBase].mass; @@ -4254,12 +4260,13 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) } } } - + #endif if (!IsPlayerSprite(pSprite) || gPlayer[pSprite->type - kDudePlayer1].godMode == 0) { switch (pSprite2->type) { case kDudeTchernobog: actDamageSprite(pSprite2->index, pSprite, DAMAGE_TYPE_3, pXSprite->health << 2); break; + #ifdef NOONE_EXTENSIONS case kDudeModernCustom: case kDudeModernCustomBurning: int dmg = 0; @@ -4274,6 +4281,7 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) else if (powerupCheck(&gPlayer[pSprite->type - kDudePlayer1], kPwUpJumpBoots) > 0) actDamageSprite(pSprite2->index, pSprite, DAMAGE_TYPE_3, dmg); else actDamageSprite(pSprite2->index, pSprite, DAMAGE_TYPE_0, dmg); break; + #endif } @@ -4304,7 +4312,8 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) spritetype *pSprite2 = &sprite[nHitSprite]; //XSPRITE *pXSprite2 = &Xsprite[pSprite2->extra]; - // by NoOne: add size shroom abilities + #ifdef NOONE_EXTENSIONS + // add size shroom abilities if ((IsPlayerSprite(pSprite2) && isShrinked(pSprite2)) || (IsPlayerSprite(pSprite) && isGrown(pSprite))) { if (xvel[pSprite->xvel] != 0 && IsDudeSprite(pSprite2)) { int mass1 = dudeInfo[pSprite->type - kDudeBase].mass; @@ -4324,25 +4333,7 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) } } } - - /*switch (pSprite->type) { - case kDudeModernCustom: - case kDudeModernCustomBurning: - { - if (IsDudeSprite(pSprite2) && !IsPlayerSprite(pSprite2)) { - int mass1 = getSpriteMassBySize(pSprite); - int mass2 = getSpriteMassBySize(pSprite2); - - if ((mass1 - mass2) >= mass2) { - if ((pXSprite->target == pSprite2->xvel && !dudeIsMelee(pXSprite) && Chance(0x0500)) || pXSprite->target != pSprite2->xvel) - actKickObject(pSprite, pSprite2); - if (pSprite2->extra >= 0 && !isActive(pSprite2->xvel)) - aiActivateDude(pSprite2, &xsprite[pSprite2->extra]); - } - } - break; - } - }*/ + #endif switch (pSprite2->type) { case kThingKickablePail: @@ -4378,7 +4369,8 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) spritetype *pSprite2 = &sprite[nHitSprite]; XSPRITE *pXSprite2 = &xsprite[pSprite2->extra]; - // by NoOne: add size shroom abilities + #ifdef NOONE_EXTENSIONS + // add size shroom abilities if ((IsPlayerSprite(pSprite2) && isShrinked(pSprite2)) || (IsPlayerSprite(pSprite) && isGrown(pSprite))) { int mass1 = dudeInfo[pSprite->type - kDudeBase].mass; @@ -4398,26 +4390,8 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) actDamageSprite(nSprite, pSprite2, (Chance(0x2000)) ? DAMAGE_TYPE_0 : DAMAGE_TYPE_2, dmg); } } + #endif - /*switch (pSprite->type) { - case kDudeModernCustom: - case kDudeModernCustomBurning: - { - if (IsDudeSprite(pSprite2) && !IsPlayerSprite(pSprite2)) { - int mass1 = getSpriteMassBySize(pSprite); - int mass2 = getSpriteMassBySize(pSprite2); - - if ((mass1 - mass2) >= mass2) { - if (Chance((pXSprite->target == pSprite2->xvel) ? 0x0500 : 0x1000)) actKickObject(pSprite, pSprite2); - if (pSprite2->extra >= 0 && !isActive(pSprite2->xvel)) - aiActivateDude(pSprite2, &xsprite[pSprite2->extra]); - } - } - break; - } - }*/ - - switch (pSprite2->type) { case kThingKickablePail: if (pPlayer) { @@ -4478,7 +4452,11 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) case kDudePlayer6: case kDudePlayer7: case kDudePlayer8: + #ifdef NOONE_EXTENSIONS if (pPlayer && !isShrinked(pSprite)) + #else + if (pPlayer) + #endif actDamageSprite(nSprite, pSprite2,DAMAGE_TYPE_2, 8); break; } @@ -4486,7 +4464,8 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) break; } - // by NoOne: add more trigger statements for Touch flag + #ifdef NOONE_EXTENSIONS + // add more trigger statements for Touch flag if (gModernMap && IsDudeSprite(pSprite)) { // Touch sprites @@ -4519,6 +4498,7 @@ void ProcessTouchObjects(spritetype *pSprite, int nXSprite) if (nHWall != -1 || nHSprite != -1) xvel[nSprite] += 5; } + #endif } void actAirDrag(spritetype *pSprite, int a2) @@ -4796,9 +4776,13 @@ void MoveDude(spritetype *pSprite) actImpactMissile(pHitSprite, 3); gHitInfo = hitInfo; } - + #ifdef NOONE_EXTENSIONS if (!gModernMap && pHitXSprite && pHitXSprite->Touch && !pHitXSprite->state && !pHitXSprite->isTriggered) trTriggerSprite(nHitSprite, pHitXSprite, kCmdSpriteTouch); + #else + if (pHitXSprite && pHitXSprite->Touch && !pHitXSprite->state && !pHitXSprite->isTriggered) + trTriggerSprite(nHitSprite, pHitXSprite, kCmdSpriteTouch); + #endif if (pDudeInfo->lockOut && pHitXSprite && pHitXSprite->Push && !pHitXSprite->key && !pHitXSprite->DudeLockout && !pHitXSprite->state && !pHitXSprite->busy && !pPlayer) trTriggerSprite(nHitSprite, pHitXSprite, kCmdSpritePush); @@ -4971,19 +4955,26 @@ void MoveDude(spritetype *pSprite) } } break; - // By NoOne: part of "change of global view palette for stacks" feature case kMarkerUpWater: case kMarkerUpGoo: { - pXSprite->medium = (nLink == kMarkerUpGoo ? kMediumGoo : kMediumWater); + int chance = 0xa00; int medium = kMediumWater; + if (nLink == kMarkerUpGoo){ + medium = kMediumGoo; + chance = 0x400; + } + + pXSprite->medium = medium; if (pPlayer) { + #ifdef NOONE_EXTENSIONS // look for palette in data2 of marker. If value <= 0, use default ones. pPlayer->nWaterPal = 0; int nXUpper = sprite[gUpperLink[nSector]].extra; if (nXUpper >= 0) pPlayer->nWaterPal = xsprite[nXUpper].data2; + #endif pPlayer->posture = 1; pXSprite->burnTime = 0; @@ -5003,8 +4994,7 @@ void MoveDude(spritetype *pSprite) break; case kDudeBurningCultist: { - // There is no difference between water and goo except following chance: - if (Chance(nLink == kMarkerUpGoo ? 0x400 : 0xa00)) + if (Chance(chance)) { pSprite->type = kDudeCultistTommy; pXSprite->burnTime = 0; @@ -5052,11 +5042,14 @@ void MoveDude(spritetype *pSprite) case kDudeBurningInnocent: actKillDude(pSprite->index, pSprite, DAMAGE_TYPE_0, 1000 << 4); break; + #ifdef NOONE_EXTENSIONS case kDudeModernCustom: evPost(nSprite, 3, 0, kCallbackEnemeyBubble); if (!canSwim(pSprite)) actKillDude(pSprite->index, pSprite, DAMAGE_TYPE_0, 1000 << 4); break; + #endif } + } break; } @@ -5464,7 +5457,9 @@ void actExplodeSprite(spritetype *pSprite) case kThingArmedProxBomb: case kThingArmedRemoteBomb: case kThingArmedTNTBundle: + #ifdef NOONE_EXTENSIONS case kModernThingTNTProx: + #endif nType = kExplosionStandard; if (gSpriteHit[nXSprite].florhit == 0) seqSpawn(4,3,nXSprite,-1); @@ -5499,11 +5494,13 @@ void actExplodeSprite(spritetype *pSprite) pSprite = pSprite2; break; } - case kTrapExploder: // By NoOne: allow to customize hidden exploder trap + case kTrapExploder: { // Defaults for exploder nType = 1; int nSnd = 304; int nSeq = 4; + #ifdef NOONE_EXTENSIONS + // By NoOne: allow to customize hidden exploder trap if (gModernMap) { // Temp variables for override via data fields int tSnd = 0; int tSeq = 0; @@ -5526,6 +5523,7 @@ void actExplodeSprite(spritetype *pSprite) if (tSeq > 0) nSeq = tSeq; if (tSnd > 0) nSnd = tSnd; } + #endif if (gSysRes.Lookup(nSeq, "SEQ")) seqSpawn(nSeq, 3, nXSprite, -1); @@ -5601,10 +5599,10 @@ void actProcessSprites(void) { int nSprite; int nNextSprite; - + #ifdef NOONE_EXTENSIONS if (gModernMap) { - // by NoOne: process additional proximity sprites + // process additional proximity sprites if (gProxySpritesCount > 0) { for (int i = 0; i < gProxySpritesCount; i++) { if (sprite[gProxySpritesList[i]].extra < 0) continue; @@ -5641,7 +5639,7 @@ void actProcessSprites(void) } } - // by NoOne: process sight sprites (for players only) + // process sight sprites (for players only) if (gSightSpritesCount > 0) { for (int i = 0; i < gSightSpritesCount; i++) { if (sprite[gSightSpritesList[i]].extra < 0) continue; @@ -5664,7 +5662,7 @@ void actProcessSprites(void) } } - // by NoOne: process Debris sprites for movement + // process Debris sprites for movement if (gPhysSpritesCount > 0) { //viewSetSystemMessage("PHYS COUNT: %d", gPhysSpritesCount); for (int i = 0; i < gPhysSpritesCount; i++) { @@ -5724,6 +5722,7 @@ void actProcessSprites(void) } } } + #endif for (nSprite = headspritestat[kStatThing]; nSprite >= 0; nSprite = nextspritestat[nSprite]) { @@ -5749,9 +5748,11 @@ void actProcessSprites(void) } if (pXSprite->Proximity) { - // by NoOne: don't process locked or 1-shot things for proximity + #ifdef NOONE_EXTENSIONS + // don't process locked or 1-shot things for proximity if (gModernMap && (pXSprite->locked || pXSprite->isTriggered)) continue; + #endif if (pSprite->type == kThingDroppedLifeLeech) pXSprite->target = -1; for (int nSprite2 = headspritestat[kStatDude]; nSprite2 >= 0; nSprite2 = nNextSprite) @@ -5764,13 +5765,18 @@ void actProcessSprites(void) XSPRITE *pXSprite2 = &xsprite[pSprite2->extra]; if ((unsigned int)pXSprite2->health > 0) { - // by NoOne: allow dudeLockout for proximity flag + #ifdef NOONE_EXTENSIONS + // allow dudeLockout for proximity flag if (gModernMap && pSprite->type != kThingDroppedLifeLeech && pXSprite->DudeLockout && !IsPlayerSprite(pSprite2)) continue; + #endif int proxyDist = 96; + #ifdef NOONE_EXTENSIONS if (pSprite->type == kModernThingEnemyLifeLeech) proxyDist = 512; - else if (pSprite->type == kThingDroppedLifeLeech && pXSprite->target == -1) { + else + #endif + if (pSprite->type == kThingDroppedLifeLeech && pXSprite->target == -1) { int nOwner = actOwnerIdToSpriteId(pSprite->owner); spritetype *pOwner = &sprite[nOwner]; PLAYER *pPlayer = &gPlayer[pOwner->type - kDudePlayer1]; @@ -5789,18 +5795,20 @@ void actProcessSprites(void) if (CheckProximity(pSprite2, pSprite->x, pSprite->y, pSprite->z, pSprite->sectnum, proxyDist)) { switch (pSprite->type) { - case kModernThingTNTProx: - if (!IsPlayerSprite(pSprite2)) continue; - pSprite->pal = 0; - break; case kThingDroppedLifeLeech: if (!Chance(0x4000) && nNextSprite >= 0) continue; if (pSprite2->cstat & CLIPMASK0) pXSprite->target = pSprite2->index; else continue; break; + #ifdef NOONE_EXTENSIONS + case kModernThingTNTProx: + if (!IsPlayerSprite(pSprite2)) continue; + pSprite->pal = 0; + break; case kModernThingEnemyLifeLeech: if (pXSprite->target != pSprite2->xvel) continue; break; + #endif } if (pSprite->owner == -1) actPropagateSpriteOwner(pSprite, pSprite2); trTriggerSprite(nSprite, pXSprite, kCmdSpriteProximity); @@ -5885,6 +5893,7 @@ void actProcessSprites(void) case kThingDripBlood: MakeSplash(pSprite, pXSprite); break; + #ifdef NOONE_EXTENSIONS case kModernThingThrowableRock: seqSpawn(24, 3, nXSprite, -1); if ((hit & 0xc000) == 0xc000) @@ -5897,6 +5906,7 @@ void actProcessSprites(void) actDamageSprite(actSpriteOwnerToSpriteId(pSprite), pObject, DAMAGE_TYPE_0, pXSprite->data1); } break; + #endif case kThingBone: seqSpawn(24, 3, nXSprite, -1); if ((hit&0xc000) == 0xc000) @@ -5973,10 +5983,12 @@ void actProcessSprites(void) gAffectedXWalls[0] = -1; int radius = pExplodeInfo->radius; - // By NoOne: Allow to override explosion radius by data4 field of any sprite which have statnum 2 set in editor + #ifdef NOONE_EXTENSIONS + // Allow to override explosion radius by data4 field of any sprite which have statnum 2 set in editor // or of Hidden Exploder. if (gModernMap && pXSprite->data4 > 0) radius = pXSprite->data4; + #endif GetClosestSpriteSectors(nSector, x, y, radius, gAffectedSectors, v24c, gAffectedXWalls); @@ -6046,7 +6058,8 @@ void actProcessSprites(void) } } - // by NoOne: add impulse for sprites from physics list + #ifdef NOONE_EXTENSIONS + // add impulse for sprites from physics list if (gPhysSpritesCount > 0 && pExplodeInfo->dmgType != 0 && pXSprite->data1 != 0) { for (int i = 0; i < gPhysSpritesCount; i++) { if (gPhysSpritesList[i] == -1) continue; @@ -6059,7 +6072,7 @@ void actProcessSprites(void) else debrisConcuss(nOwner, i, x, y, z, pExplodeInfo->dmgType); } } - + #endif for (int p = connecthead; p >= 0; p = connectpoint2[p]) { spritetype *pSprite2 = gPlayer[p].pSprite; @@ -6070,15 +6083,19 @@ void actProcessSprites(void) int t = divscale16(pXSprite->data2, nDist); gPlayer[p].flickerEffect += t; } - - // By NoOne: if data4 > 0, do not remove explosion. This can be useful when designer wants put explosion generator in map manually - // via sprite statnum 2. - + #ifdef NOONE_EXTENSIONS if (!gModernMap || !(pSprite->flags & kModernTypeFlag1)) { + // if data4 > 0, do not remove explosion. This can be useful when designer wants put explosion generator in map manually + // via sprite statnum 2. pXSprite->data1 = ClipLow(pXSprite->data1 - 4, 0); pXSprite->data2 = ClipLow(pXSprite->data2 - 4, 0); pXSprite->data3 = ClipLow(pXSprite->data3 - 4, 0); } + #else + pXSprite->data1 = ClipLow(pXSprite->data1 - 4, 0); + pXSprite->data2 = ClipLow(pXSprite->data2 - 4, 0); + pXSprite->data3 = ClipLow(pXSprite->data3 - 4, 0); + #endif if (pXSprite->data1 == 0 && pXSprite->data2 == 0 && pXSprite->data3 == 0 && seqGetStatus(3, nXSprite) < 0) actPostSprite(nSprite, kStatFree); @@ -6151,7 +6168,8 @@ void actProcessSprites(void) } } - // By NoOne: handle incarnations of custom dude + #ifdef NOONE_EXTENSIONS + // handle incarnations of custom dude if (pSprite->type == kDudeModernCustom && pXSprite->txID > 0 && pXSprite->sysData1 == kGenDudeTransformStatus) { xvel[pSprite->index] = yvel[pSprite->index] = 0; if (seqGetStatus(3, nXSprite) < 0) { @@ -6261,7 +6279,7 @@ void actProcessSprites(void) } } } - + #endif if (pSprite->type == kDudeCerberusTwoHead) { if (pXSprite->health <= 0 && seqGetStatus(3, nXSprite) < 0) @@ -6479,7 +6497,8 @@ spritetype *actSpawnDude(spritetype *pSource, short nType, int a3, int a4) if (gSysRes.Lookup(dudeInfo[nDude].seqStartID, "SEQ")) seqSpawn(dudeInfo[nDude].seqStartID, 3, pSprite2->extra, -1); - // By NoOne: add a way to inherit some values of spawner type 18 by dude. + #ifdef NOONE_EXTENSIONS + // add a way to inherit some values of spawner type 18 by dude. // This way designer can count enemies via switches and do many other interesting things. if (gModernMap && pSource->flags & kModernTypeFlag1) { switch (pSource->type) { // allow inheriting only for selected source types @@ -6504,6 +6523,7 @@ spritetype *actSpawnDude(spritetype *pSource, short nType, int a3, int a4) break; } } + #endif aiInitSprite(pSprite2); return pSprite2; @@ -6572,7 +6592,9 @@ spritetype * actSpawnThing(int nSector, int x, int y, int z, int nThingType) pXThing->isTriggered = 0; break; case kThingDroppedLifeLeech: + #ifdef NOONE_EXTENSIONS case kModernThingEnemyLifeLeech: + #endif pXThing->data1 = 0; pXThing->data2 = 0; pXThing->data3 = 0; @@ -7007,6 +7029,7 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6, { int t = pSprite->type == kThingBloodChunks ? 0 : dudeInfo[pSprite->type-kDudeBase].mass; + #ifdef NOONE_EXTENSIONS if (IsDudeSprite(pSprite)) { switch (pSprite->type) { case kDudeModernCustom: @@ -7015,6 +7038,7 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6, break; } } + #endif if (t > 0 && pVectorData->impulse) { @@ -7070,8 +7094,8 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6, if (Chance(pVectorData->splatChance)) fxSpawnBlood(pSprite, pVectorData->dmg<<4); } - - // by NoOne: add impulse for sprites from physics list + #ifdef NOONE_EXTENSIONS + // add impulse for sprites from physics list if (gPhysSpritesCount > 0 && pVectorData->impulse) { int nIndex = isDebris(pSprite->index); if (nIndex != -1 && (xsprite[pSprite->extra].physAttr & kPhysDebrisVector)) { @@ -7090,7 +7114,7 @@ void actFireVector(spritetype *pShooter, int a2, int a3, int a4, int a5, int a6, //actPostSprite(pSprite->index, kStatThing); // if it was a thing, return it's statnum back } } - + #endif break; } } @@ -7320,7 +7344,8 @@ void ActorLoadSaveConstruct(void) } -// By NoOne: The following functions required for random event features +#ifdef NOONE_EXTENSIONS +// The following functions required for random event features //------------------------- int GetDataVal(spritetype* pSprite, int data) { if (pSprite->extra >= 0) { @@ -7427,9 +7452,9 @@ spritetype* spawnRandomDude(spritetype* pSource) { } //------------------------- -// By NoOne: this function plays sound predefined in missile info +// this function plays sound predefined in missile info bool sfxPlayMissileSound(spritetype* pSprite, int missileId) { - MissileType* pMissType = &missileInfo[missileId - kMissileBase]; + MISSILEINFO_EXTRA* pMissType = &gMissileInfoExtra[missileId - kMissileBase]; if (Chance(0x4000)) sfxPlay3DSound(pSprite, pMissType->fireSound[0], -1, 0); else @@ -7438,9 +7463,9 @@ bool sfxPlayMissileSound(spritetype* pSprite, int missileId) { return true; } -// By NoOne: this function plays sound predefined in vector info +// this function plays sound predefined in vector info bool sfxPlayVectorSound(spritetype* pSprite, int vectorId) { - VECTORDATA* pVectorData = &gVectorData[vectorId]; + VECTORINFO_EXTRA* pVectorData = &gVectorInfoExtra[vectorId]; if (Chance(0x4000)) sfxPlay3DSound(pSprite, pVectorData->fireSound[0], -1, 0); else @@ -7449,7 +7474,7 @@ bool sfxPlayVectorSound(spritetype* pSprite, int vectorId) { return true; } -// By NoOne: this function allows to spawn new custom dude and inherit spawner settings, +// this function allows to spawn new custom dude and inherit spawner settings, // so custom dude can have different weapons, hp and so on... spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist) { @@ -7876,6 +7901,7 @@ bool ceilIsTooLow(spritetype* pSprite) { return false; } + bool isImmune(spritetype* pSprite, int dmgType, int minScale) { if (dmgType >= kDmgFall && dmgType < kDmgMax && pSprite->extra >= 0 && xsprite[pSprite->extra].locked != 1) { @@ -7890,6 +7916,7 @@ bool isImmune(spritetype* pSprite, int dmgType, int minScale) { return true; } +#endif #ifdef POLYMER diff --git a/source/blood/src/actor.h b/source/blood/src/actor.h index 04ce1676c..5d3516eda 100644 --- a/source/blood/src/actor.h +++ b/source/blood/src/actor.h @@ -64,16 +64,12 @@ enum VECTOR_TYPE { VECTOR_TYPE_19, VECTOR_TYPE_20, VECTOR_TYPE_21, - VECTOR_TYPE_22, + #ifdef NOONE_EXTENSIONS + kVectorGenDudePunch, + #endif kVectorMax, }; -enum { -kRandomizeItem = 0, -kRandomizeDude = 1, -kRandomizeTX = 2, -}; - struct THINGINFO { short startHealth; @@ -89,7 +85,6 @@ struct THINGINFO unsigned char xrepeat; // xrepeat unsigned char yrepeat; // yrepeat int dmgControl[kDamageMax]; // damage - bool allowThrow; // By NoOne: indicates if kDudeModernCustom can throw it }; struct AMMOITEMDATA @@ -138,8 +133,6 @@ struct MissileType unsigned char yrepeat; char shade; 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 @@ -147,7 +140,7 @@ struct EXPLOSION unsigned char repeat; char dmg; char dmgRng; - int radius; // radius + int radius; int dmgType; int burnTime; int ticks; @@ -172,22 +165,8 @@ struct VECTORDATA { int bloodSplats; // blood splats int splatChance; // blood splat chance 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 WEAPONITEMDATA gWeaponItemData[]; 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 actPostProcess(void); void MakeSplash(spritetype *pSprite, XSPRITE *pXSprite); +void actBuildMissile(spritetype* pMissile, int nXSprite, int nSprite); + +#ifdef NOONE_EXTENSIONS spritetype* DropRandomPickupObject(spritetype* pSprite, short prevItem); spritetype* spawnRandomDude(spritetype* pSprite); int GetDataVal(spritetype* pSprite, int data); @@ -290,13 +272,46 @@ bool sfxPlayVectorSound(spritetype* pSprite, int vectorId); spritetype* actSpawnCustomDude(spritetype* pSprite, int nDist); int getSpriteMassBySize(spritetype* pSprite); bool ceilIsTooLow(spritetype* pSprite); -void actBuildMissile(spritetype* pMissile, int nXSprite, int nSprite); int isDebris(int nSprite); int debrisGetFreeIndex(void); void debrisMove(int listIndex); void debrisConcuss(int nOwner, int listIndex, int x, int y, int z, int dmg); 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 short gProxySpritesList[kMaxSuperXSprites]; extern short gSightSpritesList[kMaxSuperXSprites]; @@ -304,6 +319,8 @@ extern short gPhysSpritesList[kMaxSuperXSprites]; extern short gProxySpritesCount; extern short gSightSpritesCount; extern short gPhysSpritesCount; +#endif + extern int DudeDifficulty[]; END_BLD_NS diff --git a/source/blood/src/ai.cpp b/source/blood/src/ai.cpp index 80bf13418..128a370c3 100644 --- a/source/blood/src/ai.cpp +++ b/source/blood/src/ai.cpp @@ -48,7 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "aitchern.h" #include "aizomba.h" #include "aizombf.h" -#include "aiunicult.h" // By NoOne: add custom dude +#include "aiunicult.h" #include "blood.h" #include "db.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 }; int dword_138BB0[5] = {0x2000, 0x4000, 0x8000, 0xa000, 0xe000}; - +#ifdef NOONE_EXTENSIONS void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) { switch (pSprite->type) { case kDudeModernCustom: @@ -89,6 +89,7 @@ void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite) { break; } } +#endif bool sub_5BDA8(spritetype *pSprite, int nSeq) { @@ -166,7 +167,8 @@ bool CanMove(spritetype *pSprite, int a2, int nAngle, int nRange) if (pXSector->Depth) Depth = 1; 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 // 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. @@ -180,6 +182,9 @@ bool CanMove(spritetype *pSprite, int a2, int nAngle, int nRange) Crusher = 1; break; } + #else + Crusher = 1; + #endif } } int nUpper = gUpperLink[nSector]; @@ -233,11 +238,13 @@ bool CanMove(spritetype *pSprite, int a2, int nAngle, int nRange) if (floorZ - bottom > 0x2000) return false; break; + #ifdef NOONE_EXTENSIONS case kDudeModernCustom: case kDudeModernCustomBurning: if ((Crusher && !isImmune(pSprite, pXSector->damageType)) || ((Water || Underwater) && !canSwim(pSprite))) return false; return true; fallthrough__; + #endif case kDudeZombieAxeNormal: case kDudePhantasm: case kDudeGillBeast: @@ -407,7 +414,7 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite) } break; } - +#ifdef NOONE_EXTENSIONS case kDudeModernCustom: { 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); else aiGenDudeNewState(pSprite, &genDudeBurnChase); break; +#endif case kDudeCultistTommyProne: { DUDEEXTRA_at6_u1 *pDudeExtraE = &gDudeExtra[pSprite->extra].at6.u1; pDudeExtraE->at8 = 1; pDudeExtraE->at0 = 0; @@ -679,7 +687,9 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite) } case kDudeGargoyleStatueFlesh: 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 (pSprite->type == kDudeGargoyleStatueFlesh) aiNewState(pSprite, pXSprite, &statueFBreakSEQ); else aiNewState(pSprite, pXSprite, &statueSBreakSEQ); @@ -690,6 +700,13 @@ void aiActivateDude(spritetype *pSprite, XSPRITE *pXSprite) if (pSprite->type == kDudeGargoyleStatueFlesh) aiNewState(pSprite, pXSprite, &gargoyleFMorph); 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; case kDudeCerberusTwoHead: if (pXSprite->target == -1) @@ -1006,6 +1023,7 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T evKill(nSprite, 3, kCallbackFXFlameLick); } break; +#ifdef NOONE_EXTENSIONS case kDudeModernCustomBurning: if (Chance(0x2000) && gDudeExtra[pSprite->extra].at0 < (int)gFrameClock) { playGenDudeSound(pSprite, kGenDudeSndBurning); @@ -1077,6 +1095,7 @@ int aiDamageSprite(spritetype *pSprite, XSPRITE *pXSprite, int nSource, DAMAGE_T } break; } +#endif case kDudeCultistBeast: 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)) { DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type-kDudeBase]; switch (pSprite->type) { +#ifdef NOONE_EXTENSIONS case kDudeModernCustom: { GENDUDEEXTRA* pExtra = genDudeExtra(pSprite); int rChance = getRecoilChance(pSprite); if (pExtra->canElectrocute && pDudeExtra->at4 && !spriteIsUnderwater(pSprite, false)) { @@ -1156,6 +1176,7 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite) pDudeExtra->at4 = 0; break; } +#endif case kDudeCultistTommy: case kDudeCultistShotgun: case kDudeCultistTesla: @@ -1186,9 +1207,11 @@ void RecoilDude(spritetype *pSprite, XSPRITE *pXSprite) case kDudeBurningCultist: aiNewState(pSprite, pXSprite, &cultistBurnGoto); break; +#ifdef NOONE_EXTENSIONS case kDudeModernCustomBurning: aiGenDudeNewState(pSprite, &genDudeBurnGoto); break; +#endif case kDudeZombieButcher: aiPlay3DSound(pSprite, 1202, AI_SFX_PRIORITY_2, -1); if (pDudeExtra->at4) @@ -1454,31 +1477,33 @@ void aiProcessDudes(void) { int nXSprite = pSprite->extra; 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 (pSprite->type >= kDudeVanillaMax && pSprite->type < kDudeMax) - genDudeProcess(pSprite, pXSprite); + switch (pSprite->type){ + #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->moveFunc) - pXSprite->aiState->moveFunc(pSprite, pXSprite); + if (pXSprite->aiState->thinkFunc && (gFrame & 3) == (nSprite & 3)) + pXSprite->aiState->thinkFunc(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->nextState); - } - - if (pXSprite->health > 0 && ((pDudeInfo->hinderDamage << 4) <= cumulDamage[nXSprite])) { - pXSprite->data3 = cumulDamage[nXSprite]; - RecoilDude(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->nextState); + } + if (pXSprite->health > 0 && ((pDudeInfo->hinderDamage << 4) <= cumulDamage[nXSprite])) { + pXSprite->data3 = cumulDamage[nXSprite]; + RecoilDude(pSprite, pXSprite); + } + break; } } memset(cumulDamage, 0, sizeof(cumulDamage)); @@ -1505,6 +1530,7 @@ void aiInitSprite(spritetype *pSprite) pDudeExtra->at4 = 0; pDudeExtra->at0 = 0; switch (pSprite->type) { +#ifdef NOONE_EXTENSIONS case kDudeModernCustom: { DUDEEXTRA_at6_u1* pDudeExtraE = &gDudeExtra[nXSprite].at6.u1; pDudeExtraE->at8 = pDudeExtraE->at0 = 0; @@ -1516,6 +1542,7 @@ void aiInitSprite(spritetype *pSprite) aiGenDudeNewState(pSprite, &genDudeBurnGoto); pXSprite->burnTime = 1200; break; +#endif case kDudeCultistTommy: case kDudeCultistShotgun: case kDudeCultistTesla: @@ -1707,10 +1734,11 @@ void aiInitSprite(spritetype *pSprite) case kDudeZombieAxeLaying: pSprite->flags = 7; break; - case kDudePodMother: // by NoOne: FakeDude type + #ifdef NOONE_EXTENSIONS + case kDudePodMother: // FakeDude type if (gModernMap) break; 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 kDudeTentacleGreen: case kDudePodFire: @@ -1723,6 +1751,7 @@ void aiInitSprite(spritetype *pSprite) } fallthrough__; // go default + #endif default: pSprite->flags = 15; break; diff --git a/source/blood/src/ai.h b/source/blood/src/ai.h index e2bff58cb..2d8d050eb 100644 --- a/source/blood/src/ai.h +++ b/source/blood/src/ai.h @@ -106,8 +106,9 @@ 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 +#ifdef NOONE_EXTENSIONS +// this function required for kModernDudeTargetChanger void aiSetGenIdleState(spritetype* pSprite, XSPRITE* pXSprite); +#endif END_BLD_NS diff --git a/source/blood/src/aiburn.cpp b/source/blood/src/aiburn.cpp index 3606ae29e..81c0fa664 100644 --- a/source/blood/src/aiburn.cpp +++ b/source/blood/src/aiburn.cpp @@ -128,9 +128,11 @@ static void thinkGoto(spritetype *pSprite, XSPRITE *pXSprite) case kDudeBurningTinyCaleb: aiNewState(pSprite, pXSprite, &tinycalebBurnSearch); break; + #ifdef NOONE_EXTENSIONS case kDudeModernCustomBurning: aiNewState(pSprite, pXSprite, &genDudeBurnSearch); break; + #endif } } aiThinkTarget(pSprite, pXSprite); @@ -160,9 +162,11 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite) case kDudeBurningTinyCaleb: aiNewState(pSprite, pXSprite, &tinycalebBurnGoto); break; + #ifdef NOONE_EXTENSIONS case kDudeModernCustomBurning: aiNewState(pSprite, pXSprite, &genDudeBurnGoto); break; + #endif } return; } @@ -196,9 +200,11 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite) case kDudeBurningTinyCaleb: aiNewState(pSprite, pXSprite, &tinycalebBurnSearch); break; + #ifdef NOONE_EXTENSIONS case kDudeModernCustomBurning: aiNewState(pSprite, pXSprite, &genDudeBurnSearch); break; + #endif } return; } @@ -234,9 +240,11 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite) case kDudeBurningTinyCaleb: aiNewState(pSprite, pXSprite, &tinycalebBurnAttack); break; + #ifdef NOONE_EXTENSIONS case kDudeModernCustomBurning: aiNewState(pSprite, pXSprite, &genDudeBurnSearch); break; + #endif } } return; @@ -264,9 +272,11 @@ static void thinkChase(spritetype *pSprite, XSPRITE *pXSprite) case kDudeBurningTinyCaleb: aiNewState(pSprite, pXSprite, &tinycalebBurnGoto); break; + #ifdef NOONE_EXTENSIONS case kDudeModernCustomBurning: aiNewState(pSprite, pXSprite, &genDudeBurnSearch); break; + #endif } pXSprite->target = -1; } diff --git a/source/blood/src/aiunicult.cpp b/source/blood/src/aiunicult.cpp index 44102939b..757f4b684 100644 --- a/source/blood/src/aiunicult.cpp +++ b/source/blood/src/aiunicult.cpp @@ -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 "common_game.h" +#ifdef NOONE_EXTENSIONS #include "compat.h" #include "build.h" #include "pragmas.h" #include "mmulti.h" -#include "common_game.h" + #include "actor.h" #include "ai.h" #include "aiunicult.h" @@ -222,7 +224,7 @@ static void punchCallback(int, int nXIndex) { if (!playGenDudeSound(pSprite, kGenDudeSndAttackMelee)) 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; const THINGINFO* pThinkInfo = &thingInfo[curWeapon - kThingBase]; - if (!pThinkInfo->allowThrow) return; + if (!gThingInfoExtra[curWeapon - kThingBase].allowThrow) return; else if (!playGenDudeSound(pSprite, kGenDudeSndAttackThrow)) sfxPlay3DSound(pSprite, 455, -1, 0); @@ -521,7 +523,7 @@ static void thinkChase( spritetype* pSprite, XSPRITE* pXSprite ) { spritetype* pLeech = leechIsDropped(pSprite); VECTORDATA* meleeVector = &gVectorData[22]; if (weaponType == kGenDudeWeaponThrow) { if (klabs(losAngle) < kAng15) { - if (!thingInfo[curWeapon - kThingBase].allowThrow) { + if (!gThingInfoExtra[curWeapon - kThingBase].allowThrow) { if (spriteIsUnderwater(pSprite)) aiGenDudeNewState(pSprite, &genDudeChaseW); else aiGenDudeNewState(pSprite, &genDudeChaseL); 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) { // check also for damage resistance (all possible damages missile can use) 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; } } @@ -1993,4 +1995,4 @@ bool genDudePrepare(spritetype* pSprite, int propId) { return true; } -END_BLD_NS +#endifEND_BLD_NS diff --git a/source/blood/src/aiunicult.h b/source/blood/src/aiunicult.h index 44d8fb04c..784c0e92b 100644 --- a/source/blood/src/aiunicult.h +++ b/source/blood/src/aiunicult.h @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- #pragma once +#ifdef NOONE_EXTENSIONS #include "ai.h" #include "eventq.h" @@ -220,4 +221,4 @@ bool genDudePrepare(spritetype* pSprite, int propId = kGenDudePropertyAll); void genDudeUpdate(spritetype* pSprite); void genDudeProcess(spritetype* pSprite, XSPRITE* pXSprite); bool genDudeAdjustSlope(spritetype* pSprite, XSPRITE* pXSprite, int dist, int weaponType, int by = 64); -END_BLD_NS +#endifEND_BLD_NS diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 77743c47c..6dc2050be 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -593,6 +593,7 @@ void StartLevel(GAMEOPTIONS *gameOptions) } + #ifdef NOONE_EXTENSIONS if (gModernMap) { switch (pSprite->type) { @@ -664,6 +665,7 @@ void StartLevel(GAMEOPTIONS *gameOptions) } } } + #endif } } scrLoadPLUs(); @@ -675,7 +677,8 @@ void StartLevel(GAMEOPTIONS *gameOptions) gStartZone[i].sectnum = startsectnum; 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) { gStartZoneTeam1[i].x = startpos.x; gStartZoneTeam1[i].y = startpos.y; @@ -689,6 +692,7 @@ void StartLevel(GAMEOPTIONS *gameOptions) gStartZoneTeam2[i].sectnum = startsectnum; gStartZoneTeam2[i].ang = startang; } + #endif } InitSectorFX(); warpInit(); diff --git a/source/blood/src/callback.cpp b/source/blood/src/callback.cpp index 6ed39027d..b24d1921c 100644 --- a/source/blood/src/callback.cpp +++ b/source/blood/src/callback.cpp @@ -343,9 +343,11 @@ void EnemyBubble(int nSprite) // 11 void CounterCheck(int nSector) // 12 { dassert(nSector >= 0 && nSector < kMaxSectors); - - // By NoOne: remove check below, so every sector can be counter if command 12 (this callback) received. - //if (pSector->type != kSectorCounter) return; + + // remove check below, so every sector can be counter if command 12 (this callback) received. + #ifndef NOONE_EXTENSIONS + if (sector[nSector].type != kSectorCounter) return; + #endif if (sector[nSector].extra <= 0) return; XSECTOR *pXSector = &xsector[sector[nSector].extra]; @@ -566,7 +568,9 @@ void LeechStateTimer(int nSprite) // 20 if (pSprite->statnum == kStatThing && !(pSprite->flags & 32)) { switch (pSprite->type) { case kThingDroppedLifeLeech: + #ifdef NOONE_EXTENSIONS case kModernThingEnemyLifeLeech: + #endif xsprite[pSprite->extra].stateTimer = 0; break; } @@ -708,6 +712,7 @@ void DropVoodoo(int nSprite) // unused } } +#ifdef NOONE_EXTENSIONS void UniMissileBurst(int nSprite) // 22 { dassert(nSprite >= 0 && nSprite < kMaxSprites); @@ -766,12 +771,13 @@ void makeMissileBlocking(int nSprite) // 23 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) = { fxFlameLick, @@ -796,9 +802,11 @@ void(*gCallback[kCallbackMax])(int) = fxPodBloodSplat, LeechStateTimer, DropVoodoo, // unused +#ifdef NOONE_EXTENSIONS UniMissileBurst, makeMissileBlocking, genDudeUpdateCallback, +#endif }; END_BLD_NS diff --git a/source/blood/src/callback.h b/source/blood/src/callback.h index ef98a19cb..9990e11ce 100644 --- a/source/blood/src/callback.h +++ b/source/blood/src/callback.h @@ -49,9 +49,11 @@ enum CALLBACK_ID { kCallbackFXPodBloodSplat = 19, kCallbackLeechStateTimer = 20, kCallbackDropVoodoo = 21, // unused + #ifdef NOONE_EXTENSIONS kCallbackMissileBurst = 22, // by NoOne kCallbackMissileSpriteBlock = 23, // by NoOne kCallbackGenDudeUpdate = 24, // by NoOne + #endif kCallbackMax, }; diff --git a/source/blood/src/common_game.h b/source/blood/src/common_game.h index f270ce30e..feaa452c4 100644 --- a/source/blood/src/common_game.h +++ b/source/blood/src/common_game.h @@ -85,9 +85,12 @@ void _consoleSysMsg(const char* pMessage, ...); // defined by NoOne: // ------------------------------- -#define kMaxPAL 5 -#define kFreeQAVEntry 108 +///////////////////////////////////////////////////////////// +#define NOONE_EXTENSIONS 1 +//////////////////////////////////////////////////////////// + +#define kMaxPAL 5 #define kUserPLUStart 15 #define kDmgFall 0 @@ -126,11 +129,9 @@ kStatSpares = 13, kStatFlare = 14, kStatDebris = 15, kStatPathMarker = 16, -kStatModernDudeTargetChanger = 20, // gModernMap only kStatFree = 1024, }; - // POWERUPS ///////////////////////////////////////////////////// enum { kPwUpFeatherFall = 12, @@ -196,30 +197,12 @@ enum { kSwitchPadlock = 23, 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 kDecorationTorch = 30, kDecorationCandle = 32, // (weapons) kItemWeaponBase = 40, - kModernRandom = 40, // gModernMap only kItemWeaponSawedoff = 41, kItemWeaponTommygun = 42, kItemWeaponVoodooDoll = 44, @@ -231,7 +214,6 @@ enum { kItemAmmoSawedoffFew = 67, kItemAmmoTommygunFew = 69, kAmmoItemVoodooDoll = 70, - kModernRandom2 = 80, // gModernMap Only kItemAmmoMax = 81, kItemBase = 100, @@ -266,8 +248,6 @@ enum { kItemReflectShots = 124, kItemBeastVision = 125, kItemShroomDelirium = 128, - kItemShroomGrow = 129, // gModernMap only - kItemShroomShrink = 130, // gModernMap only kItemArmorAsbest = 139, kItemArmorBasic = 140, @@ -280,7 +260,6 @@ enum { kItemFlagBBase = 146, kItemFlagA = 147, kItemFlagB = 148, - kItemModernMapLevel = 150, // once picked up, draws whole minimap kItemMax = 151, // dudes @@ -339,8 +318,6 @@ enum { kDudeBurningTinyCaleb = 252, kDudeBurningBeast = 253, kDudeVanillaMax = 254, - kDudeModernCustom = kDudeVanillaMax, // gModern map only - kDudeModernCustomBurning = 255, // gModern map only kDudeMax = 256, kMissileBase = 300, @@ -394,9 +371,6 @@ enum { kThingPodGreenBall = 430, kThingDroppedLifeLeech = 431, 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, // traps @@ -410,8 +384,7 @@ enum { kGenDripWater = 701, kGenDripBlood = 702, kGenMissileFireball = 703, - kGenMissileEctoSkull = 704, // does not work in vanilla - kGenModernMissileUniversal = 704, // gModernMap only + kGenMissileEctoSkull = 704, kGenDart = 705, kGenBubble = 706, kGenBubbleMulti = 707, @@ -422,6 +395,54 @@ enum { 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 ///////////////////////////////////////////////// enum { @@ -471,18 +492,6 @@ kAiStateAttack = 6, #define kPhysMove 0x0001 // affected by movement physics #define kPhysGravity 0x0002 // affected by gravity #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 #define kSecCParallax 0x01 @@ -495,7 +504,6 @@ kAiStateAttack = 6, #define kSecCRelAlign 0x40 #define kSecCFloorShade 0x8000 - #define kAng5 28 #define kAng15 85 #define kAng30 170 diff --git a/source/blood/src/db.cpp b/source/blood/src/db.cpp index 5e593c9b2..b4e7d64c9 100644 --- a/source/blood/src/db.cpp +++ b/source/blood/src/db.cpp @@ -54,7 +54,9 @@ PolymerLight_t gPolymerLight[kMaxSprites]; char qsprite_filler[kMaxSprites], qsector_filler[kMaxSectors]; int gVisibility; +#ifdef NOONE_EXTENSIONS bool gModernMap = false; +#endif 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(show2dwall, 0, sizeof(show2dwall)); memset(show2dsprite, 0, sizeof(show2dsprite)); - + #ifdef NOONE_EXTENSIONS gModernMap = false; + #endif #ifdef USE_OPENGL 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) { 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, // 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; + #endif } else { 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; } - // 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 if (!gModernMap && pXSprite->rxID == kChannelMapModernize && pXSprite->rxID == pXSprite->txID && pXSprite->command == kCmdModernFeaturesEnable) gModernMap = true; + #endif } if ((sprite[i].cstat & 0x30) == 0x30) { diff --git a/source/blood/src/db.h b/source/blood/src/db.h index 5870c76c2..ad6c39780 100644 --- a/source/blood/src/db.h +++ b/source/blood/src/db.h @@ -28,8 +28,12 @@ BEGIN_BLD_NS #define kMaxXWalls 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 +extern bool gModernMap; +#endif // by NoOne: functions to quckly check range of specifical arrays inline bool xspriRangeIsFine(int nXindex) { @@ -43,9 +47,6 @@ inline bool xsectRangeIsFine(int nXindex) { inline bool xwallRangeIsFine(int nXindex) { return (nXindex >= 0 && nXindex < kMaxXWalls); } - -extern bool gModernMap; - #pragma pack(push, 1) struct AISTATE; @@ -115,9 +116,12 @@ struct XSPRITE { unsigned int height : 16; unsigned int stateTimer : 16; // ai timer 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 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 + }; struct XSECTOR { @@ -189,7 +193,11 @@ struct XSECTOR { unsigned int floorpal : 4; // Floor pal2 unsigned int floorYPanFrac : 8; // Floor y panning frac 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 windAlways : 1; // Wind always unsigned int dudeLockout : 1; diff --git a/source/blood/src/eventq.cpp b/source/blood/src/eventq.cpp index d9c8c50bf..8054ea1fc 100644 --- a/source/blood/src/eventq.cpp +++ b/source/blood/src/eventq.cpp @@ -380,11 +380,13 @@ void evSend(int nIndex, int nType, int rxId, COMMAND_ID command) case kChannelLevelExitSecret: levelEndLevel(1); 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: if (command >= kCmdNumberic) levelEndLevelCustom(command - kCmdNumberic); else viewSetSystemMessage("Invalid Level-Exit# command by xobject #%d (object type %d)", nIndex, nType); return; + #endif case kChannelSetTotalSecrets: if (command >= kCmdNumberic) levelSetupSecret(command - kCmdNumberic); 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; } - + #ifdef NOONE_EXTENSIONS if (gModernMap) { // 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++) { if (event.type != rxBucket[i].type || event.index != rxBucket[i].index) { switch (rxBucket[i].type) { diff --git a/source/blood/src/gameutil.cpp b/source/blood/src/gameutil.cpp index 8054faf5e..65e30775a 100644 --- a/source/blood/src/gameutil.cpp +++ b/source/blood/src/gameutil.cpp @@ -917,12 +917,14 @@ int picHeight(short nPic, short repeat) { 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) { std::default_random_engine stdRandom; stdRandom.seed(std::random_device()()); std::uniform_int_distribution dist_a_b(a, b); return dist_a_b(stdRandom); } +#endif END_BLD_NS diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index 763ec5a79..be5165518 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -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. void levelEndLevelCustom(int nLevel) { @@ -374,6 +375,7 @@ void levelEndLevelCustom(int nLevel) { gNextLevel = nLevel; } +#endif void levelRestart(void) { diff --git a/source/blood/src/levels.h b/source/blood/src/levels.h index de8c09a5f..462aad2bb 100644 --- a/source/blood/src/levels.h +++ b/source/blood/src/levels.h @@ -118,8 +118,10 @@ void levelGetNextLevels(int nEpisode, int nLevel, int *pnEndingA, int *pnEndingB // arg: 0 is normal exit, 1 is secret level 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); +#endif void levelRestart(void); int levelGetMusicIdx(const char *str); diff --git a/source/blood/src/loadsave.cpp b/source/blood/src/loadsave.cpp index 269f326c2..b24ee06ad 100644 --- a/source/blood/src/loadsave.cpp +++ b/source/blood/src/loadsave.cpp @@ -314,7 +314,9 @@ void MyLoadSave::Load(void) Read(&gMapRev, sizeof(gMapRev)); Read(&gSongId, sizeof(gSkyCount)); Read(&gFogMode, sizeof(gFogMode)); +#ifdef NOONE_EXTENSIONS Read(&gModernMap, sizeof(gModernMap)); +#endif gCheatMgr.sub_5BCF4(); } @@ -395,7 +397,9 @@ void MyLoadSave::Save(void) Write(&gMapRev, sizeof(gMapRev)); Write(&gSongId, sizeof(gSkyCount)); Write(&gFogMode, sizeof(gFogMode)); +#ifdef NOONE_EXTENSIONS Write(&gModernMap, sizeof(gModernMap)); +#endif } void LoadSavedInfo(void) diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index 50b2c9a87..202d853cd 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -124,33 +124,6 @@ int Handicap[] = { 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] = { // normal human @@ -281,6 +254,7 @@ DAMAGEINFO damageInfo[7] = { { 0, 0, 0, 0, 0, 0, 0 } }; +#ifdef NOONE_EXTENSIONS TRPLAYERCTRL gPlayerCtrl[kMaxPlayers]; QAV* qavSceneLoad(int qavId) { @@ -292,8 +266,6 @@ 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; @@ -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) { if (powerupCheck(&gPlayer[pSprite->type - kDudePlayer1], kPwUpGrowShroom) > 0) 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; return true; } +#endif void deactivateSizeShrooms(PLAYER* pPlayer) { powerupDeactivate(pPlayer, kPwUpGrowShroom); @@ -418,6 +381,16 @@ PLAYER* getPlayerById(short id) { 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) { @@ -430,6 +403,7 @@ char powerupActivate(PLAYER *pPlayer, int nPowerUp) pPlayer->packSlots[nPack].isActive = 1; switch (nPowerUp + kItemBase) { + #ifdef NOONE_EXTENSIONS case kItemModernMapLevel: if (gModernMap) gFullMap = true; break; @@ -452,6 +426,7 @@ char powerupActivate(PLAYER *pPlayer, int nPowerUp) actDamageSprite(pPlayer->pSprite->xvel, pPlayer->pSprite, DAMAGE_TYPE_3, 65535); } break; + #endif case kItemFeatherFall: case kItemJumpBoots: pPlayer->damageControl[0]++; @@ -491,6 +466,7 @@ void powerupDeactivate(PLAYER *pPlayer, int nPowerUp) pPlayer->packSlots[nPack].isActive = 0; switch (nPowerUp + kItemBase) { + #ifdef NOONE_EXTENSIONS case kItemShroomShrink: if (gModernMap) { resetPlayerSize(pPlayer); @@ -501,6 +477,7 @@ void powerupDeactivate(PLAYER *pPlayer, int nPowerUp) case kItemShroomGrow: if (gModernMap) resetPlayerSize(pPlayer); break; + #endif case kItemFeatherFall: case kItemJumpBoots: pPlayer->damageControl[0]--; @@ -800,7 +777,8 @@ void playerStart(int nPlayer) if (gGameOptions.nGameType <= 1) 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. else if (gModernMap && gGameOptions.nGameType == 3 && gTeamsSpawnUsed == true) { int maxRetries = 5; @@ -822,7 +800,10 @@ void playerStart(int nPlayer) if (pStartZone != NULL) break; } - } else { + + } + #endif + else { pStartZone = &gStartZone[Random(8)]; } @@ -914,7 +895,9 @@ void playerStart(int nPlayer) pPlayer->weaponTimer = 0; pPlayer->weaponState = 0; pPlayer->weaponQav = -1; + #ifdef NOONE_EXTENSIONS playerResetQavScene(pPlayer); // reset qav scene + #endif pPlayer->hand = 0; pPlayer->nWaterPal = 0; playerResetPowerUps(pPlayer); @@ -975,25 +958,29 @@ void playerReset(PLAYER *pPlayer) pPlayer->packSlots[i].isActive = 0; pPlayer->packSlots[i].curAmount = 0; } - +#ifdef NOONE_EXTENSIONS ///////////////// // reset qav scene playerResetQavScene(pPlayer); - +#endif // reset posture (mainly required for resetting movement speed and jump height) playerResetPosture(pPlayer); ///////////////// + } + void playerResetPosture(PLAYER* pPlayer) { memcpy(pPlayer->pPosture, gPostureDefaults, sizeof(gPostureDefaults)); } -void playerResetQavScene(PLAYER* pPlayer) { - QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; - pQavScene->index = pQavScene->dummy = pPlayer->sceneQav = -1; - pQavScene->qavResrc = NULL; -} +#ifdef NOONE_EXTENSIONS + void playerResetQavScene(PLAYER* pPlayer) { + QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; + pQavScene->index = pQavScene->dummy = pPlayer->sceneQav = -1; + pQavScene->qavResrc = NULL; + } +#endif int dword_21EFB0[8]; ClockTicks dword_21EFD0[8]; @@ -1036,10 +1023,16 @@ char PickupItem(PLAYER *pPlayer, spritetype *pItem) { switch (pItem->type) { case kItemShadowCloak: + #ifdef NOONE_EXTENSIONS if (isGrown(pPlayer->pSprite) || !powerupActivate(pPlayer, nType)) return false; + #else + if (!powerupActivate(pPlayer, nType)) return false; + #endif break; + #ifdef NOONE_EXTENSIONS case kItemShroomShrink: case kItemShroomGrow: + if (gModernMap) { switch (pItem->type) { case kItemShroomShrink: @@ -1052,7 +1045,9 @@ char PickupItem(PLAYER *pPlayer, spritetype *pItem) { powerupActivate(pPlayer, nType); } + break; + #endif case kItemFlagABase: case kItemFlagBBase: { if (gGameOptions.nGameType != 3 || pItem->extra <= 0) return 0; @@ -1203,9 +1198,11 @@ char PickupItem(PLAYER *pPlayer, spritetype *pItem) { case kItemHealthLifeSeed: case kItemHealthRedPotion: { 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) addPower = xsprite[sprite[pItem->xvel].extra].data1; + #endif if (!actHealDude(pXSprite, addPower, gPowerUpInfo[nType].maxTime)) return 0; return 1; @@ -1230,11 +1227,12 @@ char PickupAmmo(PLAYER* pPlayer, spritetype* pAmmo) { int nAmmoType = pAmmoItemData->type; if (pPlayer->ammoCount[nAmmoType] >= gAmmoInfo[nAmmoType].max) return 0; - else if (!gModernMap || pAmmo->extra < 0 || xsprite[pAmmo->extra].data1 <= 0) - pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType]+pAmmoItemData->count, gAmmoInfo[nAmmoType].max); - // by NoOne: allow custom amount for item - else + #ifdef NOONE_EXTENSIONS + else if (gModernMap && pAmmo->extra >= 0 && xsprite[pAmmo->extra].data1 > 0) // allow custom amount for item 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; sfxPlay3DSound(pPlayer->pSprite, 782, -1, 0); @@ -1250,11 +1248,13 @@ char PickupWeapon(PLAYER *pPlayer, spritetype *pWeapon) { return 0; pPlayer->hasWeapon[nWeaponType] = 1; if (nAmmoType == -1) return 0; - // By NoOne: allow to set custom ammo count for weapon pickups - if (!gModernMap || pWeapon->extra < 0 || xsprite[pWeapon->extra].data1 <= 0) - pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + pWeaponItemData->count, gAmmoInfo[nAmmoType].max); - else + // allow to set custom ammo count for weapon pickups + #ifdef NOONE_EXTENSIONS + 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 + pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType] + pWeaponItemData->count, gAmmoInfo[nAmmoType].max); int nNewWeapon = WeaponUpgrade(pPlayer, nWeaponType); 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; - else if (!gModernMap || pWeapon->extra < 0 || xsprite[pWeapon->extra].data1 <= 0) - pPlayer->ammoCount[nAmmoType] = ClipHigh(pPlayer->ammoCount[nAmmoType]+pWeaponItemData->count, gAmmoInfo[nAmmoType].max); + #ifdef NOONE_EXTENSIONS + 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 - 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); return 1; @@ -1281,12 +1283,13 @@ void PickUp(PLAYER *pPlayer, spritetype *pSprite) int nType = pSprite->type; char pickedUp = 0; int customMsg = -1; - - if (gModernMap) { // by NoOne: allow custom INI message instead "Picked up" - XSPRITE* pXSprite = (pSprite->extra >= 0) ? &xsprite[pSprite->extra] : NULL; - if (pXSprite != NULL && pXSprite->txID != 3 && pXSprite->lockMsg > 0) - customMsg = pXSprite->lockMsg; - } + #ifdef NOONE_EXTENSIONS + if (gModernMap) { // allow custom INI message instead "Picked up" + XSPRITE* pXSprite = (pSprite->extra >= 0) ? &xsprite[pSprite->extra] : NULL; + if (pXSprite != NULL && pXSprite->txID != 3 && pXSprite->lockMsg > 0) + customMsg = pXSprite->lockMsg; + } + #endif if (nType >= kItemBase && nType <= kItemMax) { pickedUp = PickupItem(pPlayer, pSprite); @@ -1578,7 +1581,9 @@ void ProcessInput(PLAYER *pPlayer) break; default: if (!pPlayer->cantJump && pInput->buttonFlags.jump && pXSprite->height == 0) { + #ifdef NOONE_EXTENSIONS if ((packItemActive(pPlayer, 4) && pPosture->pwupJumpZ != 0) || pPosture->normalJumpZ != 0) + #endif sfxPlay3DSound(pSprite, 700, 0, 0); if (packItemActive(pPlayer, 4)) zvel[nSprite] = pPosture->pwupJumpZ; //-0x175555; @@ -2332,17 +2337,18 @@ void PlayerLoadSave::Load(void) Read(&gNetPlayers, sizeof(gNetPlayers)); Read(&gProfile, sizeof(gProfile)); Read(&gPlayer, sizeof(gPlayer)); - - Read((void*)&buffer, sizeof(kPlayerCtrlSigStart)); - Read(&gPlayerCtrl, sizeof(gPlayerCtrl)); - Read((void*)&buffer, sizeof(kPlayerCtrlSigEnd)); - + #ifdef NOONE_EXTENSIONS + Read((void*)&buffer, sizeof(kPlayerCtrlSigStart)); + Read(&gPlayerCtrl, sizeof(gPlayerCtrl)); + Read((void*)&buffer, sizeof(kPlayerCtrlSigEnd)); + #endif for (int i = 0; i < gNetPlayers; i++) { gPlayer[i].pSprite = &sprite[gPlayer[i].nSprite]; gPlayer[i].pXSprite = &xsprite[gPlayer[i].pSprite->extra]; 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 (gPlayerCtrl[i].qavScene.qavResrc == NULL) gPlayer[i].sceneQav = -1; @@ -2356,13 +2362,8 @@ void PlayerLoadSave::Load(void) } } } - - // 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]; - } - }*/ + #endif + } } @@ -2373,19 +2374,11 @@ void PlayerLoadSave::Save(void) Write(&gProfile, sizeof(gProfile)); Write(&gPlayer, sizeof(gPlayer)); - - ////// 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]; - } - } - }*/ + #ifdef NOONE_EXTENSIONS Write((void*)kPlayerCtrlSigStart, sizeof(kPlayerCtrlSigStart)); Write(&gPlayerCtrl, sizeof(gPlayerCtrl)); Write((void*)kPlayerCtrlSigEnd, sizeof(kPlayerCtrlSigEnd)); - ////// + #endif } static PlayerLoadSave *myLoadSave; diff --git a/source/blood/src/player.h b/source/blood/src/player.h index a964294ee..b02f20994 100644 --- a/source/blood/src/player.h +++ b/source/blood/src/player.h @@ -61,11 +61,6 @@ struct PACKINFO 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 { int frontAccel; @@ -224,19 +219,34 @@ struct POWERUPINFO int maxTime; }; -// by NoOne: this one stores qavs anims that can be played by trigger -struct QAVSCENE { +#ifdef NOONE_EXTENSIONS + // 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 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 { 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 *gMe, *gView; @@ -324,17 +334,5 @@ void sub_41250(PLAYER *pPlayer); void playerLandingSound(PLAYER *pPlayer); void PlayerSurvive(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 diff --git a/source/blood/src/seq.cpp b/source/blood/src/seq.cpp index 83b6b11a1..fb4cdb7b6 100644 --- a/source/blood/src/seq.cpp +++ b/source/blood/src/seq.cpp @@ -302,10 +302,11 @@ void SEQINST::Update(ACTIVE *pActive) sfxPlay3DSound(&sprite[xsprite[pActive->xindex].reference], sound, -1, 0); } + + // by NoOne: add surfaceSound trigger feature spritetype* pSprite = &sprite[xsprite[pActive->xindex].reference]; 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 int surf = tileGetSurfType(pSprite->sectnum + 0x4000); if (!surf) break; 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]); } } - - break; } case 4: diff --git a/source/blood/src/triggers.cpp b/source/blood/src/triggers.cpp index 514702938..7da5f81e3 100644 --- a/source/blood/src/triggers.cpp +++ b/source/blood/src/triggers.cpp @@ -35,7 +35,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "db.h" #include "endgame.h" #include "eventq.h" - #include "aiunicult.h" #include "fx.h" #include "gameutil.h" @@ -60,12 +59,16 @@ BEGIN_BLD_NS int basePath[kMaxSectors]; void FireballTrapSeqCallback(int, int); +#ifdef NOONE_EXTENSIONS void UniMissileTrapSeqCallback(int, int); +#endif void MGunFireSeqCallback(int, int); void MGunOpenSeqCallback(int, int); int nFireballTrapClient = seqRegisterClient(FireballTrapSeqCallback); +#ifdef NOONE_EXTENSIONS int nUniMissileTrapClient = seqRegisterClient(UniMissileTrapSeqCallback); +#endif int nMGunFireClient = seqRegisterClient(MGunFireSeqCallback); int nMGunOpenClient = seqRegisterClient(MGunOpenSeqCallback); @@ -112,43 +115,7 @@ char SetSpriteState(int nSprite, XSPRITE* pXSprite, int nState) return 1; } -char modernTypeSetSpriteState(int nSprite, XSPRITE *pXSprite, int nState) -{ - if ((pXSprite->busy&0xffff) == 0 && pXSprite->state == nState) return 0; - pXSprite->busy = nState<<16; - pXSprite->state = nState; - evKill(nSprite, 3); - if ((sprite[nSprite].flags & kHitagRespawn) != 0 && sprite[nSprite].inittype >= kDudeBase && sprite[nSprite].inittype < kDudeMax) { - pXSprite->respawnPending = 3; - evPost(nSprite, 3, gGameOptions.nMonsterRespawnTime, kCallbackRespawn); - return 1; - } - - if (pXSprite->restState != nState && pXSprite->waitTime > 0) - evPost(nSprite, 3, (pXSprite->waitTime*120) / 10, pXSprite->restState ? kCmdOn : kCmdOff); - if (pXSprite->txID != 0 && ((pXSprite->triggerOn && pXSprite->state) || (pXSprite->triggerOff && !pXSprite->state))) { - - // by NoOne: Sending new command instead of link is *required*, because types above - //are universal and can paste properties in different objects. - switch (pXSprite->command) { - case kCmdLink: - case kCmdModernUse: - evSend(nSprite, 3, pXSprite->txID, kCmdModernUse); // just send command to change properties - return 1; - case kCmdUnlock: - evSend(nSprite, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command); // send normal command first - evSend(nSprite, 3, pXSprite->txID, kCmdModernUse); // then send command to change properties - return 1; - default: - evSend(nSprite, 3, pXSprite->txID, kCmdModernUse); // send first command to change properties - evSend(nSprite, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command); // then send normal command - return 1; - } - - } - return 1; -} char SetWallState(int nWall, XWALL *pXWall, int nState) { @@ -369,19 +336,20 @@ void ActivateGenerator(int); void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) { spritetype *pSprite = &sprite[nSprite]; - - if (gModernMap) { - switch (event.cmd) { - case kCmdUnlock: - case kCmdToggleLock: - switch (pSprite->type) { - case kModernWindGenerator: - if (pXSprite->locked) stopWindOnSectors(pXSprite); - break; - } - break; + #ifdef NOONE_EXTENSIONS + if (gModernMap) { + switch (event.cmd) { + case kCmdUnlock: + case kCmdToggleLock: + switch (pSprite->type) { + case kModernWindGenerator: + if (pXSprite->locked) stopWindOnSectors(pXSprite); + break; + } + break; + } } - } + #endif switch (event.cmd) { case kCmdLock: @@ -395,6 +363,7 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) return; } + #ifdef NOONE_EXTENSIONS if (gModernMap) { switch (pSprite->type) { @@ -437,7 +406,37 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) return; } break; // go normal operate switch + case kMarkerDudeSpawn: + if (gGameOptions.nMonsterSettings && pXSprite->data1 >= kDudeBase && pXSprite->data1 < kDudeVanillaMax) { + spritetype* pSpawn = NULL; + // add spawn random dude feature - works only if at least 2 data fields are not empty. + if ((pSpawn = spawnRandomDude(pSprite)) == NULL) + pSpawn = actSpawnDude(pSprite, pXSprite->data1, -1, 0); + + if (pSpawn) { + XSPRITE *pXSpawn = &xsprite[pSpawn->extra]; + gKillMgr.sub_263E0(1); + switch (pXSprite->data1) { + case kDudeBurningInnocent: + case kDudeBurningCultist: + case kDudeBurningZombieButcher: + case kDudeBurningTinyCaleb: + case kDudeBurningBeast: { + pXSpawn->health = dudeInfo[pXSprite->data1 - kDudeBase].startHealth << 4; + pXSpawn->burnTime = 10; + pXSpawn->target = -1; + aiActivateDude(pSpawn, pXSpawn); + break; + default: + if (pSprite->flags & kModernTypeFlag3) aiActivateDude(pSpawn, pXSpawn); + break; + } + } + + } + } + return; // Random Event Switch takes random data field and uses it as TX ID case kModernRandomTX: { @@ -1102,7 +1101,8 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) return; } } - + #endif + if (pSprite->statnum == kStatDude && pSprite->type >= kDudeBase && pSprite->type < kDudeMax) { switch (event.cmd) { @@ -1261,16 +1261,7 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) break; case kMarkerDudeSpawn: if (gGameOptions.nMonsterSettings && pXSprite->data1 >= kDudeBase && pXSprite->data1 < kDudeMax) { - - spritetype* pSpawn = NULL; - // By NoOne: add spawn random dude feature - works only if at least 2 data fields are not empty. - if (gModernMap) { - if ((pSpawn = spawnRandomDude(pSprite)) == NULL) - pSpawn = actSpawnDude(pSprite, pXSprite->data1, -1, 0); - } else { - pSpawn = actSpawnDude(pSprite, pXSprite->data1, -1, 0); - } - + spritetype* pSpawn = actSpawnDude(pSprite, pXSprite->data1, -1, 0); if (pSpawn) { XSPRITE *pXSpawn = &xsprite[pSpawn->extra]; gKillMgr.sub_263E0(1); @@ -1286,11 +1277,9 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) aiActivateDude(pSpawn, pXSpawn); break; default: - if (gModernMap && (pSprite->flags & kModernTypeFlag3)) aiActivateDude(pSpawn, pXSpawn); break; } } - } } break; @@ -1350,7 +1339,9 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) break; case kThingArmedProxBomb: +#ifdef NOONE_EXTENSIONS case kModernThingTNTProx: +#endif if (pSprite->statnum != kStatRespawn) { switch (event.cmd) { case kCmdSpriteProximity: @@ -1441,687 +1432,6 @@ void OperateSprite(int nSprite, XSPRITE *pXSprite, EVENT event) } } -// by NoOne: this function stops wind on all TX sectors affected by WindGen after it goes off state. -void stopWindOnSectors(XSPRITE* pXSource) { - spritetype* pSource = &sprite[pXSource->reference]; - - if (pXSource->txID <= 0) { - - if (sector[pSource->sectnum].extra >= 0) - xsector[sector[pSource->sectnum].extra].windVel = 0; - - return; - } - - for (int i = bucketHead[pXSource->txID]; i < bucketHead[pXSource->txID + 1]; i++) { - if (rxBucket[i].type != 6) continue; - XSECTOR * pXSector = &xsector[sector[rxBucket[i].index].extra]; - if ((pXSector->state == 1 && !pXSector->windAlways) || (sprite[pXSource->reference].flags & kModernTypeFlag1)) - pXSector->windVel = 0; - } -} - -void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer) { - - int nSource = sprite[pXSource->reference].index; TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; - QAV* pQav = qavSceneLoad(pXSource->data2); - if (pQav != NULL) { - - // save current weapon - pXSource->dropMsg = pPlayer->curWeapon; - - short nIndex = pCtrl->qavScene.index; - if (nIndex > -1 && nIndex != nSource && sprite[nIndex].extra >= 0) - pXSource->dropMsg = xsprite[sprite[nIndex].extra].dropMsg; - - if (nIndex < 0) - WeaponLower(pPlayer); - - pXSource->sysData1 = ClipLow((pQav->at10 * pXSource->waitTime) / 4, 0); // how many times animation should be played - - pCtrl->qavScene.index = nSource; - pCtrl->qavScene.qavResrc = pQav; - pCtrl->qavScene.dummy = -1; - - pCtrl->qavScene.qavResrc->Preload(); - - pPlayer->sceneQav = pXSource->data2; - pPlayer->weaponTimer = pCtrl->qavScene.qavResrc->at10; - pPlayer->qavCallback = (pXSource->data3 > 0) ? ClipRange(pXSource->data3 - 1, 0, 32) : -1; - pPlayer->qavLoop = false; - - } - -} - -void trPlayerCtrlStopScene(XSPRITE* pXSource, PLAYER* pPlayer) { - - TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; - //viewSetSystemMessage("OFF %d", pCtrl->qavScene.index); - - pXSource->sysData1 = 0; - pCtrl->qavScene.index = -1; - pCtrl->qavScene.qavResrc = NULL; - pPlayer->sceneQav = -1; - - // restore weapon - if (pPlayer->pXSprite->health > 0) { - int oldWeapon = (pXSource->dropMsg != 0) ? pXSource->dropMsg : 1; - pPlayer->input.newWeapon = pPlayer->curWeapon = oldWeapon; - WeaponRaise(pPlayer); - } - -} - -void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer) { - - pPlayer->pXSprite->txID = pXSource->txID; - pPlayer->pXSprite->command = pXSource->data2; - pPlayer->pXSprite->triggerOn = pXSource->triggerOn; - pPlayer->pXSprite->triggerOff = pXSource->triggerOff; - pPlayer->pXSprite->busyTime = pXSource->busyTime; - pPlayer->pXSprite->waitTime = pXSource->waitTime; - pPlayer->pXSprite->restState = pXSource->restState; - - pPlayer->pXSprite->Push = pXSource->Push; - pPlayer->pXSprite->Impact = pXSource->Impact; - pPlayer->pXSprite->Vector = pXSource->Vector; - pPlayer->pXSprite->Touch = pXSource->Touch; - pPlayer->pXSprite->Sight = pXSource->Sight; - pPlayer->pXSprite->Proximity = pXSource->Proximity; - - pPlayer->pXSprite->Decoupled = pXSource->Decoupled; - pPlayer->pXSprite->Interrutable = pXSource->Interrutable; - pPlayer->pXSprite->DudeLockout = pXSource->DudeLockout; - - //pPlayer->pXSprite->data1 = pXSource->data1; - //pPlayer->pXSprite->data2 = pXSource->data2; - //pPlayer->pXSprite->data3 = pXSource->data3; - //pPlayer->pXSprite->data4 = pXSource->data4; - - pPlayer->pXSprite->key = pXSource->key; - pPlayer->pXSprite->dropMsg = pXSource->dropMsg; - -} - -void useObjResizer(XSPRITE* pXSource, short objType, int objIndex) { - switch (objType) { - // for sectors - case 6: - if (valueIsBetween(pXSource->data1, -1, 32767)) - sector[objIndex].floorxpanning = ClipRange(pXSource->data1, 0, 255); - - if (valueIsBetween(pXSource->data2, -1, 32767)) - sector[objIndex].floorypanning = ClipRange(pXSource->data2, 0, 255); - - if (valueIsBetween(pXSource->data3, -1, 32767)) - sector[objIndex].ceilingxpanning = ClipRange(pXSource->data3, 0, 255); - - if (valueIsBetween(pXSource->data4, -1, 65535)) - sector[objIndex].ceilingypanning = ClipRange(pXSource->data4, 0, 255); - break; - // for sprites - case 3: - - // resize by seq scaling - if (sprite[pXSource->reference].flags & kModernTypeFlag1) { - if (valueIsBetween(pXSource->data1, -255, 32767)) { - int mulDiv = (valueIsBetween(pXSource->data2, 0, 257)) ? pXSource->data2 : 256; - if (pXSource->data1 > 0) xsprite[sprite[objIndex].extra].scale = mulDiv * ClipHigh(pXSource->data1, 25); - else if (pXSource->data1 < 0) xsprite[sprite[objIndex].extra].scale = mulDiv / ClipHigh(abs(pXSource->data1), 25); - else xsprite[sprite[objIndex].extra].scale = 0; - - // request properties update for custom dude - 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[kGenDudePropertyDmgScale] = true; - evPost(objIndex, 3, kGenDudeUpdTimeRate, kCallbackGenDudeUpdate); - break; - } - } - - // resize by repeats - } else { - - if (valueIsBetween(pXSource->data1, -1, 32767)) - sprite[objIndex].xrepeat = ClipRange(pXSource->data1, 0, 255); - - if (valueIsBetween(pXSource->data2, -1, 32767)) - sprite[objIndex].yrepeat = ClipRange(pXSource->data2, 0, 255); - - } - - if (valueIsBetween(pXSource->data3, -1, 32767)) - sprite[objIndex].xoffset = ClipRange(pXSource->data3, 0, 255); - - if (valueIsBetween(pXSource->data4, -1, 65535)) - sprite[objIndex].yoffset = ClipRange(pXSource->data4, 0, 255); - break; - - // for walls - case 0: - if (valueIsBetween(pXSource->data1, -1, 32767)) - wall[objIndex].xrepeat = ClipRange(pXSource->data1, 0, 255); - - if (valueIsBetween(pXSource->data2, -1, 32767)) - wall[objIndex].yrepeat = ClipRange(pXSource->data2, 0, 255); - - if (valueIsBetween(pXSource->data3, -1, 32767)) - wall[objIndex].xpanning = ClipRange(pXSource->data3, 0, 255); - - if (valueIsBetween(pXSource->data4, -1, 65535)) - wall[objIndex].ypanning = ClipRange(pXSource->data4, 0, 255); - break; - } - -} - -void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { - - spritetype* pSource = &sprite[pXSource->reference]; - - switch (objType) { - - // for walls - case 0: { - walltype* pWall = &wall[objIndex]; int old = -1; - - // data3 = set wall hitag - if (valueIsBetween(pXSource->data3, -1, 32767)) { - if ((pSource->flags & kModernTypeFlag1)) pWall->hitag = pWall->hitag |= pXSource->data3; - else pWall->hitag = pXSource->data3; - } - - // data4 = set wall cstat - if (valueIsBetween(pXSource->data4, -1, 65535)) { - old = pWall->cstat; - - // set new cstat - if ((pSource->flags & kModernTypeFlag1)) pWall->cstat = pWall->cstat |= pXSource->data4; // relative - else pWall->cstat = pXSource->data4; // absolute - - // and hanlde exceptions - if ((old & 0x2) && !(pWall->cstat & 0x2)) pWall->cstat |= 0x2; // kWallBottomSwap - if ((old & 0x4) && !(pWall->cstat & 0x4)) pWall->cstat |= 0x4; // kWallBottomOrg, kWallOutsideOrg - if ((old & 0x20) && !(pWall->cstat & 0x20)) pWall->cstat |= 0x20; // kWallOneWay - - if (old & 0xc000) { - - if (!(pWall->cstat & 0xc000)) - pWall->cstat |= 0xc000; // kWallMoveMask - - if ((old & 0x0) && !(pWall->cstat & 0x0)) pWall->cstat |= 0x0; // kWallMoveNone - else if ((old & 0x4000) && !(pWall->cstat & 0x4000)) pWall->cstat |= 0x4000; // kWallMoveForward - else if ((old & 0x8000) && !(pWall->cstat & 0x8000)) pWall->cstat |= 0x8000; // kWallMoveBackward - - } - } - - break; - } - - // for sprites - case 3: { - spritetype* pSprite = &sprite[objIndex]; bool thing2debris = false; - XSPRITE* pXSprite = &xsprite[pSprite->extra]; int old = -1; - - // data3 = set sprite hitag - if (valueIsBetween(pXSource->data3, -1, 32767)) { - old = pSprite->hitag; - - // set new hitag - if ((pSource->flags & kModernTypeFlag1)) pSprite->hitag = pSource->hitag |= pXSource->data3; // relative - else pSprite->hitag = pXSource->data3; // absolute - - // and handle exceptions - if ((old & kHitagFree) && !(pSprite->hitag & kHitagFree)) pSprite->hitag |= kHitagFree; - if ((old & kHitagRespawn) && !(pSprite->hitag & kHitagRespawn)) pSprite->hitag |= kHitagRespawn; - - // prepare things for different (debris) physics. - if (pSprite->statnum == kStatThing && debrisGetFreeIndex() >= 0) thing2debris = true; - - } - - // data2 = sprite physics settings - if ((pXSource->data2 >= 0 && pXSource->data3 <= 33) || thing2debris) { - switch (pSprite->statnum) { - case kStatDude: // dudes already treating in game - case kStatFree: - case kStatMarker: - case kStatPathMarker: // path marker - break; - default: - // store physics attributes in xsprite to avoid setting hitag for modern types! - int flags = (pXSprite->physAttr != 0) ? pXSprite->physAttr : 0; - - if (thing2debris) { - - // converting thing to debris - if ((pSprite->hitag & kPhysMove) != 0) flags |= kPhysMove; - else flags &= ~kPhysMove; - - if ((pSprite->hitag & kPhysGravity) != 0) flags |= (kPhysGravity | kPhysFalling); - else flags &= ~(kPhysGravity | kPhysFalling); - - pSprite->hitag &= ~(kPhysMove | kPhysGravity | kPhysFalling); - xvel[objIndex] = yvel[objIndex] = zvel[objIndex] = 0; pXSprite->restState = pXSprite->state; - - } else { - - // first digit of data2: set main physics attributes - switch (pXSource->data2) { - case 0: - flags &= ~kPhysMove; - flags &= ~(kPhysGravity | kPhysFalling); - break; - - case 1: case 10: case 11: case 12: case 13: - flags |= kPhysMove; - flags &= ~(kPhysGravity | kPhysFalling); - break; - - case 2: case 20: case 21: case 22: case 23: - flags &= ~kPhysMove; - flags |= (kPhysGravity | kPhysFalling); - break; - - case 3: case 30: case 31: case 32: case 33: - flags |= kPhysMove; - flags |= (kPhysGravity | kPhysFalling); - break; - } - - // second digit of data2: set physics flags - switch (pXSource->data2) { - case 0: case 1: case 2: case 3: - case 10: case 20: case 30: - flags &= ~kPhysDebrisVector; - flags &= ~kPhysDebrisExplode; - break; - - case 11: case 21: case 31: - flags |= kPhysDebrisVector; - flags &= ~kPhysDebrisExplode; - break; - - case 12: case 22: case 32: - flags &= ~kPhysDebrisVector; - flags |= kPhysDebrisExplode; - break; - - case 13: case 23: case 33: - flags |= kPhysDebrisVector; - flags |= kPhysDebrisExplode; - break; - } - - } - - int nIndex = isDebris(objIndex); // check if there is no sprite in list - - // adding physics sprite in list - if ((flags & kPhysGravity) != 0 || (flags & kPhysMove) != 0) { - - if (nIndex != -1) pXSprite->physAttr = flags; // just update physics attributes - else if ((nIndex = debrisGetFreeIndex()) < 0) - viewSetSystemMessage("Max (%d) Physics affected sprites reached!", kMaxSuperXSprites); - else { - - pXSprite->physAttr = flags; // update physics attributes - - // allow things to became debris, so they use different physics... - if (pSprite->statnum == kStatThing) changespritestat(objIndex, 0); - //actPostSprite(nDest, kStatDecoration); // !!!! not working here for some reason - - gPhysSpritesList[nIndex] = objIndex; - if (nIndex >= gPhysSpritesCount) gPhysSpritesCount++; - getSpriteMassBySize(pSprite); // create physics cache - - } - - // removing physics from sprite in list (don't remove sprite from list) - } else if (nIndex != -1) { - - pXSprite->physAttr = flags; - xvel[objIndex] = yvel[objIndex] = zvel[objIndex] = 0; - if (pSprite->lotag >= kThingBase && pSprite->lotag < kThingMax) - changespritestat(objIndex, kStatThing); // if it was a thing - restore statnum - - } - - break; - } - } - - // data4 = sprite cstat - if (valueIsBetween(pXSource->data4, -1, 65535)) { - - old = pSprite->cstat; - - // set new cstat - if ((pSource->flags & kModernTypeFlag1)) pSprite->cstat = pSprite->cstat |= pXSource->data4; // relative - else pSprite->cstat = pXSource->data4; // absolute - - // and handle exceptions - if ((old & 0x1000) && !(pSprite->cstat & 0x1000)) pSprite->cstat |= 0x1000; //kSpritePushable - if ((old & 0x80) && !(pSprite->cstat & 0x80)) pSprite->cstat |= 0x80; // kSpriteOriginAlign - - if (old & 0x6000) { - - if (!(pSprite->cstat & 0x6000)) - pSprite->cstat |= 0x6000; // kSpriteMoveMask - - if ((old & 0x0) && !(pSprite->cstat & 0x0)) pSprite->cstat |= 0x0; // kSpriteMoveNone - else if ((old & 0x2000) && !(pSprite->cstat & 0x2000)) pSprite->cstat |= 0x2000; // kSpriteMoveForward, kSpriteMoveFloor - else if ((old & 0x4000) && !(pSprite->cstat & 0x4000)) pSprite->cstat |= 0x4000; // kSpriteMoveReverse, kSpriteMoveCeiling - - } - - } - - break; - } - - // for sectors - case 6: { - - XSECTOR* pXSector = &xsector[sector[objIndex].extra]; - - // data1 = sector underwater status and depth level - if (pXSource->data1 == 0) pXSector->Underwater = false; - else if (pXSource->data1 == 1) pXSector->Underwater = true; - else if (pXSource->data1 > 9) pXSector->Depth = 7; - else if (pXSource->data1 > 1) pXSector->Depth = pXSource->data1 - 2; - - - // data2 = sector visibility - if (valueIsBetween(pXSource->data2, -1, 32767)) { - if (pXSource->data2 > 234) sector[objIndex].visibility = 234; - else sector[objIndex].visibility = pXSource->data2; - } - - // data3 = sector ceil cstat - if (valueIsBetween(pXSource->data3, -1, 32767)) { - if ((pSource->flags & kModernTypeFlag1)) sector[objIndex].ceilingstat = sector[objIndex].ceilingstat |= pXSource->data3; - else sector[objIndex].ceilingstat = pXSource->data3; - } - - // data4 = sector floor cstat - if (valueIsBetween(pXSource->data4, -1, 65535)) { - if ((pSource->flags & kModernTypeFlag1)) sector[objIndex].floorstat = sector[objIndex].floorstat |= pXSource->data4; - else sector[objIndex].floorstat = pXSource->data4; - } - - break; - - } - - // no TX id - case -1: { - - // data2 = global visibility - if (valueIsBetween(pXSource->data2, -1, 32767)) - gVisibility = ClipRange(pXSource->data2, 0, 4096); - } - - break; - } - -} - -void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { - spritetype* pSource = &sprite[pXSource->reference]; - XSECTOR* pXSector = (sector[pSource->sectnum].extra >= 0) ? &xsector[sector[pSource->sectnum].extra] : NULL; - - pSprite->x = pSource->x; pSprite->y = pSource->y; - pSprite->z += (sector[pSource->sectnum].floorz - sector[pSprite->sectnum].floorz); - - if (pSource->flags & kModernTypeFlag1) // force telefrag - TeleFrag(pSprite->xvel, pSource->sectnum); - - changespritesect((short)pSprite->xvel, pSource->sectnum); - 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 (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; - - viewBackupSpriteLoc(pSprite->xvel, pSprite); - - if (pXSource->data4 > 0) - sfxPlay3DSound(pSource, pXSource->data4, -1, 0); - - if (IsPlayerSprite(pSprite)) { - - PLAYER* pPlayer = &gPlayer[pSprite->type - kDudePlayer1]; - playerResetInertia(pPlayer); - - if (pXSource->data2 == 1) - pPlayer->zViewVel = pPlayer->zWeaponVel = 0; - } -} - - -void useEffectGen(XSPRITE * pXSource, spritetype * pSprite) { - if (pSprite == NULL) pSprite = &sprite[pXSource->reference]; - if (pSprite->extra < 0) return; - - int fxId = pXSource->data2 + Random(pXSource->data3); - int pos, top, bottom; GetSpriteExtents(pSprite, &top, &bottom); spritetype* pEffect = NULL; - - // select where exactly effect should be spawned - switch (pXSource->data4) { - case 1: - pos = bottom; // bottom of sprite - break; - default: - pos = top; // top of sprite - break; - } - - if (fxId > 0 && fxId < 57 && (pEffect = gFX.fxSpawn((FX_ID) fxId, pSprite->sectnum, pSprite->x, pSprite->y, pos, 0)) != NULL) { - - if (pEffect->cstat & CSTAT_SPRITE_ONE_SIDED) pEffect->cstat &= ~CSTAT_SPRITE_ONE_SIDED; - - if (pSprite->flags & kModernTypeFlag1) { - pEffect->pal = pSprite->pal; - pEffect->xrepeat = pSprite->xrepeat; - pEffect->yrepeat = pSprite->yrepeat; - pEffect->shade = pSprite->shade; - } - } -} - - -void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) { - - spritetype* pSource = &sprite[pXSource->reference]; - XSECTOR* pXSector = NULL; bool forceWind = false; - int nXSector = 0; - if (pSector == NULL) { - - if (sector[pSource->sectnum].extra < 0) { - int nXSector = dbInsertXSector(pSource->sectnum); - if (nXSector > 0) pXSector = &xsector[nXSector]; - else return; - - forceWind = true; - - } else { - pXSector = &xsector[sector[pSource->sectnum].extra]; - nXSector = sector[pXSector->reference].extra; - } - - } else { - pXSector = &xsector[pSector->extra]; - nXSector = sector[pXSector->reference].extra; - } - - if (pSource->flags) { - pXSector->panAlways = 1; - pXSector->windAlways = 1; - } else if (forceWind) - pXSector->windAlways = 1; - - if (pXSource->data2 > 32766) pXSource->data2 = 32767; - - if (pXSource->data1 == 1 || pXSource->data1 == 3) pXSector->windVel = Random(pXSource->data2); - else pXSector->windVel = pXSource->data2; - - if (pXSource->data1 == 2 || pXSource->data1 == 3) { - short ang = pSource->ang; - while (pSource->ang == ang) - pSource->ang = Random3(kAng360); - } - - pXSector->windAng = pSource->ang; - - if (pXSource->data3 > 0 && pXSource->data3 < 4) { - switch (pXSource->data3) { - case 1: - pXSector->panFloor = true; - pXSector->panCeiling = false; - break; - case 2: - pXSector->panFloor = false; - pXSector->panCeiling = true; - break; - case 3: - pXSector->panFloor = true; - pXSector->panCeiling = true; - break; - } - - short oldPan = pXSector->panVel; - pXSector->panAngle = pXSector->windAng; - pXSector->panVel = pXSector->windVel; - - // add to panList if panVel was set to 0 previously - if (oldPan == 0 && pXSector->panVel != 0 && panCount < kMaxXSprites) { - - int i; - for (i = 0; i < panCount; i++) { - if (panList[i] != nXSector) continue; - break; - } - - if (i == panCount) - panList[panCount++] = nXSector; - } - - } -} - - - -void useSpriteDamager(XSPRITE* pXSource, spritetype* pSprite) { - spritetype* pSource = &sprite[pXSource->reference]; - if (pSprite != NULL && xspriRangeIsFine(pSprite->extra) && xsprite[pSprite->extra].health > 0) { - DAMAGE_TYPE dmgType = (DAMAGE_TYPE)ClipRange(pXSource->data2, kDmgFall, kDmgElectric); - int dmg = (pXSource->data3 == 0) ? 65535 : ClipRange(pXSource->data3 << 1, 1, 65535); - if (pXSource->data2 >= 0) actDamageSprite(pSource->index, pSprite, dmgType, dmg); - else if (pXSource->data2 == -1 && IsDudeSprite(pSprite)) { - PLAYER* pPlayer = getPlayerById(pSprite->type); - if (pPlayer == NULL || !pPlayer->godMode) { - xsprite[pSprite->extra].health = ClipLow(xsprite[pSprite->extra].health - dmg, 0); - if (xsprite[pSprite->extra].health == 0) { - if (pPlayer == NULL) actKillDude(pSource->index, pSprite, DAMAGE_TYPE_0, 4); - else playerDamageSprite(pSource->index, pPlayer, DAMAGE_TYPE_0, 4); - } - } - } - } -} - -void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) { - if (pXSource->data2 > 0 && !gSysRes.Lookup(pXSource->data2, "SEQ")) { - consoleSysMsg("Missing sequence #%d",pXSource->data2); - return; - } - - switch (objType) { - case 6: - if (pXSource->data2 <= 0) { - if (pXSource->data3 == 3 || pXSource->data3 == 1) - seqKill(2, sector[index].extra); - if (pXSource->data3 == 3 || pXSource->data3 == 2) - seqKill(1, sector[index].extra); - } - else { - if (pXSource->data3 == 3 || pXSource->data3 == 1) - seqSpawn(pXSource->data2, 2, sector[index].extra, -1); - if (pXSource->data3 == 3 || pXSource->data3 == 2) - seqSpawn(pXSource->data2, 1, sector[index].extra, -1); - } - return; - - case 0: - if (pXSource->data2 <= 0) { - if (pXSource->data3 == 3 || pXSource->data3 == 1) - seqKill(0, wall[index].extra); - if ((pXSource->data3 == 3 || pXSource->data3 == 2) && (wall[index].cstat & CSTAT_WALL_MASKED)) - seqKill(4, wall[index].extra); - } - else { - - if (pXSource->data3 == 3 || pXSource->data3 == 1) - seqSpawn(pXSource->data2, 0, wall[index].extra, -1); - if (pXSource->data3 == 3 || pXSource->data3 == 2) { - - if (wall[index].nextwall < 0) { - if (pXSource->data3 == 3) - seqSpawn(pXSource->data2, 0, wall[index].extra, -1); - - } - else { - if (!(wall[index].cstat & CSTAT_WALL_MASKED)) - wall[index].cstat |= CSTAT_WALL_MASKED; - - seqSpawn(pXSource->data2, 4, wall[index].extra, -1); - } - } - - if (pXSource->data4 > 0) { - - int cx, cy, cz; - cx = (wall[index].x + wall[wall[index].point2].x) >> 1; - cy = (wall[index].y + wall[wall[index].point2].y) >> 1; - int nSector = sectorofwall(index); - int32_t ceilZ, floorZ; - getzsofslope(nSector, cx, cy, &ceilZ, &floorZ); - int32_t ceilZ2, floorZ2; - getzsofslope(wall[index].nextsector, cx, cy, &ceilZ2, &floorZ2); - ceilZ = ClipLow(ceilZ, ceilZ2); - floorZ = ClipHigh(floorZ, floorZ2); - cz = (ceilZ + floorZ) >> 1; - - sfxPlay3DSound(cx, cy, cz, pXSource->data4, nSector); - - } - - } - return; - - case 3: - if (pXSource->data2 <= 0) seqKill(3, sprite[index].extra); - else { - seqSpawn(pXSource->data2, 3, sprite[index].extra, -1); - if (pXSource->data4 > 0) sfxPlay3DSound(&sprite[index], pXSource->data4, -1, 0); - } - return; - } -} - void SetupGibWallState(walltype *pWall, XWALL *pXWall) { walltype *pWall2 = NULL; @@ -2167,29 +1477,30 @@ void OperateWall(int nWall, XWALL *pXWall, EVENT event) { return; } - // by NoOne: make 1-Way switch type for walls to work... - if (gModernMap) { + // make 1-Way switch type for walls to work... + #ifdef NOONE_EXTENSIONS + if (gModernMap) { - switch (pWall->type) { - case kSwitchOneWay: - switch (event.cmd) { - case kCmdOff: - SetWallState(nWall, pXWall, 0); - break; - case kCmdOn: - SetWallState(nWall, pXWall, 1); - break; - default: - SetWallState(nWall, pXWall, pXWall->restState ^ 1); - break; - } - return; - default: - break; - } + switch (pWall->type) { + case kSwitchOneWay: + switch (event.cmd) { + case kCmdOff: + SetWallState(nWall, pXWall, 0); + break; + case kCmdOn: + SetWallState(nWall, pXWall, 1); + break; + default: + SetWallState(nWall, pXWall, pXWall->restState ^ 1); + break; + } + return; + default: + break; + } - } - + } + #endif switch (pWall->type) { case kWallGib: if (GetWallType(nWall) != pWall->type) break; @@ -2400,11 +1711,15 @@ void TranslateSector(int nSector, int a2, int a3, int a4, int a5, int a6, int a7 for (int nSprite = headspritesect[nSector]; nSprite >= 0; nSprite = nextspritesect[nSprite]) { spritetype *pSprite = &sprite[nSprite]; - // By NoOne: allow to move markers by sector movements in game if flags 1 is added in editor. + // allow to move markers by sector movements in game if flags 1 is added in editor. switch (pSprite->statnum) { case kStatMarker: case kStatPathMarker: - if (!gModernMap || !(pSprite->flags & 0x1)) continue; + #ifdef NOONE_EXTENSIONS + if (!gModernMap || !(pSprite->flags & 0x1)) continue; + #else + continue; + #endif break; } @@ -2986,9 +2301,11 @@ void OperatePath(unsigned int nSector, XSECTOR *pXSector, EVENT event) } } - // by NoOne: trigger marker after it gets reached - if (gModernMap && pXSprite2->state != 1) - trTriggerSprite(pSprite2->xvel, pXSprite2, kCmdOn); + // trigger marker after it gets reached + #ifdef NOONE_EXTENSIONS + if (gModernMap && pXSprite2->state != 1) + trTriggerSprite(pSprite2->xvel, pXSprite2, kCmdOn); + #endif if (nSprite < 0) { viewSetSystemMessage("Unable to find path marker with id #%d for path sector #%d", nId, nSector); @@ -3015,22 +2332,23 @@ void OperateSector(unsigned int nSector, XSECTOR *pXSector, EVENT event) dassert(nSector < (unsigned int)numsectors); sectortype *pSector = §or[nSector]; - if (gModernMap) { - switch (pSector->type) { - // By NoOne: reset counter sector state and make it work again after unlock, so it can be used again. - case kSectorCounter: - switch (event.cmd) { - case kCmdUnlock: - case kCmdToggleLock: - if (pXSector->locked != 1) break; - pXSector->state = 0; - evPost(nSector, 6, 0, kCallbackCounterCheck); - break; - } - break; + #ifdef NOONE_EXTENSIONS + if (gModernMap) { + switch (pSector->type) { + // reset counter sector state and make it work again after unlock, so it can be used again. + case kSectorCounter: + switch (event.cmd) { + case kCmdUnlock: + case kCmdToggleLock: + if (pXSector->locked != 1) break; + pXSector->state = 0; + evPost(nSector, 6, 0, kCallbackCounterCheck); + break; + } + break; + } } - } - + #endif switch (event.cmd) { case kCmdLock: pXSector->locked = 1; @@ -3168,11 +2486,13 @@ void LinkSector(int nSector, XSECTOR *pXSector, EVENT event) case kSectorRotate: RDoorBusy(nSector, nBusy); break; - /* By NoOne: add link support for counter sectors so they can change necessary type and count of types*/ + #ifdef NOONE_EXTENSIONS + // add link support for counter sectors so they can change necessary type and count of types case kSectorCounter: pXSector->waitTimeA = xsector[sector[event.index].extra].waitTimeA; pXSector->data = xsector[sector[event.index].extra].data; break; + #endif default: pXSector->busy = nBusy; if ((pXSector->busy&0xffff) == 0) @@ -3185,7 +2505,8 @@ void LinkSprite(int nSprite, XSPRITE *pXSprite, EVENT event) { spritetype *pSprite = &sprite[nSprite]; int nBusy = GetSourceBusy(event); switch (pSprite->type) { - //By NoOne: these can be linked too now, so it's possible to change palette, underwater status and more... + #ifdef NOONE_EXTENSIONS + // these can be linked too now, so it's possible to change palette, underwater status and more... case kMarkerLowWater: case kMarkerUpWater: case kMarkerUpGoo: @@ -3280,7 +2601,7 @@ void LinkSprite(int nSprite, XSPRITE *pXSprite, EVENT event) { } } break; - // By NoOne: add a way to link between path markers, so path sectors can change their path on the fly. + // add a way to link between path markers, so path sectors can change their path on the fly. case kMarkerPath: { // only path marker to path marker link allowed @@ -3299,6 +2620,7 @@ void LinkSprite(int nSprite, XSPRITE *pXSprite, EVENT event) { } } break; + #endif case kSwitchCombo: { if (event.type == 3) @@ -3360,9 +2682,11 @@ void trMessageSector(unsigned int nSector, EVENT event) { case kCmdLink: LinkSector(nSector, pXSector, event); break; + #ifdef NOONE_EXTENSIONS case kCmdModernUse: pastePropertiesInObj(6, nSector, event); break; + #endif default: OperateSector(nSector, pXSector, event); break; @@ -3399,9 +2723,11 @@ void trMessageWall(unsigned int nWall, EVENT event) { case kCmdLink: LinkWall(nWall, pXWall, event); break; + #ifdef NOONE_EXTENSIONS case kCmdModernUse: pastePropertiesInObj(0, nWall, event); break; + #endif default: OperateWall(nWall, pXWall, event); break; @@ -3436,9 +2762,11 @@ void trMessageSprite(unsigned int nSprite, EVENT event) { case kCmdLink: LinkSprite(nSprite, pXSprite, event); break; + #ifdef NOONE_EXTENSIONS case kCmdModernUse: pastePropertiesInObj(3, nSprite, event); break; + #endif default: OperateSprite(nSprite, pXSprite, event); break; @@ -3448,10 +2776,732 @@ void trMessageSprite(unsigned int nSprite, EVENT event) { } } +#ifdef NOONE_EXTENSIONS + +// this function stops wind on all TX sectors affected by WindGen after it goes off state. +void stopWindOnSectors(XSPRITE* pXSource) { + spritetype* pSource = &sprite[pXSource->reference]; + + if (pXSource->txID <= 0) { + + if (sector[pSource->sectnum].extra >= 0) + xsector[sector[pSource->sectnum].extra].windVel = 0; + + return; + } + + for (int i = bucketHead[pXSource->txID]; i < bucketHead[pXSource->txID + 1]; i++) { + if (rxBucket[i].type != 6) continue; + XSECTOR * pXSector = &xsector[sector[rxBucket[i].index].extra]; + if ((pXSector->state == 1 && !pXSector->windAlways) || (sprite[pXSource->reference].flags & kModernTypeFlag1)) + pXSector->windVel = 0; + } +} + +void trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer) { + + int nSource = sprite[pXSource->reference].index; TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; + QAV* pQav = qavSceneLoad(pXSource->data2); + if (pQav != NULL) { + + // save current weapon + pXSource->dropMsg = pPlayer->curWeapon; + + short nIndex = pCtrl->qavScene.index; + if (nIndex > -1 && nIndex != nSource && sprite[nIndex].extra >= 0) + pXSource->dropMsg = xsprite[sprite[nIndex].extra].dropMsg; + + if (nIndex < 0) + WeaponLower(pPlayer); + + pXSource->sysData1 = ClipLow((pQav->at10 * pXSource->waitTime) / 4, 0); // how many times animation should be played + + pCtrl->qavScene.index = nSource; + pCtrl->qavScene.qavResrc = pQav; + pCtrl->qavScene.dummy = -1; + + pCtrl->qavScene.qavResrc->Preload(); + + pPlayer->sceneQav = pXSource->data2; + pPlayer->weaponTimer = pCtrl->qavScene.qavResrc->at10; + pPlayer->qavCallback = (pXSource->data3 > 0) ? ClipRange(pXSource->data3 - 1, 0, 32) : -1; + pPlayer->qavLoop = false; + + } + +} + +void trPlayerCtrlStopScene(XSPRITE* pXSource, PLAYER* pPlayer) { + + TRPLAYERCTRL* pCtrl = &gPlayerCtrl[pPlayer->nPlayer]; + //viewSetSystemMessage("OFF %d", pCtrl->qavScene.index); + + pXSource->sysData1 = 0; + pCtrl->qavScene.index = -1; + pCtrl->qavScene.qavResrc = NULL; + pPlayer->sceneQav = -1; + + // restore weapon + if (pPlayer->pXSprite->health > 0) { + int oldWeapon = (pXSource->dropMsg != 0) ? pXSource->dropMsg : 1; + pPlayer->input.newWeapon = pPlayer->curWeapon = oldWeapon; + WeaponRaise(pPlayer); + } + +} + +void trPlayerCtrlLink(XSPRITE* pXSource, PLAYER* pPlayer) { + + pPlayer->pXSprite->txID = pXSource->txID; + pPlayer->pXSprite->command = pXSource->data2; + pPlayer->pXSprite->triggerOn = pXSource->triggerOn; + pPlayer->pXSprite->triggerOff = pXSource->triggerOff; + pPlayer->pXSprite->busyTime = pXSource->busyTime; + pPlayer->pXSprite->waitTime = pXSource->waitTime; + pPlayer->pXSprite->restState = pXSource->restState; + + pPlayer->pXSprite->Push = pXSource->Push; + pPlayer->pXSprite->Impact = pXSource->Impact; + pPlayer->pXSprite->Vector = pXSource->Vector; + pPlayer->pXSprite->Touch = pXSource->Touch; + pPlayer->pXSprite->Sight = pXSource->Sight; + pPlayer->pXSprite->Proximity = pXSource->Proximity; + + pPlayer->pXSprite->Decoupled = pXSource->Decoupled; + pPlayer->pXSprite->Interrutable = pXSource->Interrutable; + pPlayer->pXSprite->DudeLockout = pXSource->DudeLockout; + + //pPlayer->pXSprite->data1 = pXSource->data1; + //pPlayer->pXSprite->data2 = pXSource->data2; + //pPlayer->pXSprite->data3 = pXSource->data3; + //pPlayer->pXSprite->data4 = pXSource->data4; + + pPlayer->pXSprite->key = pXSource->key; + pPlayer->pXSprite->dropMsg = pXSource->dropMsg; + +} + +void useObjResizer(XSPRITE* pXSource, short objType, int objIndex) { + switch (objType) { + // for sectors + case 6: + if (valueIsBetween(pXSource->data1, -1, 32767)) + sector[objIndex].floorxpanning = ClipRange(pXSource->data1, 0, 255); + + if (valueIsBetween(pXSource->data2, -1, 32767)) + sector[objIndex].floorypanning = ClipRange(pXSource->data2, 0, 255); + + if (valueIsBetween(pXSource->data3, -1, 32767)) + sector[objIndex].ceilingxpanning = ClipRange(pXSource->data3, 0, 255); + + if (valueIsBetween(pXSource->data4, -1, 65535)) + sector[objIndex].ceilingypanning = ClipRange(pXSource->data4, 0, 255); + break; + // for sprites + case 3: + + // resize by seq scaling + if (sprite[pXSource->reference].flags & kModernTypeFlag1) { + if (valueIsBetween(pXSource->data1, -255, 32767)) { + int mulDiv = (valueIsBetween(pXSource->data2, 0, 257)) ? pXSource->data2 : 256; + if (pXSource->data1 > 0) xsprite[sprite[objIndex].extra].scale = mulDiv * ClipHigh(pXSource->data1, 25); + else if (pXSource->data1 < 0) xsprite[sprite[objIndex].extra].scale = mulDiv / ClipHigh(abs(pXSource->data1), 25); + else xsprite[sprite[objIndex].extra].scale = 0; + + // request properties update for custom dude + 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[kGenDudePropertyDmgScale] = true; + evPost(objIndex, 3, kGenDudeUpdTimeRate, kCallbackGenDudeUpdate); + break; + } + } + + // resize by repeats + } else { + + if (valueIsBetween(pXSource->data1, -1, 32767)) + sprite[objIndex].xrepeat = ClipRange(pXSource->data1, 0, 255); + + if (valueIsBetween(pXSource->data2, -1, 32767)) + sprite[objIndex].yrepeat = ClipRange(pXSource->data2, 0, 255); + + } + + if (valueIsBetween(pXSource->data3, -1, 32767)) + sprite[objIndex].xoffset = ClipRange(pXSource->data3, 0, 255); + + if (valueIsBetween(pXSource->data4, -1, 65535)) + sprite[objIndex].yoffset = ClipRange(pXSource->data4, 0, 255); + break; + + // for walls + case 0: + if (valueIsBetween(pXSource->data1, -1, 32767)) + wall[objIndex].xrepeat = ClipRange(pXSource->data1, 0, 255); + + if (valueIsBetween(pXSource->data2, -1, 32767)) + wall[objIndex].yrepeat = ClipRange(pXSource->data2, 0, 255); + + if (valueIsBetween(pXSource->data3, -1, 32767)) + wall[objIndex].xpanning = ClipRange(pXSource->data3, 0, 255); + + if (valueIsBetween(pXSource->data4, -1, 65535)) + wall[objIndex].ypanning = ClipRange(pXSource->data4, 0, 255); + break; + } + +} + +void usePropertiesChanger(XSPRITE* pXSource, short objType, int objIndex) { + + spritetype* pSource = &sprite[pXSource->reference]; + + switch (objType) { + + // for walls + case 0: { + walltype* pWall = &wall[objIndex]; int old = -1; + + // data3 = set wall hitag + if (valueIsBetween(pXSource->data3, -1, 32767)) { + if ((pSource->flags & kModernTypeFlag1)) pWall->hitag = pWall->hitag |= pXSource->data3; + else pWall->hitag = pXSource->data3; + } + + // data4 = set wall cstat + if (valueIsBetween(pXSource->data4, -1, 65535)) { + old = pWall->cstat; + + // set new cstat + if ((pSource->flags & kModernTypeFlag1)) pWall->cstat = pWall->cstat |= pXSource->data4; // relative + else pWall->cstat = pXSource->data4; // absolute + + // and hanlde exceptions + if ((old & 0x2) && !(pWall->cstat & 0x2)) pWall->cstat |= 0x2; // kWallBottomSwap + if ((old & 0x4) && !(pWall->cstat & 0x4)) pWall->cstat |= 0x4; // kWallBottomOrg, kWallOutsideOrg + if ((old & 0x20) && !(pWall->cstat & 0x20)) pWall->cstat |= 0x20; // kWallOneWay + + if (old & 0xc000) { + + if (!(pWall->cstat & 0xc000)) + pWall->cstat |= 0xc000; // kWallMoveMask + + if ((old & 0x0) && !(pWall->cstat & 0x0)) pWall->cstat |= 0x0; // kWallMoveNone + else if ((old & 0x4000) && !(pWall->cstat & 0x4000)) pWall->cstat |= 0x4000; // kWallMoveForward + else if ((old & 0x8000) && !(pWall->cstat & 0x8000)) pWall->cstat |= 0x8000; // kWallMoveBackward + + } + } + + break; + } + + // for sprites + case 3: { + spritetype* pSprite = &sprite[objIndex]; bool thing2debris = false; + XSPRITE* pXSprite = &xsprite[pSprite->extra]; int old = -1; + + // data3 = set sprite hitag + if (valueIsBetween(pXSource->data3, -1, 32767)) { + old = pSprite->hitag; + + // set new hitag + if ((pSource->flags & kModernTypeFlag1)) pSprite->hitag = pSource->hitag |= pXSource->data3; // relative + else pSprite->hitag = pXSource->data3; // absolute + + // and handle exceptions + if ((old & kHitagFree) && !(pSprite->hitag & kHitagFree)) pSprite->hitag |= kHitagFree; + if ((old & kHitagRespawn) && !(pSprite->hitag & kHitagRespawn)) pSprite->hitag |= kHitagRespawn; + + // prepare things for different (debris) physics. + if (pSprite->statnum == kStatThing && debrisGetFreeIndex() >= 0) thing2debris = true; + + } + + // data2 = sprite physics settings + if ((pXSource->data2 >= 0 && pXSource->data3 <= 33) || thing2debris) { + switch (pSprite->statnum) { + case kStatDude: // dudes already treating in game + case kStatFree: + case kStatMarker: + case kStatPathMarker: // path marker + break; + default: + // store physics attributes in xsprite to avoid setting hitag for modern types! + int flags = (pXSprite->physAttr != 0) ? pXSprite->physAttr : 0; + + if (thing2debris) { + + // converting thing to debris + if ((pSprite->hitag & kPhysMove) != 0) flags |= kPhysMove; + else flags &= ~kPhysMove; + + if ((pSprite->hitag & kPhysGravity) != 0) flags |= (kPhysGravity | kPhysFalling); + else flags &= ~(kPhysGravity | kPhysFalling); + + pSprite->hitag &= ~(kPhysMove | kPhysGravity | kPhysFalling); + xvel[objIndex] = yvel[objIndex] = zvel[objIndex] = 0; pXSprite->restState = pXSprite->state; + + } else { + + // first digit of data2: set main physics attributes + switch (pXSource->data2) { + case 0: + flags &= ~kPhysMove; + flags &= ~(kPhysGravity | kPhysFalling); + break; + + case 1: case 10: case 11: case 12: case 13: + flags |= kPhysMove; + flags &= ~(kPhysGravity | kPhysFalling); + break; + + case 2: case 20: case 21: case 22: case 23: + flags &= ~kPhysMove; + flags |= (kPhysGravity | kPhysFalling); + break; + + case 3: case 30: case 31: case 32: case 33: + flags |= kPhysMove; + flags |= (kPhysGravity | kPhysFalling); + break; + } + + // second digit of data2: set physics flags + switch (pXSource->data2) { + case 0: case 1: case 2: case 3: + case 10: case 20: case 30: + flags &= ~kPhysDebrisVector; + flags &= ~kPhysDebrisExplode; + break; + + case 11: case 21: case 31: + flags |= kPhysDebrisVector; + flags &= ~kPhysDebrisExplode; + break; + + case 12: case 22: case 32: + flags &= ~kPhysDebrisVector; + flags |= kPhysDebrisExplode; + break; + + case 13: case 23: case 33: + flags |= kPhysDebrisVector; + flags |= kPhysDebrisExplode; + break; + } + + } + + int nIndex = isDebris(objIndex); // check if there is no sprite in list + + // adding physics sprite in list + if ((flags & kPhysGravity) != 0 || (flags & kPhysMove) != 0) { + + if (nIndex != -1) pXSprite->physAttr = flags; // just update physics attributes + else if ((nIndex = debrisGetFreeIndex()) < 0) + viewSetSystemMessage("Max (%d) Physics affected sprites reached!", kMaxSuperXSprites); + else { + + pXSprite->physAttr = flags; // update physics attributes + + // allow things to became debris, so they use different physics... + if (pSprite->statnum == kStatThing) changespritestat(objIndex, 0); + //actPostSprite(nDest, kStatDecoration); // !!!! not working here for some reason + + gPhysSpritesList[nIndex] = objIndex; + if (nIndex >= gPhysSpritesCount) gPhysSpritesCount++; + getSpriteMassBySize(pSprite); // create physics cache + + } + + // removing physics from sprite in list (don't remove sprite from list) + } else if (nIndex != -1) { + + pXSprite->physAttr = flags; + xvel[objIndex] = yvel[objIndex] = zvel[objIndex] = 0; + if (pSprite->lotag >= kThingBase && pSprite->lotag < kThingMax) + changespritestat(objIndex, kStatThing); // if it was a thing - restore statnum + + } + + break; + } + } + + // data4 = sprite cstat + if (valueIsBetween(pXSource->data4, -1, 65535)) { + + old = pSprite->cstat; + + // set new cstat + if ((pSource->flags & kModernTypeFlag1)) pSprite->cstat = pSprite->cstat |= pXSource->data4; // relative + else pSprite->cstat = pXSource->data4; // absolute + + // and handle exceptions + if ((old & 0x1000) && !(pSprite->cstat & 0x1000)) pSprite->cstat |= 0x1000; //kSpritePushable + if ((old & 0x80) && !(pSprite->cstat & 0x80)) pSprite->cstat |= 0x80; // kSpriteOriginAlign + + if (old & 0x6000) { + + if (!(pSprite->cstat & 0x6000)) + pSprite->cstat |= 0x6000; // kSpriteMoveMask + + if ((old & 0x0) && !(pSprite->cstat & 0x0)) pSprite->cstat |= 0x0; // kSpriteMoveNone + else if ((old & 0x2000) && !(pSprite->cstat & 0x2000)) pSprite->cstat |= 0x2000; // kSpriteMoveForward, kSpriteMoveFloor + else if ((old & 0x4000) && !(pSprite->cstat & 0x4000)) pSprite->cstat |= 0x4000; // kSpriteMoveReverse, kSpriteMoveCeiling + + } + + } + + break; + } + + // for sectors + case 6: { + + XSECTOR* pXSector = &xsector[sector[objIndex].extra]; + + // data1 = sector underwater status and depth level + if (pXSource->data1 == 0) pXSector->Underwater = false; + else if (pXSource->data1 == 1) pXSector->Underwater = true; + else if (pXSource->data1 > 9) pXSector->Depth = 7; + else if (pXSource->data1 > 1) pXSector->Depth = pXSource->data1 - 2; + + + // data2 = sector visibility + if (valueIsBetween(pXSource->data2, -1, 32767)) { + if (pXSource->data2 > 234) sector[objIndex].visibility = 234; + else sector[objIndex].visibility = pXSource->data2; + } + + // data3 = sector ceil cstat + if (valueIsBetween(pXSource->data3, -1, 32767)) { + if ((pSource->flags & kModernTypeFlag1)) sector[objIndex].ceilingstat = sector[objIndex].ceilingstat |= pXSource->data3; + else sector[objIndex].ceilingstat = pXSource->data3; + } + + // data4 = sector floor cstat + if (valueIsBetween(pXSource->data4, -1, 65535)) { + if ((pSource->flags & kModernTypeFlag1)) sector[objIndex].floorstat = sector[objIndex].floorstat |= pXSource->data4; + else sector[objIndex].floorstat = pXSource->data4; + } + + break; + + } + + // no TX id + case -1: { + + // data2 = global visibility + if (valueIsBetween(pXSource->data2, -1, 32767)) + gVisibility = ClipRange(pXSource->data2, 0, 4096); + } + + break; + } + +} + +void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { + spritetype* pSource = &sprite[pXSource->reference]; + XSECTOR* pXSector = (sector[pSource->sectnum].extra >= 0) ? &xsector[sector[pSource->sectnum].extra] : NULL; + + pSprite->x = pSource->x; pSprite->y = pSource->y; + pSprite->z += (sector[pSource->sectnum].floorz - sector[pSprite->sectnum].floorz); + + if (pSource->flags & kModernTypeFlag1) // force telefrag + TeleFrag(pSprite->xvel, pSource->sectnum); + + changespritesect((short)pSprite->xvel, pSource->sectnum); + 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 (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; + + viewBackupSpriteLoc(pSprite->xvel, pSprite); + + if (pXSource->data4 > 0) + sfxPlay3DSound(pSource, pXSource->data4, -1, 0); + + if (IsPlayerSprite(pSprite)) { + + PLAYER* pPlayer = &gPlayer[pSprite->type - kDudePlayer1]; + playerResetInertia(pPlayer); + + if (pXSource->data2 == 1) + pPlayer->zViewVel = pPlayer->zWeaponVel = 0; + } +} + + +void useEffectGen(XSPRITE * pXSource, spritetype * pSprite) { + if (pSprite == NULL) pSprite = &sprite[pXSource->reference]; + if (pSprite->extra < 0) return; + + int fxId = pXSource->data2 + Random(pXSource->data3); + int pos, top, bottom; GetSpriteExtents(pSprite, &top, &bottom); spritetype* pEffect = NULL; + + // select where exactly effect should be spawned + switch (pXSource->data4) { + case 1: + pos = bottom; // bottom of sprite + break; + default: + pos = top; // top of sprite + break; + } + + if (fxId > 0 && fxId < 57 && (pEffect = gFX.fxSpawn((FX_ID) fxId, pSprite->sectnum, pSprite->x, pSprite->y, pos, 0)) != NULL) { + + if (pEffect->cstat & CSTAT_SPRITE_ONE_SIDED) pEffect->cstat &= ~CSTAT_SPRITE_ONE_SIDED; + + if (pSprite->flags & kModernTypeFlag1) { + pEffect->pal = pSprite->pal; + pEffect->xrepeat = pSprite->xrepeat; + pEffect->yrepeat = pSprite->yrepeat; + pEffect->shade = pSprite->shade; + } + } +} + + +void useSectorWindGen(XSPRITE* pXSource, sectortype* pSector) { + + spritetype* pSource = &sprite[pXSource->reference]; + XSECTOR* pXSector = NULL; bool forceWind = false; + int nXSector = 0; + if (pSector == NULL) { + + if (sector[pSource->sectnum].extra < 0) { + int nXSector = dbInsertXSector(pSource->sectnum); + if (nXSector > 0) pXSector = &xsector[nXSector]; + else return; + + forceWind = true; + + } else { + pXSector = &xsector[sector[pSource->sectnum].extra]; + nXSector = sector[pXSector->reference].extra; + } + + } else { + pXSector = &xsector[pSector->extra]; + nXSector = sector[pXSector->reference].extra; + } + + if (pSource->flags) { + pXSector->panAlways = 1; + pXSector->windAlways = 1; + } else if (forceWind) + pXSector->windAlways = 1; + + if (pXSource->data2 > 32766) pXSource->data2 = 32767; + + if (pXSource->data1 == 1 || pXSource->data1 == 3) pXSector->windVel = Random(pXSource->data2); + else pXSector->windVel = pXSource->data2; + + if (pXSource->data1 == 2 || pXSource->data1 == 3) { + short ang = pSource->ang; + while (pSource->ang == ang) + pSource->ang = Random3(kAng360); + } + + pXSector->windAng = pSource->ang; + + if (pXSource->data3 > 0 && pXSource->data3 < 4) { + switch (pXSource->data3) { + case 1: + pXSector->panFloor = true; + pXSector->panCeiling = false; + break; + case 2: + pXSector->panFloor = false; + pXSector->panCeiling = true; + break; + case 3: + pXSector->panFloor = true; + pXSector->panCeiling = true; + break; + } + + short oldPan = pXSector->panVel; + pXSector->panAngle = pXSector->windAng; + pXSector->panVel = pXSector->windVel; + + // add to panList if panVel was set to 0 previously + if (oldPan == 0 && pXSector->panVel != 0 && panCount < kMaxXSprites) { + + int i; + for (i = 0; i < panCount; i++) { + if (panList[i] != nXSector) continue; + break; + } + + if (i == panCount) + panList[panCount++] = nXSector; + } + + } +} + + + +void useSpriteDamager(XSPRITE* pXSource, spritetype* pSprite) { + spritetype* pSource = &sprite[pXSource->reference]; + if (pSprite != NULL && xspriRangeIsFine(pSprite->extra) && xsprite[pSprite->extra].health > 0) { + DAMAGE_TYPE dmgType = (DAMAGE_TYPE)ClipRange(pXSource->data2, kDmgFall, kDmgElectric); + int dmg = (pXSource->data3 == 0) ? 65535 : ClipRange(pXSource->data3 << 1, 1, 65535); + if (pXSource->data2 >= 0) actDamageSprite(pSource->index, pSprite, dmgType, dmg); + else if (pXSource->data2 == -1 && IsDudeSprite(pSprite)) { + PLAYER* pPlayer = getPlayerById(pSprite->type); + if (pPlayer == NULL || !pPlayer->godMode) { + xsprite[pSprite->extra].health = ClipLow(xsprite[pSprite->extra].health - dmg, 0); + if (xsprite[pSprite->extra].health == 0) { + if (pPlayer == NULL) actKillDude(pSource->index, pSprite, DAMAGE_TYPE_0, 4); + else playerDamageSprite(pSource->index, pPlayer, DAMAGE_TYPE_0, 4); + } + } + } + } +} + +void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) { + if (pXSource->data2 > 0 && !gSysRes.Lookup(pXSource->data2, "SEQ")) { + consoleSysMsg("Missing sequence #%d",pXSource->data2); + return; + } + + switch (objType) { + case 6: + if (pXSource->data2 <= 0) { + if (pXSource->data3 == 3 || pXSource->data3 == 1) + seqKill(2, sector[index].extra); + if (pXSource->data3 == 3 || pXSource->data3 == 2) + seqKill(1, sector[index].extra); + } + else { + if (pXSource->data3 == 3 || pXSource->data3 == 1) + seqSpawn(pXSource->data2, 2, sector[index].extra, -1); + if (pXSource->data3 == 3 || pXSource->data3 == 2) + seqSpawn(pXSource->data2, 1, sector[index].extra, -1); + } + return; + + case 0: + if (pXSource->data2 <= 0) { + if (pXSource->data3 == 3 || pXSource->data3 == 1) + seqKill(0, wall[index].extra); + if ((pXSource->data3 == 3 || pXSource->data3 == 2) && (wall[index].cstat & CSTAT_WALL_MASKED)) + seqKill(4, wall[index].extra); + } + else { + + if (pXSource->data3 == 3 || pXSource->data3 == 1) + seqSpawn(pXSource->data2, 0, wall[index].extra, -1); + if (pXSource->data3 == 3 || pXSource->data3 == 2) { + + if (wall[index].nextwall < 0) { + if (pXSource->data3 == 3) + seqSpawn(pXSource->data2, 0, wall[index].extra, -1); + + } + else { + if (!(wall[index].cstat & CSTAT_WALL_MASKED)) + wall[index].cstat |= CSTAT_WALL_MASKED; + + seqSpawn(pXSource->data2, 4, wall[index].extra, -1); + } + } + + if (pXSource->data4 > 0) { + + int cx, cy, cz; + cx = (wall[index].x + wall[wall[index].point2].x) >> 1; + cy = (wall[index].y + wall[wall[index].point2].y) >> 1; + int nSector = sectorofwall(index); + int32_t ceilZ, floorZ; + getzsofslope(nSector, cx, cy, &ceilZ, &floorZ); + int32_t ceilZ2, floorZ2; + getzsofslope(wall[index].nextsector, cx, cy, &ceilZ2, &floorZ2); + ceilZ = ClipLow(ceilZ, ceilZ2); + floorZ = ClipHigh(floorZ, floorZ2); + cz = (ceilZ + floorZ) >> 1; + + sfxPlay3DSound(cx, cy, cz, pXSource->data4, nSector); + + } + + } + return; + + case 3: + if (pXSource->data2 <= 0) seqKill(3, sprite[index].extra); + else { + seqSpawn(pXSource->data2, 3, sprite[index].extra, -1); + if (pXSource->data4 > 0) sfxPlay3DSound(&sprite[index], pXSource->data4, -1, 0); + } + return; + } +} + bool valueIsBetween(int val, int min, int max) { return (val > min && val < max); } -// By NoOne: this function used by various new modern types. + +char modernTypeSetSpriteState(int nSprite, XSPRITE *pXSprite, int nState) +{ + if ((pXSprite->busy&0xffff) == 0 && pXSprite->state == nState) return 0; + pXSprite->busy = nState<<16; + pXSprite->state = nState; + evKill(nSprite, 3); + if ((sprite[nSprite].flags & kHitagRespawn) != 0 && sprite[nSprite].inittype >= kDudeBase && sprite[nSprite].inittype < kDudeMax) { + pXSprite->respawnPending = 3; + evPost(nSprite, 3, gGameOptions.nMonsterRespawnTime, kCallbackRespawn); + return 1; + } + + if (pXSprite->restState != nState && pXSprite->waitTime > 0) + evPost(nSprite, 3, (pXSprite->waitTime*120) / 10, pXSprite->restState ? kCmdOn : kCmdOff); + + if (pXSprite->txID != 0 && ((pXSprite->triggerOn && pXSprite->state) || (pXSprite->triggerOff && !pXSprite->state))) { + + //Sending new command instead of link is *required*, because types above + //are universal and can paste properties in different objects. + switch (pXSprite->command) { + case kCmdLink: + case kCmdModernUse: + evSend(nSprite, 3, pXSprite->txID, kCmdModernUse); // just send command to change properties + return 1; + case kCmdUnlock: + evSend(nSprite, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command); // send normal command first + evSend(nSprite, 3, pXSprite->txID, kCmdModernUse); // then send command to change properties + return 1; + default: + evSend(nSprite, 3, pXSprite->txID, kCmdModernUse); // send first command to change properties + evSend(nSprite, 3, pXSprite->txID, (COMMAND_ID)pXSprite->command); // then send normal command + return 1; + } + + } + return 1; +} + +// this function used by various new modern types. void pastePropertiesInObj(int type, int nDest, EVENT event) { if (event.type != 3) return; @@ -4007,7 +4057,7 @@ void pastePropertiesInObj(int type, int nDest, EVENT event) { } } -// By NoOne: the following functions required for kModernDudeTargetChanger +// the following functions required for kModernDudeTargetChanger //--------------------------------------- spritetype* getTargetInRange(spritetype* pSprite, int minDist, int maxDist, short data, short teamMode) { DUDEINFO* pDudeInfo = &dudeInfo[pSprite->type - kDudeBase]; XSPRITE* pXSprite = &xsprite[pSprite->extra]; @@ -4138,7 +4188,7 @@ bool dudeCanSeeTarget(XSPRITE* pXDude, DUDEINFO* pDudeInfo, spritetype* pTarget) } -// by NoOne: this function required if monsters in genIdle ai state. It wakes up monsters +// this function required if monsters in genIdle ai state. It wakes up monsters // when kModernDudeTargetChanger goes to off state, so they won't ignore the world. void activateDudes(int rx) { for (int i = bucketHead[rx]; i < bucketHead[rx + 1]; i++) { @@ -4150,7 +4200,7 @@ void activateDudes(int rx) { } -// by NoOne: this function sets target to -1 for all dudes that hunting for nSprite +// this function sets target to -1 for all dudes that hunting for nSprite void freeTargets(int nSprite) { for (int nTarget = headspritestat[kStatDude]; nTarget >= 0; nTarget = nextspritestat[nTarget]) { if (!IsDudeSprite(&sprite[nTarget]) || sprite[nTarget].extra < 0) continue; @@ -4161,7 +4211,7 @@ void freeTargets(int nSprite) { return; } -// by NoOne: this function sets target to -1 for all targets that hunting for dudes affected by selected kModernDudeTargetChanger +// this function sets target to -1 for all targets that hunting for dudes affected by selected kModernDudeTargetChanger void freeAllTargets(XSPRITE* pXSource) { if (pXSource->txID <= 0) return; for (int i = bucketHead[pXSource->txID]; i < bucketHead[pXSource->txID + 1]; i++) { @@ -4293,7 +4343,7 @@ bool setDataValueOfObject(int objType, int objIndex, int dataIndex, int value) { } } -// by NoOne: this function checks if all TX objects have the same value +// this function checks if all TX objects have the same value bool goalValueIsReached(XSPRITE* pXSprite) { for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) { if (getDataFieldOfObject(rxBucket[i].type, rxBucket[i].index, pXSprite->data1) != pXSprite->data3) @@ -4302,7 +4352,7 @@ bool goalValueIsReached(XSPRITE* pXSprite) { return true; } -// by NoOne: this function tells if there any dude found for kModernDudeTargetChanger +// this function tells if there any dude found for kModernDudeTargetChanger bool getDudesForTargetChg(XSPRITE* pXSprite) { for (int i = bucketHead[pXSprite->txID]; i < bucketHead[pXSprite->txID + 1]; i++) { if (rxBucket[i].type != 3) continue; @@ -4451,7 +4501,62 @@ bool isMeleeUnit(spritetype* pDude) { return false; } } + +// Callback for trap that can fire any missile specified in data1 +void UniMissileTrapSeqCallback(int, int nXSprite) +{ + + XSPRITE* pXSprite = &xsprite[nXSprite]; int dx = 0, dy = 0, dz = 0; + spritetype* pSprite = &sprite[pXSprite->reference]; + + if (pXSprite->data1 < kMissileBase || pXSprite->data1 >= kMissileMax) + return; + + if (pSprite->cstat & 32) { + if (pSprite->cstat & 8) dz = 0x4000; + else dz = -0x4000; + } else { + dx = Cos(pSprite->ang) >> 16; + dy = Sin(pSprite->ang) >> 16; + dz = pXSprite->data3 << 6; // add slope controlling + if (dz > 0x10000) dz = 0x10000; + else if (dz < -0x10000) dz = -0x10000; + } + + spritetype* pMissile = NULL; + pMissile = actFireMissile(pSprite, 0, 0, dx, dy, dz, pXSprite->data1); + if (pMissile != NULL) { + + // inherit some properties of the generator + if (pSprite->flags & kModernTypeFlag1) { + + pMissile->xrepeat = pSprite->xrepeat; + pMissile->yrepeat = pSprite->yrepeat; + + pMissile->pal = pSprite->pal; + pMissile->shade = pSprite->shade; + + } + + // add velocity controlling + if (pXSprite->data2 > 0) { + + int velocity = pXSprite->data2 << 12; + xvel[pMissile->xvel] = mulscale(velocity, dx, 14); + yvel[pMissile->xvel] = mulscale(velocity, dy, 14); + zvel[pMissile->xvel] = mulscale(velocity, dz, 14); + + } + + // add bursting for missiles + if (pMissile->type != kMissileFlareAlt && pXSprite->data4 > 0) + evPost(pMissile->xvel, 3, (pXSprite->data4 > 500) ? 500 : pXSprite->data4 - 1, kCallbackMissileBurst); + + } + +} //--------------------------------------- +#endif void ProcessMotion(void) { @@ -4634,8 +4739,11 @@ void trInit(void) switch (pSector->type) { case kSectorCounter: - //By NoOne: no need to trigger once it, instead lock so it can be unlocked and used again. - if (!gModernMap) pXSector->triggerOnce = 1; + // no need to trigger once it, instead lock so it can be unlocked and used again. + #ifdef NOONE_EXTENSIONS + if (!gModernMap) + #endif + pXSector->triggerOnce = 1; evPost(i, 6, 0, kCallbackCounterCheck); break; case kSectorZMotion: @@ -4704,6 +4812,7 @@ void trInit(void) case kSwitchPadlock: pXSprite->triggerOnce = 1; break; + #ifdef NOONE_EXTENSIONS case kModernRandom: case kModernRandom2: case kModernSeqSpawner: @@ -4711,11 +4820,12 @@ void trInit(void) case kModernDudeTargetChanger: case kModernEffectSpawner: case kModernWindGenerator: + case kGenModernMissileUniversal: + #endif case kGenTrigger: case kGenDripWater: case kGenDripBlood: case kGenMissileFireball: - case kGenModernMissileUniversal: case kGenDart: case kGenBubble: case kGenBubbleMulti: @@ -4723,7 +4833,9 @@ void trInit(void) InitGenerator(i); break; case kThingArmedProxBomb: + #ifdef NOONE_EXTENSIONS case kModernThingTNTProx: + #endif pXSprite->Proximity = 1; break; case kThingFallingRock: @@ -4767,7 +4879,8 @@ void InitGenerator(int nSprite) dassert(nXSprite > 0); XSPRITE *pXSprite = &xsprite[nXSprite]; switch (sprite[nSprite].type) { - // By NoOne: intialize modern generators + #ifdef NOONE_EXTENSIONS + // intialize modern generators case kModernRandom: case kModernRandom2: pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; @@ -4798,6 +4911,7 @@ void InitGenerator(int nSprite) if (pXSprite->state != pXSprite->restState) evPost(nSprite, 3, 0, kCmdRepeat); return; + #endif case kGenTrigger: pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; pSprite->cstat |= CSTAT_SPRITE_INVISIBLE; @@ -4816,37 +4930,39 @@ void ActivateGenerator(int nSprite) dassert(nXSprite > 0); XSPRITE *pXSprite = &xsprite[nXSprite]; switch (pSprite->type) { - case kModernRandom: - case kModernRandom2: { - // let's first search for previously dropped items and remove it - if (pXSprite->dropMsg > 0) { - for (short nItem = headspritestat[kStatItem]; nItem >= 0; nItem = nextspritestat[nItem]) { - spritetype* pItem = &sprite[nItem]; - if ((unsigned int)pItem->type == pXSprite->dropMsg && pItem->x == pSprite->x && pItem->y == pSprite->y && pItem->z == pSprite->z) { - gFX.fxSpawn((FX_ID)29, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0); - deletesprite(nItem); - break; + #ifdef NOONE_EXTENSIONS + case kModernRandom: + case kModernRandom2: { + // let's first search for previously dropped items and remove it + if (pXSprite->dropMsg > 0) { + for (short nItem = headspritestat[kStatItem]; nItem >= 0; nItem = nextspritestat[nItem]) { + spritetype* pItem = &sprite[nItem]; + if ((unsigned int)pItem->type == pXSprite->dropMsg && pItem->x == pSprite->x && pItem->y == pSprite->y && pItem->z == pSprite->z) { + gFX.fxSpawn((FX_ID)29, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, 0); + deletesprite(nItem); + break; + } } } - } - // then drop item - spritetype* pDrop = DropRandomPickupObject(pSprite, pXSprite->dropMsg); + // then drop item + spritetype* pDrop = DropRandomPickupObject(pSprite, pXSprite->dropMsg); - // check if generator affected by physics - if (pDrop != NULL && isDebris(pSprite->xvel) != -1 && (pDrop->extra >= 0 || dbInsertXSprite(pDrop->xvel) > 0)) { - int nIndex = debrisGetFreeIndex(); - if (nIndex >= 0) { - xsprite[pDrop->extra].physAttr |= kPhysMove | kPhysGravity | kPhysFalling; // must fall always - pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; + // check if generator affected by physics + if (pDrop != NULL && isDebris(pSprite->xvel) != -1 && (pDrop->extra >= 0 || dbInsertXSprite(pDrop->xvel) > 0)) { + int nIndex = debrisGetFreeIndex(); + if (nIndex >= 0) { + xsprite[pDrop->extra].physAttr |= kPhysMove | kPhysGravity | kPhysFalling; // must fall always + pSprite->cstat &= ~CSTAT_SPRITE_BLOCK; - gPhysSpritesList[nIndex] = pDrop->xvel; - if (nIndex >= gPhysSpritesCount) gPhysSpritesCount++; - getSpriteMassBySize(pDrop); // create mass cache + gPhysSpritesList[nIndex] = pDrop->xvel; + if (nIndex >= gPhysSpritesCount) gPhysSpritesCount++; + getSpriteMassBySize(pDrop); // create mass cache + } } + break; } - break; - } + #endif case kGenDripWater: case kGenDripBlood: { int top, bottom; @@ -4855,12 +4971,17 @@ void ActivateGenerator(int nSprite) break; } case kGenSound: { - // By NoOne: allow custom pitch and volume for sounds in SFX gen. - if (!gModernMap) sfxPlay3DSound(pSprite, pXSprite->data2, -1, 0); - else { - int pitch = pXSprite->data4 << 1; if (pitch < 2000) pitch = 0; - sfxPlay3DSoundCP(pSprite, pXSprite->data2, -1, 0, pitch, pXSprite->data3); - } + // allow custom pitch and volume for sounds in SFX gen. + #ifdef NOONE_EXTENSIONS + if (!gModernMap) sfxPlay3DSound(pSprite, pXSprite->data2, -1, 0); + else { + int pitch = pXSprite->data4 << 1; if (pitch < 2000) pitch = 0; + sfxPlay3DSoundCP(pSprite, pXSprite->data2, -1, 0, pitch, pXSprite->data3); + } + #else + sfxPlay3DSound(pSprite, pXSprite->data2, -1, 0); + #endif + break; } case kGenMissileFireball: @@ -4876,10 +4997,12 @@ void ActivateGenerator(int nSprite) break; } break; - // By NoOne: EctoSkull gen can now fire any missile - case kGenModernMissileUniversal: - if (gModernMap) UniMissileTrapSeqCallback(3, nXSprite); - break; + #ifdef NOONE_EXTENSIONS + // kGenEctoSkull gen can now fire any missile + case kGenModernMissileUniversal: + if (gModernMap) UniMissileTrapSeqCallback(3, nXSprite); + break; + #endif case kGenBubble: case kGenBubbleMulti: { int top, bottom; @@ -4901,59 +5024,6 @@ void FireballTrapSeqCallback(int, int nXSprite) actFireMissile(pSprite, 0, 0, Cos(pSprite->ang)>>16, Sin(pSprite->ang)>>16, 0, kMissileFireball); } -// By NoOne: Callback for trap that can fire any missile specified in data1 -void UniMissileTrapSeqCallback(int, int nXSprite) -{ - - XSPRITE* pXSprite = &xsprite[nXSprite]; int dx = 0, dy = 0, dz = 0; - spritetype* pSprite = &sprite[pXSprite->reference]; - - if (pXSprite->data1 < kMissileBase || pXSprite->data1 >= kMissileMax) - return; - - if (pSprite->cstat & 32) { - if (pSprite->cstat & 8) dz = 0x4000; - else dz = -0x4000; - } else { - dx = Cos(pSprite->ang) >> 16; - dy = Sin(pSprite->ang) >> 16; - dz = pXSprite->data3 << 6; // add slope controlling - if (dz > 0x10000) dz = 0x10000; - else if (dz < -0x10000) dz = -0x10000; - } - - spritetype* pMissile = NULL; - pMissile = actFireMissile(pSprite, 0, 0, dx, dy, dz, pXSprite->data1); - if (pMissile != NULL) { - - // inherit some properties of the generator - if (pSprite->flags & kModernTypeFlag1) { - - pMissile->xrepeat = pSprite->xrepeat; - pMissile->yrepeat = pSprite->yrepeat; - - pMissile->pal = pSprite->pal; - pMissile->shade = pSprite->shade; - - } - - // add velocity controlling - if (pXSprite->data2 > 0) { - - int velocity = pXSprite->data2 << 12; - xvel[pMissile->xvel] = mulscale(velocity, dx, 14); - yvel[pMissile->xvel] = mulscale(velocity, dy, 14); - zvel[pMissile->xvel] = mulscale(velocity, dz, 14); - - } - - // add bursting for missiles - if (pMissile->type != kMissileFlareAlt && pXSprite->data4 > 0) - evPost(pMissile->xvel, 3, (pXSprite->data4 > 500) ? 500 : pXSprite->data4 - 1, kCallbackMissileBurst); - - } - -} void MGunFireSeqCallback(int, int nXSprite) { diff --git a/source/blood/src/triggers.h b/source/blood/src/triggers.h index 9a759e8d8..27970058b 100644 --- a/source/blood/src/triggers.h +++ b/source/blood/src/triggers.h @@ -32,9 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "player.h" BEGIN_BLD_NS -#define kPlayerCtrlSigStart "<<<>>>" // save game TRPLAYERCTRL block end - void trTriggerSector(unsigned int nSector, XSECTOR *pXSector, int command); void trMessageSector(unsigned int nSector, EVENT event); void trTriggerWall(unsigned int nWall, XWALL *pXWall, int command); @@ -45,8 +42,12 @@ void trProcessBusy(void); void trInit(void); void trTextOver(int nId); -// By NoOne: functions required for new features +#ifdef NOONE_EXTENSIONS +// functions required for new features // ------------------------------------------------------- +#define kPlayerCtrlSigStart "<<<>>>" // save game TRPLAYERCTRL block end + void pastePropertiesInObj(int type, int nDest, EVENT event); spritetype* getTargetInRange(spritetype* pSprite, int minDist, int maxDist, short data, short teamMode); 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 trPlayerCtrlStartScene(XSPRITE* pXSource, PLAYER* pPlayer); void trPlayerCtrlStopScene(XSPRITE* pXSource, PLAYER* pPlayer); +char modernTypeSetSpriteState(int nSprite, XSPRITE* pXSprite, int nState); // ------------------------------------------------------- +#endif// ------------------------------------------------------- END_BLD_NS diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 49203d495..78d431304 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -3498,12 +3498,17 @@ void viewDrawScreen(bool sceneonly) nPalette = pSector->floorpal; } + #ifdef NOONE_EXTENSIONS if (gView->sceneQav < 0) WeaponDraw(gView, nShade, cX, cY, nPalette); else if (gView->pXSprite->health > 0) qavSceneDraw(gView, nShade, cX, cY, nPalette); else { gView->sceneQav = gView->weaponQav = -1; gView->weaponTimer = gView->curWeapon = 0; } + #else + WeaponDraw(gView, nShade, cX, cY, nPalette); + #endif + } diff --git a/source/blood/src/warp.cpp b/source/blood/src/warp.cpp index 5707d89ee..97bbf781b 100644 --- a/source/blood/src/warp.cpp +++ b/source/blood/src/warp.cpp @@ -36,11 +36,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS ZONE gStartZone[8]; -ZONE gStartZoneTeam1[8]; -ZONE gStartZoneTeam2[8]; - -bool gTeamsSpawnUsed = false; - +#ifdef NOONE_EXTENSIONS + ZONE gStartZoneTeam1[8]; + ZONE gStartZoneTeam2[8]; + bool gTeamsSpawnUsed = false; +#endif void warpInit(void) { for (int i = 0; i < kMaxSectors; i++) @@ -48,7 +48,9 @@ void warpInit(void) gUpperLink[i] = -1; gLowerLink[i] = -1; } + #ifdef NOONE_EXTENSIONS int team1 = 0; int team2 = 0; gTeamsSpawnUsed = false; // increment if team start positions specified. + #endif for (int nSprite = 0; nSprite < kMaxSprites; nSprite++) { if (sprite[nSprite].statnum < kMaxStatus) { @@ -79,27 +81,30 @@ void warpInit(void) pZone->sectnum = pSprite->sectnum; pZone->ang = pSprite->ang; - // By NoOne: fill player spawn position according team of player in TEAMS mode. - if (gModernMap && gGameOptions.nGameType == 3) { - if (pXSprite->data2 == 1) { - pZone = &gStartZoneTeam1[team1]; - pZone->x = pSprite->x; - pZone->y = pSprite->y; - pZone->z = pSprite->z; - pZone->sectnum = pSprite->sectnum; - pZone->ang = pSprite->ang; - team1++; + #ifdef NOONE_EXTENSIONS + // fill player spawn position according team of player in TEAMS mode. + if (gModernMap && gGameOptions.nGameType == 3) { + if (pXSprite->data2 == 1) { + pZone = &gStartZoneTeam1[team1]; + pZone->x = pSprite->x; + pZone->y = pSprite->y; + pZone->z = pSprite->z; + pZone->sectnum = pSprite->sectnum; + pZone->ang = pSprite->ang; + team1++; - } else if (pXSprite->data2 == 2) { - pZone = &gStartZoneTeam2[team2]; - pZone->x = pSprite->x; - pZone->y = pSprite->y; - pZone->z = pSprite->z; - pZone->sectnum = pSprite->sectnum; - pZone->ang = pSprite->ang; - team2++; + } else if (pXSprite->data2 == 2) { + pZone = &gStartZoneTeam2[team2]; + pZone->x = pSprite->x; + pZone->y = pSprite->y; + pZone->z = pSprite->z; + pZone->sectnum = pSprite->sectnum; + pZone->ang = pSprite->ang; + team2++; + } } - } + #endif + } DeleteSprite(nSprite); } @@ -135,6 +140,7 @@ void warpInit(void) } } + #ifdef NOONE_EXTENSIONS // check if there is enough start positions for teams, if any used if (team1 > 0 || team2 > 0) { gTeamsSpawnUsed = true; @@ -143,6 +149,7 @@ void warpInit(void) viewSetSystemMessage("Team A positions: %d, Team B positions: %d.", team1, team2); } } + #endif for (int i = 0; i < kMaxSectors; i++) { diff --git a/source/blood/src/warp.h b/source/blood/src/warp.h index 9ab794141..f06a41fa8 100644 --- a/source/blood/src/warp.h +++ b/source/blood/src/warp.h @@ -30,9 +30,11 @@ struct ZONE { short sectnum, ang; }; extern ZONE gStartZone[8]; +#ifdef NOONE_EXTENSIONS extern ZONE gStartZoneTeam1[8]; extern ZONE gStartZoneTeam2[8]; extern bool gTeamsSpawnUsed; +#endif void warpInit(void); int CheckLink(spritetype *pSprite); diff --git a/source/blood/src/weapon.cpp b/source/blood/src/weapon.cpp index 0400b24ea..b0cd69514 100644 --- a/source/blood/src/weapon.cpp +++ b/source/blood/src/weapon.cpp @@ -1936,7 +1936,7 @@ char sub_4F484(PLAYER *pPlayer) void WeaponProcess(PLAYER *pPlayer) { pPlayer->flashEffect = ClipLow(pPlayer->flashEffect - 1, 0); - + #ifdef NOONE_EXTENSIONS if (gPlayerCtrl[pPlayer->nPlayer].qavScene.index >= 0 && pPlayer->pXSprite->health > 0) { QAVSCENE* pQavScene = &gPlayerCtrl[pPlayer->nPlayer].qavScene; @@ -1960,6 +1960,7 @@ void WeaponProcess(PLAYER *pPlayer) { return; } + #endif if (pPlayer->pXSprite->health == 0) {