diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index e65a227b6..9dc4950ce 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -121,6 +121,8 @@ enum GAMEFLAG_PSEXHUMED = GAMEFLAG_POWERSLAVE | GAMEFLAG_EXHUMED, // the two games really are the same, except for the name and the publisher. GAMEFLAG_WORLDTOUR = 0x00008000, GAMEFLAG_DUKEDC = 0x00010000, + GAMEGLAG_WH = 0x00020000, + GAMEFLAG_WH2 = 0x00040000, GAMEFLAGMASK = 0x0000FFFF, // flags allowed from grpinfo // We still need these for the parsers. @@ -202,6 +204,11 @@ inline bool isShareware() return g_gameType & GAMEFLAG_SHAREWARE; } +inline bool isWh2() +{ + return g_gameType & GAMEFLAG_WH2; +} + TArray GrpScan(); void S_PauseSound(bool notmusic, bool notsfx); void S_ResumeSound(bool notsfx); diff --git a/source/games/whaven/CMakeLists.txt b/source/games/whaven/CMakeLists.txt index 90b0f9d23..cd1bb3b69 100644 --- a/source/games/whaven/CMakeLists.txt +++ b/source/games/whaven/CMakeLists.txt @@ -23,7 +23,19 @@ set( PCH_SOURCES src/aiskully.cpp src/aispider.cpp src/aiwillow.cpp + src/items.cpp src/names.cpp + src/potions.cpp + src/sndnames.cpp + src/spellbooks.cpp + src/weapons.cpp + src/wepdata.cpp + src/whani.cpp + src/whfx.cpp + src/whmap.cpp + src/whobj.cpp + src/whplr.cpp + src/whtag.cpp ) add_game_library2( whaven ) diff --git a/source/games/whaven/src/ai.cpp b/source/games/whaven/src/ai.cpp index cc1221c25..f108f2d59 100644 --- a/source/games/whaven/src/ai.cpp +++ b/source/games/whaven/src/ai.cpp @@ -35,30 +35,6 @@ void createSkullyAI(); void createSpiderAI(); void createWillowAI(); -void premapDemon(short i); -void premapDevil(short i); -void premapDragon(short i); -void premapFatwitch(short i); -void premapFish(short i); -void premapFred(short i); -void premapGoblin(short i); -void premapGonzo(short i); -void premapGron(short i); -void premapGuardian(short i); -void premapImp(short i); -void premapJudy(short i); -void premapKatie(short i); -void premapKobold(short i); -void premapKurt(short i); -void premapMinotaur(short i); -void premapNewGuy(short i); -void premapRat(short i); -void premapSkeleton(short i); -void premapSkully(short i); -void premapSpider(short i); -void premapWillow(short i); - - void initAI() { @@ -75,7 +51,7 @@ void initAI() * PATROL */ - if (game.WH2) + if (isWh2()) createImpAI(); else createGoblinAI(); @@ -123,7 +99,7 @@ static void aiInit() { killcnt++; } else if (pic == RAT) { - .premapRat(i); + premapRat(i); } else if (pic == FISH) { premapFish(i); @@ -137,12 +113,12 @@ static void aiInit() { case GOBLINSTAND: case GOBLINCHILL: killcnt++; - if (game.WH2 && spr.picnum == IMP) { + if (isWh2() && spr.picnum == IMP) { premapImp(i); break; } - if (!game.WH2) + if (!isWh2()) premapGoblin(i); break; case DEVIL: @@ -251,7 +227,7 @@ void aiProcess() { for (i = headspritestat[PATROL]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; short movestat = (short)movesprite((short)i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 3, ((sintable[spr.ang]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); if (zr_florz > spr.z + (48 << 8)) { @@ -293,14 +269,14 @@ void aiProcess() { for (i = headspritestat[CHASE]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].chase != null) enemy[spr.detail].chase.process(plr, i); } for (i = headspritestat[RESURECT]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].resurect != null) { enemy[spr.detail].resurect.process(plr, i); } @@ -308,7 +284,7 @@ void aiProcess() { for (i = headspritestat[FINDME]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].search != null) enemy[spr.detail].search.process(plr, i); @@ -316,7 +292,7 @@ void aiProcess() { for (i = headspritestat[NUKED]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (spr.picnum == ZFIRE) { spr.lotag -= TICSPERFRAME; @@ -331,14 +307,14 @@ void aiProcess() { for (i = headspritestat[FROZEN]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].frozen != null) enemy[spr.detail].frozen.process(plr, i); } for (i = headspritestat[PAIN]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].pain != null) enemy[spr.detail].pain.process(plr, i); @@ -346,7 +322,7 @@ void aiProcess() { for (i = headspritestat[FACE]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].face != null) enemy[spr.detail].face.process(plr, i); @@ -354,9 +330,9 @@ void aiProcess() { for (i = headspritestat[ATTACK]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; - if (game.WH2 && attacktheme == 0) { + if (isWh2() && attacktheme == 0) { attacktheme = 1; startsong((rand() % 2) + 2); } @@ -367,7 +343,7 @@ void aiProcess() { for (i = headspritestat[FLEE]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].flee != null) enemy[spr.detail].flee.process(plr, i); @@ -375,7 +351,7 @@ void aiProcess() { for (i = headspritestat[CAST]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].cast != null) enemy[spr.detail].cast.process(plr, i); @@ -383,14 +359,14 @@ void aiProcess() { for (i = headspritestat[DIE]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].die != null) enemy[spr.detail].die.process(plr, i); } for (i = headspritestat[SKIRMISH]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].skirmish != null) enemy[spr.detail].skirmish.process(plr, i); @@ -398,7 +374,7 @@ void aiProcess() { for (i = headspritestat[STAND]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (enemy[spr.detail] != null && enemy[spr.detail].stand != null) enemy[spr.detail].stand.process(plr, i); @@ -406,7 +382,7 @@ void aiProcess() { for (i = headspritestat[CHILL]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; switch (spr.detail) { case GOBLINTYPE: goblinChill(plr, i); @@ -419,7 +395,7 @@ void aiProcess() { for (i = headspritestat[DEAD]; i >= 0; i = nextsprite) { nextsprite = nextspritestat[i]; - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0); switch (checkfluid(i, zr_florhit)) { @@ -449,7 +425,7 @@ int aimove(short i) { setsprite(i, ox, oy, oz); if ((movestate & kHitTypeMask) != kHitWall) { - if (game.WH2) + if (isWh2()) sprite[i].z += WH2GRAVITYCONSTANT; else sprite[i].z += GRAVITYCONSTANT; @@ -463,7 +439,7 @@ int aimove(short i) { } int aifly(short i) { - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; int movestate = movesprite(i, ((sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, ((sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, CLIFFCLIP); @@ -481,7 +457,7 @@ int aifly(short i) { } void aisearch(PLAYER& plr, short i, boolean fly) { - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; spr.lotag -= TICSPERFRAME; // if (plr.invisibletime > 0) { @@ -542,7 +518,7 @@ void aisearch(PLAYER& plr, short i, boolean fly) { } boolean checksector6(short i) { - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (sector[spr.sectnum].floorz - (32 << 8) < sector[spr.sectnum].ceilingz) { if (sector[spr.sectnum].lotag == 6) newstatus(i, DIE); @@ -556,7 +532,7 @@ boolean checksector6(short i) { } int checkfluid(int i, int zr_florhit) { - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; if (isValidSector(spr.sectnum) && (zr_florhit & kHitTypeMask) == kHitSector && (sector[spr.sectnum].floorpicnum == WATER /* || sector[spr.sectnum].floorpicnum == LAVA2 */ || sector[spr.sectnum].floorpicnum == LAVA || sector[spr.sectnum].floorpicnum == SLIME || sector[spr.sectnum].floorpicnum == FLOORMIRROR @@ -577,7 +553,7 @@ int checkfluid(int i, int zr_florhit) { } void processfluid(int i, int zr_florhit, boolean fly) { - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; switch (checkfluid(i, zr_florhit)) { case TYPELAVA: if (!fly) { @@ -601,7 +577,7 @@ void castspell(PLAYER& plr, int i) { sprite[j].x = sprite[i].x; sprite[j].y = sprite[i].y; - if (game.WH2 || sprite[i].picnum == SPAWNFIREBALL) + if (isWh2() || sprite[i].picnum == SPAWNFIREBALL) sprite[j].z = sprite[i].z - ((tilesizy[sprite[i].picnum] >> 1) << 8); else sprite[j].z = getflorzofslope(sprite[i].sectnum, sprite[i].x, sprite[i].y) - ((tilesizy[sprite[i].picnum] >> 1) << 8); @@ -621,7 +597,7 @@ void castspell(PLAYER& plr, int i) { int discrim = ksqrt((plr.x - sprite[j].x) * (plr.x - sprite[j].x) + (plr.y - sprite[j].y) * (plr.y - sprite[j].y)); if (discrim == 0) discrim = 1; - if (game.WH2) + if (isWh2()) sprite[j].zvel = (short)(((plr.z + (8 << 8) - sprite[j].z) << 7) / discrim); else sprite[j].zvel = (short)(((plr.z + (48 << 8) - sprite[j].z) << 7) / discrim); @@ -703,7 +679,7 @@ void attack(PLAYER& plr, int i) { } int k = 5; - if (!game.WH2) { + if (!isWh2()) { k = krand() % 100; if (k > (plr.armortype << 3)) k = 15; @@ -726,7 +702,7 @@ void attack(PLAYER& plr, int i) { if ((krand() % 2) != 0) playsound_loc(S_BREATH1 + (krand() % 6), sprite[i].x, sprite[i].y); - if (game.WH2) + if (isWh2()) k = (krand() % 5) + 5; else k >>= 2; @@ -738,7 +714,7 @@ void attack(PLAYER& plr, int i) { case DEVILTYPE: playsound_loc(S_DEMONTHROW, sprite[i].x, sprite[i].y); - if (!game.WH2) + if (!isWh2()) k >>= 2; break; @@ -748,7 +724,7 @@ void attack(PLAYER& plr, int i) { playsound_loc(S_KOBOLDHIT, plr.x, plr.y); playsound_loc(S_BREATH1 + (krand() % 6), plr.x, plr.y); } - if (game.WH2) + if (isWh2()) k = (krand() % 5) + 5; else k >>= 2; @@ -763,7 +739,7 @@ void attack(PLAYER& plr, int i) { k >>= 3; break; case IMPTYPE: - if (!game.WH2) + if (!isWh2()) break; playsound_loc(S_RIP1 + (krand() % 3), sprite[i].x, sprite[i].y); if ((krand() % 2) != 0) { @@ -779,7 +755,7 @@ void attack(PLAYER& plr, int i) { } break; case GOBLINTYPE: - if (game.WH2) + if (isWh2()) break; playsound_loc(S_GENSWING, sprite[i].x, sprite[i].y); @@ -836,7 +812,7 @@ void attack(PLAYER& plr, int i) { if (sprite[i].picnum != GRONSWATTACK) break; - if (game.WH2) { + if (isWh2()) { k = (krand() % 20) + 5; if (sprite[i].shade > 30) { k += krand() % 10; @@ -855,7 +831,7 @@ void attack(PLAYER& plr, int i) { playsound_loc(S_GENSWING, sprite[i].x, sprite[i].y); if (krand() % 10 > 4) playsound_loc(S_SWORD1 + (krand() % 6), sprite[i].x, sprite[i].y); - if (game.WH2) + if (isWh2()) k = (krand() % 25) + 5; break; } @@ -938,7 +914,7 @@ boolean checkdist(PLAYER& plr, int i) { } boolean checkdist(int i, int x, int y, int z) { - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; int attackdist = 512; int attackheight = 120; @@ -1032,7 +1008,7 @@ void monsterweapon(int i) { case MINOTAURDEAD: weap.xrepeat = 25; weap.yrepeat = 20; - if (!game.WH2) { + if (!isWh2()) { if (krand() % 100 > 50) { weap.picnum = WEAPON4; } @@ -1193,7 +1169,7 @@ PLAYER& aiGetPlayerTarget(short i) { } boolean actoruse(short i) { - SPRITE spr = sprite[i]; + SPRITE& spr = sprite[i]; neartag(spr.x, spr.y, spr.z, spr.sectnum, spr.ang, neartag, 1024, 3); diff --git a/source/games/whaven/src/ai.h b/source/games/whaven/src/ai.h index 33dc5635c..07b17b7a4 100644 --- a/source/games/whaven/src/ai.h +++ b/source/games/whaven/src/ai.h @@ -115,6 +115,7 @@ enum EAIConst }; extern Enemy enemy[MAXTYPES]; +extern int checksight_ang; void aiProcess(); int aimove(short i); @@ -135,6 +136,32 @@ void monsterweapon(int i); PLAYER& aiGetPlayerTarget(short i); boolean actoruse(short i); +void initAI(); + +void premapDemon(short i); +void premapDevil(short i); +void premapDragon(short i); +void premapFatwitch(short i); +void premapFish(short i); +void premapFred(short i); +void premapGoblin(short i); +void premapGonzo(short i); +void premapGron(short i); +void premapGuardian(short i); +void premapImp(short i); +void premapJudy(short i); +void premapKatie(short i); +void premapKobold(short i); +void premapKurt(short i); +void premapMinotaur(short i); +void premapNewGuy(short i); +void premapRat(short i); +void premapSkeleton(short i); +void premapSkully(short i); +void premapSpider(short i); +void premapWillow(short i); + + inline int findplayer() { return 0; // no multiplayer support, apparently... } diff --git a/source/games/whaven/src/aidevil.cpp b/source/games/whaven/src/aidevil.cpp index 1f7c93521..b5fbabf50 100644 --- a/source/games/whaven/src/aidevil.cpp +++ b/source/games/whaven/src/aidevil.cpp @@ -215,7 +215,7 @@ static void frozen(PLAYER& plr, short i) { static void nuked(PLAYER& plr, short i) { SPRITE& spr = sprite[i]; - if (game.WH2) { + if (isWh2()) { chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang); trailingsmoke(i, false); newstatus((short)i, DIE); @@ -254,7 +254,7 @@ static void cast(PLAYER& plr, short i) { void createDevilAI() { auto &e = enemy[DEVILTYPE]; - e.info.Init(game.WH2 ? 50 : 36, game.WH2 ? 50 : 36, 2048, 120, 0, 64, false, 50, 0); + e.info.Init(isWh2() ? 50 : 36, isWh2() ? 50 : 36, 2048, 120, 0, 64, false, 50, 0); e.chase = chase; e.die = die; e.pain = pain; diff --git a/source/games/whaven/src/aigron.cpp b/source/games/whaven/src/aigron.cpp index 7ad1f5f24..3d3b2b945 100644 --- a/source/games/whaven/src/aigron.cpp +++ b/source/games/whaven/src/aigron.cpp @@ -181,7 +181,7 @@ static void search(PLAYER& plr, short i) { static void nuked(PLAYER& plr, short i) { SPRITE& spr = sprite[i]; - if (game.WH2) { + if (isWh2()) { chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang); trailingsmoke(i, false); newstatus((short)i, DIE); @@ -467,7 +467,7 @@ static void throwhalberd(int s) { void createGronAI() { auto& e = enemy[GRONTYPE]; - e.info.Init(game.WH2 ? 35 : 30, game.WH2 ? 35 : 30, -1, 120, 0, 64, false, 300, 0); + e.info.Init(isWh2() ? 35 : 30, isWh2() ? 35 : 30, -1, 120, 0, 64, false, 300, 0); e.info.getAttackDist = [](EnemyInfo& e, SPRITE& spr) { int out = e.attackdist; @@ -485,7 +485,7 @@ void createGronAI() { e.info.getHealth = [](EnemyInfo& e, SPRITE& spr) { - if (game.WH2) { + if (isWh2()) { if (spr.picnum == GRONHAL) return adjusthp(65); if (spr.picnum == GRONMU) diff --git a/source/games/whaven/src/aiguardian.cpp b/source/games/whaven/src/aiguardian.cpp index 966de1c67..0a6380b15 100644 --- a/source/games/whaven/src/aiguardian.cpp +++ b/source/games/whaven/src/aiguardian.cpp @@ -73,7 +73,7 @@ static void chase(PLAYER& plr, short i) { static void nuked(PLAYER& plr, short i) { SPRITE& spr = sprite[i]; - if (game.WH2) { + if (isWh2()) { chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang); trailingsmoke(i, false); newstatus((short)i, DIE); @@ -227,7 +227,7 @@ static void cast(PLAYER& plr, short i) { void createGuardianAI() { auto& e = enemy[GUARDIANTYPE]; - e.info.Init(game.WH2 ? 35 : 32, game.WH2 ? 35 : 32, 4096, 120, 0, 64, true, game.WH2 ? 100 : 200, 0); + e.info.Init(isWh2() ? 35 : 32, isWh2() ? 35 : 32, 4096, 120, 0, 64, true, isWh2() ? 100 : 200, 0); e.chase = chase; e.nuked = nuked; e.attack = attack; diff --git a/source/games/whaven/src/aikobold.cpp b/source/games/whaven/src/aikobold.cpp index 9edb5889f..5db03361b 100644 --- a/source/games/whaven/src/aikobold.cpp +++ b/source/games/whaven/src/aikobold.cpp @@ -263,7 +263,7 @@ static void frozen(PLAYER& plr, short i) { static void nuked(PLAYER& plr, short i) { SPRITE& spr = sprite[i]; - if (game.WH2) { + if (isWh2()) { chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang); trailingsmoke(i, false); newstatus((short)i, DIE); @@ -333,7 +333,7 @@ static void checkexpl(PLAYER& plr, short i) { void createKoboldAI() { auto& e = enemy[KOBOLDTYPE]; - e.info.Init(game.WH2 ? 60 : 54, game.WH2 ? 60 : 54, 1024, 120, 0, 64, false, 20, 0); + e.info.Init(isWh2() ? 60 : 54, isWh2() ? 60 : 54, 1024, 120, 0, 64, false, 20, 0); e.chase = chase; e.die = die; e.pain = pain; diff --git a/source/games/whaven/src/aiminotaur.cpp b/source/games/whaven/src/aiminotaur.cpp index 148ee91f2..afd4e7ad5 100644 --- a/source/games/whaven/src/aiminotaur.cpp +++ b/source/games/whaven/src/aiminotaur.cpp @@ -129,7 +129,7 @@ static void skirmish(PLAYER& plr, short i) { static void nuked(PLAYER& plr, short i) { SPRITE& spr = sprite[i]; - if (game.WH2) { + if (isWh2()) { chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang); trailingsmoke(i, false); newstatus((short)i, DIE); @@ -333,7 +333,7 @@ void createMinotaurAI() { //picanm[MINOTAUR + 16] = 0; auto& e = enemy[MINOTAURTYPE]; - e.info.Init(64, 64, 1024 + 512, 120, 0, 64, false, game.WH2 ? 80 : 100, 0); + e.info.Init(64, 64, 1024 + 512, 120, 0, 64, false, isWh2() ? 80 : 100, 0); e.chase = chase; e.resurect = resurect; e.skirmish = skirmish; diff --git a/source/games/whaven/src/aiskeleton.cpp b/source/games/whaven/src/aiskeleton.cpp index 989e66c95..ab4408c0b 100644 --- a/source/games/whaven/src/aiskeleton.cpp +++ b/source/games/whaven/src/aiskeleton.cpp @@ -271,7 +271,7 @@ static void frozen(PLAYER& plr, short i) { static void nuked(PLAYER& plr, short i) { SPRITE& spr = sprite[i]; - if (game.WH2) { + if (isWh2()) { chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang); trailingsmoke(i, false); newstatus((short)i, DIE); @@ -354,7 +354,7 @@ static void checkexpl(PLAYER& plr, short i) { void createSkeletonAI() { auto& e = enemy[SKELETONTYPE]; - e.info.Init(game.WH2 ? 35 : 24, game.WH2 ? 35 : 24, 1024, 120, 0, 64, false, game.WH2 ? 25 : 30, 0); + e.info.Init(isWh2() ? 35 : 24, isWh2() ? 35 : 24, 1024, 120, 0, 64, false, isWh2() ? 25 : 30, 0); e.chase = chase; e.die = die; e.face = face; diff --git a/source/games/whaven/src/aiwillow.cpp b/source/games/whaven/src/aiwillow.cpp index 9165ed0f9..97a76a712 100644 --- a/source/games/whaven/src/aiwillow.cpp +++ b/source/games/whaven/src/aiwillow.cpp @@ -84,7 +84,7 @@ static void attack(PLAYER& plr, short i) { if (plr.shockme < 0) if ((krand() & 1) != 0) { plr.shockme = 120; - if (!game.WH2) { + if (!isWh2()) { plr.lvl--; switch (plr.lvl) { case 1: @@ -230,7 +230,7 @@ static void die(PLAYER& plr, short i) { static void nuked(PLAYER& plr, short i) { SPRITE& spr = sprite[i]; - if (game.WH2) { + if (isWh2()) { chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang); trailingsmoke(i, false); newstatus((short)i, DIE); @@ -267,7 +267,7 @@ static void willowDrain(PLAYER& plr, short i) { void createWillowAI() { auto& e = enemy[WILLOWTYPE]; - e.info.Init(32, 32, 512, 120, 0, 64, true, game.WH2 ? 5 : 400, 0); + e.info.Init(32, 32, 512, 120, 0, 64, true, isWh2() ? 5 : 400, 0); e.chase = chase; e.attack = attack; e.face = face; diff --git a/source/games/whaven/src/globals.h b/source/games/whaven/src/globals.h index 31064bf86..e2fdc269b 100644 --- a/source/games/whaven/src/globals.h +++ b/source/games/whaven/src/globals.h @@ -202,6 +202,10 @@ enum TBLACKKEY = 15, TGLASSKEY = 16, TIVORYKEY = 17, + + MAXWEAPONS = 10, + MAXPOTIONS = 5, + }; END_WH_NS diff --git a/source/games/whaven/src/item.h b/source/games/whaven/src/item.h new file mode 100644 index 000000000..7702a7fdf --- /dev/null +++ b/source/games/whaven/src/item.h @@ -0,0 +1,20 @@ +#pragma once + +struct Item { + + using Callback = void (*)(PLAYER &plr, short i); + + int sizx, sizy; + boolean treasures, cflag; + Callback pickup; + + void Init(int sizx, int sizy, boolean treasure, boolean cflag, Callback call) + { + this->sizx = sizx; + this->sizy = sizy; + this->treasures = treasure; + this->cflag = cflag; + this->callback = call; + } +}; + diff --git a/source/games/whaven/src/items.cpp b/source/games/whaven/src/items.cpp new file mode 100644 index 000000000..39c8be413 --- /dev/null +++ b/source/games/whaven/src/items.cpp @@ -0,0 +1,1129 @@ + #include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + +Item items[MAXITEMS]; + +boolean isItemSprite(int i) { + return (sprite[i].detail & 0xFF) >= ITEMSBASE && (sprite[i].detail & 0xFF) < MAXITEMS; +} + +void InitItems() +{ + int a = 0; + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // SILVERBAG + { + showmessage("Silver!", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, engine.krand() % 100 + 10); + }); + + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // GOLDBAG + { + showmessage("Gold!", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, engine.krand() % 100 + 10); + }); + + items[a++].Init(27, 28, true, false, [](PLAYER& plr, short i) // HELMET + { + showmessage("Hero Time", 360); + engine.deletesprite(i); + if (!isWh2()) + addarmor(plr, 10); + plr.helmettime = 7200; + // JSA_DEMO3 + treasuresfound++; + SND_Sound(S_STING1 + engine.krand() % 2); + addscore(plr, 10); + }); + + items[a++].Init(26, 26, true, false, [](PLAYER& plr, short i) // PLATEARMOR + { + if (plr.armor <= 149) { + showmessage("Plate Armor", 360); + engine.deletesprite(i); + plr.armortype = 3; + plr.armor = 0; + addarmor(plr, 150); + SND_Sound(S_POTION1); + addscore(plr, 40); + treasuresfound++; + } + }); + + items[a++].Init(26, 26, true, false, [](PLAYER& plr, short i) // CHAINMAIL + { + if (plr.armor <= 99) { + showmessage("Chain Mail", 360); + engine.deletesprite(i); + plr.armortype = 2; + plr.armor = 0; + addarmor(plr, 100); + SND_Sound(S_POTION1); + addscore(plr, 20); + treasuresfound++; + } + }); + items[a++].Init(47, 50, false, false, [](PLAYER& plr, short i) // LEATHERARMOR + { + if (plr.armor <= 49) { + showmessage("Leather Armor", 360); + engine.deletesprite(i); + plr.armortype = 1; + plr.armor = 0; + addarmor(plr, 50); + SND_Sound(S_POTION1); + addscore(plr, 10); + treasuresfound++; + } + }); + items[a++].Init(56, 49, true, false, [](PLAYER &plr, short i) // GIFTBOX + { + sprite[i].detail = 0; + treasuresfound++; + playsound_loc(S_TREASURE1, sprite[i].x, sprite[i].y); + int j = engine.krand() % 8; + switch (j) { + case 0: + switch (engine.krand() % 5) { + case 0: + if (!potionspace(plr, 0)) + break; + showmessage("Health Potion", 360); + updatepotion(plr, HEALTHPOTION); + plr.currentpotion = 0; + SND_Sound(S_POTION1); + addscore(plr, 10); + break; + case 1: + if (!potionspace(plr, 1)) + break; + showmessage("Strength Potion", 360); + updatepotion(plr, STRENGTHPOTION); + plr.currentpotion = 1; + SND_Sound(S_POTION1); + addscore(plr, 20); + break; + case 2: + if (!potionspace(plr, 2)) + break; + showmessage("Cure Poison Potion", 360); + updatepotion(plr, ARMORPOTION); + plr.currentpotion = 2; + SND_Sound(S_POTION1); + addscore(plr, 15); + break; + case 3: + if (!potionspace(plr, 3)) + break; + showmessage("Resist Fire Potion", 360); + updatepotion(plr, FIREWALKPOTION); + plr.currentpotion = 3; + SND_Sound(S_POTION1); + addscore(plr, 15); + break; + case 4: + if (!potionspace(plr, 4)) + break; + showmessage("Invisibility Potion", 360); + updatepotion(plr, INVISIBLEPOTION); + plr.currentpotion = 4; + SND_Sound(S_POTION1); + addscore(plr, 30); + break; + } + sprite[i].picnum = OPENCHEST; + break; + case 1: + switch (engine.krand() % 8) { + case 0: + if (plr.orbammo[0] < 10) { + plr.orb[0] = 1; + plr.orbammo[0]++; + showmessage("Scare Scroll", 360); + SND_Sound(S_POTION1); + } + break; + case 1: + if (plr.orbammo[1] < 10) { + plr.orb[1] = 1; + plr.orbammo[1]++; + showmessage("Night Vision Scroll", 360); + SND_Sound(S_POTION1); + } + break; + case 2: + if (plr.orbammo[2] < 10) { + plr.orb[2] = 1; + plr.orbammo[2]++; + showmessage("Freeze Scroll", 360); + SND_Sound(S_POTION1); + } + break; + case 3: + if (plr.orbammo[3] < 10) { + plr.orb[3] = 1; + plr.orbammo[3]++; + showmessage("Magic Arrow Scroll", 360); + SND_Sound(S_POTION1); + } + break; + case 4: + if (plr.orbammo[4] < 10) { + plr.orb[4] = 1; + plr.orbammo[4]++; + showmessage("Open Door Scroll", 360); + SND_Sound(S_POTION1); + } + break; + case 5: + if (plr.orbammo[5] < 10) { + plr.orb[5] = 1; + plr.orbammo[5]++; + showmessage("Fly Scroll", 360); + SND_Sound(S_POTION1); + } + break; + case 6: + if (plr.orbammo[6] < 10) { + plr.orb[6] = 1; + plr.orbammo[6]++; + showmessage("Fireball Scroll", 360); + SND_Sound(S_POTION1); + } + break; + case 7: + if (plr.orbammo[7] < 10) { + plr.orb[7] = 1; + plr.orbammo[7]++; + showmessage("Nuke Scroll", 360); + SND_Sound(S_POTION1); + } + break; + } + sprite[i].picnum = OPENCHEST; + break; + case 2: + sprite[i].picnum = OPENCHEST; + addscore(plr, (engine.krand() % 400) + 100); + showmessage("Treasure Chest", 360); + SND_Sound(S_POTION1); + break; + case 3: + // random weapon + switch ((engine.krand() % 5) + 1) { + case 1: + if (plr.ammo[1] < 12) { + plr.weapon[1] = 1; + plr.ammo[1] = 40; + showmessage("Dagger", 360); + SND_Sound(S_POTION1); + if (plr.selectedgun < 1) + autoweaponchange(plr, 1); + addscore(plr, 10); + } + break; + case 2: + if (plr.ammo[3] < 12) { + plr.weapon[3] = 1; + plr.ammo[3] = 55; + showmessage("Morning Star", 360); + SND_Sound(S_POTION1); + if (plr.selectedgun < 3) + autoweaponchange(plr, 3); + addscore(plr, 20); + } + break; + case 3: + if (plr.ammo[2] < 12) { + plr.weapon[2] = 1; + plr.ammo[2] = 30; + showmessage("Short Sword", 360); + SND_Sound(S_POTION1); + if (plr.selectedgun < 2) + autoweaponchange(plr, 2); + addscore(plr, 10); + } + break; + case 4: + if (plr.ammo[5] < 12) { + plr.weapon[5] = 1; + plr.ammo[5] = 100; + showmessage("Battle axe", 360); + SND_Sound(S_POTION1); + if (plr.selectedgun < 5) + autoweaponchange(plr, 5); + addscore(plr, 30); + } + break; + case 5: + if (plr.weapon[7] == 1) { + plr.weapon[7] = 2; + plr.ammo[7] = 1; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 30); + } + if (plr.weapon[7] == 2) { + plr.weapon[7] = 2; + plr.ammo[7]++; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 30); + } + if (plr.weapon[7] < 1) { + if (plr.ammo[7] < 12) { + plr.weapon[7] = 1; + plr.ammo[7] = 30; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 7) + autoweaponchange(plr, 7); + addscore(plr, 30); + } + } + break; + } + sprite[i].picnum = OPENCHEST; + break; + case 4: + // random armor + switch (engine.krand() & 4) { + case 0: + showmessage("Hero Time", 360); + addarmor(plr, 10); + plr.helmettime = 7200; + SND_Sound(S_STING1 + engine.krand() % 2); + break; + case 1: + if (plr.armor <= 149) { + showmessage("Plate Armor", 360); + plr.armortype = 3; + plr.armor = 0; + addarmor(plr, 150); + SND_Sound(S_POTION1); + addscore(plr, 40); + } + break; + case 2: + if (plr.armor <= 99) { + showmessage("Chain Mail", 360); + plr.armortype = 2; + plr.armor = 0; + addarmor(plr, 100); + SND_Sound(S_POTION1); + addscore(plr, 20); + } + break; + case 3: + if (plr.armor <= 49) { + showmessage("Leather Armor", 360); + plr.armortype = 1; + plr.armor = 0; + addarmor(plr, 50); + SND_Sound(S_POTION1); + addscore(plr, 20); + } + break; + } + sprite[i].picnum = OPENCHEST; + break; + case 5: + // poison chest + if ((engine.krand() & 2) == 0) { + plr.poisoned = 1; + plr.poisontime = 7200; + sprite[i].detail = GIFTBOXTYPE; + addhealth(plr, -10); + showmessage("Poisoned Chest", 360); + } else { + engine.deletesprite(i); + addscore(plr, (engine.krand() & 400) + 100); + showmessage("Treasure Chest", 360); + SND_Sound(S_POTION1); + } + break; + case 6: + for (j = 0; j < 8; j++) + explosion(i, sprite[i].x, sprite[i].y, sprite[i].z, sprite[i].owner); + playsound_loc(S_EXPLODE, sprite[i].x, sprite[i].y); + engine.deletesprite(i); + break; + default: + sprite[i].picnum = OPENCHEST; + addscore(plr, (engine.krand() % 400) + 100); + showmessage("Experience Gained", 360); + SND_Sound(S_POTION1); + break; + } + }); + + items[a++].Init(-1, -1, true, false, [](PLAYER& plr, short i) // FLASKBLUE + { + if (!potionspace(plr, 0)) + return; + showmessage("Health Potion", 360); + updatepotion(plr, HEALTHPOTION); + plr.currentpotion = 0; + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 10); + treasuresfound++; + }); + items[a++].Init(-1, -1, true, false, [](PLAYER& plr, short i) // FLASKGREEN + { + if (!potionspace(plr, 1)) + return; + showmessage("Strength Potion", 360); + updatepotion(plr, STRENGTHPOTION); + plr.currentpotion = 1; + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 15); + treasuresfound++; + }); + items[a++].Init(-1, -1, true, false, [](PLAYER& plr, short i) // FLASKOCHRE + + { + if (!potionspace(plr, 2)) + return; + showmessage("Cure Poison Potion", 360); + updatepotion(plr, ARMORPOTION); + plr.currentpotion = 2; + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 15); + treasuresfound++; + }); + items[a++].Init(-1, -1, true, false, [](PLAYER& plr, short i) // FLASKRED + { + if (!potionspace(plr, 3)) + return; + showmessage("Resist Fire Potion", 360); + updatepotion(plr, FIREWALKPOTION); + plr.currentpotion = 3; + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 20); + treasuresfound++; + }); + items[a++].Init(-1, -1, true, false, [](PLAYER& plr, short i) // FLASKTAN + { + if (!potionspace(plr, 4)) + return; + showmessage("Invisibility Potion", 360); + updatepotion(plr, INVISIBLEPOTION); + plr.currentpotion = 4; + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 30); + treasuresfound++; + }); + items[a++].Init(14, 14, true, false, [](PLAYER& plr, short i) // DIAMONDRING + { + plr.treasure[TDIAMONDRING] = 1; + showmessage("DIAMOND RING", 360); + plr.armor = 0; + addarmor(plr, 200); + plr.armortype = 3; + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 25); + treasuresfound++; + }); + items[a++].Init(30, 23, true, false, [](PLAYER& plr, short i) // SHADOWAMULET + { + plr.treasure[TSHADOWAMULET] = 1; + showmessage("SHADOW AMULET", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + plr.shadowtime = 7500; + addscore(plr, 50); + treasuresfound++; + }); + items[a++].Init(-1, -1, true, false, [](PLAYER& plr, short i) // GLASSSKULL + { + plr.treasure[TGLASSSKULL] = 1; + showmessage("GLASS SKULL", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + switch (plr.lvl) { + case 1: + plr.score = 2300; + break; + case 2: + plr.score = 4550; + break; + case 3: + plr.score = 9050; + break; + case 4: + plr.score = 18050; + break; + case 5: + plr.score = 36050; + break; + case 6: + plr.score = 75050; + break; + case 7: + plr.score = 180500; + break; + case 8: + plr.score = 280500; + break; + } + addscore(plr, 10); + }); + items[a++].Init(51, 54, true, false, [](PLAYER& plr, short i) // AHNK + { + plr.treasure[TAHNK] = 1; + showmessage("ANKH", 360); + plr.health = 0; + addhealth(plr, 250); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 100); + treasuresfound++; + }); + items[a++].Init(32, 32, true, false, [](PLAYER& plr, short i) // BLUESCEPTER + { + plr.treasure[TBLUESCEPTER] = 1; + showmessage("Water walk scepter", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 10); + treasuresfound++; + }); + items[a++].Init(32, 32, true, false, [](PLAYER& plr, short i) // YELLOWSCEPTER + + { + plr.treasure[TYELLOWSCEPTER] = 1; + showmessage("Fire walk scepter", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 10); + treasuresfound++; + }); + items[a++].Init(14, 14, true, false, [](PLAYER& plr, short i) // ADAMANTINERING + + { + // ring or protection +5 + plr.treasure[TADAMANTINERING] = 1; + showmessage("ADAMANTINE RING", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 30); + treasuresfound++; + }); + items[a++].Init(42, 28, true, false, [](PLAYER& plr, short i) // ONYXRING + + { + // protection from missile + // anit-missile for level only + // dont forget to cleanup values + plr.treasure[TONYXRING] = 1; + showmessage("ONYX RING", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 35); + treasuresfound++; + }); + items[a++].Init(-1, -1, true, true, [](PLAYER& plr, short i) // PENTAGRAM + + { + if (sector[plr.sector].lotag == 4002) + return; + else { + plr.treasure[TPENTAGRAM] = 1; + showmessage("PENTAGRAM", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + addscore(plr, 100); + }); + items[a++].Init(64, 64, true, false, [](PLAYER& plr, short i) // CRYSTALSTAFF + + { + plr.treasure[TCRYSTALSTAFF] = 1; + showmessage("CRYSTAL STAFF", 360); + plr.health = 0; + addhealth(plr, 250); + plr.armortype = 2; + plr.armor = 0; + addarmor(plr, 300); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + addscore(plr, 150); + }); + items[a++].Init(26, 28, true, false, [](PLAYER& plr, short i) // AMULETOFTHEMIST + + { + plr.treasure[TAMULETOFTHEMIST] = 1; + showmessage("AMULET OF THE MIST", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + plr.invisibletime = 3200; + addscore(plr, 75); + treasuresfound++; + }); + items[a++].Init(64, 64, true, false, [](PLAYER& plr, short i) // HORNEDSKULL + + { + if (isWh2()) { + final Runnable ending3 = new Runnable(){ + + public void run() { + if (gCutsceneScreen.init("ending3.smk")) + game.changeScreen(gCutsceneScreen.setSkipping(game.main).escSkipping(true)); + else + game.changeScreen(gMenuScreen); + } + }; + Runnable ending2 = new Runnable(){ + + public void run() { + if (gCutsceneScreen.init("ending2.smk")) + game.changeScreen(gCutsceneScreen.setSkipping(ending3).escSkipping(true)); + else + game.changeScreen(gMenuScreen); + } + }; + if (gCutsceneScreen.init("ending1.smk")) + game.changeScreen(gCutsceneScreen.setSkipping(ending2).escSkipping(true)); + else + game.changeScreen(gMenuScreen); + return; + } + plr.treasure[THORNEDSKULL] = 1; + showmessage("HORNED SKULL", 360); + engine.deletesprite(i); + SND_Sound(S_STING2); + addscore(plr, 750); + treasuresfound++; + }); + items[a++].Init(32, 32, true, false, [](PLAYER& plr, short i) // THEHORN + + { + plr.treasure[TTHEHORN] = 1; + showmessage("Ornate Horn", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + plr.vampiretime = 7200; + // gain 5-10 hp when you kill something + // for 60 seconds + addscore(plr, 350); + treasuresfound++; + }); + items[a++].Init(30, 20, true, false, [](PLAYER& plr, short i) // SAPHIRERING + + { + plr.treasure[TSAPHIRERING] = 1; + showmessage("SAPPHIRE RING", 360); + plr.armortype = 3; + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 25); + treasuresfound++; + }); + items[a++].Init(24, 24, true, false, [](PLAYER& plr, short i) // BRASSKEY + + { + plr.treasure[TBRASSKEY] = 1; + showmessage("BRASS KEY", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 15); + treasuresfound++; + }); + items[a++].Init(24, 24, true, false, [](PLAYER& plr, short i) // BLACKKEY + + { + plr.treasure[TBLACKKEY] = 1; + showmessage("BLACK KEY", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 15); + }); + items[a++].Init(24, 24, true, false, [](PLAYER& plr, short i) // GLASSKEY + + { + plr.treasure[TGLASSKEY] = 1; + showmessage("GLASS KEY", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 15); + treasuresfound++; + }); + items[a++].Init(24, 24, true, false, [](PLAYER& plr, short i) // IVORYKEY + + { + plr.treasure[TIVORYKEY] = 1; + showmessage("IVORY KEY", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 15); + treasuresfound++; + }); + items[a++].Init(35, 36, true, true, [](PLAYER& plr, short i) // SCROLLSCARE + + { + if (plr.orbammo[0] < 10) { + plr.orb[0] = 1; + plr.orbammo[0]++; + changebook(plr, 0); + showmessage("Scare Scroll", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + }); + items[a++].Init(35, 36, true, true, [](PLAYER& plr, short i) // SCROLLNIGHT + + { + if (plr.orbammo[1] < 10) { + plr.orb[1] = 1; + plr.orbammo[1]++; + changebook(plr, 1); + showmessage("Night Vision Scroll", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + }); + items[a++].Init(35, 36, true, true, [](PLAYER& plr, short i) // SCROLLFREEZE + + { + if (plr.orbammo[2] < 10) { + plr.orb[2] = 1; + plr.orbammo[2]++; + changebook(plr, 2); + showmessage("Freeze Scroll", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + }); + items[a++].Init(35, 36, true, true, [](PLAYER& plr, short i) // SCROLLMAGIC + + { + if (plr.orbammo[3] < 10) { + plr.orb[3] = 1; + plr.orbammo[3]++; + changebook(plr, 3); + showmessage("Magic Arrow Scroll", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + }); + items[a++].Init(35, 36, true, true, [](PLAYER& plr, short i) // SCROLLOPEN + + { + if (plr.orbammo[4] < 10) { + plr.orb[4] = 1; + plr.orbammo[4]++; + changebook(plr, 4); + showmessage("Open Door Scroll", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + }); + items[a++].Init(35, 36, true, true, [](PLAYER& plr, short i) // SCROLLFLY + + { + if (plr.orbammo[5] < 10) { + plr.orb[5] = 1; + plr.orbammo[5]++; + changebook(plr, 5); + showmessage("Fly Scroll", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + }); + items[a++].Init(35, 36, true, true, [](PLAYER& plr, short i) // SCROLLFIREBALL + + { + if (plr.orbammo[6] < 10) { + plr.orb[6] = 1; + plr.orbammo[6]++; + changebook(plr, 6); + showmessage("Fireball Scroll", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + }); + items[a++].Init(35, 36, true, true, [](PLAYER& plr, short i) // SCROLLNUKE + + { + if (plr.orbammo[7] < 10) { + plr.orb[7] = 1; + plr.orbammo[7]++; + changebook(plr, 7); + showmessage("Nuke Scroll", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + treasuresfound++; + } + }); + items[a++].Init(27, 27, false, false, [](PLAYER& plr, short i) // QUIVER + + { + if (plr.ammo[6] < 100) { + plr.ammo[6] += 20; + if (plr.ammo[6] > 100) + plr.ammo[6] = 100; + showmessage("Quiver of magic arrows", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 10); + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // WALLBOW BOW + + { + plr.weapon[6] = 1; + plr.ammo[6] += 10; + if (plr.ammo[6] > 100) + plr.ammo[6] = 100; + showmessage("Magic bow", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 6) + autoweaponchange(plr, 6); + addscore(plr, 10); + }); + items[a++].Init(34, 21, false, false, [](PLAYER& plr, short i) // WEAPON1 + + { + if (plr.ammo[1] < 12) { + plr.weapon[1] = 1; + plr.ammo[1] = 40; + showmessage("Dagger", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 1) + autoweaponchange(plr, 1); + addscore(plr, 10); + } + }); + items[a++].Init(34, 21, false, false, [](PLAYER& plr, short i) // WEAPON1A + + { + if (plr.ammo[1] < 12) { + plr.weapon[1] = 3; + plr.ammo[1] = 80; + showmessage("Jeweled Dagger", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + autoweaponchange(plr, 1); + addscore(plr, 30); + } + }); + items[a++].Init(34, 21, false, false, [](PLAYER& plr, short i) // GOBWEAPON + + { + if (plr.ammo[2] < 12) { + plr.weapon[2] = 1; + plr.ammo[2] = 20; + showmessage("Short sword", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 2) + autoweaponchange(plr, 2); + addscore(plr, 10); + } + }); + items[a++].Init(26, 26, false, false, [](PLAYER& plr, short i) // WEAPON2 + + { + if (plr.ammo[3] < 12) { + plr.weapon[3] = 1; + plr.ammo[3] = 55; + showmessage("Morning Star", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 3) + autoweaponchange(plr, 3); + addscore(plr, 20); + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // WALLSWORD WEAPON3A + + { + if (plr.ammo[4] < 12) { + plr.weapon[4] = 1; + plr.ammo[4] = 160; + showmessage("Broad Sword", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + autoweaponchange(plr, 4); + addscore(plr, 60); + } + }); + items[a++].Init(44, 39, false, false, [](PLAYER& plr, short i) // WEAPON3 + + { + if (plr.ammo[4] < 12) { + plr.weapon[4] = 1; + plr.ammo[4] = 80; + showmessage("Broad Sword", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 4) + autoweaponchange(plr, 4); + addscore(plr, 30); + } + }); + items[a++].Init(25, 20, false, false, [](PLAYER& plr, short i) // WALLAXE WEAPON4 + + { + if (plr.ammo[5] < 12) { + plr.weapon[5] = 1; + plr.ammo[5] = 100; + showmessage("Battle axe", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 5) + autoweaponchange(plr, 5); + addscore(plr, 30); + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // THROWHALBERD + + { + // EG fix: don't collect moving halberds, be hurt by them as you should be + // ...but only if you don't have the Onyx Ring + if (sprite[i].statnum != INACTIVE && plr.treasure[TONYXRING] == 0) { + addhealth(plr, -((engine.krand() % 20) + 5)); // Inflict pain + // make it look and sound painful, too + if ((engine.krand() % 9) == 0) { + playsound_loc(S_PLRPAIN1 + (engine.rand() % 2), sprite[i].x, sprite[i].y); + } + startredflash(10); + engine.deletesprite(i); + return; + } + if (sprite[i].statnum != INACTIVE && plr.treasure[TONYXRING] != 0) { + // Can we grab? + if (plr.ammo[9] < 12 && plr.weapon[9] != 3) { + // You grabbed a halberd out of midair, so go ahead and be smug about it + if ((engine.rand() % 10) > 6) + SND_Sound(S_PICKUPAXE); + // fall through to collect + } + else { + // Can't grab, so just block getting hit + engine.deletesprite(i); + return; + } + } + + if (plr.ammo[9] < 12) { + plr.weapon[9] = 1; + plr.ammo[9] = 30; + showmessage("Halberd", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 9) + autoweaponchange(plr, 9); + addscore(plr, 30); + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // WEAPON5 + + { + if (plr.ammo[9] < 12) { + plr.weapon[9] = 1; + plr.ammo[9] = 30; + showmessage("Halberd", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 9) + autoweaponchange(plr, 9); + addscore(plr, 30); + } + }); + items[a++].Init(12, 12, false, false, [](PLAYER& plr, short i) // GONZOBSHIELD + + { + if (plr.shieldpoints < 100) { + plr.shieldtype = 2; + plr.shieldpoints = 200; + droptheshield = false; + engine.deletesprite(i); + showmessage("Magic Shield", 360); + SND_Sound(S_POTION1); + addscore(plr, 50); + } + }); + items[a++].Init(26, 26, false, false, [](PLAYER& plr, short i) // SHIELD + + { + if (plr.shieldpoints < 100) { + plr.shieldpoints = 100; + plr.shieldtype = 1; + engine.deletesprite(i); + showmessage("Shield", 360); + droptheshield = false; // EG 17 Oct 2017 + SND_Sound(S_POTION1); + addscore(plr, 10); + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // WEAPON5B + + { + if (plr.ammo[9] < 12) { // XXX orly? + engine.deletesprite(i); + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // WALLPIKE + + { + if (plr.weapon[7] == 1) { + plr.weapon[7] = 2; + plr.ammo[7] = 2; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_PICKUPAXE); + addscore(plr, 30); + } + if (plr.weapon[7] == 2) { + plr.weapon[7] = 2; + plr.ammo[7]++; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_PICKUPAXE); + // score(plr, 30); + } + if (plr.weapon[7] < 1) { + if (plr.ammo[7] < 12) { + plr.weapon[7] = 1; + plr.ammo[7] = 30; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 7) + autoweaponchange(plr, 7); + addscore(plr, 30); + } + } + }); + items[a++].Init(20, 15, false, true, [](PLAYER& plr, short i) // WEAPON6 + + { + if (plr.weapon[7] == 1) { + plr.weapon[7] = 2; + plr.ammo[7] = 10; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + addscore(plr, 30); + } + if (plr.weapon[7] == 2) { + plr.weapon[7] = 2; + plr.ammo[7] += 10; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + // score(plr, 30); + } + if (plr.weapon[7] < 1) { + if (plr.ammo[7] < 12) { + plr.weapon[7] = 2; + plr.ammo[7] = 10; + showmessage("Pike axe", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 7) + autoweaponchange(plr, 7); + addscore(plr, 30); + } + } + }); + items[a++].Init(41, 36, false, true, [](PLAYER& plr, short i) // WEAPON7 + + { + if (plr.ammo[8] < 12) { + plr.weapon[8] = 1; + plr.ammo[8] = 250; + showmessage("Magic sword", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + if (plr.selectedgun < 8) + autoweaponchange(plr, 8); + addscore(plr, 30); + } + }); + items[a++].Init(32, 18, false, false, [](PLAYER& plr, short i) // GYSER + + { + if (plr.manatime < 1 && plr.invincibletime <= 0 && !plr.godMode) { + playsound_loc(S_FIREBALL, sprite[i].x, sprite[i].y); + addhealth(plr, -1); + startredflash(30); + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // SPIKEBLADE + + { + if (plr.invincibletime <= 0 && !plr.godMode && !justteleported) { + addhealth(plr, -plr.health); + plr.horiz = 200; + plr.spiked = 1; + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // SPIKE + + { + if (plr.invincibletime <= 0 && !plr.godMode && !justteleported) { + addhealth(plr, -plr.health); + plr.horiz = 200; + plr.spiked = 1; + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // SPIKEPOLE + + { + if (plr.invincibletime <= 0 && !plr.godMode && !justteleported) { + addhealth(plr, -plr.health); + plr.horiz = 200; + plr.spiked = 1; + } + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // MONSTERBALL + + { + if (plr.manatime < 1 && plr.invincibletime <= 0 && !plr.godMode) + addhealth(plr, -1); + }); + items[a++].Init(-1, -1, false, false, [](PLAYER& plr, short i) // WEAPON8 + + { + if (plr.ammo[8] < 12) { + plr.weapon[8] = 1; + plr.ammo[8] = 250; + showmessage("Two Handed Sword", 360); + engine.deletesprite(i); + SND_Sound(S_POTION1); + autoweaponchange(plr, 8); + addscore(plr, 30); + } + }); +}; + + +END_WH_NS \ No newline at end of file diff --git a/source/games/whaven/src/names.cpp b/source/games/whaven/src/names.cpp index 3f085f3ac..e972b88e8 100644 --- a/source/games/whaven/src/names.cpp +++ b/source/games/whaven/src/names.cpp @@ -1,6 +1,8 @@ #include "ns.h" #include "gamecontrol.h" +BEGIN_WH_NS + short KNIFEREADY; short KNIFEATTACK; short RFIST; @@ -167,7 +169,7 @@ short SHIELD; void InitNames() { - if(!game.WH2) { + if(!isWh2()) { KNIFEREADY = 1249; KNIFEATTACK = 1261; RFIST = 1268; diff --git a/source/games/whaven/src/player.h b/source/games/whaven/src/player.h index ff2e2853a..1a84ce360 100644 --- a/source/games/whaven/src/player.h +++ b/source/games/whaven/src/player.h @@ -83,8 +83,16 @@ struct PLAYER { boolean noclip; // no copy assignments for this one! + PLAYER() = default; PLAYER(const PLAYER&) = delete; PLAYER& operator=(const PLAYER&) = delete; }; +struct WEAPONINF { + int daweapontics; + int daweaponframe; + int currx; + int curry; +}; + END_WH_NS diff --git a/source/games/whaven/src/potions.cpp b/source/games/whaven/src/potions.cpp new file mode 100644 index 000000000..5b5deac21 --- /dev/null +++ b/source/games/whaven/src/potions.cpp @@ -0,0 +1,193 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + +int potiontilenum; + +void potiontext(PLAYER& plr) { + if( plr.potion[plr.currentpotion] > 0) + switch(plr.currentpotion) { + case 0: + showmessage("Health Potion", 240); + break; + case 1: + showmessage("Strength Potion", 240); + break; + case 2: + showmessage("Cure Poison Potion", 240); + break; + case 3: + showmessage("Resist Fire Potion", 240); + break; + case 4: + showmessage("Invisibility Potion", 240); + break; + } +} + +void potionchange(int snum) +{ + PLAYER& plr = player[snum]; + + int key = ((plr.pInput.bits & (15 << 16)) >> 16) - 1; + if(key != -1 && key < 7) + { + if(key == 5 || key == 6) + { + key = ( key == 5 ? -1 : 1 ); + plr.currentpotion += key; + if(plr.currentpotion < 0) + plr.currentpotion = 4; + if(plr.currentpotion >= MAXPOTIONS) + plr.currentpotion = 0; + } else plr.currentpotion = key; + SND_Sound(S_BOTTLES); + potiontext(plr); + } +} + +void usapotion(PLAYER& plr) { + + if( plr.currentpotion == 0 && plr.health >= plr.maxhealth ) + return; + + if( plr.currentpotion == 2 && plr.poisoned == 0 ) + return; + + if( plr.potion[plr.currentpotion] <= 0) + return; + else + plr.potion[plr.currentpotion]--; + + switch(plr.currentpotion) { + case 0: // health potion + if( plr.health+25 > plr.maxhealth) { + plr.health=0; + SND_Sound(S_DRINK); + addhealth(plr, plr.maxhealth); + } + else { + SND_Sound(S_DRINK); + addhealth(plr, 25); + } + startblueflash(10); + break; + case 1: // strength + plr.strongtime=3200; + SND_Sound(S_DRINK); + startredflash(10); + break; + case 2: // anti venom + SND_Sound(S_DRINK); + plr.poisoned=0; + plr.poisontime=0; + startwhiteflash(10); + showmessage("poison cured", 360); + addhealth(plr, 0); + break; + case 3: // fire resist + SND_Sound(S_DRINK); + plr.manatime=3200; + startwhiteflash(10); + if( lavasnd != -1 ) { + stopsound(lavasnd); + lavasnd = -1; + } + break; + case 4: // invisi + SND_Sound(S_DRINK); + plr.invisibletime=3200; + startgreenflash(10); + break; + } +} + +boolean potionspace(PLAYER& plr, int vial) { + if(plr.potion[vial] > 9) + return false; + else + return true; +} + +void updatepotion(PLAYER& plr, int vial) { + switch(vial) { + case HEALTHPOTION: + plr.potion[0]++; + break; + case STRENGTHPOTION: + plr.potion[1]++; + break; + case ARMORPOTION: + plr.potion[2]++; + break; + case FIREWALKPOTION: + plr.potion[3]++; + break; + case INVISIBLEPOTION: + plr.potion[4]++; + break; + } +} + +void potionpic(PLAYER& plr, int currentpotion, int x, int y, int scale) { + int tilenum = SFLASKBLUE; + + if( netgame ) + return; + x = x + mulscale(200, scale, 16); + y = y - mulscale(94, scale, 16); + engine.rotatesprite(x<<16,y<<16,scale,0,SPOTIONBACKPIC,0, 0, 8 | 16, 0, 0, xdim, ydim-1); + engine.rotatesprite((x - mulscale(4, scale, 16))<<16,(y - mulscale(7, scale, 16))<<16,scale,0,SPOTIONARROW+currentpotion,0, 0, 8 | 16, 0, 0, xdim, ydim-1); + + x += mulscale(4, scale, 16); + for(int i = 0; i < MAXPOTIONS; i++) { + if(plr.potion[i] < 0) + plr.potion[i] = 0; + if(plr.potion[i] > 0) { + switch(i) { + case 1: + tilenum=SFLASKGREEN; + break; + case 2: + tilenum=SFLASKOCHRE; + break; + case 3: + tilenum=SFLASKRED; + break; + case 4: + tilenum=SFLASKTAN; + break; + } + potiontilenum=tilenum; + + engine.rotatesprite((x + mulscale(i*20, scale, 16))<<16,(y + mulscale(19, scale, 16))<<16,scale,0,potiontilenum,0, 0, 8 | 16, 0, 0, xdim, ydim-1); + char potionbuf[50]; + Bitoa(plr.potion[i],potionbuf); + + game.getFont(3).drawText(x + mulscale(7 +(i*20), scale, 16),y+mulscale(7, scale, 16), potionbuf, scale, 0, 0, TextAlign.Left, 0, false); + } + else + engine.rotatesprite((x + mulscale(i*20, scale, 16))<<16,(y + mulscale(19, scale, 16))<<16,scale,0,SFLASKBLACK,0, 0, 8 | 16, 0, 0, xdim, ydim-1); + } +} + +void randompotion(int i) { + if( (engine.krand()%100) > 20) + return; + + int j=engine.insertsprite(sprite[i].sectnum,(short)0); + + sprite[j].x=sprite[i].x; + sprite[j].y=sprite[i].y; + sprite[j].z=sprite[i].z-(12<<8); + sprite[j].shade=-12; + sprite[j].pal=0; + sprite[j].cstat=0; + sprite[j].cstat&=~3; + sprite[j].xrepeat=64; + sprite[j].yrepeat=64; + int type = engine.krand()%4; + sprite[j].picnum = (short) (FLASKBLUE + type); + sprite[j].detail = (short) (FLASKBLUETYPE + type); +} diff --git a/source/games/whaven/src/sndnames.cpp b/source/games/whaven/src/sndnames.cpp new file mode 100644 index 000000000..09f00f1bd --- /dev/null +++ b/source/games/whaven/src/sndnames.cpp @@ -0,0 +1,301 @@ +#include "ns.h" +#include "gamecontrol.h" + +int S_THUNDER1 = 0; +int S_THUNDER2 = 1; +int S_THUNDER3 = 2; +int S_THUNDER4 = 3; +int S_WINDLOOP1 = 4; +int S_WAVELOOP1 = 5; +int S_LAVALOOP1 = 6; +int S_FIRELOOP1 = 7; +int S_STONELOOP1 = 8; +int S_BATSLOOP = 9; +int S_PLRWEAPON0 = 10; +int S_PLRWEAPON1 = 11; +int S_PLRWEAPON2 = 12; +int S_PLRWEAPON3 = 13; +int S_PLRWEAPON4 = 14; +int S_GOBLIN1 = 15; +int S_GOBLIN2 = 16; +int S_GOBLIN3 = 17; +int S_GOBPAIN1 = 18; +int S_GOBPAIN2 = 19; +int S_GOBDIE1 = 20; +int S_GOBDIE2 = 21; +int S_GOBDIE3 = 22; +int S_KSNARL1 = 23; +int S_KSNARL2 = 24; +int S_KSNARL3 = 25; +int S_KSNARL4 = 26; +int S_KPAIN1 = 27; +int S_KPAIN2 = 28; +int S_KDIE1 = 29; +int S_KDIE2 = 30; +int S_DEMON1 = 31; +int S_DEMON2 = 32; +int S_DEMON3 = 33; +int S_DEMON4 = 34; +int S_DEMON5 = 35; +int S_DEMONDIE1 = 36; +int S_DEMONDIE2 = 37; +int S_MSNARL1 = 38; +int S_MSNARL2 = 39; +int S_MSNARL3 = 40; +int S_MSNARL4 = 41; +int S_MPAIN1 = 42; +int S_MDEATH1 = 43; +int S_DRAGON1 = 44; +int S_DRAGON2 = 45; +int S_DRAGON3 = 46; +int S_RIP1 = 47; +int S_RIP2 = 48; +int S_RIP3 = 49; +int S_SKELHIT1 = 50; +int S_SKELHIT2 = 51; +int S_SKELETONDIE = 52; +int S_GUARDIAN1 = 53; +int S_GUARDIAN2 = 54; +int S_GUARDIANPAIN1 = 55; +int S_GUARDIANPAIN2 = 56; +int S_GUARDIANDIE = 57; +int S_WISP = 58; +int S_WISP2 = 59; +int S_SPLASH1 = 60; +int S_SPLASH2 = 61; +int S_SPLASH3 = 62; +int S_SPLASH4 = 63; +int S_SPLASH5 = 64; +int S_SPLASH6 = 65; +int S_WILLOWDIE = 66; +int S_FATWITCHDIE = 67; +int S_JUDY1 = 68; +int S_JUDY2 = 69; +int S_JUDY3 = 70; +int S_JUDY4 = 71; +int S_JUDYDIE = 72; +int S_SKULLWITCH1 = 73; +int S_SKULLWITCH2 = 74; +int S_SKULLWITCH3 = 75; +int S_SKULLWITCHDIE = 76; +int S_GRONDEATHA = 77; +int S_GRONDEATHB = 78; +int S_GRONDEATHC = 79; +int S_CHAIN1 = 80; +int S_FLAME1 = 81; +int S_GRONPAINA = 82; +int S_GRONPAINB = 83; +int S_GRONPAINC = 84; +int S_CLUNK = 85; +int S_DEMONTHROW = 86; +int S_WITCHTHROW = 87; +int S_DOOR1 = 88; +int S_DOOR2 = 89; +int S_DOOR3 = 90; +int S_CREAKDOOR1 = 91; +int S_CREAKDOOR2 = 92; +int S_CREAKDOOR3 = 93; +int S_STING1 = 94; +int S_STING2 = 95; +int S_POTION1 = 96; +int S_GENTHROW = 97; +int S_GENSWING = 98; +int S_ARROWHIT = 99; +int S_WALLHIT1 = 100; +int S_GONG = 101; +int S_SPELL1 = 102; +int S_FREEZE = 103; +int S_FREEZEDIE = 104; +int S_TRAP1 = 105; +int S_TRAP2 = 106; +int S_RATS1 = 107; +int S_RATS2 = 108; +int S_WINDLOOP2 = 109; +int S_BREATH1 = 110; +int S_BREATH2 = 111; +int S_PUSH1 = 112; +int S_PUSH2 = 113; +int S_PLRPAIN1 = 114; +int S_PLRPAIN2 = 115; +int S_GORE1 = 116; +int S_GORE2 = 117; +int S_GORE1A = 118; +int S_GORE1B = 119; +int S_DEADSTEP = 120; +int S_HEARTBEAT = 121; +int S_SOFTCHAINWALK = 122; +int S_SOFTCREAKWALK = 123; +int S_LOUDCHAINWALK = 124; +int S_GRATEWALK = 125; +int S_SCARYDUDE = 126; +int S_WATERY = 127; +int S_GLASSBREAK1 = 128; +int S_GLASSBREAK2 = 129; +int S_GLASSBREAK3 = 130; +int S_TREASURE1 = 131; +int S_SWORD1 = 132; +int S_SWORD2 = 133; +int S_SWORDCLINK1 = 134; +int S_SWORDCLINK2 = 135; +int S_SWORDCLINK3 = 136; +int S_SWORDCLINK4 = 137; +int S_SOCK1 = 138; +int S_SOCK2 = 139; +int S_SOCK3 = 140; +int S_SOCK4 = 141; +int S_KOBOLDHIT = 142; +int S_SPIDERBITE = 143; +int S_FIREBALL = 144; +int S_WOOD1 = 145; +int S_CHAINDOOR1 = 146; +int S_PULLCHAIN1 = 147; +int S_PICKUPAXE = 148; +int S_EXPLODE = 149; +int S_SKELSEE = 150; +int S_BARRELBREAK = 151; +int S_WARP = 152; +int S_PICKUPFLAG = 155; +int S_DROPFLAG = 156; +int S_LAUGH = 157; +int S_DRINK = 158; +int S_PAGE = 159; +int S_BOTTLES = 160; +int S_CRACKING = 161; +int S_PLRDIE1 = 162; +int S_FATLAUGH = 163; + +void InitSoundNames() +{ + if (isWh2()) { + S_WINDLOOP1 = 3; + S_WAVELOOP1 = 4; + S_LAVALOOP1 = 5; + S_FIRELOOP1 = 6; + S_STONELOOP1 = 7; + S_BATSLOOP = 8; + S_PLRWEAPON0 = 9; + S_PLRWEAPON1 = 10; + S_PLRWEAPON2 = 11; + S_PLRWEAPON3 = 12; + S_PLRWEAPON4 = 13; + S_KSNARL1 = 14; + S_KSNARL2 = 15; + S_KSNARL3 = 16; + S_KSNARL4 = 17; + S_KPAIN1 = 18; + S_KPAIN2 = 19; + S_KDIE1 = 20; + S_KDIE2 = 21; + S_DEMON1 = 22; + S_DEMON2 = 23; + S_DEMON3 = 24; + S_DEMON4 = 25; + S_DEMON5 = 26; + S_DEMONDIE1 = 27; + S_DEMONDIE2 = 28; + S_MSNARL1 = 29; + S_MSNARL2 = 30; + S_MSNARL3 = 31; + S_MSNARL4 = 32; + S_MPAIN1 = 33; + S_MDEATH1 = 34; + S_RIP1 = 35; + S_RIP2 = 36; + S_RIP3 = 37; + S_SKELHIT1 = 38; + S_SKELHIT2 = 39; + S_SKELETONDIE = 40; + S_SKELSEE = 41; + S_GUARDIAN1 = 42; + S_GUARDIAN2 = 43; + S_GUARDIANPAIN1 = 44; + S_GUARDIANPAIN2 = 45; + S_GUARDIANDIE = 46; + S_WISP = 47; + S_WISP2 = 48; + S_SPLASH1 = 49; + S_SPLASH2 = 50; + S_SPLASH3 = 51; + S_SPLASH4 = 52; + S_SPLASH5 = 53; + S_WILLOWDIE = 54; + S_JUDY1 = 55; + S_JUDYDIE = 56; + S_CHAIN1 = 57; + S_FLAME1 = 58; + S_CLUNK = 59; + S_DEMONTHROW = 60; + S_DOOR1 = 61; + S_DOOR2 = 62; + S_DOOR3 = 63; + S_CREAKDOOR1 = 64; + S_CREAKDOOR2 = 65; + S_CREAKDOOR3 = 66; + S_STING1 = 67; + S_STING2 = 68; + S_POTION1 = 69; + S_GENTHROW = 70; + S_GENSWING = 71; + S_ARROWHIT = 72; + S_WALLHIT1 = 73; + S_GONG = 74; + S_SPELL1 = 75; + S_FREEZE = 76; + S_FREEZEDIE = 77; + S_TRAP1 = 78; + S_TRAP2 = 79; + S_RATS1 = 80; + S_RATS2 = 81; + S_WINDLOOP2 = 82; + S_BREATH1 = 83; + S_BREATH2 = 84; + S_PUSH1 = 85; + S_PUSH2 = 86; + S_PLRPAIN1 = 87; + S_PLRPAIN2 = 88; + S_GORE1 = 89; + S_GORE2 = 90; + S_GORE1A = 91; + S_GORE1B = 92; + S_DEADSTEP = 93; + S_HEARTBEAT = 94; + S_SOFTCHAINWALK = 95; + S_SOFTCREAKWALK = 96; + S_LOUDCHAINWALK = 97; + S_SCARYDUDE = 98; + S_WATERY = 99; + S_GLASSBREAK1 = 100; + S_GLASSBREAK2 = 101; + S_GLASSBREAK3 = 102; + S_TREASURE1 = 103; + S_SWORD1 = 104; + S_SWORD2 = 105; + S_SWORDCLINK1 = 106; + S_SWORDCLINK2 = 107; + S_SWORDCLINK3 = 108; + S_SWORDCLINK4 = 109; + S_SOCK1 = 110; + S_SOCK2 = 111; + S_SOCK3 = 112; + S_SOCK4 = 113; + S_KOBOLDHIT = 114; + S_FIREBALL = 115; + S_PULLCHAIN1 = 116; + S_PICKUPAXE = 117; + S_EXPLODE = 118; + S_BARRELBREAK = 119; + S_WARP = 120; + S_PICKUPFLAG = 121; + S_DROPFLAG = 122; + S_LAUGH = 123; + S_DRINK = 124; + S_PAGE = 125; + S_BOTTLES = 126; + S_CRACKING = 127; + S_PLRDIE1 = 128; + S_GRONDEATHA = 136; + S_GRONDEATHB = 137; + S_GRONDEATHC = 138; + S_GRONPAINA = 142; + } +} \ No newline at end of file diff --git a/source/games/whaven/src/sndnames.h b/source/games/whaven/src/sndnames.h new file mode 100644 index 000000000..bdcacc3d3 --- /dev/null +++ b/source/games/whaven/src/sndnames.h @@ -0,0 +1,203 @@ +#include "ns.h" + +BEGIN_WH_NS + + +extern int S_THUNDER1; //0; +extern int S_THUNDER2; //1; +extern int S_THUNDER3; //2; +extern int S_THUNDER4; //3; +extern int S_WINDLOOP1; //4; +extern int S_WAVELOOP1; //5; +extern int S_LAVALOOP1; //6; +extern int S_FIRELOOP1; //7; +extern int S_STONELOOP1; //8; +extern int S_BATSLOOP; //9; +extern int S_PLRWEAPON0; //10; +extern int S_PLRWEAPON1; //11; +extern int S_PLRWEAPON2; //12; +extern int S_PLRWEAPON3; //13; +extern int S_PLRWEAPON4; //14; +extern int S_GOBLIN1; //15; +extern int S_GOBLIN2; //16; +extern int S_GOBLIN3; //17; +extern int S_GOBPAIN1; //18; +extern int S_GOBPAIN2; //19; +extern int S_GOBDIE1; //20; +extern int S_GOBDIE2; //21; +extern int S_GOBDIE3; //22; +extern int S_KSNARL1; //23; +extern int S_KSNARL2; //24; +extern int S_KSNARL3; //25; +extern int S_KSNARL4; //26; +extern int S_KPAIN1; //27; +extern int S_KPAIN2; //28; +extern int S_KDIE1; //29; +extern int S_KDIE2; //30; +extern int S_DEMON1; //31; +extern int S_DEMON2; //32; +extern int S_DEMON3; //33; +extern int S_DEMON4; //34; +extern int S_DEMON5; //35; +extern int S_DEMONDIE1; //36; +extern int S_DEMONDIE2; //37; +extern int S_MSNARL1; //38; +extern int S_MSNARL2; //39; +extern int S_MSNARL3; //40; +extern int S_MSNARL4; //41; +extern int S_MPAIN1; //42; +extern int S_MDEATH1; //43; +extern int S_DRAGON1; //44; +extern int S_DRAGON2; //45; +extern int S_DRAGON3; //46; +extern int S_RIP1; //47; +extern int S_RIP2; //48; +extern int S_RIP3; //49; +extern int S_SKELHIT1; //50; +extern int S_SKELHIT2; //51; +extern int S_SKELETONDIE; //52; +extern int S_GUARDIAN1; //53; +extern int S_GUARDIAN2; //54; +extern int S_GUARDIANPAIN1; //55; +extern int S_GUARDIANPAIN2; //56; +extern int S_GUARDIANDIE; //57; +extern int S_WISP; //58; +extern int S_WISP2; //59; +extern int S_SPLASH1; //60; +extern int S_SPLASH2; //61; +extern int S_SPLASH3; //62; +extern int S_SPLASH4; //63; +extern int S_SPLASH5; //64; +extern int S_SPLASH6; //65; +extern int S_WILLOWDIE; //66; +extern int S_FATWITCHDIE; //67; +extern int S_JUDY1; //68; +extern int S_JUDY2; //69; +extern int S_JUDY3; //70; +extern int S_JUDY4; //71; +extern int S_JUDYDIE; //72; +extern int S_SKULLWITCH1; //73; +extern int S_SKULLWITCH2; //74; +extern int S_SKULLWITCH3; //75; +extern int S_SKULLWITCHDIE; //76; +extern int S_GRONDEATHA; //77; +extern int S_GRONDEATHB; //78; +extern int S_GRONDEATHC; //79; +extern int S_CHAIN1; //80; +extern int S_FLAME1; //81; +extern int S_GRONPAINA; //82; +extern int S_GRONPAINB; //83; +extern int S_GRONPAINC; //84; +extern int S_CLUNK; //85; +extern int S_DEMONTHROW; //86; +extern int S_WITCHTHROW; //87; +extern int S_DOOR1; //88; +extern int S_DOOR2; //89; +extern int S_DOOR3; //90; +extern int S_CREAKDOOR1; //91; +extern int S_CREAKDOOR2; //92; +extern int S_CREAKDOOR3; //93; +extern int S_STING1; //94; +extern int S_STING2; //95; +extern int S_POTION1; //96; +extern int S_GENTHROW; //97; +extern int S_GENSWING; //98; +extern int S_ARROWHIT; //99; +extern int S_WALLHIT1; //100; +extern int S_GONG; //101; +extern int S_SPELL1; //102; +extern int S_FREEZE; //103; +extern int S_FREEZEDIE; //104; +extern int S_TRAP1; //105; +extern int S_TRAP2; //106; +extern int S_RATS1; //107; +extern int S_RATS2; //108; +extern int S_WINDLOOP2; //109; +extern int S_BREATH1; //110; +extern int S_BREATH2; //111; +extern int S_PUSH1; //112; +extern int S_PUSH2; //113; +extern int S_PLRPAIN1; //114; +extern int S_PLRPAIN2; //115; +extern int S_GORE1; //116; +extern int S_GORE2; //117; +extern int S_GORE1A; //118; +extern int S_GORE1B; //119; +extern int S_DEADSTEP; //120; +extern int S_HEARTBEAT; //121; +extern int S_SOFTCHAINWALK; //122; +extern int S_SOFTCREAKWALK; //123; +extern int S_LOUDCHAINWALK; //124; +extern int S_GRATEWALK; //125; +extern int S_SCARYDUDE; //126; +extern int S_WATERY; //127; +extern int S_GLASSBREAK1; //128; +extern int S_GLASSBREAK2; //129; +extern int S_GLASSBREAK3; //130; +extern int S_TREASURE1; //131; +extern int S_SWORD1; //132; +extern int S_SWORD2; //133; +extern int S_SWORDCLINK1; //134; +extern int S_SWORDCLINK2; //135; +extern int S_SWORDCLINK3; //136; +extern int S_SWORDCLINK4; //137; +extern int S_SOCK1; //138; +extern int S_SOCK2; //139; +extern int S_SOCK3; //140; +extern int S_SOCK4; //141; +extern int S_KOBOLDHIT; //142; +extern int S_SPIDERBITE; //143; +extern int S_FIREBALL; //144; +extern int S_WOOD1; //145; +extern int S_CHAINDOOR1; //146; +extern int S_PULLCHAIN1; //147; +extern int S_PICKUPAXE; //148; +extern int S_EXPLODE; //149; +extern int S_SKELSEE; //150; +extern int S_BARRELBREAK; //151; +extern int S_WARP; //152; +extern int S_PICKUPFLAG; //155; +extern int S_DROPFLAG; //156; +extern int S_LAUGH; //157; +extern int S_DRINK; //158; +extern int S_PAGE; //159; +extern int S_BOTTLES; //160; +extern int S_CRACKING; //161; +extern int S_PLRDIE1; //162; +extern int S_FATLAUGH; //163; + + +enum WHSounds { + + S_SPELL2 = 153, + S_THROWPIKE = 154, + + // WH2 Sounds + S_AGM_ATTACK = 129, + S_AGM_PAIN1 = 130, + S_AGM_PAIN2 = 131, + S_AGM_PAIN3 = 132, + S_AGM_DIE1 = 133, + S_AGM_DIE2 = 134, + S_AGM_DIE3 = 135, + S_FIRESWING = 145, + S_FIREWEAPONLOOP = 146, + S_ENERGYWEAPONLOOP = 147, + S_ENERGYSWING = 148, + S_BIGGLASSBREAK1 = 149, + S_IMPGROWL1 = 152, + S_IMPGROWL2 = 153, + S_IMPGROWL3 = 154, + S_IMPDIE1 = 155, + S_IMPDIE2 = 156, + S_SWINGDOOR = 157, + S_NUKESPELL = 158, + S_DOORSPELL = 159, + S_FIRESPELL = 160, + S_GENERALMAGIC1 = 161, + S_GENERALMAGIC2 = 162, + S_GENERALMAGIC3 = 163, + S_GENERALMAGIC4 = 164, +}; + +END_WH_NS diff --git a/source/games/whaven/src/spellbooks.cpp b/source/games/whaven/src/spellbooks.cpp new file mode 100644 index 000000000..487b9f01f --- /dev/null +++ b/source/games/whaven/src/spellbooks.cpp @@ -0,0 +1,479 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + +void activatedaorb(PLAYER& plr) { + if (plr.orbammo[plr.currentorb] <= 0) + return; + + switch (plr.currentorb) { + case 0: // SCARE + // shadowtime=1200+(plr.lvl*120); + break; + case 1: // NIGHT VISION + // nightglowtime=2400+(plr.lvl*600); + break; + case 2: // FREEZE + plr.orbactive[plr.currentorb] = -1; + break; + case 3: // MAGIC ARROW + plr.orbactive[plr.currentorb] = -1; + break; + case 4: // OPEN DOORS + plr.orbactive[plr.currentorb] = -1; + break; + case 5: // FLY + // plr.orbactive[currentorb]=3600+(plr.lvl*600); + break; + case 6: // FIREBALL + plr.orbactive[plr.currentorb] = -1; + break; + case 7: // NUKE + plr.orbactive[plr.currentorb] = -1; + break; + } + + if (plr.orbammo[plr.currentorb] <= 0) { + plr.orb[plr.currentorb] = 0; + return; + } else + plr.orbammo[plr.currentorb]--; + + plr.currweaponfired = 4; + plr.currweapontics = isWh2() ? wh2throwanimtics[plr.currentorb][0].daweapontics : throwanimtics[plr.currentorb][0].daweapontics; +} + +void castaorb(PLAYER& plr) { + int k; + float daang; + + switch (plr.currentorb) { + case 0: // SCARE + if (isWh2()) + playsound_loc(S_GENERALMAGIC4, plr.x, plr.y); + plr.shadowtime = ((plr.lvl + 1) * 120) << 2; + break; + case 1: // NIGHTVISION + plr.nightglowtime = 3600 + (plr.lvl * 120); + break; + case 2: // FREEZE + if (isWh2()) + playsound_loc(S_GENERALMAGIC3, plr.x, plr.y); + else + playsound_loc(S_SPELL1, plr.x, plr.y); + daang = plr.ang; + shootgun(plr, daang, 6); + break; + case 3: // MAGIC ARROW + if (isWh2()) { + lockon(plr,10,2); + playsound_loc(S_GENERALMAGIC2, plr.x, plr.y); + } + else { + daang = BClampAngle(plr.ang - 36); + for (k = 0; k < 10; k++) { + daang = BClampAngle(daang + (k << 1)); + shootgun(plr, daang, 2); + } + playsound_loc(S_SPELL1, plr.x, plr.y); + } + break; + case 4: // OPEN DOORS + daang = plr.ang; + shootgun(plr, daang, 7); + if (isWh2()) + playsound_loc(S_DOORSPELL, plr.x, plr.y); + else + playsound_loc(S_SPELL1, plr.x, plr.y); + break; + case 5: // FLY + plr.orbactive[plr.currentorb] = 3600 + (plr.lvl * 120); + if (isWh2()) + playsound_loc(S_GENERALMAGIC1, plr.x, plr.y); + else + playsound_loc(S_SPELL1, plr.x, plr.y); + break; + case 6: // FIREBALL + if (isWh2()) { + lockon(plr,3,3); + playsound_loc(S_FIRESPELL, plr.x, plr.y); + } + else { + daang = plr.ang; + shootgun(plr, daang, 3); + playsound_loc(S_SPELL1, plr.x, plr.y); + } + break; + case 7: // NUKE + daang = plr.ang; + shootgun(plr, daang, 4); + if (isWh2()) + playsound_loc(S_NUKESPELL, plr.x, plr.y); + else + playsound_loc(S_SPELL1, plr.x, plr.y); + break; + } +} + +void spellswitch(PLAYER& plr, int j) +{ + int i = plr.currentorb; + while(i >= 0 && i < MAXNUMORBS) { + i += j; + + if(i == -1) i = MAXNUMORBS - 1; + else if(i == MAXNUMORBS) i = 0; + + if(plr.spellbookflip != 0 || i == plr.currentorb) + break; + + if (changebook(plr, i)) { + displayspelltext(plr); + plr.spelltime = 360; + break; + } + } +} + +void bookprocess(int snum) { + PLAYER& plr = player[snum]; + + if (plr.currweaponanim == 0 && plr.currweaponflip == 0) { + int bits = plr.pInput.bits; + int spell = ((bits & (15 << 12)) >> 12) - 1; + + if(spell != -1 && spell < 10) + { + if(spell != 9 && spell != 8) { + if (changebook(plr, spell)) { + displayspelltext(plr); + plr.spelltime = 360; + } else return; + } else + spellswitch(plr, spell == 9 ? -1 : 1); + plr.orbshot = 0; + } + } + + for (int j = 0; j < MAXNUMORBS; j++) { + if (plr.orbactive[j] > -1) { + plr.orbactive[j] -= TICSPERFRAME; + } + } +} + +boolean changebook(PLAYER& plr, int i) { + if(plr.orbammo[i] <= 0 || plr.currentorb == i) + return false; + plr.currentorb = i; + if (plr.spellbookflip == 0) { + plr.spellbook = 0; + plr.spellbooktics = 10; + plr.spellbookflip = 1; + SND_Sound(S_PAGE); + return true; + } + return false; +} + +boolean lvlspellcheck(PLAYER& plr) { + if(isWh2()) return true; + + switch (plr.currentorb) { + case 0: + case 1: + return true; + case 2: + if (plr.lvl > 1) + return true; + else + showmessage("must attain 2nd level", 360); + break; + case 3: + if (plr.lvl > 1) + return true; + else + showmessage("must attain 2nd level", 360); + break; + case 4: + if (plr.lvl > 2) + return true; + else + showmessage("must attain 3rd level", 360); + break; + case 5: + if (plr.lvl > 2) + return true; + else + showmessage("must attain 3rd level", 360); + + break; + case 6: + if (plr.lvl > 3) + return true; + else + showmessage("must attain 4th level", 360); + break; + case 7: + if (plr.lvl > 4) + return true; + else + showmessage("must attain 5th level", 360); + break; + } + return false; +} + +void speelbookprocess(PLAYER& plr) { + if (plr.spelltime > 0) + plr.spelltime -= TICSPERFRAME; + + if (plr.spellbookflip == 1) { + plr.spellbooktics -= TICSPERFRAME; + if (plr.spellbooktics < 0) + plr.spellbook++; + if (plr.spellbook > 8) + plr.spellbook = 8; + if (plr.spellbook == 8) + plr.spellbookflip = 0; + } +} + +void nukespell(PLAYER& plr, short j) { + if(sprite[j].detail != WILLOWTYPE && sprite[j].pal == 6) //don't nuke freezed enemies + return; + + if (isWh2()) { + // dont nuke a shade + if (sprite[j].shade > 30) + return; + + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + sprite[j].cstat &= ~3; + sprite[j].shade = 6; + sprite[j].lotag = 360; + sprite[j].ang = (short) plr.ang; + sprite[j].hitag = 0; + addscore(plr, 150); + + int k = engine.insertsprite(sprite[j].sectnum, NUKED); + sprite[k].lotag = 360; + sprite[k].xrepeat = 30; + sprite[k].yrepeat = 12; + sprite[k].picnum = ZFIRE; + sprite[k].pal = 0; + sprite[k].ang = sprite[j].ang; + sprite[k].x = sprite[j].x; + sprite[k].y = sprite[j].y; + sprite[k].z = sprite[j].z; + sprite[k].cstat = sprite[j].cstat; + + return; + } + + switch (sprite[j].detail) { + case WILLOWTYPE: + case SPIDERTYPE: + engine.deletesprite((short) j); + addscore(plr, 10); + break; + case KOBOLDTYPE: + sprite[j].picnum = KOBOLDCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case DEVILTYPE: + sprite[j].picnum = DEVILCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case GOBLINTYPE: + case IMPTYPE: + sprite[j].picnum = GOBLINCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case MINOTAURTYPE: + sprite[j].picnum = MINOTAURCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case SKELETONTYPE: + sprite[j].picnum = SKELETONCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case GRONTYPE: + sprite[j].picnum = GRONCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case DRAGONTYPE: + sprite[j].picnum = DRAGONCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case GUARDIANTYPE: + sprite[j].picnum = GUARDIANCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case FATWITCHTYPE: + sprite[j].picnum = FATWITCHCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case SKULLYTYPE: + sprite[j].picnum = SKULLYCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + break; + case JUDYTYPE: + if (mapon < 24) { + sprite[j].picnum = JUDYCHAR; + newstatus(j, NUKED); + sprite[j].pal = 0; + sprite[j].cstat |= 1; + addscore(plr, 150); + } + break; + } +} + +void medusa(PLAYER& plr, short j) { + if(sprite[j].hitag <= 0) //don't freeze dead enemies + return; + + newstatus(j, FROZEN); + int pic = sprite[j].picnum; + switch (sprite[j].detail) { + + case NEWGUYTYPE: + sprite[j].picnum = NEWGUYPAIN; + break; + case KURTTYPE: + sprite[j].picnum = GONZOCSWPAIN; + break; + case GONZOTYPE: + if(pic == GONZOCSW || pic == GONZOCSWAT) + sprite[j].picnum = GONZOCSWPAIN; + else if(pic == GONZOGSW || pic == GONZOGSWAT) + sprite[j].picnum = GONZOGSWPAIN; + else if(pic == GONZOGHM || pic == GONZOGHMAT + || pic == GONZOGSH || pic == GONZOGSHAT) + sprite[j].picnum = GONZOGHMPAIN; + break; + case KATIETYPE: + sprite[j].picnum = KATIEPAIN; + break; + case KOBOLDTYPE: + sprite[j].picnum = KOBOLDDIE; + break; + case DEVILTYPE: + sprite[j].picnum = DEVILDIE; + break; + case FREDTYPE: + sprite[j].picnum = FREDDIE; + break; + case GOBLINTYPE: + case IMPTYPE: + if(isWh2()) sprite[j].picnum = IMPDIE; + else sprite[j].picnum = GOBLINDIE; + break; + case MINOTAURTYPE: + sprite[j].picnum = MINOTAURDIE; + break; + case SPIDERTYPE: + sprite[j].picnum = SPIDERDIE; + break; + case SKELETONTYPE: + sprite[j].picnum = SKELETONDIE; + break; + case GRONTYPE: + if(pic == GRONHAL || pic == GRONHALATTACK) + sprite[j].picnum = (short) GRONHALDIE; + else if(pic == GRONMU || pic == GRONMUATTACK) + sprite[j].picnum = (short) GRONMUDIE; + else if(pic == GRONSW || pic == GRONSWATTACK) + sprite[j].picnum = (short) GRONSWDIE; + break; + } + sprite[j].pal = 6; + sprite[j].cstat |= 1; + addscore(plr, 100); +} + +void displayspelltext(PLAYER& plr) { + switch (plr.currentorb) { + case 0: + showmessage("scare spell", 360); + break; + case 1: + showmessage("night vision spell", 360); + break; + case 2: + showmessage("freeze spell", 360); + break; + case 3: + showmessage("magic arrow spell", 360); + break; + case 4: + showmessage("open door spell", 360); + break; + case 5: + showmessage("fly spell", 360); + break; + case 6: + showmessage("fireball spell", 360); + break; + case 7: + showmessage("nuke spell", 360); + break; + } +} + +void orbpic(PLAYER& plr, int currentorb) { + if (plr.orbammo[currentorb] < 0) + plr.orbammo[currentorb] = 0; + + Bitoa(plr.orbammo[currentorb], tempchar); + + int y = 382; + if (currentorb == 2) + y = 381; + if (currentorb == 3) + y = 383; + if (currentorb == 6) + y = 383; + if (currentorb == 7) + y = 380; + + int spellbookpage = sspellbookanim[currentorb][8].daweaponframe; + overwritesprite(121 << 1, y, spellbookpage, 0, 0, 0); + game.getFont(4).drawText(126 << 1,439, tempchar, 0, 0, TextAlign.Left, 0, false); +} + +END_WH_NS diff --git a/source/games/whaven/src/weapons.cpp b/source/games/whaven/src/weapons.cpp new file mode 100644 index 000000000..b19ea68c9 --- /dev/null +++ b/source/games/whaven/src/weapons.cpp @@ -0,0 +1,2491 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + +static int weaponuseless = 0; +static boolean madeahit; +static int weapondropgoal; +static int arrowcnt, throwpikecnt; + + +// EG 17 Oct 2017: Backport shield toggle +int dropshieldcnt = 0; +boolean droptheshield = false; +int dahand = 0; +int weapondrop; +int snakex, snakey; +int enchantedsoundhandle = -1; + +boolean checkmedusadist(int i, int x, int y, int z, int lvl) { + int attackdist = (isWh2() ? 8192 : 1024) + (lvl << 9); + + if ((klabs(x - sprite[i].x) + klabs(y - sprite[i].y) < attackdist) + && (klabs((z >> 8) - ((sprite[i].z >> 8) - (tilesizy[sprite[i].picnum] >> 1))) <= 120)) + return true; + else + return false; +} + +void autoweaponchange(PLAYER& plr, int dagun) { + if (plr.currweaponanim > 0 || dagun == plr.selectedgun || plr.currweaponflip > 0) + return; + + plr.selectedgun = dagun; + plr.hasshot = 0; + plr.currweaponfired = 2; // drop weapon + + if (enchantedsoundhandle != -1) { + SND_StopLoop(enchantedsoundhandle); + enchantedsoundhandle=-1; + } + switch (plr.selectedgun) { + case 0: + weapondropgoal = 40; + weapondrop = 0; + case 1: + weapondropgoal = 100; + weapondrop = 0; + break; + case 2: + if (enchantedsoundhandle == -1 && plr.weapon[plr.selectedgun] == 3) { + enchantedsoundhandle = playsound(S_FIREWEAPONLOOP, 0, 0, -1); + } + weapondropgoal = (isWh2() ? 40 : 100); + weapondrop = 0; + break; + case 3: + if (enchantedsoundhandle == -1 && plr.weapon[plr.selectedgun] == 3) { + enchantedsoundhandle = playsound(S_ENERGYWEAPONLOOP, 0, 0, -1); + } + weapondropgoal = 100; + weapondrop = 0; + break; + case 4: + weapondropgoal = 40; + weapondrop = 0; + break; + case 5: + if (enchantedsoundhandle == -1 && plr.weapon[plr.selectedgun] == 3) { + enchantedsoundhandle = playsound(S_ENERGYWEAPONLOOP, 0, 0, -1); + } + weapondropgoal = 40; + weapondrop = 0; + break; + case 6: + if (enchantedsoundhandle == -1 && plr.weapon[plr.selectedgun] == 3) { + enchantedsoundhandle = playsound(S_FIREWEAPONLOOP, 0, 0, -1); + } + weapondropgoal = 40; + weapondrop = 0; + if (plr.ammo[6] < 0) + plr.ammo[6] = 0; + break; + case 7: + if (enchantedsoundhandle == -1 && plr.weapon[plr.selectedgun] == 3) { + enchantedsoundhandle = playsound(S_ENERGYWEAPONLOOP, 0, 0, -1); + } + weapondropgoal = 40; + weapondrop = 0; + if (plr.weapon[7] == 2) { + if (plr.ammo[7] < 0) + plr.ammo[7] = 0; + } + break; + case 8: +// if (enchantedsoundhandle == -1 && plr.weapon[plr.selectedgun] == 3) { +// enchantedsoundhandle = playsound(S_FIREWEAPONLOOP, 0, 0, -1); +// } + weapondropgoal = 40; + weapondrop = 0; + break; + case 9: + weapondropgoal = 40; + weapondrop = 0; + break; + } +} + +void weaponchange(int snum) { + PLAYER& plr = player[snum]; + if (plr.currweaponanim == 0 && plr.currweaponflip == 0) { + int bits = plr.pInput.bits; + int key = ((bits & (15 << 8)) >> 8) - 1; + if (key != -1 && key < 12) { + if (key == 10 || key == 11) { + int k = plr.currweapon; + key = (key == 10 ? -1 : 1); + while (k >= 0 && k < 10) { + k += key; + + if (k == -1) + k = 9; + else if (k == 10) + k = 0; + + if (plr.weapon[k] > 0) { + key = k; + break; + } + } + } + int gun = key; + if (plr.weapon[gun] > 0) { + if (plr.currweaponanim <= 0 && gun != plr.selectedgun && plr.currweaponflip <= 0) { + if (enchantedsoundhandle != -1) { + SND_StopLoop(enchantedsoundhandle); + enchantedsoundhandle = -1; + } + } + + autoweaponchange(plr, gun); + } + } + } +} + +void plrfireweapon(PLAYER& plr) { + if (plr.currweaponfired == 4) { + if (isWh2()) { + plr.currweapontics = wh2throwanimtics[plr.currentorb][0].daweapontics; + } else + plr.currweapontics = throwanimtics[plr.currentorb][0].daweapontics; + return; + } + + if (plr.ammo[plr.selectedgun] <= 0) { + if (plr.currweapon == 6) { + for (int i = 0; i < MAXWEAPONS; i++) { + if (plr.ammo[i] > 0 && plr.weapon[i] == 1) { + plr.selectedgun = i; + plr.hasshot = 0; + plr.currweaponfired = 2; // drop weapon + weapondropgoal = 100; + weapondrop = 0; + } + } + } + return; + } else { + madeahit = false; + plr.ammo[plr.selectedgun]--; + + if (isWh2() && plr.weapon[plr.selectedgun] == 3) { + if (plr.ammo[plr.selectedgun] == 0) { + plr.weapon[plr.selectedgun] = plr.preenchantedweapon[plr.selectedgun]; + plr.ammo[plr.selectedgun] = plr.preenchantedammo[plr.selectedgun]; + if (enchantedsoundhandle != -1) { + SND_StopLoop(enchantedsoundhandle); + enchantedsoundhandle = -1; + } + } + } + + if (plr.ammo[plr.selectedgun] <= 0 || plr.ammo[plr.selectedgun] == 10) { + switch (plr.selectedgun) { + case 0: // fist + plr.ammo[0] = 9999; + break; + case 1: // knife + if (plr.ammo[plr.selectedgun] == 10) { + showmessage("Dagger is damaged", 360); + } + if (plr.ammo[plr.selectedgun] <= 0) { + plr.ammo[1] = 0; + plr.weapon[1] = 0; + showmessage("Dagger is Useless", 360); + weaponuseless = 1; + } + break; + case 2: // short sword + if (plr.ammo[plr.selectedgun] == 10) { + showmessage("Short Sword is damaged", 360); + } + if (plr.ammo[plr.selectedgun] <= 0) { + plr.ammo[2] = 0; + plr.weapon[2] = 0; + showmessage("Short Sword is Useless", 360); + weaponuseless = 1; + } + break; + case 3: // mace + if (plr.ammo[plr.selectedgun] == 10) { + showmessage("Morning Star is damaged", 360); + } + if (plr.ammo[plr.selectedgun] <= 0) { + plr.ammo[3] = 0; + plr.weapon[3] = 0; + showmessage("Morning Star is Useless", 360); + weaponuseless = 1; + } + break; + + case 4: // sword + if (plr.ammo[plr.selectedgun] == 10) { + showmessage("Sword is damaged", 360); + } + if (plr.ammo[plr.selectedgun] <= 0) { + plr.ammo[4] = 0; + plr.weapon[4] = 0; + showmessage("Sword is Useless", 360); + weaponuseless = 1; + } + break; + case 5: // battle axe + if (plr.ammo[plr.selectedgun] == 10) { + showmessage("Battle axe is damaged", 360); + } + if (plr.ammo[plr.selectedgun] <= 0) { + plr.ammo[5] = 0; + plr.weapon[5] = 0; + showmessage("Battle axe is Useless", 360); + weaponuseless = 1; + } + break; + case 6: // bow + break; + case 7: // pike + if (plr.weapon[7] == 1) { + if (plr.ammo[plr.selectedgun] == 10) { + showmessage("Pike is damaged", 360); + } + if (plr.ammo[plr.selectedgun] <= 0) { + plr.ammo[7] = 0; + plr.weapon[7] = 0; + showmessage("Pike is Useless", 360); + weaponuseless = 1; + } + } + if (plr.weapon[7] == 2 && plr.ammo[7] <= 0) { + plr.weapon[7] = 1; + plr.ammo[7] = 30; + } + break; + case 8: // two handed sword + if (plr.ammo[plr.selectedgun] == 10) { + showmessage("Magic Sword is damaged", 360); + } + if (plr.ammo[plr.selectedgun] <= 0) { + plr.ammo[8] = 0; + plr.weapon[8] = 0; + showmessage("Magic Sword is Useless", 360); + weaponuseless = 1; + } + break; + case 9: // halberd + if (plr.ammo[plr.selectedgun] == 10) { + showmessage("Halberd is damaged", 360); + } + if (plr.ammo[plr.selectedgun] <= 0) { + plr.ammo[9] = 0; + plr.weapon[9] = 0; + showmessage("Halberd is Useless", 360); + weaponuseless = 1; + } + break; + } + } + } + + if (weaponuseless == 1) + for (int i = 0; i < MAXWEAPONS; i++) { + if (plr.weapon[i] > 0 && plr.ammo[i] > 0) { + plr.currweapon = plr.selectedgun = i; + plr.currweaponfired = 3; // ready weapon + plr.currweaponflip = 0; + weaponuseless = 0; + } + } + else + plr.currweaponfired = 1; + + plr.currweapon = plr.selectedgun; + + plr.currweaponattackstyle = krand() % 2; + + if (plr.weapon[7] == 2 && plr.currweapon == 7) { + plr.currweaponattackstyle = 0; + } else if (isWh2() && plr.weapon[7] == 3 && plr.currweapon == 7) { + plr.currweaponattackstyle = 0; + } + + if (plr.currweapon == 9) { + if (krand() % 100 > 80) + plr.currweaponattackstyle = 0; + else + plr.currweaponattackstyle = 1; + } + + if (plr.currweaponanim > 11) { + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1) + plr.currweapontics = weaponanimtics[plr.currweapon][0].daweapontics; + else + plr.currweapontics = zweaponanimtics[plr.currweapon][0].daweapontics; + } else + plr.currweapontics = weaponanimtics[plr.currweapon][0].daweapontics; + } +} + +void weaponsprocess(int snum) { + PLAYER& plr = player[snum]; + + if (plr.shadowtime <= 0) { + if (plr.weapon[plr.currweapon] == 3) { + if (enchantedsoundhandle == -1 && plr.weapon[plr.selectedgun] == 3) { + switch (plr.selectedgun) { + case 2: + enchantedsoundhandle = playsound(S_FIREWEAPONLOOP, 0, 0, -1); + break; + case 3: + case 5: + enchantedsoundhandle = playsound(S_ENERGYWEAPONLOOP, 0, 0, -1); + break; + case 6: + enchantedsoundhandle = playsound(S_FIREWEAPONLOOP, 0, 0, -1); + break; + case 7: + enchantedsoundhandle = playsound(S_ENERGYWEAPONLOOP, 0, 0, -1); + break; + case 8: + enchantedsoundhandle = playsound(S_ENERGYWEAPONLOOP, 0, 0, -1); + break; + } + } + } + } + + if (plr.currweapon == 0 && dahand == 0) + if (krand() % 2 == 0) + dahand = 1; + else + dahand = 2; + + switch (plr.currweaponfired) { + case 6: + switch (plr.currweapon) { + case 1: // knife + if (plr.currweaponframe == KNIFEATTACK2 + 1) + if ((plr.currweaponanim == 2 || plr.currweaponanim == 10) && plr.currweapontics == 8) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 3: // morning + if (plr.currweaponframe == MORNINGATTACK2 + 3) + if (plr.currweaponanim == 3 && plr.currweapontics == 12) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + } + + if (plr.currweaponframe == RFIST + 5 || plr.currweaponframe == KNIFEATTACK + 6 + || plr.currweaponframe == ZKNIFEATTACK + 5 // new + || plr.currweaponframe == MORNINGSTAR + 5 || plr.currweaponframe == SWORDATTACK + 7 + || plr.currweaponframe == BOWWALK + 5 || plr.currweaponframe == ZBOWATTACK + 4 + || plr.currweaponframe == KNIFEATTACK2 + 2 || plr.currweaponframe == ZKNIFEATTACK2 + 2 + || plr.currweaponframe == SWORDATTACK2 + 6 || plr.currweaponframe == MORNINGATTACK2 + 3 + || plr.currweaponframe == HALBERDATTACK1 + 3 || plr.currweaponframe == HALBERDATTACK2 + 3 + || plr.currweaponframe == BIGAXEATTACK + 7 || plr.currweaponframe == BIGAXEATTACK2 + 6 + || plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == PIKEATTACK2 + 4 + || plr.currweaponframe == EXCALATTACK1 + 7 || plr.currweaponframe == EXCALATTACK2 + 5 + || plr.currweaponframe == GOBSWORDATTACK2 + 4 || plr.currweaponframe == GOBSWORDATTACK + 4 + || plr.currweaponframe == ZSHORTATTACK + 7 || plr.currweaponframe == ZSHORTATTACK2 + 4 + || plr.currweaponframe == ZSTARATTACK + 7 || plr.currweaponframe == ZSTARATTACK2 + 3 + || plr.currweaponframe == ZAXEATTACK + 12 || plr.currweaponframe == ZAXEATTACK2 + 6 + || plr.currweaponframe == ZPIKEATTACK + 4 || plr.currweaponframe == ZPIKEATTACK2 + 4 + || plr.currweaponframe == ZTWOHANDATTACK + 12 || plr.currweaponframe == ZTWOHANDATTACK2 + 5 + || plr.currweaponframe == ZHALBERDATTACK + 4 || plr.currweaponframe == ZHALBERDATTACK2 + 3) + + swingdaweapon(plr); + + plr.currweapontics -= TICSPERFRAME; + if (plr.helmettime > 0) + plr.currweapontics--; + + if (plr.currweapontics < 0) { + plr.currweaponanim++; + + if (plr.currweaponanim > 11) { + plr.currweaponanim = 0; + plr.currweaponfired = 0; + plr.currweaponflip = 0; + plr.currweapon = plr.selectedgun; + if (dahand > 0) + dahand = 0; + } + + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweapontics = lefthandanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = lefthandanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } else { + plr.currweapontics = zlefthandanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = zlefthandanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + + } + } else { + plr.currweapontics = lefthandanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = lefthandanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else { + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweaponframe = lefthandanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } else { + plr.currweaponframe = zlefthandanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else + plr.currweaponframe = lefthandanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + + if (plr.currweapon == 0 && plr.currweaponframe == 0) { + dahand = 0; + plr.currweaponanim = 0; + plr.currweaponfired = 0; + } + + if (plr.selectedgun == 4 && plr.currweaponframe == 0) { + plr.currweaponanim = 0; + plr.currweaponfired = 0; + plr.currweaponflip = 0; + plr.currweapon = plr.selectedgun; + } + break; + case 1: // fire + switch (plr.currweapon) { + case 0: // fist + if (plr.currweaponframe == RFIST + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 10) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 1: // knife + if (plr.currweaponframe == KNIFEATTACK + 6 || plr.currweaponframe == ZKNIFEATTACK + 5) + if (plr.currweaponanim == 8 && plr.currweapontics == 8) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == KNIFEATTACK2 + 2 || plr.currweaponframe == ZKNIFEATTACK2 + 2) + if ((plr.currweaponanim == 5 || plr.currweaponanim == 9) && plr.currweapontics == 8) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 2: // shortsword + if (plr.currweaponframe == GOBSWORDATTACK + 4 || plr.currweaponframe == ZSHORTATTACK + 7) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == GOBSWORDATTACK2 + 4 || plr.currweaponframe == ZSHORTATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 3: // morning + if (plr.currweaponframe == MORNINGSTAR + 5 || plr.currweaponframe == ZSTARATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == MORNINGATTACK2 + 3 || plr.currweaponframe == ZSTARATTACK2 + 3) + if (plr.currweaponanim == 3 && plr.currweapontics == 12) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 4: // sword + if (plr.currweaponframe == SWORDATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == SWORDATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 8) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 5: // battleaxe + if (plr.currweaponframe == BIGAXEATTACK + 7 || plr.currweaponframe == ZAXEATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == BIGAXEATTACK2 + 6 || plr.currweaponframe == ZAXEATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 6: // bow + if (plr.currweaponframe == BOWWALK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == ZBOWATTACK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 7: // pike + if (plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == ZPIKEATTACK + 4) + if (plr.currweaponanim == 8 && plr.currweapontics == 10) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == PIKEATTACK2 + 4 || plr.currweaponframe == ZPIKEATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 8: // two handed sword + if (plr.currweaponframe == EXCALATTACK1 + 7 || plr.currweaponframe == ZTWOHANDATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == EXCALATTACK2 + 5 || plr.currweaponframe == ZTWOHANDATTACK2 + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 8) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + case 9: // halberd + if (plr.currweaponframe == HALBERDATTACK1 + 3 || plr.currweaponframe == ZHALBERDATTACK + 4) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + if (plr.currweaponframe == HALBERDATTACK2 + 3 || plr.currweaponframe == ZHALBERDATTACK2 + 3) + if (plr.currweaponanim == 4 && plr.currweapontics == 12) + swingdasound(plr.currweapon, plr.weapon[plr.currweapon] == 3); + break; + } + + if (plr.currweaponframe == RFIST + 5 || plr.currweaponframe == KNIFEATTACK + 6 + || plr.currweaponframe == ZKNIFEATTACK + 5 // new + || plr.currweaponframe == MORNINGSTAR + 5 || plr.currweaponframe == SWORDATTACK + 7 + || plr.currweaponframe == BOWWALK + 5 || plr.currweaponframe == ZBOWATTACK + 4 + || plr.currweaponframe == KNIFEATTACK2 + 2 || plr.currweaponframe == ZKNIFEATTACK2 + 2 + || plr.currweaponframe == SWORDATTACK2 + 6 || plr.currweaponframe == MORNINGATTACK2 + 3 + || plr.currweaponframe == HALBERDATTACK1 + 3 || plr.currweaponframe == HALBERDATTACK2 + 3 + || plr.currweaponframe == BIGAXEATTACK + 7 || plr.currweaponframe == BIGAXEATTACK2 + 6 + || plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == PIKEATTACK2 + 4 + || plr.currweaponframe == EXCALATTACK1 + 7 || plr.currweaponframe == EXCALATTACK2 + 5 + || plr.currweaponframe == GOBSWORDATTACK2 + 4 || plr.currweaponframe == GOBSWORDATTACK + 4 + || plr.currweaponframe == ZSHORTATTACK + 7 || plr.currweaponframe == ZSHORTATTACK2 + 4 + || plr.currweaponframe == ZSTARATTACK + 7 || plr.currweaponframe == ZSTARATTACK2 + 3 + || plr.currweaponframe == ZAXEATTACK + 12 || plr.currweaponframe == ZAXEATTACK2 + 6 + || plr.currweaponframe == ZPIKEATTACK + 4 || plr.currweaponframe == ZPIKEATTACK2 + 4 + || plr.currweaponframe == ZTWOHANDATTACK + 12 || plr.currweaponframe == ZTWOHANDATTACK2 + 5 + || plr.currweaponframe == ZHALBERDATTACK + 4 || plr.currweaponframe == ZHALBERDATTACK2 + 3) + + swingdaweapon(plr); + + plr.currweapontics -= TICSPERFRAME; + if (plr.helmettime > 0) + plr.currweapontics--; + + if (plr.shieldpoints <= 0) + droptheshield = true; + + if ((plr.currweaponframe == SWORDATTACK + 7 || plr.currweaponframe == SWORDATTACK2 + 7) + && plr.currweapontics < 0 && droptheshield) { + if (rand() % 100 > 50) { + + if (isWh2()) { + if (plr.ammo[1] > 0 && plr.weapon[3] == 0) { + plr.currweapon = 1; + plr.currweapontics = 6; + plr.currweaponanim = 0; + plr.currweaponfired = 6; + plr.hasshot = 0; + plr.currweaponflip = 1; + } + if (plr.ammo[3] > 0) { + plr.currweapon = 3; + plr.currweapontics = 6; + plr.currweaponanim = 0; + plr.currweaponfired = 6; + plr.hasshot = 0; + plr.currweaponflip = 1; + } + } else { + if (plr.lvl >= 4 && plr.lvl <= 4 && plr.ammo[1] > 0) { + plr.currweapon = 1; + plr.currweapontics = 6; + plr.currweaponanim = 0; + plr.currweaponfired = 6; + plr.hasshot = 0; + plr.currweaponflip = 1; + } else if (plr.lvl >= 5 && plr.ammo[3] > 0) { + plr.currweapon = 3; + plr.currweapontics = 6; + plr.currweaponanim = 0; + plr.currweaponfired = 6; + plr.hasshot = 0; + plr.currweaponflip = 1; + } + } + } + } + if (plr.currweapontics < 0) { + plr.currweaponanim++; + if (plr.currweaponanim > 11) { + plr.currweaponanim = 0; + plr.currweaponfired = 0; + if (dahand > 0) + dahand = 0; + } + if (plr.currweaponattackstyle == 0) { + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweapontics = weaponanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = weaponanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } else { + plr.currweapontics = zweaponanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = zweaponanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else { + plr.currweapontics = weaponanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = weaponanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else { + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweapontics = weaponanimtics2[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = weaponanimtics2[plr.currweapon][plr.currweaponanim].daweaponframe; + } else { + plr.currweapontics = zweaponanimtics2[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = zweaponanimtics2[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else { + plr.currweapontics = weaponanimtics2[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = weaponanimtics2[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } + } else { + if (isWh2()) { + if (plr.currweaponattackstyle == 0) { + // flip + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweaponframe = weaponanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } else { + plr.currweaponframe = zweaponanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else { + // flip + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweaponframe = weaponanimtics2[plr.currweapon][plr.currweaponanim].daweaponframe; + } else { + plr.currweaponframe = zweaponanimtics2[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } + } else { + if (plr.currweaponattackstyle == 0) { + // flip + plr.currweaponframe = weaponanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } else { + // flip + plr.currweaponframe = weaponanimtics2[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } + } + + if (plr.currweapon == 0 && plr.currweaponframe == 0) { + dahand = 0; + plr.currweaponanim = 0; + plr.currweaponfired = 0; + } + break; + + case 0: // walking + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) + plr.currweapontics = weaponanimtics[plr.currweapon][0].daweapontics; + else + plr.currweapontics = zweaponanimtics[plr.currweapon][0].daweapontics; + + if (plr.currweapon == 6 && plr.ammo[6] <= 0) { + // wango + if (plr.weapon[plr.currweapon] == 1) + plr.currweaponframe = BOWREADYEND; + else + plr.currweaponframe = ZBOWWALK; + } else { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) + plr.currweaponframe = weaponanimtics[plr.currweapon][0].daweaponframe; + else + plr.currweaponframe = zweaponanimtics[plr.currweapon][0].daweaponframe; + } + } else { + plr.currweapontics = weaponanimtics[plr.currweapon][0].daweapontics; + + if (plr.currweapon == 6 && plr.ammo[6] <= 0) + plr.currweaponframe = BOWREADYEND; + else + plr.currweaponframe = weaponanimtics[plr.currweapon][0].daweaponframe; + } + if ((plr.pInput.fvel|plr.pInput.svel) != 0) { + snakex = (sintable[(lockclock << 4) & 2047] >> 12); + snakey = (sintable[(totalclock << 4) & 2047] >> 12); + } + break; + case 2: // unready + if (plr.currweapon == 1) + weapondrop += TICSPERFRAME << 1; + else + weapondrop += TICSPERFRAME; + if (weapondrop > weapondropgoal) { + plr.currweaponfired = 3; +// weaponraise = 40; + plr.currweapon = plr.selectedgun; + } + + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) + plr.currweapontics = weaponanimtics[plr.currweapon][0].daweapontics; + else + plr.currweapontics = zweaponanimtics[plr.currweapon][0].daweapontics; + + if (plr.currweapon == 6 && plr.ammo[6] <= 0) { + if (plr.weapon[plr.currweapon] == 1) + plr.currweaponframe = BOWREADYEND; + else + // currweaponframe=ZBOWREADYEND; + plr.currweaponframe = ZBOWWALK; + } else { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) + plr.currweaponframe = weaponanimtics[plr.currweapon][0].daweaponframe; + else + plr.currweaponframe = zweaponanimtics[plr.currweapon][0].daweaponframe; + } + } else { + plr.currweapontics = weaponanimtics[plr.currweapon][0].daweapontics; + + if (plr.currweapon == 6 && plr.ammo[6] <= 0) + plr.currweaponframe = BOWREADYEND; + else + plr.currweaponframe = weaponanimtics[plr.currweapon][0].daweaponframe; + } + break; + case 3: // ready + plr.currweapontics -= TICSPERFRAME; + if (plr.currweapontics < 0) { + plr.currweaponanim++; + if (plr.currweaponanim == 12) { + plr.currweaponanim = 0; + plr.currweaponfired = 0; + + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweaponframe = readyanimtics[plr.currweapon][11].daweaponframe; + } else { + plr.currweaponframe = zreadyanimtics[plr.currweapon][11].daweaponframe; + } + } else + plr.currweaponframe = readyanimtics[plr.currweapon][11].daweaponframe; + break; + } + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweapontics = readyanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = readyanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } else { + plr.currweapontics = zreadyanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = zreadyanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else { + plr.currweapontics = readyanimtics[plr.currweapon][plr.currweaponanim].daweapontics; + plr.currweaponframe = readyanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else { + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweaponframe = readyanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + + } else { + plr.currweaponframe = zreadyanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + } else + plr.currweaponframe = readyanimtics[plr.currweapon][plr.currweaponanim].daweaponframe; + } + break; + case 5: // cock + plr.currweapontics -= (TICSPERFRAME); + if (plr.currweapontics < 0) { + plr.currweaponanim++; + if (plr.currweaponanim == 4) { + plr.currweaponanim = 0; + plr.currweaponfired = 0; + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweaponframe = cockanimtics[3].daweaponframe; + } else { + if (plr.weapon[plr.currweapon] == 3) { + plr.currweaponframe = zcockanimtics[4].daweaponframe; + } else { + plr.currweaponframe = cockanimtics[4].daweaponframe; + + } + } + + } else + plr.currweaponframe = cockanimtics[3].daweaponframe; + break; + } + + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweapontics = cockanimtics[plr.currweaponanim].daweapontics; + plr.currweaponframe = cockanimtics[plr.currweaponanim].daweaponframe; + } else { + if (plr.weapon[plr.currweapon] == 3) { + plr.currweapontics = zcockanimtics[plr.currweaponanim].daweapontics; + plr.currweaponframe = zcockanimtics[plr.currweaponanim].daweaponframe; + + } else { + plr.currweapontics = cockanimtics[plr.currweaponanim].daweapontics; + plr.currweaponframe = cockanimtics[plr.currweaponanim].daweaponframe; + } + } + } else { + plr.currweapontics = cockanimtics[plr.currweaponanim].daweapontics; + plr.currweaponframe = cockanimtics[plr.currweaponanim].daweaponframe; + } + } else { + if (isWh2()) { + if (plr.weapon[plr.currweapon] == 1 || plr.weapon[7] == 2) { + plr.currweaponframe = cockanimtics[plr.currweaponanim].daweaponframe; + } else { + if (plr.weapon[plr.currweapon] == 3) { + plr.currweaponframe = zcockanimtics[plr.currweaponanim].daweaponframe; + } else { + plr.currweaponframe = zcockanimtics[plr.currweaponanim].daweaponframe; + } + } + } else + plr.currweaponframe = cockanimtics[plr.currweaponanim].daweaponframe; + } + break; + case 4: // throw the orb + + if (plr.currweaponframe == 0) + castaorb(plr); + + plr.currweapontics -= (TICSPERFRAME); + if (plr.currweapontics < 0) { + plr.currweaponanim++; + if (plr.currweaponanim > 12) { + plr.currweaponanim = 0; + plr.currweaponfired = 0; + plr.orbshot = 0; + + if (isWh2()) { + plr.currweaponframe = wh2throwanimtics[plr.currentorb][plr.currweaponanim].daweaponframe; + } else + plr.currweaponframe = throwanimtics[plr.currentorb][plr.currweaponanim].daweaponframe; + break; + } + + if (isWh2()) { + plr.currweapontics = wh2throwanimtics[plr.currentorb][plr.currweaponanim].daweapontics; + plr.currweaponframe = wh2throwanimtics[plr.currentorb][plr.currweaponanim].daweaponframe; + } else { + plr.currweapontics = throwanimtics[plr.currentorb][plr.currweaponanim].daweapontics; + plr.currweaponframe = throwanimtics[plr.currentorb][plr.currweaponanim].daweaponframe; + } + + } else { + if (isWh2()) { + plr.currweaponframe = wh2throwanimtics[plr.currentorb][plr.currweaponanim].daweaponframe; + } else + plr.currweaponframe = throwanimtics[plr.currentorb][plr.currweaponanim].daweaponframe; + } + break; + } + + if(plr.currweaponfired != 4 && plr.orbammo[plr.currentorb] <= 0) + spellswitch(plr, 1); + + if (plr.shieldpoints > 0 && (plr.currweaponfired == 0 || plr.currweaponfired == 1) && plr.selectedgun > 0 + && plr.selectedgun < 5 && !droptheshield) { + if (plr.currweaponfired == 1) { + snakex = (sintable[(lockclock << 4) & 2047] >> 12); + snakey = (sintable[(totalclock << 4) & 2047] >> 12); + if (droptheshield) { + dropshieldcnt += (TICSPERFRAME << 1); + snakey += dropshieldcnt; + } + } + + if (dropshieldcnt > 200) { + dropshieldcnt = 0; + droptheshield = true; + } + } +} + +void madenoise(PLAYER& plr, int val, int x, int y, int z) { + short nextsprite; + for (short i = headspritestat[FACE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + if ((klabs(x - sprite[i].x) + klabs(y - sprite[i].y) < (val * 4096))) + newstatus(i, FINDME); + } +} + +void shootgun(PLAYER& plr, float ang, int guntype) { + int k = 0, daz2; + short j, i; + + int daang = (int) ang; + + if(plr.hasshot == 1) + return; + + switch (guntype) { + case 0: + daz2 = (int) (100 - plr.horiz) * 2000; + + hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position + sintable[(daang + 2560) & 2047], // X vector of 3D ang + sintable[(daang + 2048) & 2047], // Y vector of 3D ang + daz2, // Z vector of 3D ang + pHitInfo, CLIPMASK1); + + if (pHitInfo.hitsprite >= 0) + madeahit = true; + + if (pHitInfo.hitwall >= 0) { + if ((klabs(plr.x - pHitInfo.hitx) + klabs(plr.y - pHitInfo.hity) < 512) + && (klabs((plr.z >> 8) - ((pHitInfo.hitz >> 8) - (64))) <= (512 >> 3))) { + madeahit = true; + switch (plr.currweapon) { + case 0: // fist + if (plr.currweaponframe == RFIST + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 10) + swingdapunch(plr, plr.currweapon); + break; + case 1: // knife + if (plr.currweaponframe == KNIFEATTACK + 6) + if (plr.currweaponanim == 8 && plr.currweapontics == 8) + swingdapunch(plr, plr.currweapon); + if (plr.currweaponframe == KNIFEATTACK2 + 2) + if (plr.currweaponanim == 5 || plr.currweaponanim == 9 && plr.currweapontics == 8) + swingdapunch(plr, plr.currweapon); + break; + case 2: // short sword + if (plr.currweaponframe == GOBSWORDATTACK + 4 || plr.currweaponframe == ZSHORTATTACK + 7) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdapunch(plr, plr.currweapon); + if (plr.currweaponframe == GOBSWORDATTACK + 4 || plr.currweaponframe == ZSHORTATTACK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdapunch(plr, plr.currweapon); + break; + case 3: // morning + if (plr.currweaponframe == MORNINGSTAR + 5 || plr.currweaponframe == ZSTARATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdapunch(plr, plr.currweapon); + if (plr.currweaponframe == MORNINGATTACK2 + 3 || plr.currweaponframe == ZSTARATTACK + 3) + if (plr.currweaponanim == 3 && plr.currweapontics == 12) + swingdapunch(plr, plr.currweapon); + break; + case 4: // sword + if (plr.currweaponframe == SWORDATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) { + swingdapunch(plr, plr.currweapon); + madenoise(plr, 2, plr.x, plr.y, plr.z); + } + if (plr.currweaponframe == SWORDATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 8) { + swingdapunch(plr, plr.currweapon); + madenoise(plr, 2, plr.x, plr.y, plr.z); + } + break; + case 5: // battleaxe + if (plr.currweaponframe == BIGAXEATTACK + 7 || plr.currweaponframe == ZAXEATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdapunch(plr, plr.currweapon); + if (plr.currweaponframe == BIGAXEATTACK2 + 6 || plr.currweaponframe == ZAXEATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + swingdapunch(plr, plr.currweapon); + break; + case 6: // bow + if (plr.currweaponframe == BOWWALK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + swingdapunch(plr, plr.currweapon); + if (plr.currweaponframe == ZBOWATTACK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + swingdapunch(plr, plr.currweapon); + break; + case 7: // pike + if (plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == ZPIKEATTACK + 4) + if (plr.currweaponanim == 8 && plr.currweapontics == 10) + swingdapunch(plr, plr.currweapon); + if (plr.currweaponframe == PIKEATTACK2 + 4 || plr.currweaponframe == ZPIKEATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdapunch(plr, plr.currweapon); + break; + case 8: // two handed sword + if (plr.currweaponframe == EXCALATTACK1 + 7 || plr.currweaponframe == ZTWOHANDATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + swingdapunch(plr, plr.currweapon); + if (plr.currweaponframe == EXCALATTACK2 + 5 || plr.currweaponframe == ZTWOHANDATTACK2 + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 8) + swingdapunch(plr, plr.currweapon); + break; + case 9: // halberd + if (plr.currweaponframe == HALBERDATTACK1 + 3 || plr.currweaponframe == ZHALBERDATTACK + 4) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + swingdapunch(plr, plr.currweapon); + if (plr.currweaponframe == HALBERDATTACK2 + 3 || plr.currweaponframe == ZHALBERDATTACK2 + 3) + if (plr.currweaponanim == 4 && plr.currweapontics == 12) + swingdapunch(plr, plr.currweapon); + break; + } + } + } + + if (checkweapondist(pHitInfo.hitsprite, plr.x, plr.y, plr.z, plr.selectedgun)) { + madeahit = true; + + switch (sprite[pHitInfo.hitsprite].detail) { + + case DEMONTYPE: + case GONZOTYPE: + case KATIETYPE: + case KURTTYPE: + case NEWGUYTYPE: + case GRONTYPE: + case KOBOLDTYPE: + case DRAGONTYPE: + case DEVILTYPE: + case FREDTYPE: + case SKELETONTYPE: + case GOBLINTYPE: + case IMPTYPE: + case MINOTAURTYPE: + case SPIDERTYPE: + case SKULLYTYPE: + case FATWITCHTYPE: + case FISHTYPE: + case RATTYPE: + case WILLOWTYPE: + case GUARDIANTYPE: + case JUDYTYPE: + if (netgame) { + // XXX netshootgun(pHitInfo.hitsprite,currweapon); + } + + if(sprite[pHitInfo.hitsprite].statnum == DIE || sprite[pHitInfo.hitsprite].statnum == DEAD) //already dying + break; + + if (isWh2() && plr.currweapon == 3) + if (plr.weapon[plr.currweapon] == 3) { + explosion(pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, 4096); + } + + if (plr.invisibletime > 0) { + if (isWh2()) { + if ((krand() & 32) > 15) + plr.invisibletime = -1; + } else { + if ((krand() & 1) != 0) + plr.invisibletime = -1; + } + } + + switch (plr.selectedgun) { + case 0: // fist + if (isWh2()) { + k = (krand() % 5) + 1; + break; + } + k = (krand() & 5) + 1; + break; + case 1: // dagger + if (isWh2()) { + k = (krand() % 5) + 5; + break; + } + + if (plr.currweaponattackstyle == 0) + k = (krand() & 5) + 10; + else + k = (krand() & 3) + 5; + + break; + case 2: // short sword + if (isWh2()) { + k = (krand() % 10) + 5; + break; + } + + if (plr.currweaponattackstyle == 0) + k = (krand() & 10) + 10; + else + k = (krand() & 6) + 10; + break; + case 3: // morning star + if (isWh2()) { + k = (krand() % 15) + 5; + break; + } + + if (plr.currweaponattackstyle == 0) + k = (krand() & 8) + 10; + else + k = (krand() & 8) + 15; + break; + case 4: // broad sword + if (isWh2()) { + k = (krand() % 20) + 5; + break; + } + + if (plr.currweaponattackstyle == 0) + k = (krand() & 5) + 20; + else + k = (krand() & 5) + 15; + break; + case 5: // battle axe + if (isWh2()) { + k = (krand() % 25) + 5; + switch (sprite[pHitInfo.hitsprite].detail) { + case GRONTYPE: + case NEWGUYTYPE: + case KURTTYPE: + case GONZOTYPE: + k += k >> 1; + break; + } + break; + } + + if (plr.currweaponattackstyle == 0) + k = (krand() & 5) + 25; + else + k = (krand() & 5) + 20; + break; + case 6: // bow + if (isWh2()) { + k = (krand() % 30) + 5; + break; + } + + if (plr.currweaponattackstyle == 0) + k = (krand() & 15) + 5; + else + k = (krand() & 15) + 5; + break; + case 7: // pike axe + if (isWh2()) { + k = (krand() % 35) + 5; + break; + } + if (plr.currweaponattackstyle == 0) + k = (krand() & 15) + 10; + else + k = (krand() & 15) + 5; + break; + case 8: // two handed sword + if (isWh2()) { + k = (krand() % 40) + 5; + break; + } + if (plr.currweaponattackstyle == 0) + k = (krand() & 15) + 45; + else + k = (krand() & 15) + 40; + break; + case 9: // halberd + if (isWh2()) { + k = (krand() % 45) + 5; + break; + } + + if (plr.currweaponattackstyle == 0) + k = (krand() & 15) + 25; + else + k = (krand() & 15) + 15; + break; + + } + + k += plr.lvl; + if (isWh2() && plr.weapon[plr.currweapon] == 3) { + k <<= 1; + } + + if (plr.vampiretime > 0) { + if (plr.health <= plr.maxhealth) + addhealth(plr, (krand() % 10) + 1); + } + if (plr.helmettime > 0) + k <<= 1; + if (plr.strongtime > 0) { + k += k >> 1; + + switch (plr.currweapon) { + case 0: // fist + if (plr.currweaponframe == RFIST + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + break; + case 1: // knife + if (plr.currweaponframe == KNIFEATTACK + 6) + if (plr.currweaponanim == 8 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == KNIFEATTACK2 + 2) + if (plr.currweaponanim == 5 || plr.currweaponanim == 9 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + break; + case 2: // short sword + if (plr.currweaponframe == GOBSWORDATTACK + 4 || plr.currweaponframe == ZSHORTATTACK + 7) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == GOBSWORDATTACK2 + 4 || plr.currweaponframe == ZSHORTATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + break; + case 3: // morning + if (plr.currweaponframe == MORNINGSTAR + 5 || plr.currweaponframe == ZSTARATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == MORNINGATTACK2 + 3 || plr.currweaponframe == ZSTARATTACK2 + 3) + if (plr.currweaponanim == 3 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + break; + case 4: // sword + if (plr.currweaponframe == SWORDATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == SWORDATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + break; + case 5: // battleaxe + if (plr.currweaponframe == BIGAXEATTACK + 7 || plr.currweaponframe == ZAXEATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == BIGAXEATTACK2 + 6 || plr.currweaponframe == ZAXEATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + break; + case 6: // bow + if (plr.currweaponframe == BOWWALK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == ZBOWATTACK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + swingdacrunch(plr, plr.currweapon); + break; + case 7: // pike + if (plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == ZPIKEATTACK + 4) + if (plr.currweaponanim == 8 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == PIKEATTACK2 + 4 || plr.currweaponframe == ZPIKEATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + break; + case 8: // two handed sword + if (plr.currweaponframe == EXCALATTACK1 + 7 || plr.currweaponframe == ZTWOHANDATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == EXCALATTACK2 + 5 || plr.currweaponframe == ZTWOHANDATTACK2 + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + break; + case 9: // halberd + if (plr.currweaponframe == HALBERDATTACK1 + 3 || plr.currweaponframe == ZHALBERDATTACK + 4) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == HALBERDATTACK2 + 3 || plr.currweaponframe == ZHALBERDATTACK2 + 3) + if (plr.currweaponanim == 4 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + break; + } + sprite[pHitInfo.hitsprite].hitag -= (k << 1); + if (isWh2() && plr.weapon[plr.currweapon] == 3 && plr.currweapon == 8 + && sprite[pHitInfo.hitsprite].pal != 6) { + if (sprite[pHitInfo.hitsprite].hitag <= 0) { + sprite[pHitInfo.hitsprite].hitag = 1; + } + if (krand() % 100 > 50) + medusa(plr, pHitInfo.hitsprite); + break; + } + + else if (plr.currweapon != 0) { + + // JSA GORE1 you have strong time + if (krand() % 100 > 50) { + if (sprite[pHitInfo.hitsprite].picnum == SKELETON + || sprite[pHitInfo.hitsprite].picnum == SKELETONATTACK + || sprite[pHitInfo.hitsprite].picnum == SKELETONDIE) + playsound_loc(S_SKELHIT1 + (krand() % 2), sprite[pHitInfo.hitsprite].x, + sprite[pHitInfo.hitsprite].y); + } + + // HERE + switch (plr.currweapon) { + case 0: // fist + break; + case 1: // knife + if (plr.currweaponframe == KNIFEATTACK + 6) + if (plr.currweaponanim == 8 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == KNIFEATTACK2 + 2) + if (plr.currweaponanim == 5 || plr.currweaponanim == 9 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 2: // short sword + if (plr.currweaponframe == GOBSWORDATTACK + 4 + || plr.currweaponframe == ZSHORTATTACK + 7) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == GOBSWORDATTACK2 + 4 + || plr.currweaponframe == ZSHORTATTACK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 3: // morning + if (plr.currweaponframe == MORNINGSTAR + 5 || plr.currweaponframe == ZSTARATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == MORNINGATTACK2 + 3 + || plr.currweaponframe == ZSTARATTACK2 + 3) + if (plr.currweaponanim == 3 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 4: // sword + if (plr.currweaponframe == SWORDATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == SWORDATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 8) + break; + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, + pHitInfo.hitsect, daang); + case 5: // battleaxe + if (plr.currweaponframe == BIGAXEATTACK + 7 || plr.currweaponframe == ZAXEATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == BIGAXEATTACK2 + 6 || plr.currweaponframe == ZAXEATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + break; + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, + pHitInfo.hitsect, daang); + case 6: // bow + if (plr.currweaponframe == BOWWALK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == ZBOWATTACK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 7: // pike + if (plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == ZPIKEATTACK + 4) + if (plr.currweaponanim == 8 && plr.currweapontics == 10) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == PIKEATTACK2 + 4 || plr.currweaponframe == ZPIKEATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + break; + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, + pHitInfo.hitsect, daang); + case 8: // two handed sword + if (plr.currweaponframe == EXCALATTACK1 + 7 + || plr.currweaponframe == ZTWOHANDATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == EXCALATTACK2 + 5 + || plr.currweaponframe == ZTWOHANDATTACK2 + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 8) + break; + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, + pHitInfo.hitsect, daang); + case 9: // halberd + if (plr.currweaponframe == HALBERDATTACK1 + 3 + || plr.currweaponframe == ZHALBERDATTACK + 4) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == HALBERDATTACK2 + 3 + || plr.currweaponframe == ZHALBERDATTACK2 + 3) + if (plr.currweaponanim == 4 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + } + } + + } else { + switch (plr.currweapon) { + case 0: // fist + if (plr.currweaponframe == RFIST + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + break; + case 1: // knife + if (plr.currweaponframe == KNIFEATTACK + 6) + if (plr.currweaponanim == 8 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == KNIFEATTACK2 + 2) + if (plr.currweaponanim == 5 || plr.currweaponanim == 9 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + break; + case 2: // SHORT SWORD + if (plr.currweaponframe == GOBSWORDATTACK + 4 || plr.currweaponframe == ZSHORTATTACK + 7) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == GOBSWORDATTACK2 + 4 || plr.currweaponframe == ZSHORTATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + break; + case 3: // morning + if (plr.currweaponframe == MORNINGSTAR + 5 || plr.currweaponframe == ZSTARATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == MORNINGATTACK2 + 3 || plr.currweaponframe == ZSTARATTACK2 + 3) + if (plr.currweaponanim == 3 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + break; + case 4: // sword + if (plr.currweaponframe == SWORDATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == SWORDATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + break; + case 5: // battleaxe + if (plr.currweaponframe == BIGAXEATTACK + 7 || plr.currweaponframe == ZAXEATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == BIGAXEATTACK2 + 6 || plr.currweaponframe == ZAXEATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + break; + case 6: // bow + if (plr.currweaponframe == BOWWALK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == ZBOWATTACK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + swingdacrunch(plr, plr.currweapon); + break; + + case 7: // pike + if (plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == ZPIKEATTACK + 4) + if (plr.currweaponanim == 8 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == PIKEATTACK2 + 4 || plr.currweaponframe == ZPIKEATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + swingdacrunch(plr, plr.currweapon); + break; + case 8: // two handed sword + if (plr.currweaponframe == EXCALATTACK1 + 7 || plr.currweaponframe == ZTWOHANDATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == EXCALATTACK2 + 5 || plr.currweaponframe == ZTWOHANDATTACK2 + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 8) + swingdacrunch(plr, plr.currweapon); + break; + case 9: // halberd + if (plr.currweaponframe == HALBERDATTACK1 + 3 || plr.currweaponframe == ZHALBERDATTACK + 4) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + if (plr.currweaponframe == HALBERDATTACK2 + 3 || plr.currweaponframe == ZHALBERDATTACK2 + 3) + if (plr.currweaponanim == 4 && plr.currweapontics == 12) + swingdacrunch(plr, plr.currweapon); + break; + } + sprite[pHitInfo.hitsprite].hitag -= k; + + if (isWh2() && plr.weapon[plr.currweapon] == 3 && plr.currweapon == 8 + && sprite[pHitInfo.hitsprite].pal != 6) { + if (sprite[pHitInfo.hitsprite].hitag <= 0) { + sprite[pHitInfo.hitsprite].hitag = 1; + } + if (krand() % 100 > 75) + medusa(plr, pHitInfo.hitsprite); + break; + } + + if (plr.currweapon != 0) { + // JSA GORE normal + if (krand() % 100 > 50) { + if (sprite[pHitInfo.hitsprite].picnum == SKELETON + || sprite[pHitInfo.hitsprite].picnum == SKELETONATTACK + || sprite[pHitInfo.hitsprite].picnum == SKELETONDIE) + playsound_loc(S_SKELHIT1 + (krand() % 2), sprite[pHitInfo.hitsprite].x, + sprite[pHitInfo.hitsprite].y); + } + // HERE + switch (plr.currweapon) { + case 0: // fist + break; + case 1: // knife + if (plr.currweaponframe == KNIFEATTACK + 6) + if (plr.currweaponanim == 8 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == KNIFEATTACK2 + 2) + if (plr.currweaponanim == 5 || plr.currweaponanim == 9 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 2: // short sword + if (plr.currweaponframe == GOBSWORDATTACK + 4 + || plr.currweaponframe == ZSHORTATTACK + 7) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == GOBSWORDATTACK2 + 4 + || plr.currweaponframe == ZSHORTATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 3: // morning + if (plr.currweaponframe == MORNINGSTAR + 5 || plr.currweaponframe == ZSTARATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == MORNINGATTACK2 + 3 + || plr.currweaponframe == ZSTARATTACK2 + 3) + if (plr.currweaponanim == 3 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 4: // sword + if (plr.currweaponframe == SWORDATTACK + 7) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == SWORDATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 5: // battleaxe + if (plr.currweaponframe == BIGAXEATTACK + 7 || plr.currweaponframe == ZAXEATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == BIGAXEATTACK2 + 6 || plr.currweaponframe == ZAXEATTACK2 + 6) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 6: // bow + if (plr.currweaponframe == BOWWALK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == ZBOWATTACK + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 6) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 7: // pike + if (plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == ZPIKEATTACK + 4) + if (plr.currweaponanim == 8 && plr.currweapontics == 10) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == PIKEATTACK2 + 4 || plr.currweaponframe == ZPIKEATTACK2 + 4) + if (plr.currweaponanim == 4 && plr.currweapontics == 10) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 8: // two handed sword + if (plr.currweaponframe == EXCALATTACK1 + 7 + || plr.currweaponframe == ZTWOHANDATTACK + 12) + if (plr.currweaponanim == 7 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == EXCALATTACK2 + 5 + || plr.currweaponframe == ZTWOHANDATTACK2 + 5) + if (plr.currweaponanim == 5 && plr.currweapontics == 8) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + case 9: // halberd + if (plr.currweaponframe == HALBERDATTACK1 + 3 + || plr.currweaponframe == ZHALBERDATTACK + 4) + if (plr.currweaponanim == 6 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + if (plr.currweaponframe == HALBERDATTACK2 + 3 + || plr.currweaponframe == ZHALBERDATTACK2 + 3) + if (plr.currweaponanim == 4 && plr.currweapontics == 12) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, + pHitInfo.hitz, pHitInfo.hitsect, daang); + break; + } + } + } + + if (netgame) { + break; + } + + if (sprite[pHitInfo.hitsprite].hitag <= 0) { + if (plr.selectedgun > 1) { + // JSA GORE on death ? + // RAF ans:death + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, + pHitInfo.hitsect, daang); + if (sprite[pHitInfo.hitsprite].picnum == SKELETON + || sprite[pHitInfo.hitsprite].picnum == SKELETONATTACK + || sprite[pHitInfo.hitsprite].picnum == SKELETONDIE) + playsound_loc(S_SKELHIT1 + (krand() % 2), sprite[pHitInfo.hitsprite].x, + sprite[pHitInfo.hitsprite].y); + } + newstatus(pHitInfo.hitsprite, DIE); + } + sprite[pHitInfo.hitsprite].ang = (short) (plr.ang + ((krand() & 32) - 64)); + if (sprite[pHitInfo.hitsprite].hitag > 0) + newstatus(pHitInfo.hitsprite, PAIN); + break; + } // switch enemytype + + switch (sprite[pHitInfo.hitsprite].detail) { + case GRONTYPE: + case KOBOLDTYPE: + case DRAGONTYPE: + case DEVILTYPE: + case FREDTYPE: + case SKELETONTYPE: + case GOBLINTYPE: + case IMPTYPE: + case MINOTAURTYPE: + case SKULLYTYPE: + case SPIDERTYPE: + case FATWITCHTYPE: + case JUDYTYPE: + case NEWGUYTYPE: + case GONZOTYPE: + case KURTTYPE: + if (sprite[pHitInfo.hitsprite].pal == 6) { + // JSA_NEW + SND_Sound(S_SOCK1 + (krand() % 4)); + playsound_loc(S_FREEZEDIE, pHitInfo.hitx, pHitInfo.hity); + for (k = 0; k < 32; k++) + icecubes(pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, + pHitInfo.hitsprite); + addscore(plr, 100); + deletesprite((short) pHitInfo.hitsprite); + } + break; + } // switch frozen + + switch (sprite[pHitInfo.hitsprite].picnum) { + case STAINGLASS1: + case STAINGLASS2: + case STAINGLASS3: + case STAINGLASS4: + case STAINGLASS5: + case STAINGLASS6: + case STAINGLASS7: + case STAINGLASS8: + case STAINGLASS9: + if (!isWh2()) + break; + case BARREL: + case VASEA: + case VASEB: + case VASEC: + + newstatus(pHitInfo.hitsprite, BROKENVASE); + break; + } // switch + } // if weapondist + + if (!madeahit) { + plr.ammo[plr.currweapon]++; + madeahit = true; + } + break; + case 1: //bow's arrow + daz2 = (int) (100 - plr.horiz) * 2000; + + hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position + sintable[(daang + 2560) & 2047], // X vector of 3D ang + sintable[(daang + 2048) & 2047], // Y vector of 3D ang + daz2, // Z vector of 3D ang + pHitInfo, CLIPMASK1); + + if (pHitInfo.hitwall > 0 && pHitInfo.hitsprite < 0) { // XXX WH2 sector lotag < 6 || > 8 + if (isWh2()) { + arrowcnt = (arrowcnt + 1) % ARROWCOUNTLIMIT; + if (arrowsprite[arrowcnt] != -1) { + deletesprite((short) arrowsprite[arrowcnt]); + arrowsprite[arrowcnt] = -1; + } + } + + neartag(pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, (short) pHitInfo.hitsect, (short) daang, + neartag, 1024, 3); + + if (neartag.tagsector < 0) { + j = insertsprite(pHitInfo.hitsect, (short) 0); + sprite[j].x = pHitInfo.hitx; + sprite[j].y = pHitInfo.hity; + sprite[j].z = pHitInfo.hitz + (8 << 8); + sprite[j].cstat = 17;// was16 + sprite[j].picnum = WALLARROW; + sprite[j].shade = 0; + sprite[j].pal = 0; + sprite[j].xrepeat = 16; + sprite[j].yrepeat = 48; + sprite[j].ang = (short) (((daang) - 512 + (krand() & 128 - 64)) & 2047); + sprite[j].xvel = 0; + sprite[j].yvel = 0; + sprite[j].zvel = 0; + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 32; + sprite[j].hitag = 0; + playsound_loc(S_ARROWHIT, sprite[j].x, sprite[j].y); + + if (isWh2() && plr.weapon[6] == 3 && plr.currweapon == 6) { + j = insertsprite(pHitInfo.hitsect, FIRECHUNK); + sprite[j].x = pHitInfo.hitx; + sprite[j].y = pHitInfo.hity; + sprite[j].z = pHitInfo.hitz + (14 << 8); + sprite[j].cstat = 0; + sprite[j].picnum = ARROWFLAME; + sprite[j].shade = 0; + sprite[j].pal = 0; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].ang = 0; + sprite[j].xvel = 0; + sprite[j].yvel = 0; + sprite[j].zvel = 0; + sprite[j].owner = 0; + sprite[j].lotag = 1200; + sprite[j].hitag = 0; + } + } + + if (netgame) { +// netshootgun(-1,5); + } + } + if (pHitInfo.hitwall > 0 && pHitInfo.hitsprite > 0) { + j = insertsprite(pHitInfo.hitsect, FX); + sprite[j].x = pHitInfo.hitx; + sprite[j].y = pHitInfo.hity; + sprite[j].z = pHitInfo.hitz + (8 << 8); + sprite[j].cstat = 2; + sprite[j].picnum = PLASMA; + sprite[j].shade = -32; + sprite[j].pal = 0; + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + sprite[j].ang = (short) daang; + sprite[j].xvel = 0; + sprite[j].yvel = 0; + sprite[j].zvel = 0; + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 32; + sprite[j].hitag = 0; + movesprite((short) j, ((sintable[(sprite[j].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[j].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + } + if ((pHitInfo.hitsprite >= 0) && (sprite[pHitInfo.hitsprite].statnum < MAXSTATUS)) { + switch (sprite[pHitInfo.hitsprite].detail) { + case KURTTYPE: + case KATIETYPE: + case NEWGUYTYPE: + case GONZOTYPE: + case GRONTYPE: + case KOBOLDTYPE: + case DRAGONTYPE: + case DEMONTYPE: + case DEVILTYPE: + case FREDTYPE: + case SKELETONTYPE: + case GOBLINTYPE: + case IMPTYPE: + case MINOTAURTYPE: + case SPIDERTYPE: + case SKULLYTYPE: + case FATWITCHTYPE: + case FISHTYPE: + case RATTYPE: + case WILLOWTYPE: + case GUARDIANTYPE: + case JUDYTYPE: + if (netgame) { +// netshootgun(pHitInfo.hitsprite,currweapon); + break; + } + if (isWh2()) + sprite[pHitInfo.hitsprite].hitag -= (krand() & 30) + 15; + else + sprite[pHitInfo.hitsprite].hitag -= (krand() & 15) + 15; + + if (sprite[pHitInfo.hitsprite].hitag <= 0) { + newstatus(pHitInfo.hitsprite, DIE); + if (sprite[pHitInfo.hitsprite].picnum == RAT) + chunksofmeat(plr, pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, + pHitInfo.hitsect, daang); + } else { + sprite[pHitInfo.hitsprite].ang = (short) (getangle(plr.x - sprite[pHitInfo.hitsprite].x, + plr.y - sprite[pHitInfo.hitsprite].y) & 2047); + newstatus(pHitInfo.hitsprite, PAIN); + } + break; + } + + switch (sprite[pHitInfo.hitsprite].detail) { + // SHATTER FROZEN CRITTER + case GRONTYPE: + case KOBOLDTYPE: + case DRAGONTYPE: + case DEVILTYPE: + case FREDTYPE: + case SKELETONTYPE: + case GOBLINTYPE: + case IMPTYPE: + case MINOTAURTYPE: + case SKULLYTYPE: + case SPIDERTYPE: + case FATWITCHTYPE: + case JUDYTYPE: + case NEWGUYTYPE: + case GONZOTYPE: + case KURTTYPE: + if (sprite[pHitInfo.hitsprite].pal == 6) { + // JSA_NEW + SND_Sound(S_SOCK1 + (krand() % 4)); + playsound_loc(S_FREEZEDIE, pHitInfo.hitx, pHitInfo.hity); + for (k = 0; k < 32; k++) + icecubes(pHitInfo.hitsprite, pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, + pHitInfo.hitsprite); + deletesprite((short) pHitInfo.hitsprite); + } + } // switch frozen + + switch (sprite[pHitInfo.hitsprite].picnum) { + case STAINGLASS1: + case STAINGLASS2: + case STAINGLASS3: + case STAINGLASS4: + case STAINGLASS5: + case STAINGLASS6: + case STAINGLASS7: + case STAINGLASS8: + case STAINGLASS9: + if (!isWh2()) + break; + + case BARREL: + case VASEA: + case VASEB: + case VASEC: + newstatus(pHitInfo.hitsprite, BROKENVASE); + break; + } // switch + } + break; + + case 6: // MEDUSA + for (i = 0; i < MAXSPRITES; i++) { + // cansee + if (i != plr.spritenum) { + switch (sprite[i].detail) { + case FREDTYPE: + case KOBOLDTYPE: + case GOBLINTYPE: + case IMPTYPE: + case MINOTAURTYPE: + case SPIDERTYPE: + case SKELETONTYPE: + case GRONTYPE: + case GONZOTYPE: + case KURTTYPE: + case NEWGUYTYPE: + if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y, + sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum)) { + // distance check + if (checkmedusadist(i, plr.x, plr.y, plr.z, plr.lvl)) + medusa(plr, i); + } + break; + } + } + } + break; + case 7: // KNOCKSPELL + daz2 = (int) (100 - plr.horiz) * 2000; + + hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position + sintable[(daang + 2560) & 2047], // X vector of 3D ang + sintable[(daang + 2048) & 2047], // Y vector of 3D ang + daz2, // Z vector of 3D ang + pHitInfo, CLIPMASK1); + + if (pHitInfo.hitsect < 0 && pHitInfo.hitsprite < 0 || pHitInfo.hitwall >= 0) { + + neartag(pHitInfo.hitx, pHitInfo.hity, pHitInfo.hitz, (short) pHitInfo.hitsect, (short) daang, + neartag, 1024, 3); + + if (neartag.tagsector >= 0) { + if (sector[neartag.tagsector].lotag >= 60 && sector[neartag.tagsector].lotag <= 69) { + sector[neartag.tagsector].lotag = 6; + sector[neartag.tagsector].hitag = 0; + } + if (sector[neartag.tagsector].lotag >= 70 && sector[neartag.tagsector].lotag <= 79) { + sector[neartag.tagsector].lotag = 7; + sector[neartag.tagsector].hitag = 0; + } + operatesector(plr, neartag.tagsector); + } + + } + break; + case 10: // throw a pike axe + if (plr.currweaponframe == PIKEATTACK1 + 4 || plr.currweaponframe == ZPIKEATTACK + 4) { + if (plr.currweaponanim == 8 && plr.currweapontics == 10) { + if (netgame) { + // netshootgun(-1,15); + } + + if (isWh2()) { + throwpikecnt = (throwpikecnt + 1) % THROWPIKELIMIT; + if (throwpikesprite[throwpikecnt] != -1) { + deletesprite(throwpikesprite[throwpikecnt]); + throwpikesprite[throwpikecnt] = -1; + } + + if (plr.weapon[plr.currweapon] == 3) { + j = insertsprite(plr.sector, MISSILE); + throwpikesprite[throwpikecnt] = j; + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = plr.z + (24 << 8); + sprite[j].cstat = 21; + sprite[j].picnum = THROWPIKE; + sprite[j].ang = (short) (((daang + 2048 + 96) - 512) & 2047); + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + sprite[j].clipdist = 32; + sprite[j].extra = (short) daang; + sprite[j].shade = -15; + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + if (shootgunzvel != 0) { + sprite[j].zvel = (short) shootgunzvel; + shootgunzvel = 0; + } else { + sprite[j].zvel = (short) ((100 - (int) plr.horiz) << 4); + } + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 1024; + sprite[j].hitag = 0; + sprite[j].pal = 0; + movesprite((short) j, ((sintable[(sprite[j].extra + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[j].extra & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + setsprite((short) j, sprite[j].x, sprite[j].y, sprite[j].z); + } else { + j = insertsprite(plr.sector, MISSILE); + throwpikesprite[throwpikecnt] = j; + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = plr.z + (24 << 8); + sprite[j].cstat = 21; + sprite[j].picnum = THROWPIKE; + sprite[j].ang = (short) ((((int) plr.ang + 2048 + 96) - 512) & 2047); + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + sprite[j].clipdist = 32; + sprite[j].extra = (short) plr.ang; + sprite[j].shade = -15; + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + sprite[j].zvel = (short) ((100 - (int) plr.horiz) << 4); + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 1024; + sprite[j].hitag = 0; + sprite[j].pal = 0; + } + } else { + j = insertsprite(plr.sector, MISSILE); + + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = plr.z + (16 << 8); + + // sprite[j].cstat=17; + sprite[j].cstat = 21; + + sprite[j].picnum = THROWPIKE; + sprite[j].ang = (short) BClampAngle((plr.ang + 96) - 512); + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + sprite[j].clipdist = 24; + + sprite[j].extra = (short) plr.ang; + sprite[j].shade = -15; + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + // sprite[j].zvel=((krand()&256)-128); + sprite[j].zvel = (short) ((int) (100 - plr.horiz) << 4); + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 1024; + sprite[j].hitag = 0; + sprite[j].pal = 0; + } + } + } + + if (plr.currweaponframe == PIKEATTACK2 + 4) { + if (plr.currweaponanim == 4 && plr.currweapontics == 10) { + + if (isWh2()) { + throwpikecnt = (throwpikecnt + 1) % THROWPIKELIMIT; + if (throwpikesprite[throwpikecnt] != -1) { + deletesprite((short) throwpikesprite[throwpikecnt]); + throwpikesprite[throwpikecnt] = -1; + } + + if (plr.weapon[plr.currweapon] == 3) { + + j = insertsprite(plr.sector, MISSILE); + throwpikesprite[throwpikecnt] = j; + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = plr.z + (24 << 8); + sprite[j].cstat = 21; + sprite[j].picnum = THROWPIKE; + sprite[j].ang = (short) daang; + + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + sprite[j].clipdist = 32; + sprite[j].extra = (short) daang; + + sprite[j].shade = -15; + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + sprite[j].zvel = (short) ((100 - (int) plr.horiz) << 4); + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 1024; + sprite[j].hitag = 0; + sprite[j].pal = 0; + movesprite((short) j, ((sintable[(sprite[j].extra + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[j].extra & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + setsprite((short) j, sprite[j].x, sprite[j].y, sprite[j].z); + } else { + j = insertsprite(plr.sector, MISSILE); + throwpikesprite[throwpikecnt] = j; + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = plr.z + (24 << 8); + sprite[j].cstat = 21; + sprite[j].picnum = THROWPIKE; + sprite[j].ang = (short) ((((int) plr.ang + 2048 + 96) - 512) & 2047); + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + sprite[j].clipdist = 32; + sprite[j].extra = (short) plr.ang; + sprite[j].shade = -15; + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + sprite[j].zvel = (short) ((100 - (int) plr.horiz) << 4); + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 1024; + sprite[j].hitag = 0; + sprite[j].pal = 0; + } + } else { + j = insertsprite(plr.sector, MISSILE); + + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = plr.z; + + sprite[j].cstat = 21; + + sprite[j].picnum = THROWPIKE; + sprite[j].ang = (short) BClampAngle((plr.ang) - 512); + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + sprite[j].clipdist = 24; + + sprite[j].extra = (short) plr.ang; + sprite[j].shade = -15; + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + sprite[j].zvel = (short) ((krand() & 256) - 128); + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 1024; + sprite[j].hitag = 0; + sprite[j].pal = 0; + } + + } + } + break; + case 2: // parabolic trajectory + + if (netgame) { +// netshootgun(-1,12); + } + + j = insertsprite(plr.sector, MISSILE); + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = plr.z + (8 << 8) + ((krand() & 10) << 8); + sprite[j].cstat = 0; + sprite[j].picnum = PLASMA; + sprite[j].shade = -32; + sprite[j].pal = 0; + sprite[j].xrepeat = 16; + sprite[j].yrepeat = 16; + sprite[j].ang = (short) daang; + sprite[j].xvel = (short) (sintable[(daang + 2560) & 2047] >> 5); + sprite[j].yvel = (short) (sintable[(daang) & 2047] >> 5); + + if (shootgunzvel != 0) { + sprite[j].zvel = (short) shootgunzvel; + shootgunzvel = 0; + } else { + sprite[j].zvel = (short) ((int) (100 - plr.horiz) << 4); + } + + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 256; + sprite[j].hitag = 0; + sprite[j].clipdist = 48; + + movesprite((short) j, ((sintable[(sprite[j].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[j].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + + break; + case 3: + + if (netgame) { +// netshootgun(-1,13); + } + + j = insertsprite(plr.sector, MISSILE); + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = plr.z + (8 << 8); + sprite[j].cstat = 0; // Hitscan does not hit other bullets + sprite[j].picnum = MONSTERBALL; + sprite[j].shade = -32; + sprite[j].pal = 0; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].ang = (short) plr.ang; + sprite[j].xvel = (short) (sintable[(daang + 2560) & 2047] >> 7); + sprite[j].yvel = (short) (sintable[(daang) & 2047] >> 7); + + if (shootgunzvel != 0) { + sprite[j].zvel = (short) shootgunzvel; + shootgunzvel = 0; + } else { + sprite[j].zvel = (short) ((int) (100 - plr.horiz) << 4); + } + + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 256; + sprite[j].hitag = 0; + sprite[j].clipdist = 64; + + // dax=(sintable[(sprite[j].ang+512)&2047]>>6); + // day=(sintable[sprite[j].ang]>>6); + + movesprite((short) j, ((sintable[(sprite[j].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[j].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); + + break; + case 4: + + if (netgame) { +// netshootgun(-1,14); + } + + for (j = 0; j < MAXSPRITES; j++) { + switch (sprite[j].detail) { + case DEMONTYPE: + case NEWGUYTYPE: + case KURTTYPE: + case GONZOTYPE: + case IMPTYPE: + if (!isWh2()) + break; + + case SPIDERTYPE: + case KOBOLDTYPE: + case DEVILTYPE: + case GOBLINTYPE: + case MINOTAURTYPE: + case SKELETONTYPE: + case GRONTYPE: + case DRAGONTYPE: + case GUARDIANTYPE: + case FATWITCHTYPE: + case SKULLYTYPE: + case JUDYTYPE: + case WILLOWTYPE: + if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[j].x, sprite[j].y, + sprite[j].z - (tilesizy[sprite[j].picnum] << 7), sprite[j].sectnum)) + if ((isWh2() && sprite[j].owner != sprite[plr.spritenum].owner) + || checkmedusadist(j, plr.x, plr.y, plr.z, 12)) + nukespell(plr, j); + break; + } + } + break; + } +} + +boolean checkweapondist(int i, int x, int y, int z, int guntype) { + int length = 1024; + + if (guntype != 0) { + switch (guntype) { + case 1: + length = 1024; + break; + case 2: + case 3: + case 4: + case 5: + length = 1536; + break; + case 6: + length = 2048; + break; + case 7: + length = 1024; + break; + case 8: + case 9: + length = 2048; + break; + } + } + + if (i >= 0 && (klabs(x - sprite[i].x) + klabs(y - sprite[i].y) < length) + && (klabs((z >> 8) - ((sprite[i].z >> 8) - (tilesizy[sprite[i].picnum] >> 1))) <= (length >> 3))) + return true; + else + return false; +} + +void swingdapunch(PLAYER& plr, int daweapon) { + switch (daweapon) { + case 0:// hands + SND_Sound(S_SOCK4); + SND_Sound(S_PLRPAIN1 + (krand() % 2)); + addhealth(plr, -1); + startredflash(10); + break; + case 1: // knife + case 2: // mace + case 4: // sword + SND_Sound(S_WALLHIT1); + break; + case 3: // arrow + break; + case 5: + case 6: + case 7: + case 8: + SND_Sound(S_WALLHIT1); + break; + } +} + +void swingdaweapon(PLAYER& plr) { + float daang = plr.ang; + + if (plr.currweaponframe == BOWWALK + 5 && plr.ammo[6] > 0) { + plr.currweaponfired = 5; + plr.currweaponanim = 0; + } + if (plr.currweaponframe == BOWWALK + 5 && plr.ammo[6] <= 0) { + plr.currweaponfired = 0; + plr.currweaponanim = 0; + return; + } + + if (!isWh2()) { + if (plr.currweaponframe == PIKEATTACK1 + 4 + // || plr.currweaponframe == PIKEATTACK2+4 + && plr.weapon[7] == 2 && plr.ammo[7] > 0) { + shootgun(plr, daang, 10); + playsound_loc(S_THROWPIKE, plr.x, plr.y); + plr.hasshot = 1; + return; + } + } else { + if (plr.currweaponframe == BOWWALK + 5 && plr.ammo[6] > 0) { + plr.currweaponfired = 5; + plr.currweaponanim = 0; + } else if (plr.currweaponframe == ZBOWATTACK + 4 && plr.ammo[6] > 0) { + plr.currweaponfired = 5; + plr.currweaponanim = 0; + } + + if (plr.currweaponframe == BOWWALK + 5 && plr.ammo[6] <= 0) { + plr.currweaponfired = 0; + plr.currweaponanim = 0; + return; + } else if (plr.currweaponframe == ZBOWATTACK + 4 && plr.ammo[6] <= 0) { + plr.currweaponfired = 0; + plr.currweaponanim = 0; + return; + } + + if (plr.currweaponframe == PIKEATTACK1 + 4 && plr.weapon[7] == 2 && plr.ammo[7] > 0) { + shootgun(plr, daang, 10); + playsound_loc(S_GENTHROW, plr.x, plr.y); + plr.hasshot = 1; + return; + } else if (plr.currweaponframe == ZPIKEATTACK + 4 && plr.weapon[7] == 3 && plr.ammo[7] > 0) { + lockon(plr, 3, 10); + playsound_loc(S_GENTHROW, plr.x, plr.y); + plr.hasshot = 1; + return; + } + } + + switch (plr.selectedgun) { + case 0: // fist & close combat weapons + shootgun(plr, daang, 0); + plr.hasshot = 1; + break; + case 1: // knife + shootgun(plr, daang, 0); + plr.hasshot = 1; + break; + case 2: // shortsword + shootgun(plr, daang, 0); + plr.hasshot = 1; + break; + case 3: // morningstar + shootgun(plr, daang, 0); + if (isWh2() && plr.weapon[plr.selectedgun] == 3) { + lockon(plr, 1, 3); + } + + plr.hasshot = 1; + break; + case 4: // sword + shootgun(plr, daang, 0); + plr.hasshot = 1; + break; + case 5: // battleaxe + if (isWh2() && enchantedsoundhandle != -1) { + SND_Sound(S_ENERGYSWING); + } + + shootgun(plr, daang, 0); + plr.hasshot = 1; + break; + case 6: // bow + if (isWh2() && enchantedsoundhandle != -1) { + SND_Sound(S_FIREBALL); + SND_Sound(S_PLRWEAPON3); + } + shootgun(plr, daang, 1); + plr.hasshot = 1; + break; + case 7: // pike + shootgun(plr, daang, 0); + plr.hasshot = 1; + break; + case 8: // two handed + shootgun(plr, daang, 0); + plr.hasshot = 1; + break; + case 9: // halberd + shootgun(plr, daang, 0); + plr.hasshot = 1; + break; + } +} + +void swingdacrunch(PLAYER& plr, int daweapon) { + + switch (daweapon) { + case 0: // fist + playsound_loc(S_SOCK1 + (krand() % 4), plr.x, plr.y); + break; + case 1: // dagger + if ((krand() % 2) != 0) + playsound_loc(S_GORE1 + (krand() % 4), plr.x, plr.y); + break; + case 2: // short sword + playsound_loc(S_SWORD2 + (krand() % 3), plr.x, plr.y); + break; + case 3: // morningstar + playsound_loc(S_SOCK1 + (krand() % 4), plr.x, plr.y); + break; + case 4: // broad sword + playsound_loc(S_SWORD1 + (krand() % 3), plr.x, plr.y); + break; + case 5: // battle axe + if ((krand() % 2) != 0) + playsound_loc(S_SOCK1 + (krand() % 4), plr.x, plr.y); + else + playsound_loc(S_SWORD1 + (krand() % 3), plr.x, plr.y); + break; + case 6: // bow + + break; + case 7: // pike + if ((krand() % 2) != 0) + playsound_loc(S_SOCK1 + (krand() % 4), plr.x, plr.y); + else + playsound_loc(S_SWORD1 + (krand() % 3), plr.x, plr.y); + break; + case 8: // two handed sword + playsound_loc(S_SWORD1 + (krand() % 2), plr.x, plr.y); + break; + case 9: // halberd + if ((krand() % 2) != 0) + playsound_loc(S_SOCK1 + (krand() % 4), plr.x, plr.y); + else + playsound_loc(S_SWORD1 + (krand() % 3), plr.x, plr.y); + break; + } +} + +void swingdasound(int daweapon, boolean enchanted) { + + switch (daweapon) { + case 0: // fist + SND_Sound(S_PLRWEAPON0); + break; + case 1: // knife + SND_Sound(S_PLRWEAPON1); + break; + case 2: // short sword + if (isWh2() && enchanted) + SND_Sound(S_FIRESWING); + else + SND_Sound(S_PLRWEAPON4); + break; + case 3: // mace + if (isWh2() && enchanted) { + SND_Sound(S_FIRESWING); + SND_Sound(S_FIREBALL); + } else + SND_Sound(S_PLRWEAPON2); + break; + case 4: // + SND_Sound(S_PLRWEAPON4); + break; + case 5: // sword + SND_Sound(S_PLRWEAPON4); + break; + case 6: // bow + SND_Sound(S_PLRWEAPON3); + break; + case 7: // + if (isWh2() && enchanted) + SND_Sound(S_ENERGYSWING); + else + SND_Sound(S_PLRWEAPON4); + break; + case 8: // + SND_Sound(S_PLRWEAPON4); + break; + case 9: // + SND_Sound(S_PLRWEAPON4); + break; + } +} + diff --git a/source/games/whaven/src/wepdata.cpp b/source/games/whaven/src/wepdata.cpp new file mode 100644 index 000000000..9487e7304 --- /dev/null +++ b/source/games/whaven/src/wepdata.cpp @@ -0,0 +1,699 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + + +const WEAPONINF sspellbookanim[MAXNUMORBS][9] = +{ + // SCARE + {{8, SSPELLBOOK8, 121, 389}, {8, SSPELLBOOK8 + 1, 121, 377}, + {8, SSPELLBOOK8 + 2, 121, 383}, {8, SSPELLBOOK8 + 3, 121, 385}, + {8, SSPELLBOOK8 + 4, 121, 389}, {8, SSPELLBOOK8 + 5, 121, 387}, + {8, SSPELLBOOK8 + 6, 121, 389}, {8, SSPELLBOOK8 + 7, 121, 389}, + {8, SSPELLBOOK8 + 7, 121, 389} + }, + // NIGHT VISION + {{8, SSPELLBOOK6, 121, 389}, {8, SSPELLBOOK6 + 1, 121, 377}, + {8, SSPELLBOOK6 + 2, 121, 383}, {8, SSPELLBOOK6 + 3, 121, 385}, + {8, SSPELLBOOK6 + 4, 121, 389}, {8, SSPELLBOOK6 + 5, 121, 387}, + {8, SSPELLBOOK6 + 6, 121, 389}, {8, SSPELLBOOK6 + 7, 121, 389}, + {8, SSPELLBOOK6 + 7, 121, 389} + }, + // FREEZE + {{8, SSPELLBOOK3, 121, 389}, {8, SSPELLBOOK3 + 1, 121, 377}, + {8, SSPELLBOOK3 + 2, 121, 383}, {8, SSPELLBOOK3 + 3, 121, 385}, + {8, SSPELLBOOK3 + 4, 121, 389}, {8, SSPELLBOOK3 + 5, 120, 387}, + {8, SSPELLBOOK3 + 6, 120, 389}, {8, SSPELLBOOK3 + 7, 120, 389}, + {8, SSPELLBOOK3 + 7, 121, 389} + }, + // MAGIC ARROW + {{8, SSPELLBOOKBLANK, 121, 389}, {8, SSPELLBOOKBLANK + 1, 121, 377}, + {8, SSPELLBOOKBLANK + 2, 121, 383}, {8, SSPELLBOOKBLANK + 3, 121, 385}, + {8, SSPELLBOOKBLANK + 4, 121, 389}, {8, SSPELLBOOKBLANK + 5, 121, 387}, + {8, SSPELLBOOKBLANK + 6, 120, 389}, {8, SSPELLBOOKBLANK + 7, 121, 389}, + {8, SSPELLBOOKBLANK + 7, 122, 389} + }, + // OPEN DOORS + {{8, SSPELLBOOK7, 121, 389}, {8, SSPELLBOOK7 + 1, 121, 377}, + {8, SSPELLBOOK7 + 2, 121, 383}, {8, SSPELLBOOK7 + 3, 121, 385}, + {8, SSPELLBOOK7 + 4, 121, 389}, {8, SSPELLBOOK7 + 5, 121, 387}, + {8, SSPELLBOOK7 + 6, 121, 389}, {8, SSPELLBOOK7 + 7, 121, 389}, + {8, SSPELLBOOK7 + 7, 121, 389} + }, + // FLY + {{8, SSPELLBOOK2, 121, 389}, {8, SSPELLBOOK2 + 1, 121, 377}, + {8, SSPELLBOOK2 + 2, 121, 383}, {8, SSPELLBOOK2 + 3, 121, 385}, + {8, SSPELLBOOK2 + 4, 121, 389}, {8, SSPELLBOOK2 + 5, 121, 387}, + {8, SSPELLBOOK2 + 6, 121, 389}, {8, SSPELLBOOK2 + 7, 121, 389}, + {8, SSPELLBOOK2 + 7, 121, 389} + }, + // FIRE BALL + {{8, SSPELLBOOK4, 121, 389}, {8, SSPELLBOOK4 + 1, 121, 377}, + {8, SSPELLBOOK4 + 2, 121, 383}, {8, SSPELLBOOK4 + 3, 121, 385}, + {8, SSPELLBOOK4 + 4, 121, 389}, {8, SSPELLBOOK4 + 5, 121, 387}, + {8, SSPELLBOOK4 + 6, 121, 389}, {8, SSPELLBOOK4 + 6, 121, 389}, + {8, SSPELLBOOK4 + 6, 121, 389} + }, + // NUKE! + {{8, SSPELLBOOK5, 121, 389}, {8, SSPELLBOOK5 + 1, 121, 377}, + {8, SSPELLBOOK5 + 2, 121, 383}, {8, SSPELLBOOK5 + 3, 121, 385}, + {8, SSPELLBOOK5 + 4, 121, 389}, {8, SSPELLBOOK5 + 5, 121, 387}, + {8, SSPELLBOOK5 + 6, 121, 389}, {8, SSPELLBOOK5 + 6, 121, 389}, + {8, SSPELLBOOK5 + 6, 121, 389} + } + +}; + + +const WEAPONINF spikeanimtics[5] = +{ {10, DIESPIKE, 136, 145}, +{10, DIESPIKE + 1, 136, 124}, +{10, DIESPIKE + 2, 136, 100}, +{10, DIESPIKE + 3, 136, 70}, +{10, DIESPIKE + 4, 136, 50} }; + +const WEAPONINF wh2throwanimtics[MAXNUMORBS][MAXFRAMES + 1] = +{ + // MUTWOHANDS - scare spell + {{1, EMPTY, 127, 170}, {10, MUTWOHANDS + 1, 0, 128}, {10, MUTWOHANDS + 2, 0, 93}, + {10, MUTWOHANDS + 3, 0, 83}, {10, MUTWOHANDS + 4, 0, 72}, {10, MUTWOHANDS + 5, 0, 83}, + {10, MUTWOHANDS + 6, 10, 96}, {10, MUTWOHANDS + 7, 43, 109}, {10, MUTWOHANDS + 8, 69, 113}, + {10, MUTWOHANDS + 9, 65, 115}, {10, MUTWOHANDS + 10, 64, 117}, {10, MUTWOHANDS + 11, 63, 117}, + {1, EMPTY, 127, 170} + }, + // MUTWOHANDS - night vision + {{10, ZFIREBALL, 0, 177}, {10, ZFIREBALL + 1, 0, 137}, {10, ZFIREBALL + 2, 48, 82}, + {10, ZFIREBALL + 3, 127, 41}, {10, ZFIREBALL + 4, 210, 9}, {10, ZFIREBALL + 5, 284, 26}, + {10, ZFIREBALL + 6, 213, 63}, {10, ZFIREBALL + 7, 147, 99}, {10, ZFIREBALL + 8, 91, 136}, + {10, ZFIREBALL + 9, 46, 183}, {1, EMPTY, 127, 170}, {1, EMPTY, 127, 170}, + {1, EMPTY, 127, 170} + }, + // MUTWOHANDS - freeze + {{1, EMPTY, 127, 170}, {10, ZFREEZE + 1, 0, 51}, {10, ZFREEZE + 2, 0, 71}, + {10, ZFREEZE + 3, 4, 85}, {10, ZFREEZE + 4, 32, 78}, {10, ZFREEZE + 5, 51, 80}, + {10, ZFREEZE + 6, 50, 80}, {10, ZFREEZE + 7, 49, 89}, {10, ZFREEZE + 8, 49, 89}, + {10, ZFREEZE + 9, 49, 98}, {10, ZFREEZE + 10, 47, 105}, {10, ZFREEZE + 11, 48, 121}, + {1, EMPTY, 127, 170} + }, + // MUTWOHANDS - magic arrow + {{1, EMPTY, 127, 170}, {10, MUTWOHANDS + 1, 0, 128}, {10, MUTWOHANDS + 2, 0, 93}, + {10, MUTWOHANDS + 3, 0, 83}, {10, MUTWOHANDS + 4, 0, 72}, {10, MUTWOHANDS + 5, 0, 83}, + {10, MUTWOHANDS + 6, 10, 96}, {10, MUTWOHANDS + 7, 43, 109}, {10, MUTWOHANDS + 8, 69, 113}, + {10, MUTWOHANDS + 9, 65, 115}, {10, MUTWOHANDS + 10, 64, 117}, {10, MUTWOHANDS + 11, 63, 117}, + {1, EMPTY, 127, 170} + }, + // MUTWOHANDS - open door + {{15, MUTWOHANDS, 19, 155}, {15, MUTWOHANDS + 1, 0, 128}, {15, MUTWOHANDS + 2, 0, 93}, + {15, MUTWOHANDS + 3, 0, 83}, {15, MUTWOHANDS + 4, 0, 72}, {15, MUTWOHANDS + 5, 0, 83}, + {15, MUTWOHANDS + 6, 10, 96}, {15, MUTWOHANDS + 7, 43, 109}, {15, MUTWOHANDS + 8, 69, 113}, + {15, MUTWOHANDS + 9, 65, 115}, {15, MUTWOHANDS + 10, 64, 117}, {15, MUTWOHANDS + 11, 63, 117}, + {1, EMPTY, 127, 170} + }, + // MUMEDUSA - fly + {{10, ZLIGHT, 0, 177}, {10, ZLIGHT + 1, 0, 137}, {10, ZLIGHT + 2, 48, 82}, + {10, ZLIGHT + 3, 127, 41}, {10, ZLIGHT + 4, 210, 9}, {10, ZLIGHT + 5, 284, 26}, + {10, ZLIGHT + 6, 213, 63}, {10, ZLIGHT + 7, 147, 99}, {10, ZLIGHT + 8, 91, 136}, + {10, ZLIGHT + 9, 46, 183}, {1, EMPTY, 127, 170}, {1, EMPTY, 127, 170}, + {1, EMPTY, 127, 170} + }, + // MUTWOHANDS - fireball + {{1, EMPTY, 127, 170}, {10, ZFIREBALL + 1, 0, 137}, {10, ZFIREBALL + 2, 48, 82}, + {10, ZFIREBALL + 3, 127, 41}, {10, ZFIREBALL + 4, 210, 9}, {10, ZFIREBALL + 5, 284, 26}, + {10, ZFIREBALL + 6, 213, 63}, {10, ZFIREBALL + 7, 147, 99}, {10, ZFIREBALL + 8, 91, 136}, + {10, ZFIREBALL + 9, 46, 183}, {1, EMPTY, 127, 170}, {1, EMPTY, 127, 170}, + {1, EMPTY, 127, 170} + }, + // MUTWOHANDS - nuke + {{1, EMPTY, 127, 170}, {10, MUTWOHANDS + 1, 0, 128}, {10, MUTWOHANDS + 2, 0, 93}, + {10, MUTWOHANDS + 3, 0, 83}, {10, MUTWOHANDS + 4, 0, 72}, {10, MUTWOHANDS + 5, 0, 83}, + {10, MUTWOHANDS + 6, 10, 96}, {10, MUTWOHANDS + 7, 43, 109}, {10, MUTWOHANDS + 8, 69, 113}, + {10, MUTWOHANDS + 9, 65, 115}, {10, MUTWOHANDS + 10, 64, 117}, {10, MUTWOHANDS + 11, 63, 117}, + {1, EMPTY, 127, 170} + } +}; + +const WEAPONINF throwanimtics[MAXNUMORBS][MAXFRAMES + 1] = +{ + // MUTWOHANDS + { {10,MUTWOHANDS,19,155},{10,MUTWOHANDS + 1,0,128},{10,MUTWOHANDS + 2,0,93}, + {10,MUTWOHANDS + 3,0,83},{10,MUTWOHANDS + 4,0,72},{10,MUTWOHANDS + 5,0,83}, + {10,MUTWOHANDS + 6,10,96},{10,MUTWOHANDS + 7,43,109},{10,MUTWOHANDS + 8,69,113}, + {10,MUTWOHANDS + 9,65,115},{10,MUTWOHANDS + 10,64,117},{10,MUTWOHANDS + 11,63,117}, + {1,NULL,127,170} + }, + // MUMEDUSA + { {10,MUMEDUSA,0,177},{10,MUMEDUSA + 1,0,137},{10,MUMEDUSA + 2,48,82}, + {10,MUMEDUSA + 3,127,41},{10,MUMEDUSA + 4,210,9},{10,MUMEDUSA + 5,284,26}, + {10,MUMEDUSA + 6,213,63},{10,MUMEDUSA + 7,147,99},{10,MUMEDUSA + 8,91,136}, + {10,MUMEDUSA + 9,46,183},{1,NULL,127,170},{1,NULL,127,170}, + {1,NULL,127,170} + }, + // BMUTWOHANDS + { {10,MUTWOHANDS,19,155},{10,MUTWOHANDS + 1,0,128},{10,MUTWOHANDS + 2,0,93}, + {10,MUTWOHANDS + 3,0,83},{10,BMUTWOHANDS,0,74},{10,BMUTWOHANDS + 1,0,97}, + {10,BMUTWOHANDS + 2,10,109},{10,BMUTWOHANDS + 3,43,113},{10,BMUTWOHANDS + 4,69,115}, + {10,BMUTWOHANDS + 5,65,117},{10,BMUTWOHANDS + 6,64,117},{10,BMUTWOHANDS + 7,63,117}, + {1,NULL,127,170} + }, + // MUTWOHANDS + { {10,MUTWOHANDS,19,155},{10,MUTWOHANDS + 1,0,128},{10,MUTWOHANDS + 2,0,93}, + {10,MUTWOHANDS + 3,0,83},{10,MUTWOHANDS + 4,0,72},{10,MUTWOHANDS + 5,0,83}, + {10,MUTWOHANDS + 6,10,96},{10,MUTWOHANDS + 7,43,109},{10,MUTWOHANDS + 8,69,113}, + {10,MUTWOHANDS + 9,65,115},{10,MUTWOHANDS + 10,64,117},{10,MUTWOHANDS + 11,63,117}, + {1,NULL,127,170} + }, + // MUTWOHANDS + { {15,MUTWOHANDS,19,155},{15,MUTWOHANDS + 1,0,128},{15,MUTWOHANDS + 2,0,93}, + {15,MUTWOHANDS + 3,0,83},{15,MUTWOHANDS + 4,0,72},{15,MUTWOHANDS + 5,0,83}, + {15,MUTWOHANDS + 6,10,96},{15,MUTWOHANDS + 7,43,109},{15,MUTWOHANDS + 8,69,113}, + {15,MUTWOHANDS + 9,65,115},{15,MUTWOHANDS + 10,64,117},{15,MUTWOHANDS + 11,63,117}, + {1,NULL,127,170} + }, + // MUMEDUSA + { {10,MUMEDUSA,0,177},{10,MUMEDUSA + 1,0,137},{10,MUMEDUSA + 2,48,82}, + {10,MUMEDUSA + 3,127,41},{10,MUMEDUSA + 4,210,9},{10,MUMEDUSA + 5,284,26}, + {10,MUMEDUSA + 6,213,63},{10,MUMEDUSA + 7,147,99},{10,MUMEDUSA + 8,91,136}, + {10,MUMEDUSA + 9,46,183},{1,NULL,127,170},{1,NULL,127,170}, + {1,NULL,127,170} + }, + // MUTWOHANDS + { {10,MUTWOHANDS,19,155},{10,MUTWOHANDS + 1,0,128},{10,MUTWOHANDS + 2,0,93}, + {10,MUTWOHANDS + 3,0,83},{10,MUTWOHANDS + 4,0,72},{10,MUTWOHANDS + 5,0,83}, + {10,MUTWOHANDS + 6,10,96},{10,MUTWOHANDS + 7,43,109},{10,MUTWOHANDS + 8,69,113}, + {10,MUTWOHANDS + 9,65,115},{10,MUTWOHANDS + 10,64,117},{10,MUTWOHANDS + 11,63,117}, + {1,NULL,127,170} + }, + // MUTWOHANDS + { {10,MUTWOHANDS,19,155},{10,MUTWOHANDS + 1,0,128},{10,MUTWOHANDS + 2,0,93}, + {10,MUTWOHANDS + 3,0,83},{10,MUTWOHANDS + 4,0,72},{10,MUTWOHANDS + 5,0,83}, + {10,MUTWOHANDS + 6,10,96},{10,MUTWOHANDS + 7,43,109},{10,MUTWOHANDS + 8,69,113}, + {10,MUTWOHANDS + 9,65,115},{10,MUTWOHANDS + 10,64,117},{10,MUTWOHANDS + 11,63,117}, + {1,NULL,127,170} + } + +}; + +const WEAPONINF cockanimtics[MAXFRAMES + 1] = +{ + {24,NULL,10,10}, + {12,BOWREADYEND + 1,101,115},{12,BOWREADYEND + 2,112,0}, + {12,BOWREADYEND + 3,115,0},{12,BOWREADYEND + 4,75,13} +}; + +const WEAPONINF zcockanimtics[MAXFRAMES + 1] = +{ + {24, EMPTY, 10, 10}, + {12, BOWREADYEND + 1, 101, 115}, {12, BOWREADYEND + 2, 112, 0}, + {12, BOWREADYEND + 3, 115, 0}, {12, ZBOWWALK, 75, 13} +}; + +//SCOTT +const WEAPONINF zreadyanimtics[MAXWEAPONS][MAXFRAMES + 1] = +{ + // FIST + {{10, RFIST, 216, 180}, {10, RFIST, 216, 170}, {10, RFIST, 216, 160}, + {10, RFIST, 216, 150}, {10, RFIST, 216, 140}, {10, RFIST, 216, 130}, + {10, RFIST, 216, 124}, {1, RFIST, 216, 124}, {1, RFIST, 216, 124}, + {1, RFIST, 216, 122}, {1, RFIST, 216, 122}, {1, RFIST, 216, 122}, + {1, EMPTY, 147, 76} + }, + // ZKNIFE + {{10, ZKNIFEREADY, 69, 171}, {10, ZKNIFEREADY + 1, 11, 146}, {10, ZKNIFEREADY + 2, 25, 146}, + {10, ZKNIFEREADY + 3, 35, 158}, {10, ZKNIFEREADY + 4, 38, 158}, {10, ZKNIFEREADY + 5, 16, 157}, + {10, ZKNIFEREADY + 6, 37, 102}, {10, ZKNIFEREADY + 7, 239, 63}, {10, ZKNIFEREADY + 8, 214, 85}, + {10, ZKNIFEREADY + 9, 206, 110}, {10, ZKNIFEREADY + 10, 217, 108}, {10, ZKNIFEREADY + 11, 204, 95}, + {1, EMPTY, 147, 76} + }, + // ZSHORTREADY + {{12, ZSHORTREADY, 79, 169}, {12, ZSHORTREADY + 1, 95, 115}, {12, ZSHORTREADY + 2, 94, 93}, + {12, ZSHORTREADY + 3, 156, 77}, {12, ZSHORTREADY + 4, 218, 64}, {12, ZSHORTREADY + 5, 224, 57}, + {8, ZSHORTREADY + 6, 251, 54}, {1, ZSHORTREADY + 7, 243, 92}, {1, ZSHORTREADY + 7, 243, 92}, + {1, ZSHORTREADY + 7, 243, 92}, {1, ZSHORTREADY + 7, 243, 92}, {1, ZSHORTREADY + 7, 243, 92}, + {1, EMPTY, 147, 76} + }, + // ZSTARATTACK + {{6, ZSTARATTACK, 194, 195}, {6, ZSTARATTACK, 194, 185}, {6, ZSTARATTACK, 194, 175}, + {6, ZSTARATTACK, 194, 165}, {6, ZSTARATTACK, 194, 155}, {6, ZSTARATTACK, 194, 145}, + {6, ZSTARATTACK, 194, 135}, {6, ZSTARATTACK, 194, 125}, {6, ZSTARATTACK, 194, 115}, + {6, ZSTARATTACK, 194, 105}, {6, ZSTARATTACK, 194, 95}, {1, ZSTARATTACK, 194, 85}, + {1, EMPTY, 147, 76} + }, + // SWORD + {{10, SWORDPULL, 58, 160}, {10, SWORDPULL + 1, 81, 111}, {10, SWORDPULL + 2, 19, 88}, + {10, SWORDPULL + 3, 0, 93}, {10, SWORDPULL + 4, 104, 0}, {10, SWORDPULL + 5, 169, 0}, + {10, SWORDPULL + 6, 244, 38}, {6, SWORDPULL + 7, 225, 121}, {1, SWORDPULL + 7, 225, 121}, + {1, SWORDPULL + 7, 225, 121}, {1, SWORDPULL + 7, 225, 121}, {1, SWORDPULL + 7, 225, 121}, + {1, EMPTY, 147, 76} + }, + // ZAXE + {{8, ZAXEREADY, 0, 108}, {8, ZAXEREADY + 1, 0, 58}, {8, ZAXEREADY + 2, 0, 57}, + {8, ZAXEREADY + 3, 0, 69}, {8, ZAXEREADY + 4, 0, 100}, {8, ZAXEREADY + 5, 0, 9}, + {8, ZAXEREADY + 6, 33, 0}, {8, ZAXEREADY + 7, 61, 0}, {8, ZAXEREADY + 8, 73, 20}, + {8, ZAXEREADY + 9, 179, 117}, {8, EMPTY, 182, 116}, {1, EMPTY, 200, 122}, + {1, EMPTY, 147, 76} + }, + // ZBOW + {{12, ZBOWREADY, 0, 0}, {12, ZBOWREADY + 1, 0, 20}, {12, ZBOWREADY + 2, 0, 46}, + {12, ZBOWREADY + 3, 0, 26}, {12, ZBOWREADY + 4, 0, 0}, {12, ZBOWREADY + 5, 71, 0}, + {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, + {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, + {1, EMPTY, 147, 76} + }, + // ZPIKE + {{8, ZPIKEREADY, 0, 150}, {8, ZPIKEREADY + 1, 0, 94}, {8, ZPIKEREADY + 2, 47, 45}, + {8, ZPIKEREADY + 3, 138, 62}, {8, ZPIKEREADY + 4, 194, 95}, {8, ZPIKEREADY + 5, 59, 121}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 147, 76} + }, + {{12, ZTWOHANDREADY, 167, 131}, {12, ZTWOHANDREADY + 1, 71, 117}, {12, ZTWOHANDREADY, 0, 128}, + {12, ZTWOHANDREADY + 3, 0, 150}, {12, ZTWOHANDREADY + 4, 10, 74}, {12, ZTWOHANDREADY + 5, 44, 81}, + {12, ZTWOHANDREADY + 6, 0, 53}, {12, ZTWOHANDREADY + 7, 112, 0}, {12, ZTWOHANDREADY + 8, 220, 0}, + {12, ZTWOHANDREADY + 9, 198, 84}, {12, ZTWOHANDREADY + 10, 186, 120}, {12, ZTWOHANDREADY + 11, 188, 124}, + {1, EMPTY, 147, 76} + }, + {{12, HALBERDDRAW, 183, 62}, {12, HALBERDDRAW + 1, 166, 10}, {12, HALBERDDRAW + 2, 173, 29}, + {12, HALBERDDRAW + 3, 114, 35}, {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, + {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, + {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, {1, ZHALBERDATTACK, 245, 30}, + {1, EMPTY, 147, 76} + } + +}; + +const WEAPONINF readyanimtics[MAXWEAPONS][MAXFRAMES + 1] = +{ + // FIST + {{10, RFIST, 216, 180}, {10, RFIST, 216, 170}, {10, RFIST, 216, 160}, + {10, RFIST, 216, 150}, {10, RFIST, 216, 140}, {10, RFIST, 216, 130}, + {10, RFIST, 216, 124}, {1, RFIST, 216, 124}, {1, RFIST, 216, 124}, + {1, RFIST, 216, 122}, {1, RFIST, 216, 122}, {1, RFIST, 216, 122}, + {1, EMPTY, 147, 76} + }, + // KNIFE + {{10, KNIFEREADY, 69, 171}, {10, KNIFEREADY + 1, 11, 146}, {10, KNIFEREADY + 2, 25, 146}, + {10, KNIFEREADY + 3, 35, 158}, {10, KNIFEREADY + 4, 38, 158}, {10, KNIFEREADY + 5, 16, 157}, + {10, KNIFEREADY + 6, 37, 102}, {10, KNIFEREADY + 7, 239, 63}, {10, KNIFEREADY + 8, 214, 85}, + {10, KNIFEREADY + 9, 206, 110}, {10, KNIFEREADY + 10, 217, 108}, {10, KNIFEREADY + 11, 204, 95}, + {1, EMPTY, 147, 76} + }, + // GOBSWORD + {{12, GOBSWORDPULL, 79, 169}, {12, GOBSWORDPULL + 1, 95, 115}, {12, GOBSWORDPULL + 2, 94, 93}, + {12, GOBSWORDPULL + 3, 156, 77}, {12, GOBSWORDPULL + 4, 218, 64}, {12, GOBSWORDPULL + 5, 224, 57}, + {8, GOBSWORDPULL + 6, 251, 54}, {1, GOBSWORDPULL + 7, 243, 92}, {1, GOBSWORDPULL + 7, 243, 92}, + {1, GOBSWORDPULL + 7, 243, 92}, {1, GOBSWORDPULL + 7, 243, 92}, {1, GOBSWORDPULL + 7, 243, 92}, + {1, EMPTY, 147, 76} + }, + // MORNINGSTAR + {{6, MORNINGSTAR, 193, 190}, {6, MORNINGSTAR, 193, 180}, {6, MORNINGSTAR, 193, 170}, + {6, MORNINGSTAR, 193, 160}, {6, MORNINGSTAR, 193, 150}, {6, MORNINGSTAR, 193, 140}, + {6, MORNINGSTAR, 193, 130}, {6, MORNINGSTAR, 193, 120}, {6, MORNINGSTAR, 193, 110}, + {6, MORNINGSTAR, 193, 100}, {6, MORNINGSTAR, 193, 90}, {1, MORNINGSTAR, 193, 90}, + {1, EMPTY, 147, 76} + }, + // SWORD + {{10, SWORDPULL, 58, 160}, {10, SWORDPULL + 1, 81, 111}, {10, SWORDPULL + 2, 19, 88}, + {10, SWORDPULL + 3, 0, 93}, {10, SWORDPULL + 4, 104, 0}, {10, SWORDPULL + 5, 169, 0}, + {10, SWORDPULL + 6, 244, 38}, {6, SWORDPULL + 7, 225, 121}, {1, SWORDPULL + 7, 225, 121}, + {1, SWORDPULL + 7, 225, 121}, {1, SWORDPULL + 7, 225, 121}, {1, SWORDPULL + 7, 225, 121}, + {1, EMPTY, 147, 76} + }, + {{12, BIGAXEDRAW, 71, 108}, {12, BIGAXEDRAW + 1, 17, 58}, {12, BIGAXEDRAW + 2, 0, 56}, + {12, BIGAXEDRAW + 3, 0, 71}, {12, BIGAXEDRAW + 4, 0, 102}, {12, BIGAXEDRAW + 5, 0, 11}, + {12, BIGAXEDRAW + 6, 33, 0}, {12, BIGAXEDRAW + 7, 69, 0}, {12, BIGAXEDRAW + 8, 75, 20}, + {12, BIGAXEDRAW9, 150, 92}, {12, BIGAXEDRAW10, 182, 116}, {1, EMPTY, 200, 122}, + {1, EMPTY, 147, 76} + }, + // BOW + {{12, BOWREADY, 0, 0}, {12, BOWREADY + 1, 0, 20}, {12, BOWREADY + 2, 0, 46}, + {12, BOWREADY + 3, 0, 26}, {12, BOWREADY + 4, 0, 0}, {12, BOWREADY + 5, 71, 0}, + {8, BOWREADYEND, 77, 23}, {1, BOWREADYEND, 77, 23}, {1, BOWREADYEND, 77, 23}, + {1, BOWREADYEND, 77, 23}, {1, BOWREADYEND, 77, 23}, {1, BOWREADYEND, 77, 23}, + {1, EMPTY, 147, 76} + }, + {{8, PIKEDRAW, 0, 156}, {8, PIKEDRAW + 1, 15, 98}, {8, PIKEDRAW + 2, 83, 49}, + {8, PIKEDRAW + 3, 144, 66}, {8, PIKEDRAW + 4, 197, 99}, {8, PIKEDRAW + 5, 216, 131}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 147, 76} + }, + {{12, EXCALDRAW, 167, 130}, {12, EXCALDRAW + 1, 70, 117}, {12, EXCALDRAW + 2, 0, 128}, + {12, EXCALDRAW + 3, 0, 150}, {12, EXCALDRAW + 4, 4, 72}, {12, EXCALDRAW + 5, 38, 81}, + {12, EXCALDRAW + 6, 0, 44}, {12, EXCALDRAW + 7, 112, 0}, {12, EXCALDRAW + 8, 224, 0}, + {12, EXCALDRAW + 9, 198, 84}, {12, EXCALDRAW + 10, 186, 120}, {12, EXCALDRAW + 11, 188, 123}, + {1, EMPTY, 147, 76} + }, + {{12, HALBERDDRAW, 183, 62}, {12, HALBERDDRAW + 1, 166, 10}, {12, HALBERDDRAW + 2, 173, 29}, + {12, HALBERDDRAW + 3, 114, 35}, {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, + {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, + {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, {1, HALBERDATTACK1, 245, 22}, + {1, EMPTY, 147, 76} + } + +}; + +const WEAPONINF weaponanimtics[MAXWEAPONS][MAXFRAMES] = +{ + // FIST + {{10, RFIST, 216, 120}, {10, RFIST + 1, 166, 113}, {10, RFIST + 2, 156, 129}, + {10, RFIST + 3, 169, 151}, {10, RFIST + 4, 153, 124}, {10, RFIST + 5, 224, 133}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // KNIFE + {{8, KNIFEATTACK, 189, 52}, {8, KNIFEATTACK + 1, 254, 68}, {8, EMPTY, 147, 76}, + {8, EMPTY, 80, 41}, {8, KNIFEATTACK + 2, 254, 69}, {8, KNIFEATTACK + 3, 218, 80}, + {8, KNIFEATTACK + 4, 137, 83}, {8, KNIFEATTACK + 5, 136, 100}, {8, KNIFEATTACK + 6, 126, 140}, + {8, KNIFEATTACK + 5, 136, 100}, {8, KNIFEATTACK + 4, 137, 83}, {8, KNIFEATTACK, 189, 52} + }, + // GOBLINATTACK + {{10, GOBSWORDATTACK, 243, 92}, {10, GOBSWORDATTACK + 1, 255, 68}, {10, GOBSWORDATTACK + 2, 279, 65}, + {10, GOBSWORDATTACK + 3, 238, 55}, {10, GOBSWORDATTACK + 4, 153, 52}, {10, GOBSWORDATTACK + 5, 129, 152}, + {10, GOBSWORDATTACK + 6, 90, 184}, {1, EMPTY, 297, 169}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + }, + // MORNINGSTAR + {{12, MORNINGSTAR, 193, 90}, {12, MORNINGSTAR + 1, 102, 133}, {12, MORNINGSTAR + 2, 77, 164}, + {12, MORNINGSTAR + 3, 239, 86}, {12, EMPTY, 299, 86}, {12, EMPTY, 107, 52}, + {12, MORNINGSTAR + 4, 197, 24}, {12, MORNINGSTAR + 5, 125, 124}, {12, MORNINGSTAR + 6, 109, 191}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // SWORD + {{8, SWORDATTACK, 229, 123}, {8, SWORDATTACK + 1, 221, 87}, {8, SWORDATTACK + 2, 193, 21}, + {8, SWORDATTACK + 3, 173, 0}, {8, SWORDATTACK + 4, 61, 0}, {8, SWORDATTACK + 5, 33, 48}, + {8, SWORDATTACK + 6, 126, 131}, {8, SWORDATTACK + 7, 297, 164}, {3, EMPTY, 147, 76}, + {3, EMPTY, 80, 41}, {3, EMPTY, 107, 52}, {3, EMPTY, 147, 76} + }, + {{12, BIGAXEATTACK, 184, 123}, {12, BIGAXEATTACK + 1, 223, 112}, {12, BIGAXEATTACK + 2, 63, 151}, + {12, BIGAXEATTACK + 3, 91, 133}, {12, BIGAXEATTACK + 4, 127, 138}, {12, BIGAXEATTACK + 5, 106, 128}, + {12, BIGAXEATTACK + 6, 117, 49}, {12, BIGAXEATTACK + 7, 140, 0}, {12, BIGAXEATTACK + 8, 152, 47}, + {12, BIGAXEATTACK + 9, 166, 143}, {12, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // BOW + {{8, BOWWALK, 75, 13}, {8, BOWWALK + 1, 90, 0}, {8, BOWWALK + 2, 70, 0}, + {8, BOWWALK + 3, 70, 0}, {6, BOWWALK + 4, 70, 0}, {4, BOWWALK + 5, 70, 0}, + {1, EMPTY, 126, 131}, {1, EMPTY, 297, 164}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + {{10, PIKEDRAW + 5, 216, 131}, {10, EMPTY, 80, 41}, {10, EMPTY, 107, 52}, {10, EMPTY, 147, 76}, + {10, PIKEATTACK1, 0, 47}, {10, PIKEATTACK1 + 1, 0, 0}, {10, PIKEATTACK1 + 2, 0, 0}, + {10, PIKEATTACK1 + 3, 73, 0}, {10, PIKEATTACK1 + 4, 130, 27}, {10, PIKEATTACK1 + 5, 138, 125}, + {12, EMPTY, 80, 41}, {1, EMPTY, 107, 52} + }, + {{8, EXCALATTACK1, 98, 133}, {8, EXCALATTACK1 + 1, 123, 130}, {8, EXCALATTACK1 + 2, 125, 128}, + {8, EXCALATTACK1 + 3, 115, 82}, {8, EXCALATTACK1 + 4, 115, 6}, {8, EXCALATTACK1 + 5, 178, 0}, + {8, EXCALATTACK1 + 6, 155, 0}, {8, EXCALATTACK1 + 7, 143, 0}, {8, EXCALATTACK1 + 8, 90, 91}, + {8, EXCALATTACK1 + 9, 30, 159}, {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52} + }, + {{12, HALBERDATTACK1, 245, 22}, {12, EMPTY, 107, 52}, {12, EMPTY, 147, 76}, + {12, HALBERDATTACK1 + 1, 249, 45}, {12, HALBERDATTACK1 + 2, 161, 60}, {12, HALBERDATTACK1 + 3, 45, 88}, + {12, EMPTY, 80, 41}, {12, HALBERDATTACK1 + 3, 45, 88}, {12, HALBERDATTACK1 + 2, 161, 60}, + {12, HALBERDATTACK1 + 1, 249, 45}, {12, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + } +}; + +//SCOTT +const WEAPONINF zweaponanimtics[MAXWEAPONS][MAXFRAMES] = +{ + // FIST + {{10, RFIST, 216, 120}, {10, RFIST + 1, 166, 113}, {10, RFIST + 2, 156, 129}, + {10, RFIST + 3, 169, 151}, {10, RFIST + 4, 153, 124}, {10, RFIST + 5, 224, 133}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // ZKNIFE + {{8, ZKNIFEATTACK, 189, 52}, {8, ZKNIFEATTACK + 1, 254, 68}, + {16, EMPTY, 147, 76}, {8, ZKNIFEATTACK + 1, 254, 68}, + {8, ZKNIFEATTACK + 2, 218, 80}, {8, ZKNIFEATTACK + 3, 137, 83}, + {8, ZKNIFEATTACK + 4, 136, 100}, {8, ZKNIFEATTACK + 5, 126, 140}, + {8, ZKNIFEATTACK + 4, 136, 100}, {8, ZKNIFEATTACK + 3, 137, 83}, + {8, ZKNIFEATTACK + 2, 218, 80}, {1, ZKNIFEATTACK, 189, 52} + }, + // ZSHORTATTACK + {{10, ZSHORTATTACK, 243, 68}, {10, ZSHORTATTACK + 4, 255, 50}, + {10, ZSHORTATTACK + 5, 279, 66}, {10, ZSHORTATTACK + 6, 238, 52}, + {10, ZSHORTATTACK + 7, 181, 49}, {10, ZSHORTATTACK + 8, 129, 141}, + {1, EMPTY, 90, 184}, {1, EMPTY, 297, 169}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + }, + // ZSTARATTACK + {{12, ZSTARATTACK, 193, 90}, {12, ZSTARATTACK + 3, 102, 128}, + {12, ZSTARATTACK + 4, 77, 159}, {12, ZSTARATTACK + 5, 239, 79}, + {12, EMPTY, 299, 86}, {12, EMPTY, 107, 52}, + {12, ZSTARATTACK + 6, 175, 19}, {12, ZSTARATTACK + 7, 125, 124}, + {12, ZSTARATTACK + 8, 109, 187}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // SWORD + {{8, SWORDATTACK, 229, 123}, {8, SWORDATTACK + 1, 221, 87}, {8, SWORDATTACK + 2, 193, 21}, + {8, SWORDATTACK + 3, 173, 0}, {8, SWORDATTACK + 4, 61, 0}, {8, SWORDATTACK + 5, 33, 48}, + {8, SWORDATTACK + 6, 126, 131}, {8, SWORDATTACK + 7, 297, 164}, {3, EMPTY, 147, 76}, + {3, EMPTY, 80, 41}, {3, EMPTY, 107, 52}, {3, EMPTY, 147, 76} + }, + // ZAXEATTACK + {{6, ZAXEATTACK, 179, 117}, {6, ZAXEATTACK + 6, 217, 107}, + {6, ZAXEATTACK + 7, 106, 146}, {6, ZAXEATTACK + 8, 94, 128}, + {6, ZAXEATTACK + 9, 123, 132}, {6, ZAXEATTACK + 10, 102, 134}, + {6, ZAXEATTACK + 11, 112, 45}, {6, ZAXEATTACK + 12, 102, 0}, + {6, ZAXEATTACK + 13, 68, 42}, {6, ZAXEATTACK + 14, 42, 138}, + {6, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // ZBOW + {{8, ZBOWWALK, 75, 13}, {8, ZBOWATTACK, 90, 0}, {8, ZBOWATTACK + 1, 70, 0}, + {8, ZBOWATTACK + 2, 70, 0}, {6, ZBOWATTACK + 3, 70, 0}, {4, ZBOWATTACK + 4, 70, 0}, + {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, + {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, {1, EMPTY, 147, 76} + }, + // ZPIKE + {{10, ZPIKEREADY + 5, 210, 127}, {10, EMPTY, 80, 41}, {10, EMPTY, 107, 52}, {10, EMPTY, 147, 76}, + {10, ZPIKEATTACK, 0, 43}, {10, ZPIKEATTACK + 1, 0, 0}, {10, ZPIKEATTACK + 2, 0, 0}, + {10, ZPIKEATTACK + 3, 45, 0}, {10, ZPIKEATTACK + 4, 51, 23}, {10, ZPIKEATTACK + 5, 59, 121}, + {12, EMPTY, 80, 41}, {1, EMPTY, 107, 52} + }, + {{8, ZTWOHANDATTACK, 98, 133}, {8, ZTWOHANDATTACK + 6, 115, 130}, + {8, ZTWOHANDATTACK + 7, 125, 128}, {8, ZTWOHANDATTACK + 8, 116, 82}, + {8, ZTWOHANDATTACK + 9, 117, 9}, {8, ZTWOHANDATTACK + 10, 180, 0}, + {8, ZTWOHANDATTACK + 11, 174, 0}, {8, ZTWOHANDATTACK + 12, 166, 0}, + {8, ZTWOHANDATTACK + 13, 125, 90}, {8, ZTWOHANDATTACK + 14, 83, 166}, + {1, EMPTY, 30, 159}, {1, EMPTY, 80, 41} + }, + // { { 12,ZHALBERDATTACK,173,29 },{6,EMPTY,107,52}, + // { 6,EMPTY,147,76},{ 12,ZHALBERDATTACK+3,117,0 }, + // { 12,ZHALBERDATTACK+4,245,0},{12,ZHALBERDATTACK+5,237,0}, + // { 6,EMPTY,80,41 },{12,ZHALBERDATTACK+6,115,0}, + // { 12,ZHALBERDATTACK+7,9,0 },{ 12,ZHALBERDATTACK+8,0,42 }, + // { 1,ZHALBERDATTACK,173,29 },{ 1,EMPTY,147,76 } + // } + {{12, ZHALBERDATTACK, 245, 30}, {12, EMPTY, 107, 52}, {12, EMPTY, 147, 76}, + {12, HALBERDATTACK1 + 1, 249, 45}, {12, HALBERDATTACK1 + 2, 161, 60}, {12, HALBERDATTACK1 + 3, 45, 88}, + {12, EMPTY, 80, 41}, {12, HALBERDATTACK1 + 3, 45, 88}, {12, HALBERDATTACK1 + 2, 161, 60}, + {12, HALBERDATTACK1 + 1, 249, 45}, {12, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + } + + +}; + +// SCOTT +const WEAPONINF zlefthandanimtics[5][MAXFRAMES] = +{ + {{10, RFIST, 15, 121}, {10, RFIST + 1, 17, 114}, {10, RFIST + 2, 54, 131}, + {10, RFIST + 3, 76, 152}, {10, RFIST + 4, 31, 126}, {10, RFIST + 5, 26, 135}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // KNIFE + {{8, KNIFEATTACK2, 0, 113}, {8, KNIFEATTACK2 + 1, 44, 111}, {8, KNIFEATTACK2 + 2, 119, 137}, + {8, KNIFEATTACK2 + 3, 187, 159}, {16, EMPTY, 136, 100}, {8, KNIFEATTACK2 + 3, 187, 159}, + {8, KNIFEATTACK2 + 2, 119, 137}, {8, KNIFEATTACK2 + 1, 44, 111}, {8, KNIFEATTACK2, 0, 113}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // ZSHORTATTACK + {{10, ZSHORTATTACK, 255, 50}, {10, ZSHORTATTACK + 1, 279, 66}, {10, ZSHORTATTACK + 2, 238, 52}, + {10, ZSHORTATTACK + 3, 181, 49}, {10, ZSHORTATTACK + 4, 129, 141}, {10, ZSHORTATTACK + 5, 70, 93}, + {10, EMPTY, 90, 184}, {1, EMPTY, 297, 169}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + }, + // ZSTARATTACK2 + {{12, ZSTARATTACK2, 38, 141}, {12, ZSTARATTACK2 + 1, 0, 111}, {12, ZSTARATTACK2 + 2, 0, 91}, + {12, ZSTARATTACK2 + 3, 0, 47}, {12, EMPTY, 0, 24}, {1, EMPTY, 0, 24}, + {1, EMPTY, 0, 24}, {1, EMPTY, 0, 24}, {1, EMPTY, 0, 24}, + {1, EMPTY, 0, 24}, {1, EMPTY, 0, 24}, {1, EMPTY, 0, 24} + }, + // ZSHORTATTACK2 + {{10, ZSHORTATTACK2, 238, 99}, {10, ZSHORTATTACK2 + 1, 202, 11}, {10, ZSHORTATTACK2 + 2, 182, 0}, + {10, ZSHORTATTACK2 + 3, 79, 13}, {10, ZSHORTATTACK2 + 4, 79, 13}, {10, ZSHORTATTACK2 + 5, 119, 123}, + {10, ZSHORTATTACK2 + 6, 295, 179}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + } + +}; + +const WEAPONINF weaponanimtics2[MAXWEAPONS][MAXFRAMES] = +{ + // FIST + {{10, RFIST, 216, 120}, {10, RFIST + 1, 166, 113}, {10, RFIST + 2, 156, 129}, + {10, RFIST + 3, 169, 151}, {10, RFIST + 4, 153, 124}, {10, RFIST + 5, 224, 133}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // KNIFE + {{8, KNIFEATTACK, 189, 52}, {8, KNIFEATTACK + 1, 254, 68}, {16, EMPTY, 147, 76}, + {8, KNIFEATTACK2, 206, 114}, {8, KNIFEATTACK2 + 1, 107, 112}, {8, KNIFEATTACK2 + 2, 22, 138}, + {8, KNIFEATTACK2 + 3, 0, 161}, {16, EMPTY, 136, 100}, {8, KNIFEATTACK2 + 3, 0, 161}, + {8, KNIFEATTACK2 + 2, 22, 138}, {8, KNIFEATTACK2 + 1, 107, 112}, {8, KNIFEATTACK2, 206, 114} + }, + // GOBLINATTACK + {{10, GOBSWORDATTACK2, 236, 99}, {10, GOBSWORDATTACK2 + 1, 202, 24}, {10, GOBSWORDATTACK2 + 2, 181, 0}, + {10, GOBSWORDATTACK2 + 3, 52, 12}, {10, GOBSWORDATTACK2 + 4, 72, 72}, {10, GOBSWORDATTACK2 + 5, 134, 139}, + {10, GOBSWORDATTACK2 + 6, 297, 169}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + }, + // MORNINGATTACK2 + {{12, MORNINGATTACK2, 85, 136}, {12, MORNINGATTACK2 + 1, 34, 110}, {12, MORNINGATTACK2 + 2, 32, 91}, + {12, MORNINGATTACK2 + 3, 186, 47}, {12, MORNINGATTACK2 + 4, 275, 24}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + }, + // SWORD + {{8, SWORDATTACK2 + 1, 195, 63}, {8, SWORDATTACK2 + 2, 250, 54}, {8, SWORDATTACK2 + 3, 275, 37}, + {16, EMPTY, 61, 0}, {8, SWORDATTACK2 + 4, 229, 66}, {8, SWORDATTACK2 + 5, 185, 0}, + {8, SWORDATTACK2 + 6, 158, 115}, {8, SWORDATTACK2 + 7, 57, 163}, {1, EMPTY, 57, 163}, + {1, EMPTY, 57, 163}, {1, EMPTY, 57, 163}, {1, EMPTY, 57, 163} + }, + {{12, BIGAXEATTACK2, 200, 111}, {12, BIGAXEATTACK2 + 1, 5, 136}, {12, BIGAXEATTACK2 + 2, 69, 162}, + {12, BIGAXEATTACK2 + 3, 147, 164}, {12, BIGAXEATTACK2 + 4, 76, 152}, {12, BIGAXEATTACK2 + 5, 33, 95}, + {12, BIGAXEATTACK2 + 6, 0, 91}, {12, BIGAXEATTACK2 + 7, 0, 98}, {12, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // BOW + {{8, BOWWALK, 75, 13}, {8, BOWWALK + 1, 90, 0}, {8, BOWWALK + 2, 70, 0}, + {8, BOWWALK + 3, 70, 0}, {6, BOWWALK + 4, 70, 0}, {4, BOWWALK + 5, 70, 0}, + {1, EMPTY, 126, 131}, {1, EMPTY, 297, 164}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + {{10, PIKEATTACK2, 266, 147}, {10, PIKEATTACK2 + 1, 182, 117}, {10, PIKEATTACK2 + 2, 123, 84}, + {10, PIKEATTACK2 + 3, 7, 48}, {10, PIKEATTACK2 + 4, 0, 83}, {10, PIKEATTACK2 + 5, 0, 158}, + {10, PIKEATTACK2 + 6, 25, 117}, {10, PIKEATTACK2 + 7, 139, 93}, {10, PIKEATTACK2 + 8, 234, 75}, + {8, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + {{8, EXCALATTACK2, 0, 143}, {8, EXCALATTACK2 + 1, 0, 103}, {8, EXCALATTACK2 + 2, 0, 70}, + {8, EXCALATTACK2 + 3, 48, 0}, {8, EXCALATTACK2 + 4, 67, 0}, {8, EXCALATTACK2 + 5, 78, 21}, + {8, EXCALATTACK2 + 6, 165, 107}, {8, EXCALATTACK2 + 7, 260, 168}, {1, EMPTY, 130, 27}, + {1, EMPTY, 138, 125}, {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52} + }, + {{12, HALBERDATTACK1, 245, 22}, {12, HALBERDATTACK2, 114, 35}, {12, HALBERDATTACK2 + 1, 105, 87}, + {12, HALBERDATTACK2 + 2, 54, 107}, {12, HALBERDATTACK2 + 3, 48, 102}, {1, HALBERDATTACK2 + 3, 48, 102}, + {1, HALBERDATTACK2 + 3, 48, 102}, {12, HALBERDATTACK2 + 2, 54, 107}, {12, HALBERDATTACK2 + 1, 105, 87}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + } +}; + +//SCOTT +const WEAPONINF zweaponanimtics2[MAXWEAPONS][MAXFRAMES] = +{ + // FIST + {{10, RFIST, 216, 120}, {10, RFIST + 1, 166, 113}, {10, RFIST + 2, 156, 129}, + {10, RFIST + 3, 169, 151}, {10, RFIST + 4, 153, 124}, {10, RFIST + 5, 224, 133}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // ZKNIFE + {{8, ZKNIFEATTACK, 189, 52}, {8, ZKNIFEATTACK + 1, 254, 68}, {16, EMPTY, 147, 76}, + {8, ZKNIFEATTACK2, 206, 114}, {8, ZKNIFEATTACK2 + 1, 107, 112}, {8, ZKNIFEATTACK2 + 2, 22, 138}, + {8, ZKNIFEATTACK2 + 3, 0, 161}, {16, EMPTY, 136, 100}, {8, KNIFEATTACK2 + 3, 0, 161}, + {8, ZKNIFEATTACK2 + 2, 22, 138}, {8, ZKNIFEATTACK2 + 1, 107, 112}, {8, KNIFEATTACK2, 206, 114} + }, + // ZSHORTATTACK2 + {{10, ZSHORTATTACK2, 238, 99}, {10, ZSHORTATTACK2 + 1, 202, 11}, + {10, ZSHORTATTACK2 + 2, 182, 0}, {10, ZSHORTATTACK2 + 3, 79, 13}, + {10, ZSHORTATTACK2 + 4, 40, 45}, {10, ZSHORTATTACK2 + 5, 119, 123}, + {10, ZSHORTATTACK2 + 6, 295, 179}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + }, + // ZSTARATTACK2 + {{12, ZSTARATTACK2, 44, 110}, {12, ZSTARATTACK2 + 1, 26, 91}, {12, ZSTARATTACK2 + 2, 177, 38}, + {12, ZSTARATTACK2 + 3, 262, 11}, {12, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + }, + // SWORD + {{8, SWORDATTACK2 + 1, 195, 63}, {8, SWORDATTACK2 + 2, 250, 54}, {8, SWORDATTACK2 + 3, 275, 37}, + {16, EMPTY, 61, 0}, {8, SWORDATTACK2 + 4, 229, 66}, {8, SWORDATTACK2 + 5, 185, 0}, + {8, SWORDATTACK2 + 6, 158, 115}, {8, SWORDATTACK2 + 7, 57, 163}, {1, EMPTY, 57, 163}, + {1, EMPTY, 57, 163}, {1, EMPTY, 57, 163}, {1, EMPTY, 57, 163} + }, + // ZAXEATTACK2 + {{6, ZAXEATTACK2, 200, 111}, {6, ZAXEATTACK2 + 1, 5, 136}, {6, ZAXEATTACK2 + 2, 69, 162}, + {6, ZAXEATTACK2 + 3, 147, 164}, {6, ZAXEATTACK2 + 4, 76, 152}, {6, ZAXEATTACK2 + 5, 33, 95}, + {6, ZAXEATTACK2 + 6, 0, 91}, {6, ZAXEATTACK2 + 7, 0, 98}, {6, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // ZBOW + {{8, ZBOWWALK, 75, 13}, {8, ZBOWATTACK, 90, 0}, {8, ZBOWATTACK + 1, 70, 0}, + {8, ZBOWATTACK + 2, 70, 0}, {6, ZBOWATTACK + 3, 70, 0}, {4, ZBOWATTACK + 4, 70, 0}, + {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, + {1, ZBOWWALK, 75, 13}, {1, ZBOWWALK, 75, 13}, {1, EMPTY, 147, 76} + }, + + // ZPIKEATTACK2 + {{10, ZPIKEATTACK2, 266, 147}, {10, ZPIKEATTACK2 + 1, 182, 117}, {10, ZPIKEATTACK2 + 2, 123, 84}, + {10, ZPIKEATTACK2 + 3, 7, 48}, {10, ZPIKEATTACK2 + 4, 0, 83}, {10, ZPIKEATTACK2 + 5, 0, 158}, + {10, ZPIKEATTACK2 + 6, 25, 117}, {10, ZPIKEATTACK2 + 7, 139, 93}, {10, ZPIKEATTACK2 + 8, 234, 75}, + {8, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // ZTWOHANDATTACK2 + {{8, ZTWOHANDATTACK2, 0, 143}, {8, ZTWOHANDATTACK2 + 1, 0, 103}, {8, ZTWOHANDATTACK2 + 2, 0, 70}, + {8, ZTWOHANDATTACK2 + 3, 41, 0}, {8, ZTWOHANDATTACK2 + 4, 54, 0}, {8, ZTWOHANDATTACK2 + 5, 166, 21}, + {8, ZTWOHANDATTACK2 + 6, 242, 108}, {8, EMPTY, 260, 168}, {1, EMPTY, 130, 27}, + {1, EMPTY, 138, 125}, {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52} + }, + // ZHALBERDATTACK2 + {{12, HALBERDATTACK1, 245, 22}, {12, HALBERDATTACK2, 114, 35}, {12, HALBERDATTACK2 + 1, 105, 87}, + {12, HALBERDATTACK2 + 2, 54, 107}, {12, HALBERDATTACK2 + 3, 48, 102}, {1, HALBERDATTACK2 + 3, 48, 102}, + {1, HALBERDATTACK2 + 3, 48, 102}, {12, HALBERDATTACK2 + 2, 54, 107}, {12, HALBERDATTACK2 + 1, 105, 87}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + } + +}; + + +const WEAPONINF lefthandanimtics[5][MAXFRAMES] = +{ + {{10, RFIST, 15, 121}, {10, RFIST + 1, 17, 114}, {10, RFIST + 2, 54, 131}, + {10, RFIST + 3, 76, 152}, {10, RFIST + 4, 31, 126}, {10, RFIST + 5, 26, 135}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // KNIFE + {{8, KNIFEATTACK2, 0, 113}, {8, KNIFEATTACK2 + 1, 44, 111}, {8, KNIFEATTACK2 + 2, 119, 137}, + {8, KNIFEATTACK2 + 3, 187, 159}, {16, EMPTY, 136, 100}, {8, KNIFEATTACK2 + 3, 187, 159}, + {8, KNIFEATTACK2 + 2, 119, 137}, {8, KNIFEATTACK2 + 1, 44, 111}, {8, KNIFEATTACK2, 0, 113}, + {1, EMPTY, 80, 41}, {1, EMPTY, 107, 52}, {1, EMPTY, 147, 76} + }, + // GOBLINATTACK + {{10, GOBSWORDATTACK, 243, 92}, {10, GOBSWORDATTACK + 1, 255, 68}, {10, GOBSWORDATTACK + 2, 279, 65}, + {10, GOBSWORDATTACK + 3, 238, 55}, {10, GOBSWORDATTACK + 4, 153, 52}, {10, GOBSWORDATTACK + 5, 129, 152}, + {10, GOBSWORDATTACK + 6, 90, 184}, {1, EMPTY, 297, 169}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + }, + // MORNINGATTACK2 + + {{12, MORNINGATTACK2, 38, 141}, {12, MORNINGATTACK2 + 1, 0, 111}, {12, MORNINGATTACK2 + 2, 0, 91}, + {12, MORNINGATTACK2 + 3, 0, 47}, {12, MORNINGATTACK2 + 4, 0, 24}, {1, EMPTY, 0, 24}, + {1, EMPTY, 0, 24}, {1, EMPTY, 0, 24}, {1, EMPTY, 0, 24}, + {1, EMPTY, 0, 24}, {1, EMPTY, 0, 24}, {1, EMPTY, 0, 24} + + }, + + // GOBLINATTACK2 + {{10, GOBSWORDATTACK2, 236, 99}, {10, GOBSWORDATTACK2 + 1, 202, 24}, {10, GOBSWORDATTACK2 + 2, 181, 0}, + {10, GOBSWORDATTACK2 + 3, 52, 12}, {10, GOBSWORDATTACK2 + 4, 72, 72}, {10, GOBSWORDATTACK2 + 5, 134, 139}, + {10, GOBSWORDATTACK2 + 6, 297, 169}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, + {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24}, {1, EMPTY, 275, 24} + } + +}; + + +END_WH_NS diff --git a/source/games/whaven/src/wh.h b/source/games/whaven/src/wh.h index 713471db2..6e4eba99b 100644 --- a/source/games/whaven/src/wh.h +++ b/source/games/whaven/src/wh.h @@ -6,12 +6,287 @@ BEGIN_WH_NS using SPRITE = spritetype; using boolean = bool; +using byte = uint8_t; END_WH_NS #include "globals.h" #include "names.h" +#include "item.h" #include "wh1names.h" #include "wh2names.h" +#include "sndnames.h" #include "player.h" #include "ai.h" +#include "printf.h" +#include "gstrings.h" +#include "gamecontrol.h" + +BEGIN_WH_NS + + +enum EItems +{ + ITEMSBASE = 101, + SILVERBAGTYPE = 101, + GOLDBAGTYPE = 102, + HELMETTYPE = 103, + PLATEARMORTYPE = 104, + CHAINMAILTYPE = 105, + LEATHERARMORTYPE = 106, + GIFTBOXTYPE = 107, + FLASKBLUETYPE = 108, + FLASKGREENTYPE = 109, + FLASKOCHRETYPE = 110, + FLASKREDTYPE = 111, + FLASKTANTYPE = 112, + DIAMONDRINGTYPE = 113, + SHADOWAMULETTYPE = 114, + GLASSSKULLTYPE = 115, + AHNKTYPE = 116, + BLUESCEPTERTYPE = 117, + YELLOWSCEPTERTYPE = 118, + ADAMANTINERINGTYPE = 119, + ONYXRINGTYPE = 120, + PENTAGRAMTYPE = 121, + CRYSTALSTAFFTYPE = 122, + AMULETOFTHEMISTTYPE = 123, + HORNEDSKULLTYPE = 124, + THEHORNTYPE = 125, + SAPHIRERINGTYPE = 126, + BRASSKEYTYPE = 127, + BLACKKEYTYPE = 128, + GLASSKEYTYPE = 129, + IVORYKEYTYPE = 130, + SCROLLSCARETYPE = 131, + SCROLLNIGHTTYPE = 132, + SCROLLFREEZETYPE = 133, + SCROLLMAGICTYPE = 134, + SCROLLOPENTYPE = 135, + SCROLLFLYTYPE = 136, + SCROLLFIREBALLTYPE = 137, + SCROLLNUKETYPE = 138, + QUIVERTYPE = 139, + BOWTYPE = 140, + WEAPON1TYPE = 141, + WEAPON1ATYPE = 142, + GOBWEAPONTYPE = 143, + WEAPON2TYPE = 144, + WEAPON3ATYPE = 145, + WEAPON3TYPE = 146, + WEAPON4TYPE = 147, + THROWHALBERDTYPE = 148, + WEAPON5TYPE = 149, + GONZOSHIELDTYPE = 150, + SHIELDTYPE = 151, + WEAPON5BTYPE = 152, + WALLPIKETYPE = 153, + WEAPON6TYPE = 154, + WEAPON7TYPE = 155, + GYSERTYPE = 156, //WH1 + SPIKEBLADETYPE = 157, + SPIKETYPE = 158, + SPIKEPOLETYPE = 159, + MONSTERBALLTYPE = 160, + WEAPON8TYPE = 161, + MAXITEMS = 162, +}; + + +struct Delayitem { + int item; + int timer; + boolean func; + + void memmove(const Delayitem& source) + { + item = source.item; + timer = source.timer; + func = source.func; + } + +}; + +struct SwingDoor { + int wall[8]; + int sector; + int angopen; + int angclosed; + int angopendir; + int ang; + int anginc; + int x[8]; + int y[8]; +}; + +struct PLOCATION { + int x; + int y; + int z; + float ang; + float horiz; +}; + + +extern int killcnt; + +// whobj + +extern int justwarpedcnt; +extern byte flashflag; +extern short torchpattern[]; +extern int monsterwarptime; + +short adjusthp(int hp); +void timerprocess(PLAYER& plr); +int getPickHeight(); +void processobjs(PLAYER& plr); +void newstatus(short sn, int seq); +void makeafire(int i, int firetype); +void explosion(int i, int x, int y, int z, int owner); +void explosion2(int i, int x, int y, int z, int owner); +void trailingsmoke(int i, boolean ball); +void icecubes(int i, int x, int y, int z, int owner); +boolean damageactor(PLAYER& plr, int hitobject, short i); +int movesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, int cliptype); +void trowajavlin(int s); +void spawnhornskull(short i); +void spawnapentagram(int sn); + + +// whplr + +extern PLAYER player[MAXPLAYERS]; +extern PLOCATION gPrevPlayerLoc[MAXPLAYERS]; +extern short monsterangle[MAXSPRITESONSCREEN], monsterlist[MAXSPRITESONSCREEN]; +extern int shootgunzvel; +extern boolean justteleported; +extern int victor; +extern int autohoriz; // XXX NOT FOR MULTIPLAYER + +extern int pyrn; +extern int mapon; +extern int damage_vel, damage_svel, damage_angvel; + +void viewBackupPlayerLoc(int nPlayer); +void playerdead(PLAYER& plr); +void initplayersprite(PLAYER& plr); +void updateviewmap(PLAYER& plr); +void plruse(PLAYER& plr); +void chunksofmeat(PLAYER& plr, int hitsprite, int hitx, int hity, int hitz, short hitsect, int daang); +void addhealth(PLAYER& plr, int hp); +void addarmor(PLAYER& plr, int arm); +void addscore(PLAYER& plr, int score); +void goesupalevel(PLAYER& plr); + +// whtag.cpp + +extern int d_soundplayed; +extern int delaycnt; +extern Delayitem delayitem[MAXSECTORS]; + +extern short ironbarsector[16]; +extern short ironbarscnt; +extern int ironbarsgoal1[16], ironbarsgoal2[16]; +extern short ironbarsdone[16], ironbarsanim[16]; +extern int ironbarsgoal[16]; + +extern short warpsectorlist[64], warpsectorcnt; +extern short xpanningsectorlist[16], xpanningsectorcnt; +extern short ypanningwalllist[128], ypanningwallcnt; +extern short floorpanninglist[64], floorpanningcnt; +extern SwingDoor swingdoor[MAXSWINGDOORS]; +extern short swingcnt; + +extern short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt; +extern int dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16]; + + +void operatesprite(PLAYER& plr, short s); +void operatesector(PLAYER& plr, int s); +void animatetags(int nPlayer); +void dodelayitems(int tics); +void setdelayfunc(int item, int delay); + +// whmap + +extern boolean nextlevel; + +void loadnewlevel(int mapon); +void preparesectors(); +boolean prepareboard(const char* fname); + +// whani +void animateobjs(PLAYER& plr); +boolean isBlades(int pic); + +// weapons + +extern const WEAPONINF sspellbookanim[MAXNUMORBS][9]; +extern const WEAPONINF spikeanimtics[5]; +extern const WEAPONINF wh2throwanimtics[MAXNUMORBS][MAXFRAMES + 1]; +extern const WEAPONINF throwanimtics[MAXNUMORBS][MAXFRAMES + 1]; +extern const WEAPONINF cockanimtics[MAXFRAMES + 1]; +extern const WEAPONINF zcockanimtics[MAXFRAMES + 1]; +extern const WEAPONINF zreadyanimtics[MAXWEAPONS][MAXFRAMES + 1]; +extern const WEAPONINF readyanimtics[MAXWEAPONS][MAXFRAMES + 1]; +extern const WEAPONINF weaponanimtics[MAXWEAPONS][MAXFRAMES]; +extern const WEAPONINF zweaponanimtics[MAXWEAPONS][MAXFRAMES]; +extern const WEAPONINF zlefthandanimtics[5][MAXFRAMES]; +extern const WEAPONINF weaponanimtics2[MAXWEAPONS][MAXFRAMES]; +extern const WEAPONINF zweaponanimtics2[MAXWEAPONS][MAXFRAMES]; +extern const WEAPONINF lefthandanimtics[5][MAXFRAMES]; + +extern int dropshieldcnt; +extern boolean droptheshield; +extern int dahand; +extern int weapondrop; +extern int snakex, snakey; +extern int enchantedsoundhandle; + +boolean checkmedusadist(int i, int x, int y, int z, int lvl); +void autoweaponchange(PLAYER& plr, int dagun); +void weaponchange(int snum); +void plrfireweapon(PLAYER& plr); +void weaponsprocess(int snum); +void shootgun(PLAYER& plr, float ang, int guntype); +boolean checkweapondist(int i, int x, int y, int z, int guntype); +void swingdapunch(PLAYER& plr, int daweapon); +void swingdaweapon(PLAYER& plr); +void swingdacrunch(PLAYER& plr, int daweapon); +void swingdasound(int daweapon, boolean enchanted); + +boolean isItemSprite(int i); +void InitItems(); + +// spellbook + +void activatedaorb(PLAYER& plr); +void castaorb(PLAYER& plr); +void spellswitch(PLAYER& plr, int j); +void bookprocess(int snum); +boolean changebook(PLAYER& plr, int i); +boolean lvlspellcheck(PLAYER& plr); +void speelbookprocess(PLAYER& plr); +void nukespell(PLAYER& plr, short j); +void medusa(PLAYER& plr, short j); +void displayspelltext(PLAYER& plr); +void orbpic(PLAYER& plr, int currentorb); + +// potion +extern int potiontilenum; +void potiontext(PLAYER& plr); +void potionchange(int snum); +void usapotion(PLAYER& plr); +boolean potionspace(PLAYER& plr, int vial); +void updatepotion(PLAYER& plr, int vial); +void potionpic(PLAYER& plr, int currentpotion, int x, int y, int scale); +void randompotion(int i); + + +inline void showmessage(const char* msg, int) +{ + Printf(PRINT_NOTIFY, "%s\n", GStrings(msg)); +} + +END_WH_NS diff --git a/source/games/whaven/src/wh2names.h b/source/games/whaven/src/wh2names.h index b0900a84f..82d1e1582 100644 --- a/source/games/whaven/src/wh2names.h +++ b/source/games/whaven/src/wh2names.h @@ -1,4 +1,4 @@ -#include "ns.h" +#pragma once BEGIN_WH_NS diff --git a/source/games/whaven/src/whani.cpp b/source/games/whaven/src/whani.cpp new file mode 100644 index 000000000..b4ac167c2 --- /dev/null +++ b/source/games/whaven/src/whani.cpp @@ -0,0 +1,1417 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + + + +void animateobjs(PLAYER& plr) { + + boolean hitdamage = false; + short osectnum = 0, hitobject; + int dax, day, daz = 0, j, k; + short movestat = 0; + + short i, nextsprite; + short startwall, endwall; + + if (plr.sector < 0 || plr.sector >= numsectors) + return; + + if (isWh2()) { + for (i = headspritestat[SHARDOFGLASS]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + spr.lotag -= TICSPERFRAME; + switch (spr.extra) { + case 1: + spr.zvel += TICSPERFRAME << 3; + movestat = (short) movesprite((short) i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[spr.ang & 2047]) * TICSPERFRAME) << 3, spr.zvel, 4 << 8, 4 << 8, 0); + break; + case 2: + spr.zvel += TICSPERFRAME << 5; + movestat = (short) movesprite((short) i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 1, + ((sintable[spr.ang & 2047]) * TICSPERFRAME) << 1, spr.zvel, 4 << 8, 4 << 8, 0); + break; + case 3: + spr.zvel -= TICSPERFRAME << 5; + movestat = (short) movesprite((short) i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 2, + ((sintable[spr.ang & 2047]) * TICSPERFRAME) << 2, spr.zvel, 4 << 8, 4 << 8, 0); + if (spr.lotag < 0) { + spr.lotag = 30; + spr.extra = 2; + } + break; + } + if (spr.lotag < 0) { + deletesprite(i); + } + } + + for (i = headspritestat[SPARKSUP]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + + osectnum = spr.sectnum; + + spr.lotag -= TICSPERFRAME; + if (spr.lotag < -100) + spr.lotag = -100; + if (spr.lotag < 0) { + daz = spr.zvel -= TICSPERFRAME << 4; + spr.ang = (short) ((spr.ang + (TICSPERFRAME << 2)) & 2047); + + movesprite((short) i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[spr.ang & 2047]) * TICSPERFRAME) << 3, daz, 4 << 8, 4 << 8, 1); + + if (osectnum != spr.sectnum) { + spr.x = sparksx; + spr.y = sparksy; + spr.z = sparksz; + spr.ang = (short) ((krand() % 2047) & 2047); + spr.zvel = 0; + setsprite((short) i, spr.x, spr.y, spr.z); + + } + } + } + + for (i = headspritestat[SPARKSDN]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + + osectnum = spr.sectnum; + + spr.lotag -= TICSPERFRAME; + if (spr.lotag < -100) + spr.lotag = -100; + + if (spr.lotag < 0) { + + daz = spr.zvel += TICSPERFRAME << 4; + spr.ang = (short) ((spr.ang + (TICSPERFRAME << 2)) & 2047); + + movesprite((short) i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[spr.ang & 2047]) * TICSPERFRAME) << 3, daz, 4 << 8, 4 << 8, 1); + + if (osectnum != spr.sectnum) { + spr.x = sparksx; + spr.y = sparksy; + spr.z = sparksz; + spr.ang = (short) ((krand() % 2047) & 2047); + spr.zvel = 0; + setsprite((short) i, spr.x, spr.y, spr.z); + + } + } + } + + for (i = headspritestat[SPARKS]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + + osectnum = spr.sectnum; + spr.lotag -= TICSPERFRAME; + if (spr.lotag < -100) + spr.lotag = -100; + + if (spr.lotag < 0) { + + daz = 0; + spr.ang = (short) ((spr.ang + (TICSPERFRAME << 2)) & 2047); + + movesprite((short) i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[spr.ang & 2047]) * TICSPERFRAME) << 3, daz, 4 << 8, 4 << 8, 1); + + if (osectnum != spr.sectnum) { + spr.x = sparksx; + spr.y = sparksy; + spr.z = sparksz; + spr.ang = (short) ((krand() % 2047) & 2047); + spr.zvel = 0; + setsprite((short) i, spr.x, spr.y, spr.z); + + } + } + } + + for (i = headspritestat[STONETOFLESH]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + spr.lotag -= TICSPERFRAME; + if (spr.lotag < 0) { + switch (spr.picnum) { + case STONEGONZOCHM: + spr.picnum = GONZOGHM; + enemy[GONZOTYPE].info.set(spr); + spr.detail = GONZOTYPE; + sprite[i].xrepeat = 24; + sprite[i].yrepeat = 24; + sprite[i].clipdist = 32; + changespritestat(i, FACE); + sprite[i].hitag = (short) adjusthp(100); + sprite[i].lotag = 100; + sprite[i].cstat |= 0x101; + sprite[i].extra = 0; + break; + case STONEGONZOBSH: + spr.picnum = GONZOGSH; + enemy[GONZOTYPE].info.set(spr); + spr.detail = GONZOTYPE; + sprite[i].xrepeat = 24; + sprite[i].yrepeat = 24; + sprite[i].clipdist = 32; + changespritestat(i, FACE); + sprite[i].hitag = (short) adjusthp(100); + sprite[i].lotag = 100; + sprite[i].cstat |= 0x101; + sprite[i].extra = 0; + break; + case STONEGONZOGSH: + spr.picnum = GONZOGSH; + enemy[GONZOTYPE].info.set(spr); + spr.detail = GONZOTYPE; + sprite[i].xrepeat = 24; + sprite[i].yrepeat = 24; + sprite[i].clipdist = 32; + changespritestat(i, FACE); + sprite[i].hitag = (short) adjusthp(100); + sprite[i].lotag = 100; + sprite[i].cstat |= 0x101; + sprite[i].extra = 0; + break; + case STONEGRONDOVAL: + spr.picnum = GRONHAL; + enemy[GRONTYPE].info.set(spr); + spr.detail = GRONTYPE; + sprite[i].xrepeat = 30; + sprite[i].yrepeat = 30; + sprite[i].clipdist = 64; + changespritestat(i, FACE); + sprite[i].hitag = (short) adjusthp(300); + sprite[i].lotag = 100; + sprite[i].cstat |= 0x101; + sprite[i].extra = 4; + break; + case STONEGONZOBSW2: + case STONEGONZOBSW: + spr.picnum = NEWGUY; + enemy[NEWGUYTYPE].info.set(spr); + spr.detail = NEWGUYTYPE; + sprite[i].xrepeat = 26; + sprite[i].yrepeat = 26; + sprite[i].clipdist = 48; + changespritestat(i, FACE); + sprite[i].hitag = (short) adjusthp(100); + sprite[i].lotag = 100; + sprite[i].cstat |= 0x101; + sprite[i].extra = 30; + break; + } + } + } + + for (i = headspritestat[SHADE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + spr.lotag -= TICSPERFRAME; + + if (spr.lotag < 0) { + spr.picnum = GONZOBSHDEAD; + spr.shade = 31; + spr.cstat = 0x303; + spr.pal = 0; + spr.extra = 12; + newstatus((short) i, EVILSPIRIT); + } + } + + for (i = headspritestat[EVILSPIRIT]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + if (spr.picnum >= (GONZOBSHDEAD - 8)) { + if (--spr.extra <= 0) { + spr.picnum--; + spr.extra = 12; + } + } else { + j = insertsprite(spr.sectnum, FACE); + enemy[GONZOTYPE].info.set(sprite[j]); + sprite[j].x = spr.x; + sprite[j].y = spr.y; + sprite[j].z = spr.z; + sprite[j].cstat = 0x303; + sprite[j].picnum = GONZOGSH; + sprite[j].shade = 31; + sprite[j].pal = 0; + sprite[j].xrepeat = spr.xrepeat; + sprite[j].yrepeat = spr.yrepeat; + sprite[j].owner = 0; + sprite[j].lotag = 40; + sprite[j].hitag = 0; + sprite[j].detail = GONZOTYPE; + deletesprite((short) i); + } + } + + for (i = headspritestat[TORCHFRONT]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + playertorch = spr.lotag -= TICSPERFRAME; + if (plr.selectedgun > 4) { + playertorch = spr.lotag = -1; + } + setsprite((short) i, plr.x, plr.y, plr.z); + osectnum = spr.sectnum; + j = (torchpattern[lockclock % 38]); + sector[osectnum].ceilingshade = (byte) ((sector[osectnum].ceilingshade + j) >> 1); + sector[osectnum].floorshade = (byte) ((sector[osectnum].floorshade + j) >> 1); + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) { + wall[k].shade = (byte) ((wall[k].shade + j) >> 1); + } + movestat = (short) movesprite((short) i, + ((sintable[((short) plr.ang + 512) & 2047]) << TICSPERFRAME) << 8, + ((sintable[(short) plr.ang & 2047]) << TICSPERFRAME) << 8, 0, 4 << 8, 4 << 8, 0); + + spr.cstat |= 0x8000; + show2dsprite[i >> 3] &= ~(1 << (i & 7)); + + if (osectnum != spr.sectnum) { + sector[osectnum].ceilingshade = (byte) j; + + sector[osectnum].floorshade = (byte) j; + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) { + wall[k].shade = (byte) j; + } + } + if (spr.lotag < 0) { + deletesprite((short) i); + // set back to normall + sector[plr.sector].ceilingshade = ceilingshadearray[plr.sector]; + sector[plr.sector].floorshade = floorshadearray[plr.sector]; + startwall = sector[plr.sector].wallptr; + endwall = (short) (startwall + sector[plr.sector].wallnum - 1); + for (k = startwall; k <= endwall; k++) { + wall[k].shade = wallshadearray[k]; + } + sector[plr.oldsector].ceilingshade = ceilingshadearray[plr.oldsector]; + sector[plr.oldsector].floorshade = floorshadearray[plr.oldsector]; + startwall = sector[plr.oldsector].wallptr; + endwall = (short) (startwall + sector[plr.oldsector].wallnum - 1); + for (k = startwall; k <= endwall; k++) { + wall[k].shade = wallshadearray[k]; + } + sector[osectnum].ceilingshade = ceilingshadearray[osectnum]; + sector[osectnum].floorshade = floorshadearray[osectnum]; + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) { + wall[k].shade = wallshadearray[k]; + } + osectnum = plr.oldsector; + sector[osectnum].ceilingshade = ceilingshadearray[osectnum]; + sector[osectnum].floorshade = floorshadearray[osectnum]; + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) { + wall[k].shade = wallshadearray[k]; + } + } + } + } + + for (i = headspritestat[PULLTHECHAIN]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { + sprite[i].picnum++; + sprite[i].lotag = 24; + if (sprite[i].picnum == PULLCHAIN3 || sprite[i].picnum == SKULLPULLCHAIN3) { + sprite[i].lotag = 0; + changespritestat(i, (short) 0); + } + } + } + + for (i = headspritestat[ANIMLEVERDN]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { + sprite[i].picnum++; + sprite[i].lotag = 24; + if (sprite[i].picnum == LEVERDOWN) { + sprite[i].lotag = 60; + changespritestat(i, (short) 0); + } + } + } + + for (i = headspritestat[ANIMLEVERUP]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { + sprite[i].picnum--; + sprite[i].lotag = 24; + if (sprite[i].picnum == LEVERUP) { + sprite[i].lotag = 1; + changespritestat(i, (short) 0); + } + } + } + + for (i = headspritestat[WARPFX]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { + sprite[i].lotag = 12; + sprite[i].picnum++; + if (sprite[i].picnum == ANNIHILATE + 5) { + deletesprite((short) i); + } + } + } + + // FLOCKSPAWN + for (i = headspritestat[FLOCKSPAWN]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { + sprite[i].extra--; + sprite[i].lotag = (short) (krand() & 48 + 24); + bats(plr, i); + if (sprite[i].extra == 0) + changespritestat(i, (short) 0); + } + } + + // FLOCK + for (i = headspritestat[FLOCK]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + sprite[i].lotag -= TICSPERFRAME; + switch (sprite[i].extra) { + case 0: // going out of the cave + if (sprite[i].lotag < 0) { + sprite[i].extra = 1; + sprite[i].lotag = 512; + } else { + movestat = (short) movesprite((short) i, + (((int) sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, + (((int) sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (movestat != 0) + sprite[i].ang = (short) (krand() & 2047); + } + break; + case 1: // flying in circles + if (sprite[i].lotag < 0) { + sprite[i].extra = 2; + sprite[i].lotag = 512; + sprite[i].ang = (short) (((getangle(sprite[sprite[i].hitag].x - sprite[i].x, + sprite[sprite[i].hitag].y - sprite[i].y) & 2047) - 1024) & 2047); + } else { + sprite[i].z -= TICSPERFRAME << 4; + sprite[i].ang = (short) ((sprite[i].ang + (TICSPERFRAME << 2)) & 2047); + movestat = (short) movesprite((short) i, + (((int) sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, + (((int) sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (movestat != 0) + sprite[i].ang = (short) (krand() & 2047); + } + break; + case 2: // fly to roof and get deleted + if (sprite[i].lotag < 0) { + if (i == lastbat && batsnd != -1) { + stopsound(batsnd); + batsnd = -1; + } + deletesprite((short) i); + continue; + } else { + movestat = (short) movesprite((short) i, + (((int) sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, + (((int) sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if ((movestat & 0xc000) == 16384) {// Hits a ceiling / floor + if (i == lastbat && batsnd != -1) { + stopsound(batsnd); + batsnd = -1; + } + deletesprite((short) i); + continue; + } + if (movestat != 0) + sprite[i].ang = (short) (krand() & 2047); + } + break; + } + } + + // TORCHLIGHT + for (i = headspritestat[TORCHLIGHT]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + osectnum = sprite[i].sectnum; + j = (torchpattern[lockclock % 38]); + sector[osectnum].ceilingshade = (byte) j; + sector[osectnum].floorshade = (byte) j; + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) + wall[k].shade = (byte) j; + } + + // GLOWLIGHT + for (i = headspritestat[GLOWLIGHT]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + osectnum = sprite[i].sectnum; + j = (torchpattern[lockclock % 38]); + sector[osectnum].floorshade = (byte) j; + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) + wall[k].shade = (byte) j; +// startredflash(j); + } + + // BOB + for (i = headspritestat[BOB]; i >= 0; i = nextspritestat[i]) { + nextsprite = nextspritestat[i]; + sprite[i].z += (sintable[(lockclock << 4) & 2047] >> 6); + } + + // LIFT UP + for (i = headspritestat[LIFTUP]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + switch (sprite[i].lotag) { + case 1821: + game.pInt.setsprinterpolate(i, sprite[i]); + sprite[i].z -= (TICSPERFRAME << 6); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (sprite[i].z <= sector[sprite[i].sectnum].ceilingz + 32768) { + stopsound(cartsnd); + cartsnd = -1; + playsound_loc(S_CLUNK, sprite[i].x, sprite[i].y); + changespritestat(i, (short) 0); + sprite[i].lotag = 1820; + sprite[i].z = sector[sprite[i].sectnum].ceilingz + 32768; + } + break; + case 1811: + game.pInt.setsprinterpolate(i, sprite[i]); + sprite[i].z -= (TICSPERFRAME << 6); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (sprite[i].z <= sector[sprite[i].sectnum].ceilingz + 65536) { + changespritestat(i, (short) 0); + sprite[i].lotag = 1810; + sprite[i].z = sector[sprite[i].sectnum].ceilingz + 65536; + } + break; + case 1801: + game.pInt.setsprinterpolate(i, sprite[i]); + sprite[i].z -= (TICSPERFRAME << 6); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (sprite[i].z <= sector[sprite[i].sectnum].ceilingz + 65536) { + changespritestat(i, (short) 0); + sprite[i].lotag = 1800; + sprite[i].z = sector[sprite[i].sectnum].ceilingz + 65536; + } + break; + } + } + + // LIFT DN + for (i = headspritestat[LIFTDN]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + int ironbarmove = 0; + + switch (sprite[i].lotag) { + case 1820: + game.pInt.setsprinterpolate(i, sprite[i]); + ironbarmove = TICSPERFRAME << 6; + sprite[i].z += ironbarmove; + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (sprite[i].z >= (sector[sprite[i].sectnum].floorz - 32768)) { + stopsound(cartsnd); + cartsnd = -1; + playsound_loc(S_CLUNK, sprite[i].x, sprite[i].y); + changespritestat(i, (short) 0); + sprite[i].lotag = 1821; + sprite[i].z = sector[sprite[i].sectnum].floorz - 32768; + } + break; + case 1810: + game.pInt.setsprinterpolate(i, sprite[i]); + ironbarmove = TICSPERFRAME << 6; + sprite[i].z += ironbarmove; + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (sprite[i].z >= sector[sprite[i].sectnum].floorz) { + changespritestat(i, (short) 0); + sprite[i].lotag = 1811; + sprite[i].z = sector[sprite[i].sectnum].floorz; + } + break; + case 1800: + game.pInt.setsprinterpolate(i, sprite[i]); + ironbarmove = TICSPERFRAME << 6; + sprite[i].z += ironbarmove; + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (sprite[i].z >= sector[sprite[i].sectnum].floorz) { + changespritestat(i, (short) 0); + sprite[i].lotag = 1801; + sprite[i].z = sector[sprite[i].sectnum].floorz; + } + break; + } + } + + // MASPLASH + for (i = headspritestat[MASPLASH]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + game.pInt.setsprinterpolate(i, sprite[i]); + sprite[i].lotag -= TICSPERFRAME; + sprite[i].z = sector[sprite[i].sectnum].floorz + (tilesizy[sprite[i].picnum] << 8); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + + if (sprite[i].lotag <= 0) { + if ((sprite[i].picnum >= SPLASHAROO && sprite[i].picnum < LASTSPLASHAROO) + || (sprite[i].picnum >= LAVASPLASH && sprite[i].picnum < LASTLAVASPLASH) + || (sprite[i].picnum >= SLIMESPLASH && sprite[i].picnum < LASTSLIMESPLASH)) { + sprite[i].picnum++; + sprite[i].lotag = 8; + } else { + deletesprite((short) i); + } + } + } + + // SHATTER + for (i = headspritestat[SHATTER]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + sprite[i].lotag -= TICSPERFRAME; + + if (sprite[i].lotag < 0) { + sprite[i].picnum++; + sprite[i].lotag = 12; + } + switch (sprite[i].picnum) { + case FSHATTERBARREL + 2: + changespritestat(i, (short) 0); + break; + } + } + + // FIRE + for (i = headspritestat[FIRE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + + if (sprite[i].z < sector[sprite[i].sectnum].floorz) + sprite[i].z += (int) TICSPERFRAME << 8; + if (sprite[i].z > sector[sprite[i].sectnum].floorz) + sprite[i].z = sector[sprite[i].sectnum].floorz; + + if (sprite[i].lotag < 0) { + switch (sprite[i].picnum) { + case LFIRE: + sprite[i].picnum = SFIRE; + sprite[i].lotag = 2047; + break; + case SFIRE: + deletesprite(i); + continue; + } + } + + if (checkdist(i, plr.x, plr.y, plr.z)) { + addhealth(plr, -1); + flashflag = 1; + startredflash(10); + } + } + + // FALL + for (i = headspritestat[FALL]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + getzrange(sprite[i].x, sprite[i].y, sprite[i].z - 1, sprite[i].sectnum, (sprite[i].clipdist) << 2, + CLIPMASK0); + if (sprite[i].z < zr_florz) + daz = sprite[i].zvel += (TICSPERFRAME << 9); + + hitobject = (short) movesprite(i, ((sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, daz, 4 << 8, 4 << 8, 0); + + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + + if (sprite[i].picnum == FBARRELFALL || sprite[i].picnum >= BOULDER && sprite[i].picnum <= BOULDER + 3 + && (checkdist(i, plr.x, plr.y, plr.z))) { + addhealth(plr, -50); + startredflash(50); + } + + if ((hitobject & 0xc0000) == 16384) { + if (sector[sprite[i].sectnum].floorpicnum == WATER) { + makemonstersplash(SPLASHAROO, i); + } + switch (sprite[i].picnum) { + case FBARRELFALL: + newstatus(i, SHATTER); + sprite[i].lotag = 12; + break; + default: + if (sprite[i].picnum == TORCH) { + for (k = 0; k < 16; k++) + makeafire(i, 0); + deletesprite(i); + break; + } + changespritestat(i, (short) 0); + break; + } + sprite[i].hitag = 0; + } + } + + // SHOVE + for (i = headspritestat[SHOVE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + getzrange(sprite[i].x, sprite[i].y, sprite[i].z - 1, sprite[i].sectnum, (sprite[i].clipdist) << 2, + CLIPMASK0); + if (sprite[i].z < zr_florz) + daz = sprite[i].zvel += (TICSPERFRAME << 5); + + hitobject = (short) movesprite(i, ((sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, daz, 4 << 8, 4 << 8, 0); + + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + + if (sprite[i].z >= sector[sprite[i].sectnum].floorz) { + if (sector[sprite[i].sectnum].floorpicnum == WATER + || sector[sprite[i].sectnum].floorpicnum == FLOORMIRROR) { + makemonstersplash(SPLASHAROO, i); + } + newstatus(i, BROKENVASE); + continue; + } + + if ((hitobject & 0xc000) == 16384) { + newstatus(i, BROKENVASE); + continue; + } + + if ((hitobject & 0xc000) == 49152) { // Bullet hit a sprite + + if (sprite[i].owner != hitobject) { + hitdamage = damageactor(plr, hitobject, i); + if (hitdamage) { + newstatus(i, BROKENVASE); + continue; + } + } + + } + } + + // PUSH + for (i = headspritestat[PUSH]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + + osectnum = sprite[i].sectnum; + + getzrange(sprite[i].x, sprite[i].y, sprite[i].z - 1, sprite[i].sectnum, (sprite[i].clipdist) << 2, + CLIPMASK0); + if (sprite[i].z < zr_florz) + daz = sprite[i].zvel += (TICSPERFRAME << 1); + + // clip type was 1 + hitobject = (short) movesprite(i, ((sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, daz, 4 << 8, 4 << 8, 0); + + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + + if (sprite[i].lotag < 0 || (hitobject & 0xc000) == 32768) { + sprite[i].lotag = 0; + changespritestat(i, (short) 0); + if (sprite[i].z < sector[sprite[i].sectnum].floorz) { + sprite[i].zvel += 256L; + changespritestat(i, FALL); + } + } + } + + // DORMANT + for (i = headspritestat[DORMANT]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + if (isWh2()) { + SPRITE& spr = sprite[i]; + osectnum = spr.sectnum; + j = (torchpattern[lockclock % 38]); + sector[osectnum].ceilingshade = (byte) j; + sector[osectnum].floorshade = (byte) j; + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) + wall[k].shade = (byte) j; + spr.lotag -= TICSPERFRAME; + if (spr.lotag < 0) { + newstatus((short) i, ACTIVE); + } + } else { + sprite[i].lotag -= TICSPERFRAME; + sprite[i].xrepeat = sprite[i].yrepeat = 2; + if (sprite[i].lotag < 0) { + newstatus(i, ACTIVE); + } + } + } + + // ACTIVE + for (i = headspritestat[ACTIVE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + if (isWh2()) { + SPRITE& spr = sprite[i]; + spr.lotag -= TICSPERFRAME; + osectnum = spr.sectnum; + j = (torchpattern[lockclock % 38]); + sector[osectnum].ceilingshade = (byte) j; + sector[osectnum].floorshade = (byte) j; + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) + wall[k].shade = (byte) j; + if (spr.lotag < 0) { + sector[osectnum].ceilingshade = ceilingshadearray[osectnum]; + sector[osectnum].floorshade = floorshadearray[osectnum]; + startwall = sector[osectnum].wallptr; + endwall = (short) (startwall + sector[osectnum].wallnum - 1); + for (k = startwall; k <= endwall; k++) { + wall[k].shade = wallshadearray[k]; + } + newstatus((short) i, DORMANT); + } + } else { + sprite[i].lotag -= TICSPERFRAME; + sprite[i].xrepeat = 48; + sprite[i].yrepeat = 32; + if (sprite[i].lotag < 0) { + newstatus(i, DORMANT); + } + } + } + + aiProcess(); + + // New missile code + for (i = headspritestat[MISSILE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + sprite[i].lotag -= TICSPERFRAME; + + switch (sprite[i].picnum) { + case WH1THROWPIKE: + case WH2THROWPIKE: + case FATSPANK: + case MONSTERBALL: + case FIREBALL: + case PLASMA: + if ((sprite[i].picnum == WH1THROWPIKE && isWh2()) || (sprite[i].picnum == WH2THROWPIKE && !isWh2())) + break; + + if(!isValidSector(sprite[i].sectnum)) { + deletesprite((short) i); + continue; + } + + if (sprite[i].picnum == MONSTERBALL && krand() % 100 > 90) { + if (sprite[i].lotag < 200) + trailingsmoke(i, false); + } + sprite[i].z += sprite[i].zvel; + if (sprite[i].z < sector[sprite[i].sectnum].ceilingz + (4 << 8)) { + sprite[i].z = sector[sprite[i].sectnum].ceilingz + (4 << 8); + sprite[i].zvel = (short) -(sprite[i].zvel >> 1); + } + if (sprite[i].z > sector[sprite[i].sectnum].floorz - (4 << 8)) { + sprite[i].z = sector[sprite[i].sectnum].floorz - (4 << 8); + if (sector[sprite[i].sectnum].floorpicnum == WATER || sector[sprite[i].sectnum].floorpicnum == SLIME + || sector[sprite[i].sectnum].floorpicnum == FLOORMIRROR) + if (sprite[i].picnum == FISH) + sprite[i].z = sector[sprite[i].sectnum].floorz; + else { + if (krand() % 100 > 60) + makemonstersplash(SPLASHAROO, i); + } + +// if (sprite[i].picnum != THROWPIKE) { //XXX + deletesprite((short) i); + continue; +// } + } + dax = sprite[i].xvel; + day = sprite[i].yvel; + daz = ((((int) sprite[i].zvel) * TICSPERFRAME) >> 3); + break; + case BULLET: + dax = sprite[i].xvel; + day = sprite[i].yvel; + daz = sprite[i].zvel; + break; + } // switch + + osectnum = sprite[i].sectnum; + + if (sprite[i].picnum == THROWPIKE) { + sprite[i].cstat = 0; + hitobject = (short) movesprite((short) i, + ((sintable[(sprite[i].extra + 512) & 2047]) * TICSPERFRAME) << 6, + ((sintable[sprite[i].extra & 2047]) * TICSPERFRAME) << 6, daz, 4 << 8, 4 << 8, 1); + sprite[i].cstat = 21; + } else { + hitobject = (short) movesprite((short) i, + ((sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 6, // was 3 + ((sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 6, // was 3 + daz, 4 << 8, 4 << 8, 1); + } + + if (hitobject != 0 && sprite[i].picnum == MONSTERBALL) + if (sprite[i].owner == sprite[plr.spritenum].owner) { + explosion2(i, sprite[i].x, sprite[i].y, sprite[i].z, i); + } else { + explosion(i, sprite[i].x, sprite[i].y, sprite[i].z, i); + } + + if ((hitobject & 0xc000) == 16384) { // Hits a ceiling / floor + if (sprite[i].picnum == THROWPIKE) { + sprite[i].picnum++; + sprite[i].detail = WALLPIKETYPE; + changespritestat(i, (short) 0); + + continue; + } + deletesprite((short) i); + continue; + } else if ((hitobject & 0xc000) == 32768) { // hit a wall + + if (sprite[i].picnum == MONSTERBALL) { + if (sprite[i].owner == sprite[plr.spritenum].owner) + explosion2(i, sprite[i].x, sprite[i].y, sprite[i].z, i); + else + explosion(i, sprite[i].x, sprite[i].y, sprite[i].z, i); + } + if (sprite[i].picnum == THROWPIKE) { + sprite[i].picnum++; + sprite[i].detail = WALLPIKETYPE; + changespritestat(i, (short) 0); + + continue; + } + deletesprite((short) i); + continue; + } else if (sprite[i].lotag < 0 && sprite[i].picnum == PLASMA) + hitobject = 1; + + if ((hitobject & 0xc000) == 49152) { // Bullet hit a sprite + if (sprite[i].picnum == MONSTERBALL) { + if (sprite[i].owner == sprite[plr.spritenum].owner) + explosion2(i, sprite[i].x, sprite[i].y, sprite[i].z, i); + else + explosion(i, sprite[i].x, sprite[i].y, sprite[i].z, i); + } + + if (sprite[i].owner != hitobject) + hitdamage = damageactor(plr, hitobject, i); + if (hitdamage) { + deletesprite((short) i); + continue; + } + } + + if (hitobject != 0 || sprite[i].lotag < 0) { + int pic = sprite[i].picnum; + switch (pic) { + case PLASMA: + case FATSPANK: + case MONSTERBALL: + case FIREBALL: + case BULLET: + case WH1THROWPIKE: + case WH2THROWPIKE: + if ((sprite[i].picnum == WH1THROWPIKE && isWh2()) + || (sprite[i].picnum == WH2THROWPIKE && !isWh2())) + break; + + deletesprite((short) i); + continue; + } + } + } + + for (i = headspritestat[JAVLIN]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + sprite[i].lotag -= TICSPERFRAME; + if (isBlades(sprite[i].picnum)) { + sprite[i].z -= sprite[i].zvel; + if (sprite[i].z < sector[sprite[i].sectnum].ceilingz + (4 << 8)) { + sprite[i].z = sector[sprite[i].sectnum].ceilingz + (4 << 8); + sprite[i].zvel = (short) -(sprite[i].zvel >> 1); + } + if (sprite[i].z > sector[sprite[i].sectnum].floorz - (4 << 8)) { + sprite[i].z = sector[sprite[i].sectnum].floorz - (4 << 8); + if (sector[sprite[i].sectnum].floorpicnum == WATER || sector[sprite[i].sectnum].floorpicnum == SLIME + || sector[sprite[i].sectnum].floorpicnum == FLOORMIRROR) + if (krand() % 100 > 60) + makemonstersplash(SPLASHAROO, i); + deletesprite((short) i); + continue; + } + dax = sprite[i].xvel; + day = sprite[i].yvel; + if (isWh2()) + daz = sprite[i].zvel; + else + daz = (((sprite[i].zvel) * TICSPERFRAME) >> 3); + } + + osectnum = sprite[i].sectnum; + + sprite[i].cstat = 0; + + hitobject = (short) movesprite(i, ((sintable[(sprite[i].extra + 512) & 2047]) * TICSPERFRAME) << 6, + ((sintable[sprite[i].extra & 2047]) * TICSPERFRAME) << 6, daz, 4 << 8, 4 << 8, 0); + + if (sprite[i].picnum == WALLARROW || sprite[i].picnum == THROWHALBERD) + sprite[i].cstat = 0x11; + else if (sprite[i].picnum == DART) + sprite[i].cstat = 0x10; + else + sprite[i].cstat = 0x15; + + if ((hitobject & 0xc000) == 16384) { // Hits a ceiling / floor + // EG Bugfix 17 Aug 2014: Since the game thinks that a javlin hitting the + // player's pike axe is a + // floor/ceiling hit rather than a sprite hit, we'll need to check if the JAVLIN + // is + // actually in the floor/ceiling before going inactive. + if (sprite[i].z <= sector[sprite[i].sectnum].ceilingz + && sprite[i].z >= sector[sprite[i].sectnum].floorz) { + if (sprite[i].picnum == THROWPIKE) { + sprite[i].picnum++; + sprite[i].detail = WALLPIKETYPE; + } + + changespritestat(i, INACTIVE); // EG Note: RAF.H gives this a nice name, so use it + } + continue; + } else if ((hitobject & 0xc000) == 32768) { // hit a wall + + if (sprite[i].picnum == THROWPIKE) { + sprite[i].picnum++; + sprite[i].detail = WALLPIKETYPE; + } + + changespritestat(i, INACTIVE); + continue; + } + + if ((hitobject - 49152) >= 0 || (hitobject & 0xc000) == 49152) { // Bullet hit a sprite + j = (hitobject & 4095); // j is the spritenum that the bullet (spritenum i) hit + + hitdamage = damageactor(plr, hitobject, i); + if (hitdamage) + continue; + +// if (sprite[i].owner != hitobject) { +// hitdamage = damageactor(plr, hitobject, i); +// continue; +// } + + if (!hitdamage) + if (isBlades(sprite[j].picnum)) { + deletesprite((short) i); + continue; + } + } + + if (hitobject != 0) { + deletesprite((short) i); + } + } + + // CHUNK O WALL + + for (i = headspritestat[CHUNKOWALL]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + dax = sprite[i].xvel >> 3; + day = sprite[i].yvel >> 3; + daz = sprite[i].zvel -= TICSPERFRAME << 2; + movestat = (short) movesprite(i, ((sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 1); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (sprite[i].extra == 0) { + if (sprite[i].lotag < 0) { + sprite[i].lotag = 8; + sprite[i].picnum++; + if (sprite[i].picnum == SMOKEFX + 3) { + deletesprite((short) i); + continue; + } + } + } else { + if (sprite[i].lotag < 0) { + deletesprite((short) i); + } + } + } + + // CHUNK O MEAT + for (i = headspritestat[CHUNKOMEAT]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + + sprite[i].z += sprite[i].zvel; + + daz = sprite[i].zvel += TICSPERFRAME << 4; + + int xvel = ((sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3; + int yvel = ((sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3; + + if (sprite[i].picnum == BONECHUNK1 && sprite[i].picnum == BONECHUNKEND) { + daz >>= 1; + xvel >>= 1; + yvel >>= 1; + } + + movestat = (short) movesprite((short) i, xvel, yvel, daz, 4 << 8, 4 << 8, 1); + + if ((movestat & 0xc000) == 16384) { + if (sector[sprite[i].sectnum].floorpicnum == WATER || sector[sprite[i].sectnum].floorpicnum == SLIME + || sector[sprite[i].sectnum].floorpicnum == FLOORMIRROR) { + if (sprite[i].picnum == FISH) + sprite[i].z = sector[sprite[i].sectnum].floorz; + else { + if (krand() % 100 > 60) + makemonstersplash(SPLASHAROO, i); + } + sprite[i].lotag = -1; + } else { + /* EG: Add check for parallax sky */ + if (sprite[i].picnum >= BONECHUNK1 && sprite[i].picnum <= BONECHUNKEND + || (daz >= zr_ceilz && (sector[sprite[i].sectnum].ceilingstat & 1) != 0)) { + deletesprite(i); + } else { + sprite[i].cstat |= 0x0020; + sprite[i].lotag = 1200; + newstatus(i, BLOOD); + } + } + } else if ((movestat & 0xc000) == 32768) { + if (sprite[i].picnum >= BONECHUNK1 && sprite[i].picnum <= BONECHUNKEND) { + deletesprite((short) i); + } else { + sprite[i].lotag = 600; + newstatus(i, DRIP); + } + } + if (sprite[i].lotag < 0) { + deletesprite(i); + } + } + + for (i = headspritestat[BLOOD]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { + if (sprite[i].z < sector[sprite[i].sectnum].floorz) { + sprite[i].lotag = 600; + sprite[i].zvel = 0; + newstatus(i, DRIP); + } else { + deletesprite(i); + } + } + } + + for (i = headspritestat[DEVILFIRE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + if (plr.invisibletime < 0) { + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { + sprite[i].lotag = (short) (krand() & 120 + 360); + if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y, + sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum)) { + // JSA_NEW + playsound_loc(S_FIREBALL, sprite[i].x, sprite[i].y); + castspell(plr, i); + } + } + } + } + + for (i = headspritestat[DRIP]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + sprite[i].z += sprite[i].zvel; + dax = 0; + day = 0; + daz = sprite[i].zvel += TICSPERFRAME << 1; + daz = (((sprite[i].zvel) * TICSPERFRAME) << 1); + movestat = (short) movesprite(i, dax, day, daz, 4 << 8, 4 << 8, 1); + + if ((movestat & 0xc000) == 16384) { + sprite[i].lotag = 1200; + newstatus(i, BLOOD); + } + if (sprite[i].lotag < 0) { + deletesprite((short) i); + } + } + + for (i = headspritestat[SMOKE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + +// game.pInt.setsprinterpolate(i, sprite[i]); +// sprite[i].z -= (TICSPERFRAME << 6); + + if (sprite[i].xrepeat > 1) + sprite[i].xrepeat = sprite[i].yrepeat -= TICSPERFRAME; + +// setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + if (sprite[i].lotag < 0) { + deletesprite((short) i); + } + } + + if (!isWh2()) { + for (i = headspritestat[EXPLO]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + sprite[i].x += ((sprite[i].xvel * TICSPERFRAME) >> 5); + sprite[i].y += ((sprite[i].yvel * TICSPERFRAME) >> 5); + sprite[i].z -= ((sprite[i].zvel * TICSPERFRAME) >> 6); + + sprite[i].zvel += (TICSPERFRAME << 4); + + if (sprite[i].z < sector[sprite[i].sectnum].ceilingz + (4 << 8)) { + sprite[i].z = sector[sprite[i].sectnum].ceilingz + (4 << 8); + sprite[i].zvel = (short) -(sprite[i].zvel >> 1); + } + if (sprite[i].z > sector[sprite[i].sectnum].floorz - (4 << 8)) { + sprite[i].z = sector[sprite[i].sectnum].floorz - (4 << 8); + sprite[i].zvel = (short) -(sprite[i].zvel >> 1); + } + + sprite[i].xrepeat += TICSPERFRAME; + sprite[i].yrepeat += TICSPERFRAME; + + sprite[i].lotag -= TICSPERFRAME; + + if (krand() % 100 > 90) { + j = insertsprite(sprite[i].sectnum, SMOKE); + + sprite[j].x = sprite[i].x; + sprite[j].y = sprite[i].y; + sprite[j].z = sprite[i].z; + sprite[j].cstat = 0x03; + sprite[j].cstat &= ~3; + sprite[j].picnum = SMOKEFX; + sprite[j].shade = 0; + sprite[j].pal = 0; + sprite[j].xrepeat = sprite[i].xrepeat; + sprite[j].yrepeat = sprite[i].yrepeat; + + sprite[j].owner = sprite[i].owner; + sprite[j].lotag = 256; + sprite[j].hitag = 0; + } + + if (sprite[i].lotag < 0) { + deletesprite(i); + } + } + } else { + for (i = headspritestat[EXPLO]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + SPRITE& spr = sprite[i]; + spr.lotag -= TICSPERFRAME; + spr.picnum++; + if (spr.lotag < 0) { + spr.lotag = 12; + } + + j = headspritesect[spr.sectnum]; + while (j != -1) { + short nextj = nextspritesect[j]; + SPRITE tspr = sprite[j]; + long dx = klabs(spr.x - tspr.x); // x distance to sprite + long dy = klabs(spr.y - tspr.y); // y distance to sprite + long dz = klabs((spr.z >> 8) - (tspr.z >> 8)); // z distance to sprite + int dh = tilesizy[tspr.picnum] >> 1; // height of sprite + if (dx + dy < PICKDISTANCE && dz - dh <= getPickHeight()) { + if (tspr.owner == 4096) { + // strcpy(displaybuf,"hit player"); + // displaytime=120; + } else { + switch (tspr.detail) { + case SKELETONTYPE: + case KOBOLDTYPE: + case IMPTYPE: + case NEWGUYTYPE: + case KURTTYPE: + case GONZOTYPE: + case GRONTYPE: + if (tspr.hitag > 0) { + tspr.hitag -= TICSPERFRAME << 4; + if (tspr.hitag < 0) { + newstatus((short) j, DIE); + } + } + break; + } + } + } + j = nextj; + } + + if (spr.picnum == EXPLOEND) { + deletesprite((short) i); + } + } + } + + for (i = headspritestat[BROKENVASE]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { + sprite[i].picnum++; + sprite[i].lotag = 18; + + if (sprite[i].picnum == (SHATTERVASE + 6) || sprite[i].picnum == (SHATTERVASE2 + 6) + || sprite[i].picnum == (SHATTERVASE3 + 6)) + changespritestat(i, (short) 0); + else { + switch (sprite[i].picnum) { + case FSHATTERBARREL + 2: + randompotion(i); + changespritestat(i, (short) 0); + break; + case STAINGLASS1 + 6: + case STAINGLASS2 + 6: + case STAINGLASS3 + 6: + case STAINGLASS4 + 6: + case STAINGLASS5 + 6: + case STAINGLASS6 + 6: + case STAINGLASS7 + 6: + case STAINGLASS8 + 6: + case STAINGLASS9 + 6: + changespritestat(i, (short) 0); + break; + } + } + } + } + + // Go through explosion sprites + for (i = headspritestat[FX]; i >= 0; i = nextsprite) { + nextsprite = nextspritestat[i]; + sprite[i].lotag -= TICSPERFRAME; + + if (// sprite[i].picnum == PLASMA || + sprite[i].picnum == BULLET || sprite[i].picnum == EXPLOSION || sprite[i].picnum == FIREBALL + || sprite[i].picnum == MONSTERBALL || sprite[i].picnum == FATSPANK) { + + // sprite[i].z+=sprite[i].zvel; + sprite[i].zvel += (TICSPERFRAME << 5); + if (sprite[i].z < sector[sprite[i].sectnum].ceilingz + (4 << 8)) { + sprite[i].z = sector[sprite[i].sectnum].ceilingz + (4 << 8); + sprite[i].zvel = (short) -(sprite[i].zvel >> 1); + } + if (sprite[i].z > sector[sprite[i].sectnum].floorz - (4 << 8) && sprite[i].picnum != EXPLOSION) { + sprite[i].z = sector[sprite[i].sectnum].floorz - (4 << 8); + sprite[i].zvel = 0; + sprite[i].lotag = 4; + } + dax = ((((int) sprite[i].xvel) * TICSPERFRAME) >> 3); + day = ((((int) sprite[i].yvel) * TICSPERFRAME) >> 3); + daz = (((int) sprite[i].zvel) * TICSPERFRAME); + movestat = (short) movesprite((short) i, dax, day, daz, 4 << 8, 4 << 8, 1); + setsprite(i, sprite[i].x, sprite[i].y, sprite[i].z); + } + + if (sprite[i].picnum == ICECUBE && sprite[i].z < sector[sprite[i].sectnum].floorz) { + sprite[i].z += sprite[i].zvel; + + daz = sprite[i].zvel += TICSPERFRAME << 4; + + movestat = (short) movesprite((short) i, ((sintable[(sprite[i].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[i].ang & 2047]) * TICSPERFRAME) << 3, daz, 4 << 8, 4 << 8, 1); + + } + + if (sprite[i].lotag < 0 || movestat != 0) + if (sprite[i].picnum == PLASMA || sprite[i].picnum == EXPLOSION || sprite[i].picnum == FIREBALL + || sprite[i].picnum == MONSTERBALL || sprite[i].picnum == FATSPANK + || sprite[i].picnum == ICECUBE) { + deletesprite(i); + continue; + } + + if (sprite[i].z + (8 << 8) >= sector[sprite[i].sectnum].floorz && sprite[i].picnum == ICECUBE + || movestat != 0) { + sprite[i].z = sector[sprite[i].sectnum].floorz; + changespritestat(i, (short) 0); + if (sector[sprite[i].sectnum].floorpicnum == WATER || sector[sprite[i].sectnum].floorpicnum == SLIME + || sector[sprite[i].sectnum].floorpicnum == FLOORMIRROR) { + if (sprite[i].picnum == FISH) + sprite[i].z = sector[sprite[i].sectnum].floorz; + else { + if (krand() % 100 > 60) { + makemonstersplash(SPLASHAROO, i); + deletesprite((short) i); + } + } + } else { + if (sprite[i].lotag < 0) { + deletesprite((short) i); + } + } + } + } +} + +boolean isBlades(int pic) { + return pic == THROWPIKE || pic == WALLARROW || pic == DART || pic == HORIZSPIKEBLADE || pic == THROWHALBERD; +} diff --git a/source/games/whaven/src/whfx.cpp b/source/games/whaven/src/whfx.cpp new file mode 100644 index 000000000..33ee35628 --- /dev/null +++ b/source/games/whaven/src/whfx.cpp @@ -0,0 +1,1078 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + + + +short skypanlist[64], skypancnt; +short lavadrylandsector[32]; +short lavadrylandcnt; +short bobbingsectorlist[16], bobbingsectorcnt; + +int justwarpedfx = 0; +int lastbat = -1; + +short revolveclip[16]; +short revolvesector[4], revolveang[4], revolvecnt; +int revolvex[4][32], revolvey[4][32]; +int revolvepivotx[4], revolvepivoty[4]; + +static int revolvesyncstat; +static short revolvesyncang, revolvesyncrotang; +static int revolvesyncx, revolvesyncy; + +int warpx, warpy, warpz, warpang; +short warpsect; + +int scarytime = -1; +int scarysize = 0; + +void initlava() // XXX +{ + +} + +void movelava() { +}; + +void initwater() // XXX +{ + +} + +void movewater() { +}; + +void skypanfx() { + for (int i = 0; i < skypancnt; i++) { + sector[skypanlist[i]].ceilingxpanning = (short) -((lockclock >> 2) & 255); + } +} + +void panningfx() { + for (int i = 0; i < floorpanningcnt; i++) { + int whichdir = sector[floorpanninglist[i]].lotag - 80; + + switch (whichdir) { + case 0: + sector[floorpanninglist[i]].floorypanning = (short) ((lockclock >> 2) & 255); + break; + case 1: + sector[floorpanninglist[i]].floorxpanning = (short) -((lockclock >> 2) & 255); + sector[floorpanninglist[i]].floorypanning = (short) ((lockclock >> 2) & 255); + break; + case 2: + sector[floorpanninglist[i]].floorxpanning = (short) -((lockclock >> 2) & 255); + break; + case 3: + sector[floorpanninglist[i]].floorxpanning = (short) -((lockclock >> 2) & 255); + sector[floorpanninglist[i]].floorypanning = (short) -((lockclock >> 2) & 255); + break; + case 4: + sector[floorpanninglist[i]].floorypanning = (short) -((lockclock >> 2) & 255); + break; + case 5: + sector[floorpanninglist[i]].floorxpanning = (short) ((lockclock >> 2) & 255); + sector[floorpanninglist[i]].floorypanning = (short) -((lockclock >> 2) & 255); + break; + case 6: + sector[floorpanninglist[i]].floorxpanning = (short) ((lockclock >> 2) & 255); + break; + case 7: + sector[floorpanninglist[i]].floorxpanning = (short) ((lockclock >> 2) & 255); + sector[floorpanninglist[i]].floorypanning = (short) ((lockclock >> 2) & 255); + break; + default: + sector[floorpanninglist[i]].floorxpanning = 0; + sector[floorpanninglist[i]].floorypanning = 0; + break; + } + } + + for (int i = 0; i < xpanningsectorcnt; i++) { + int dasector = xpanningsectorlist[i]; + int startwall = sector[dasector].wallptr; + int endwall = startwall + sector[dasector].wallnum - 1; + for (int s = startwall; s <= endwall; s++) + wall[s].xpanning = (short) ((lockclock >> 2) & 255); + } + + for (int i = 0; i < ypanningwallcnt; i++) + wall[ypanningwalllist[i]].ypanning = (short) ~(lockclock & 255); +} + +void revolvefx() { + + short startwall, endwall; + + int dax, day; + PLAYER& plr = player[pyrn]; + + for (int i = 0; i < revolvecnt; i++) { + + startwall = sector[revolvesector[i]].wallptr; + endwall = (short) (startwall + sector[revolvesector[i]].wallnum - 1); + + revolveang[i] = (short) ((revolveang[i] + 2048 - ((TICSPERFRAME) << 1)) & 2047); + for (short k = startwall; k <= endwall; k++) { + Point out = rotatepoint(revolvepivotx[i], revolvepivoty[i], revolvex[i][k - startwall], + revolvey[i][k - startwall], revolveang[i]); + dax = out.getX(); + day = out.getY(); + dragpoint(k, dax, day); + } + + if (plr.sector == revolvesector[i]) { + revolvesyncang = (short) plr.ang; + revolvesyncrotang = 0; + revolvesyncx = plr.x; + revolvesyncy = plr.y; + revolvesyncrotang = (short) ((revolvesyncrotang + 2048 - ((TICSPERFRAME) << 1)) & 2047); + Point out = rotatepoint(revolvepivotx[i], revolvepivoty[i], revolvesyncx, revolvesyncy, + revolvesyncrotang); + viewBackupPlayerLoc(pyrn); + plr.x = out.getX(); + plr.y = out.getY(); + plr.ang = ((revolvesyncang + revolvesyncrotang) & 2047); + } + } +} + +void bobbingsector() { + for (int i = 0; i < bobbingsectorcnt; i++) { + short dasector = bobbingsectorlist[i]; + sector[dasector].floorz += (sintable[(lockclock << 4) & 2047] >> 6); + } +} + +void teleporter() { + + short dasector; + short startwall, endwall; + int i, j; + int s; + short daang; + + auto &plr = player[pyrn]; + + for (i = 0; i < warpsectorcnt; i++) { + dasector = warpsectorlist[i]; + j = ((lockclock & 127) >> 2); + if (j >= 16) + j = 31 - j; + { + sector[dasector].ceilingshade = (byte) j; + sector[dasector].floorshade = (byte) j; + startwall = sector[dasector].wallptr; + endwall = (short) (startwall + sector[dasector].wallnum - 1); + for (s = startwall; s <= endwall; s++) + wall[s].shade = (byte) j; + } + } + if (plr.sector == -1) + return; + + if (sector[plr.sector].lotag == 10) { + if (plr.sector != plr.oldsector) { + daang = (short) plr.ang; + warpfxsprite(plr.spritenum); + warp(plr.x, plr.y, plr.z, daang, plr.sector); + viewBackupPlayerLoc(pyrn); + plr.x = warpx; + plr.y = warpy; + plr.z = warpz; + daang = (short) warpang; + plr.sector = (short) warpsect; + warpfxsprite(plr.spritenum); + plr.ang = (int) daang; + justwarpedfx = 48; + playsound_loc(S_WARP, plr.x, plr.y); + setsprite(plr.spritenum, plr.x, plr.y, plr.z + (32 << 8)); + } + } + + if (sector[plr.sector].lotag == 4002) { + if (plr.sector != plr.oldsector) { + if (plr.treasure[TPENTAGRAM] == 1) { + plr.treasure[TPENTAGRAM] = 0; + if (mUserFlag == UserFlag.UserMap) { + game.changeScreen(gMenuScreen); + return; + } + switch (sector[plr.sector].hitag) { + case 1: // NEXTLEVEL + justteleported = true; + + if(isWh2()) { + gStatisticsScreen.show(plr, new Runnable() { + @Override + public void run() { + mapon++; + playsound_loc(S_CHAINDOOR1, plr.x, plr.y); + playertorch = 0; + playsound_loc(S_WARP, plr.x, plr.y); + loadnewlevel(mapon); + } + }); + break; + } + + mapon++; + playsound_loc(S_CHAINDOOR1, plr.x, plr.y); + playertorch = 0; + playsound_loc(S_WARP, plr.x, plr.y); + loadnewlevel(mapon); + break; + case 2: // ENDOFDEMO + playsound_loc(S_THUNDER1, plr.x, plr.y); + justteleported = true; + game.changeScreen(gVictoryScreen); + break; + } + } else { + // player need pentagram to teleport + showmessage("ITEM NEEDED", 360); + } + } + } +} + +void warp(int x, int y, int z, int daang, short dasector) { + warpx = x; + warpy = y; + warpz = z; + warpang = daang; + warpsect = dasector; + + for (int i = 0; i < warpsectorcnt; i++) { + if (sector[warpsectorlist[i]].hitag == sector[warpsect].hitag && warpsectorlist[i] != warpsect) { + warpsect = warpsectorlist[i]; + break; + } + } + + // find center of sector + int startwall = sector[warpsect].wallptr; + int endwall = (short) (startwall + sector[warpsect].wallnum - 1); + int dax = 0, day = 0, i = 0; + for (int s = startwall; s <= endwall; s++) { + dax += wall[s].x; + day += wall[s].y; + if (wall[s].nextsector >= 0) { + i = s; + } + } + warpx = dax / (endwall - startwall + 1); + warpy = day / (endwall - startwall + 1); + warpz = sector[warpsect].floorz - (32 << 8); + + warpsect = updatesector(warpx, warpy, warpsect); + dax = ((wall[i].x + wall[wall[i].point2].x) >> 1); + day = ((wall[i].y + wall[wall[i].point2].y) >> 1); + warpang = getangle(dax - warpx, day - warpy); +} + +void warpsprite(short spritenum) { + // EG 19 Aug 2017 - Try to prevent monsters teleporting back and forth wildly + if (monsterwarptime > 0) + return; + short dasectnum = sprite[spritenum].sectnum; + warpfxsprite(spritenum); + warp(sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z, sprite[spritenum].ang, dasectnum); + sprite[spritenum].x = warpx; + sprite[spritenum].y = warpy; + sprite[spritenum].z = warpz; + sprite[spritenum].ang = (short) warpang; + dasectnum = (short) warpsect; + + warpfxsprite(spritenum); + setsprite(spritenum, sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z); + + // EG 19 Aug 2017 - Try to prevent monsters teleporting back and forth wildly + monsterwarptime = 120; +} + +void ironbars() { + for (int i = 0; i < ironbarscnt; i++) { + if (ironbarsdone[i] == 1) { + short spritenum = ironbarsanim[i]; + switch (sprite[ironbarsanim[i]].hitag) { + case 1: + game.pInt.setsprinterpolate(spritenum, sprite[spritenum]); + sprite[ironbarsanim[i]].ang += TICSPERFRAME << 1; + if (sprite[ironbarsanim[i]].ang > 2047) + sprite[ironbarsanim[i]].ang -= 2047; + ironbarsgoal[i] += TICSPERFRAME << 1; + setsprite(spritenum, sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z); + if (ironbarsgoal[i] > 512) { + ironbarsgoal[i] = 0; + sprite[ironbarsanim[i]].hitag = 2; + ironbarsdone[i] = 0; + } + break; + case 2: + game.pInt.setsprinterpolate(spritenum, sprite[spritenum]); + sprite[ironbarsanim[i]].ang -= TICSPERFRAME << 1; + if (sprite[ironbarsanim[i]].ang < 0) + sprite[ironbarsanim[i]].ang += 2047; + ironbarsgoal[i] += TICSPERFRAME << 1; + setsprite(spritenum, sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z); + if (ironbarsgoal[i] > 512) { + ironbarsgoal[i] = 0; + sprite[ironbarsanim[i]].hitag = 1; + ironbarsdone[i] = 0; + } + break; + case 3: + game.pInt.setsprinterpolate(spritenum, sprite[spritenum]); + sprite[ironbarsanim[i]].z -= TICSPERFRAME << 4; + if (sprite[ironbarsanim[i]].z < ironbarsgoal[i]) { + sprite[ironbarsanim[i]].z = ironbarsgoal[i]; + sprite[ironbarsanim[i]].hitag = 4; + ironbarsdone[i] = 0; + ironbarsgoal[i] = sprite[ironbarsanim[i]].z + 6000; + } + setsprite(spritenum, sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z); + break; + case 4: + game.pInt.setsprinterpolate(spritenum, sprite[spritenum]); + sprite[ironbarsanim[i]].z += TICSPERFRAME << 4; + if (sprite[ironbarsanim[i]].z > ironbarsgoal[i]) { + sprite[ironbarsanim[i]].z = ironbarsgoal[i]; + sprite[ironbarsanim[i]].hitag = 3; + ironbarsdone[i] = 0; + ironbarsgoal[i] = sprite[ironbarsanim[i]].z - 6000; + } + setsprite(spritenum, sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z); + break; + } + } + } +} + +void sectorsounds() { + if (!SoundEnabled()) + return; + + PLAYER& plr = player[pyrn]; + + int sec = sector[plr.sector].extra & 0xFFFF; + if (sec != 0) { + if ((sec & 32768) != 0) { // loop on/off sector + if ((sec & 1) != 0) { // turn loop on if lsb is 1 + int index = (sec & ~0x8001) >> 1; + if (index < ambsoundarray.length && ambsoundarray[index].hsound == -1) + ambsoundarray[index].hsound = playsound(ambsoundarray[index].soundnum, 0, 0, -1); + } else { // turn loop off if lsb is 0 and its playing + int index = (sec & ~0x8000) >> 1; + if (index < ambsoundarray.length && ambsoundarray[index].hsound != -1) { + stopsound(ambsoundarray[index].hsound); + ambsoundarray[index].hsound = -1; + } + } + } else { + if (plr.z <= sector[plr.sector].floorz - (8 << 8)) + playsound_loc(sec, plr.x, plr.y); + } + } +} + + +void scaryprocess() { + if (krand() % 32768 > 32500 && krand() % 32768 > 32500 && scarytime < 0) { + scarytime = 180; + scarysize = 30; + SND_Sound(S_SCARYDUDE); + } + + if (scarytime >= 0) { + scarytime -= TICSPERFRAME << 1; + scarysize += TICSPERFRAME << 1; + } +} + +void dofx() { + lavadryland(); + scaryprocess(); + if (revolvecnt > 0) + revolvefx(); + panningfx(); + teleporter(); + bobbingsector(); + if (ironbarscnt > 0) + ironbars(); + + if ((gotpic[ANILAVA >> 3] & (1 << (ANILAVA & 7))) > 0) { + gotpic[ANILAVA >> 3] &= ~(1 << (ANILAVA & 7)); +// if (waloff[ANILAVA] != nullptr) +// movelava(waloff[ANILAVA]); XXX + } + if ((gotpic[HEALTHWATER >> 3] & (1 << (HEALTHWATER & 7))) > 0) { + gotpic[HEALTHWATER >> 3] &= ~(1 << (HEALTHWATER & 7)); +// if (waloff[HEALTHWATER] != nullptr) XXX +// movewater(waloff[HEALTHWATER]); + } + thesplash(); + thunder(); + cracks(); + if (isWh2()) { + PLAYER& plr = player[0]; + if (sector[plr.sector].lotag == 50 && sector[plr.sector].hitag > 0) + weaponpowerup(plr); + } + + GLRenderer gl = glrender(); + if (gl != nullptr) { + if (player[pyrn].poisoned != 0) { + int tilt = mulscale(sintable[(3 * totalclock) & 2047], 20, 16); + if (tilt != 0) + gl.setdrunk(tilt); + } else + gl.setdrunk(0); + } +} + +static int thunderflash; +static int thundertime; + +void thunder() { + int val; + + if (thunderflash == 0) { + visibility = 1024; + if ((gotpic[SKY >> 3] & (1 << (SKY & 7))) > 0) { + gotpic[SKY >> 3] &= ~(1 << (SKY & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY2 >> 3] & (1 << (SKY2 & 7))) > 0) { + gotpic[SKY2 >> 3] &= ~(1 << (SKY2 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY3 >> 3] & (1 << (SKY3 & 7))) > 0) { + gotpic[SKY3 >> 3] &= ~(1 << (SKY3 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY4 >> 3] & (1 << (SKY4 & 7))) > 0) { + gotpic[SKY4 >> 3] &= ~(1 << (SKY4 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY5 >> 3] & (1 << (SKY5 & 7))) > 0) { + gotpic[SKY5 >> 3] &= ~(1 << (SKY5 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY6 >> 3] & (1 << (SKY6 & 7))) > 0) { + gotpic[SKY6 >> 3] &= ~(1 << (SKY6 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY7 >> 3] & (1 << (SKY7 & 7))) > 0) { + gotpic[SKY7 >> 3] &= ~(1 << (SKY7 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY8 >> 3] & (1 << (SKY8 & 7))) > 0) { + gotpic[SKY8 >> 3] &= ~(1 << (SKY8 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY9 >> 3] & (1 << (SKY9 & 7))) > 0) { + gotpic[SKY9 >> 3] &= ~(1 << (SKY9 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } else if ((gotpic[SKY10 >> 3] & (1 << (SKY10 & 7))) > 0) { + gotpic[SKY10 >> 3] &= ~(1 << (SKY10 & 7)); + if (krand() % 32768 > 32700) { + thunderflash = 1; + thundertime = 120; + } + } + } else { + thundertime -= TICSPERFRAME; + if (thundertime < 0) { + thunderflash = 0; + SND_Sound(S_THUNDER1 + (krand() % 4)); + visibility = 1024; + } + } + + if (thunderflash == 1) { + val = krand() % 4; + switch (val) { + case 0: + visibility = 2048; + break; + case 1: + visibility = 1024; + break; + case 2: + visibility = 512; + break; + case 3: + visibility = 256; + break; + default: + visibility = 4096; + break; + } + } +} + +void thesplash() { + PLAYER& plr = player[pyrn]; + + if (plr.sector == -1) + return; + + if (sector[plr.sector].floorpicnum == WATER || sector[plr.sector].floorpicnum == LAVA + || sector[plr.sector].floorpicnum == SLIME) { + if (plr.onsomething == 0) + return; + + if (plr.sector != plr.oldsector) { + switch (sector[plr.sector].floorpicnum) { + case WATER: + makeasplash(SPLASHAROO, plr); + break; + case SLIME: + if (isWh2()) { + makeasplash(SLIMESPLASH, plr); + } else makeasplash(SPLASHAROO, plr); + break; + case LAVA: + makeasplash(LAVASPLASH, plr); + break; + } + } + } +} + +void makeasplash(int picnum, PLAYER& plr) { + int j = insertsprite(plr.sector, MASPLASH); + sprite[j].x = plr.x; + sprite[j].y = plr.y; + sprite[j].z = sector[plr.sector].floorz + (tilesizy[picnum] << 8); + sprite[j].cstat = 0; // Hitscan does not hit other bullets + sprite[j].picnum = (short) picnum; + sprite[j].shade = 0; + sprite[j].pal = 0; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].owner = 0; + sprite[j].clipdist = 16; + sprite[j].lotag = 8; + sprite[j].hitag = 0; + + switch (picnum) { + case SPLASHAROO: + case SLIMESPLASH: + if(!isWh2() && picnum == SLIMESPLASH) + break; + + playsound_loc(S_SPLASH1 + (krand() % 3), sprite[j].x, sprite[j].y); + break; + case LAVASPLASH: + break; + } + + movesprite((short) j, ((sintable[(sprite[j].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[j].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); +} + +void makemonstersplash(int picnum, int i) { + if (sprite[i].picnum == FISH) + return; + + int j = insertsprite(sprite[i].sectnum, MASPLASH); + sprite[j].x = sprite[i].x; + sprite[j].y = sprite[i].y; + sprite[j].z = sector[sprite[i].sectnum].floorz + (tilesizy[picnum] << 8); + sprite[j].cstat = 0; // Hitscan does not hit other bullets + sprite[j].picnum = (short) picnum; + sprite[j].shade = 0; + + if (sector[sprite[i].sectnum].floorpal == 9) + sprite[j].pal = 9; + else + sprite[j].pal = 0; + + if (sprite[i].picnum == RAT) { + sprite[j].xrepeat = 40; + sprite[j].yrepeat = 40; + } else { + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + } + sprite[j].owner = 0; + sprite[j].clipdist = 16; + sprite[j].lotag = 8; + sprite[j].hitag = 0; + game.pInt.setsprinterpolate(j, sprite[j]); + + // JSA 5/3 start + switch (picnum) { + case SPLASHAROO: + case SLIME: + if ((krand() % 2) != 0) { + if ((gotpic[WATER >> 3] & (1 << (WATER & 7))) > 0) { + gotpic[WATER >> 3] &= ~(1 << (WATER & 7)); + if ((krand() % 2) != 0) + playsound_loc(S_SPLASH1 + (krand() % 3), sprite[j].x, sprite[j].y); + } + } + if ((krand() % 2) != 0) { + if ((gotpic[SLIME >> 3] & (1 << (SLIME & 7))) > 0) { + gotpic[SLIME >> 3] &= ~(1 << (SLIME & 7)); + if ((krand() % 2) != 0) + playsound_loc(S_SPLASH1 + (krand() % 3), sprite[j].x, sprite[j].y); + } + } + break; + case LAVASPLASH: + break; + } +} + +void bats(PLAYER& plr, int k) { + short j = insertsprite(sprite[k].sectnum, FLOCK); + sprite[j].x = sprite[k].x; + sprite[j].y = sprite[k].y; + sprite[j].z = sprite[k].z; + sprite[j].cstat = 0; + sprite[j].picnum = BAT; + sprite[j].shade = 0; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].ang = (short) ((sprite[k].ang + (krand() & 128 - 256)) & 2047); + sprite[j].owner = (short) k; + sprite[j].clipdist = 16; + sprite[j].lotag = 128; + sprite[j].hitag = (short) k; + sprite[j].extra = 0; + + newstatus(j, FLOCK); + + if (sprite[k].extra == 1) + lastbat = j; +} + +void cracks() { + + PLAYER& plr = player[0]; + if (plr.sector == -1) + return; + + int datag = sector[plr.sector].lotag; + + if (floorpanningcnt < 64) + if (datag >= 3500 && datag <= 3599) { + sector[plr.sector].hitag = 0; + int daz = sector[plr.sector].floorz + (1024 * (sector[plr.sector].lotag - 3500)); + if ((setanimation(plr.sector, daz, 32, 0, FLOORZ)) >= 0) { + sector[plr.sector].floorpicnum = LAVA1; + sector[plr.sector].floorshade = -25; + SND_Sound(S_CRACKING); + } + sector[plr.sector].lotag = 80; + floorpanninglist[floorpanningcnt++] = plr.sector; + } + + if (datag >= 5100 && datag <= 5199) { + sector[plr.sector].hitag = 0; + sector[plr.sector].lotag = 0; + } + + if (datag >= 5200 && datag <= 5299) { + sector[plr.sector].hitag = 0; + sector[plr.sector].lotag = 0; + } + + if (datag == 3001) { + sector[plr.sector].lotag = 0; + for (short k = 0; k < MAXSPRITES; k++) { + if (sector[plr.sector].hitag == sprite[k].hitag) { + sprite[k].lotag = 36; + sprite[k].zvel = (short) (krand() & 1024 + 512); + newstatus(k, SHOVE); + } + } + } +} + +void lavadryland() { + PLAYER& plr = player[pyrn]; + + for (int k = 0; k < lavadrylandcnt; k++) { + + int s = lavadrylandsector[k]; + + if (plr.sector == s && sector[s].lotag > 0) { + + sector[s].hitag = 0; + + switch (sector[s].floorpicnum) { + case LAVA: + case ANILAVA: + case LAVA1: + sector[s].floorpicnum = COOLLAVA; + break; + case SLIME: + sector[s].floorpicnum = DRYSLIME; + break; + case WATER: + case HEALTHWATER: + sector[s].floorpicnum = DRYWATER; + break; + case LAVA2: + sector[s].floorpicnum = COOLLAVA2; + break; + } + sector[s].lotag = 0; + } + } + +} + +void warpfxsprite(int s) { + PLAYER& plr = player[pyrn]; + + int j = insertsprite(sprite[s].sectnum, WARPFX); + + sprite[j].x = sprite[s].x; + sprite[j].y = sprite[s].y; + sprite[j].z = sprite[s].z - (32 << 8); + + sprite[j].cstat = 0; + + sprite[j].picnum = ANNIHILATE; + short daang; + if (s == plr.spritenum) { + daang = (short) plr.ang; + sprite[j].ang = daang; + } else { + daang = sprite[s].ang; + sprite[j].ang = daang; + } + + sprite[j].xrepeat = 48; + sprite[j].yrepeat = 48; + sprite[j].clipdist = 16; + + sprite[j].extra = 0; + sprite[j].shade = -31; + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + sprite[j].zvel = (short) ((krand() & 256) - 128); + sprite[j].owner = (short) s; + sprite[j].lotag = 12; + sprite[j].hitag = 0; + sprite[j].pal = 0; + + int daz = (((sprite[j].zvel) * TICSPERFRAME) >> 3); + + movesprite((short) j, ((sintable[(daang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[daang & 2047]) * TICSPERFRAME) << 3, daz, 4 << 8, 4 << 8, 1); +} + +void FadeInit() { +#pragma message("Fix fades") +#if 0 + Console.Println("Initializing fade effects", 0); + registerFade("RED", new FadeEffect(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA) { + private int intensive; + + @Override + public void update(int intensive) { + this.intensive = intensive; + if (intensive > 0) { + r = 3 * (intensive + 32); + a = 2 * (intensive + 32); + } else + r = a = 0; + if (r > 255) + r = 255; + if (a > 255) + a = 255; + } + + @Override + public void draw(GL10 gl) { + gl.glBlendFunc(sfactor, dfactor); + gl.glColor4ub(r, 0, 0, a); + gl.glBegin(GL_TRIANGLES); + gl.glVertex2f(-2.5f, 1.f); + gl.glVertex2f(2.5f, 1.f); + gl.glVertex2f(.0f, -2.5f); + gl.glEnd(); + + int multiple = intensive / 2; + if (multiple > 170) + multiple = 170; + gl.glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl.glColor4ub(r > 0 ? multiple : 0, 0, 0, 0); + gl.glBegin(GL_TRIANGLES); + gl.glVertex2f(-2.5f, 1.f); + gl.glVertex2f(2.5f, 1.f); + gl.glVertex2f(.0f, -2.5f); + gl.glEnd(); + } + }); + + registerFade("WHITE", new FadeEffect(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA) { + private int intensive; + + @Override + public void update(int intensive) { + this.intensive = intensive; + if (intensive > 0) { + g = r = 10 * intensive; + a = (intensive + 32); + } else + g = r = a = 0; + + if (r > 255) + r = 255; + if (g > 255) + g = 255; + if (a > 255) + a = 255; + } + + @Override + public void draw(GL10 gl) { + gl.glBlendFunc(sfactor, dfactor); + gl.glColor4ub(r, g, 0, a); + gl.glBegin(GL_TRIANGLES); + gl.glVertex2f(-2.5f, 1.f); + gl.glVertex2f(2.5f, 1.f); + gl.glVertex2f(.0f, -2.5f); + gl.glEnd(); + + if (intensive > 0) { + int multiple = intensive; + if (multiple > 255) + multiple = 255; + gl.glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl.glColor4ub(r > 0 ? multiple : 0, g > 0 ? multiple : 0, 0, 0); + gl.glBegin(GL_TRIANGLES); + gl.glVertex2f(-2.5f, 1.f); + gl.glVertex2f(2.5f, 1.f); + gl.glVertex2f(.0f, -2.5f); + gl.glEnd(); + } + } + }); + + registerFade("GREEN", new FadeEffect(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA) { + private int intensive; + + @Override + public void update(int intensive) { + this.intensive = intensive; + if (intensive > 0) { + g = 4 * intensive; + a = (intensive + 32); + } else + g = a = 0; + + if (g > 255) + g = 255; + if (a > 255) + a = 255; + } + + @Override + public void draw(GL10 gl) { + gl.glBlendFunc(sfactor, dfactor); + gl.glColor4ub(0, g, 0, a); + gl.glBegin(GL_TRIANGLES); + gl.glVertex2f(-2.5f, 1.f); + gl.glVertex2f(2.5f, 1.f); + gl.glVertex2f(.0f, -2.5f); + gl.glEnd(); + + if (intensive > 0) { + int multiple = intensive; + if (multiple > 255) + multiple = 255; + gl.glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl.glColor4ub(0, g > 0 ? multiple : 0, 0, 0); + gl.glBegin(GL_TRIANGLES); + gl.glVertex2f(-2.5f, 1.f); + gl.glVertex2f(2.5f, 1.f); + gl.glVertex2f(.0f, -2.5f); + gl.glEnd(); + } + } + }); + + registerFade("BLUE", new FadeEffect(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA) { + private int intensive; + + @Override + public void update(int intensive) { + this.intensive = intensive; + if (intensive > 0) { + b = 4 * intensive; + a = (intensive + 32); + } else + b = a = 0; + + if (b > 255) + b = 255; + if (a > 255) + a = 255; + } + + @Override + public void draw(GL10 gl) { + gl.glBlendFunc(sfactor, dfactor); + gl.glColor4ub(0, 0, b, a); + gl.glBegin(GL_TRIANGLES); + gl.glVertex2f(-2.5f, 1.f); + gl.glVertex2f(2.5f, 1.f); + gl.glVertex2f(.0f, -2.5f); + gl.glEnd(); + + if (intensive > 0) { + int multiple = intensive; + if (multiple > 255) + multiple = 255; + gl.glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl.glColor4ub(0, 0, b > 0 ? multiple : 0, 0); + gl.glBegin(GL_TRIANGLES); + gl.glVertex2f(-2.5f, 1.f); + gl.glVertex2f(2.5f, 1.f); + gl.glVertex2f(.0f, -2.5f); + gl.glEnd(); + } + } + }); +#endif +} + +void resetEffects() { + greencount = 0; + bluecount = 0; + redcount = 0; + whitecount = 0; + updateFade("RED", 0); + updateFade("GREEN", 0); + updateFade("BLUE", 0); + updateFade("WHITE", 0); +} + +void weaponpowerup(PLAYER& plr) { + showmessage("Weapons enchanted", 360); + for (int i = 0; i < 10; i++) { + if (plr.weapon[i] != 0 && plr.weapon[i] != 3) { + plr.preenchantedweapon[i] = plr.weapon[i]; + plr.preenchantedammo[i] = plr.ammo[i]; + plr.weapon[i] = 3; + switch (difficulty) { + case 0: + plr.ammo[i] = 25; + break; + case 1: + plr.ammo[i] = 20; + break; + case 2: + case 3: + plr.ammo[i] = 10; + break; + } + + if (sector[plr.sector].hitag > 0) { + sector[plr.sector].hitag--; + if (sector[plr.sector].hitag == 0) { + short j = headspritesect[plr.sector]; + while (j != -1) { + short nextj = nextspritesect[j]; + if (sprite[j].picnum == CONE) { + deletesprite(j); + } else if (sprite[j].picnum == SPARKBALL) { + deletesprite(j); + } + j = nextj; + } + } + } + } + } +} + +void makesparks(short i, int type) { + + int j = -1; + + switch (type) { + case 1: + j = insertsprite(sprite[i].sectnum, SPARKS); + break; + case 2: + j = insertsprite(sprite[i].sectnum, SPARKSUP); + break; + case 3: + j = insertsprite(sprite[i].sectnum, SPARKSDN); + break; + } + + if (j == -1) + return; + + sprite[j].x = sprite[i].x; + sprite[j].y = sprite[i].y; + sprite[j].z = sprite[i].z; + sprite[j].cstat = 0; + sprite[j].picnum = SPARKBALL; + sprite[j].shade = 0; + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + sprite[j].ang = (short) ((krand() % 2047) & 2047); + sprite[j].owner = 0; + sprite[j].clipdist = 16; + sprite[j].lotag = (short) (krand() % 100); + sprite[j].hitag = 0; + sprite[j].extra = 0; + + sprite[j].pal = 0; +} + +void shards(int i, int type) { + short j = insertsprite(sprite[i].sectnum, SHARDOFGLASS); + + sprite[j].x = sprite[i].x + (((krand() % 512) - 256) << 2); + sprite[j].y = sprite[i].y + (((krand() % 512) - 256) << 2); + sprite[j].z = sprite[i].z - (getPlayerHeight() << 8) + (((krand() % 48) - 16) << 7); + sprite[j].zvel = (short) (krand() % 256); + sprite[j].cstat = 0; + sprite[j].picnum = (short) (SHARD + (krand() % 3)); + sprite[j].shade = 0; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].ang = (short) (sprite[i].ang + ((krand() % 512) - 256) & 2047); + sprite[j].owner = (short) i; + sprite[j].clipdist = 16; + sprite[j].lotag = (short) (120 + (krand() % 100)); + sprite[j].hitag = 0; + sprite[j].extra = (short) type; + sprite[j].pal = 0; +} + + +END_WH_NS diff --git a/source/games/whaven/src/whmap.cpp b/source/games/whaven/src/whmap.cpp new file mode 100644 index 000000000..b9729dcbd --- /dev/null +++ b/source/games/whaven/src/whmap.cpp @@ -0,0 +1,853 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + + + +boolean nextlevel; + +void loadnewlevel(int mapon) { +#if 0 + MapInfo nextmap; + if(gCurrentEpisode != nullptr && (nextmap = gCurrentEpisode.getMap(mapon)) != nullptr) { + boardfilename = nextmap.path; + Console.Println("Entering level " + boardfilename); + nextlevel = true; + gGameScreen.loadboard(boardfilename, nullptr); + } else game.show(); +#endif +} + +void preparesectors() { + int endwall, j, k = 0, startwall; + int dax, day; + int dasector; + int dax2, day2; + + for (int i = 0; i < numsectors; i++) { + ceilingshadearray[i] = sector[i].ceilingshade; + floorshadearray[i] = sector[i].floorshade; + + if(isWh2()) { + if(mapon == 13) + { + auto& s = sector[i]; + if(i == 209 && s.lotag == 62) + s.lotag = 0; + if(i == 435 && s.lotag == 0) + s.lotag = 62; + } + } + +// if (sector[i].lotag == 100) +// spikesector[spikecnt++] = i; + + if (sector[i].lotag == 70) + skypanlist[skypancnt++] = (short) i; + + if (sector[i].lotag >= 80 && sector[i].lotag <= 89) + floorpanninglist[floorpanningcnt++] = (short) i; + + if (sector[i].lotag >= 900 && sector[i].lotag <= 999) { + lavadrylandsector[lavadrylandcnt] = (short) i; + lavadrylandcnt++; + } + + if (sector[i].lotag >= 2100 && sector[i].lotag <= 2199) { + startwall = sector[i].wallptr; + endwall = startwall + sector[i].wallnum - 1; + dax = 0; + day = 0; + for (j = startwall; j <= endwall; j++) { + dax += wall[j].x; + day += wall[j].y; + } + revolvepivotx[revolvecnt] = (int) (dax / (endwall - startwall + 1)); + revolvepivoty[revolvecnt] = (int) (day / (endwall - startwall + 1)); + + k = 0; + for (j = startwall; j <= endwall; j++) { + revolvex[revolvecnt][k] = wall[j].x; + revolvey[revolvecnt][k] = wall[j].y; + k++; + } + revolvesector[revolvecnt] = (short) i; + revolveang[revolvecnt] = 0; + + revolveclip[revolvecnt] = 1; + if (sector[i].ceilingz == sector[wall[startwall].nextsector].ceilingz) + revolveclip[revolvecnt] = 0; + + revolvecnt++; + } + + switch (sector[i].lotag) { + case 131: + case 132: + case 133: + case 134: + case DOORSWINGTAG: + startwall = sector[i].wallptr; + endwall = startwall + sector[i].wallnum - 1; + for (j = startwall; j <= endwall; j++) { + if (wall[j].lotag == 4) { + k = wall[wall[wall[wall[j].point2].point2].point2].point2; + if ((wall[j].x == wall[k].x) && (wall[j].y == wall[k].y)) { + swingdoor[swingcnt].wall[0] = j; + swingdoor[swingcnt].wall[1] = wall[j].point2; + swingdoor[swingcnt].wall[2] = wall[wall[j].point2].point2; + swingdoor[swingcnt].wall[3] = wall[wall[wall[j].point2].point2].point2; + swingdoor[swingcnt].angopen = 1536; + swingdoor[swingcnt].angclosed = 0; + swingdoor[swingcnt].angopendir = -1; + } else { + swingdoor[swingcnt].wall[0] = wall[j].point2; + swingdoor[swingcnt].wall[1] = j; + swingdoor[swingcnt].wall[2] = lastwall(j); + swingdoor[swingcnt].wall[3] = lastwall(swingdoor[swingcnt].wall[2]); + swingdoor[swingcnt].angopen = 512; + swingdoor[swingcnt].angclosed = 0; + swingdoor[swingcnt].angopendir = 1; + } + for (k = 0; k < 4; k++) { + swingdoor[swingcnt].x[k] = wall[swingdoor[swingcnt].wall[k]].x; + swingdoor[swingcnt].y[k] = wall[swingdoor[swingcnt].wall[k]].y; + } + swingdoor[swingcnt].sector = i; + swingdoor[swingcnt].ang = swingdoor[swingcnt].angclosed; + swingdoor[swingcnt].anginc = 0; + swingcnt++; + } + } + break; + case 11: + xpanningsectorlist[xpanningsectorcnt++] = (short) i; + break; + case 12: + dasector = i; + dax = 0x7fffffff; + day = 0x7fffffff; + dax2 = 0x80000000; + day2 = 0x80000000; + startwall = sector[i].wallptr; + endwall = startwall + sector[i].wallnum - 1; + for (j = startwall; j <= endwall; j++) { + if (wall[j].x < dax) + dax = wall[j].x; + if (wall[j].y < day) + day = wall[j].y; + if (wall[j].x > dax2) + dax2 = wall[j].x; + if (wall[j].y > day2) + day2 = wall[j].y; + if (wall[j].lotag == 3) + k = j; + } + if (wall[k].x == dax) + dragxdir[dragsectorcnt] = -16; + if (wall[k].y == day) + dragydir[dragsectorcnt] = -16; + if (wall[k].x == dax2) + dragxdir[dragsectorcnt] = 16; + if (wall[k].y == day2) + dragydir[dragsectorcnt] = 16; + + dasector = wall[startwall].nextsector; + dragx1[dragsectorcnt] = 0x7fffffff; + dragy1[dragsectorcnt] = 0x7fffffff; + dragx2[dragsectorcnt] = 0x80000000; + dragy2[dragsectorcnt] = 0x80000000; + startwall = sector[dasector].wallptr; + endwall = startwall + sector[dasector].wallnum - 1; + for (j = startwall; j <= endwall; j++) { + if (wall[j].x < dragx1[dragsectorcnt]) + dragx1[dragsectorcnt] = wall[j].x; + if (wall[j].y < dragy1[dragsectorcnt]) + dragy1[dragsectorcnt] = wall[j].y; + if (wall[j].x > dragx2[dragsectorcnt]) + dragx2[dragsectorcnt] = wall[j].x; + if (wall[j].y > dragy2[dragsectorcnt]) + dragy2[dragsectorcnt] = wall[j].y; + } + + dragx1[dragsectorcnt] += (wall[sector[i].wallptr].x - dax); + dragy1[dragsectorcnt] += (wall[sector[i].wallptr].y - day); + dragx2[dragsectorcnt] -= (dax2 - wall[sector[i].wallptr].x); + dragy2[dragsectorcnt] -= (day2 - wall[sector[i].wallptr].y); + dragfloorz[dragsectorcnt] = sector[i].floorz; + + dragsectorlist[dragsectorcnt++] = (short) i; + break; + case 10: + case 14: + // case 15: + // captureflag sector + case 4002: + warpsectorlist[warpsectorcnt++] = (short) i; + break; + case 10000: + bobbingsectorlist[bobbingsectorcnt++] = (short) i; + } + if (sector[i].floorpicnum == TELEPAD && sector[i].lotag == 0) + warpsectorlist[warpsectorcnt++] = (short) i; + if (sector[i].floorpicnum == FLOORMIRROR) + floormirrorsector[floormirrorcnt++] = (short) i; + } + + ypanningwallcnt = 0; + for (int i = 0; i < numwalls; i++) { + wallshadearray[i] = wall[i].shade; + if (wall[i].lotag == 1) { + if (ypanningwallcnt < ypanningwalllist.length) + ypanningwalllist[ypanningwallcnt++] = (short) i; + } + } + +// // Map starts out completed WH2 XXX +// // for(i=0;i<(MAXSECTORS>>3);i++) show2dsector[i] = 0xff; +// for(i=0;i<(MAXSECTORS>>3);i++) show2dsector[i] = 0x00; +// // for(i=0;i<(MAXWALLS>>3);i++) show2dwall[i] = 0xff; +// for(i=0;i<(MAXWALLS>>3);i++) show2dwall[i] = 0x00; +// // for(i=0;i<(MAXSPRITES>>3);i++) show2dsprite[i] = 0xff; +// for(i=0;i<(MAXSPRITES>>3);i++) show2dsprite[i] = 0x00; +} + +boolean prepareboard(const char* fname) { + + short i; + short treesize; + + PLAYER plr = player[0]; + + srand(17); + + BuildPos out = nullptr; + out = loadboard(fname); + + plr.x = out.x; + plr.y = out.y; + plr.z = out.z; + plr.ang = out.ang; + plr.sector = out.sectnum; + +// int ratcnt = 0; + swingcnt = 0; + xpanningsectorcnt = 0; + ypanningwallcnt = 0; + floorpanningcnt = 0; +// crushsectorcnt=0; + revolvecnt = 0; + warpsectorcnt = 0; + dragsectorcnt = 0; + ironbarscnt = 0; + bobbingsectorcnt = 0; + playertorch = 0; + + damage_angvel = 0; + damage_svel = 0; + damage_vel = 0; + + hours = 0; + minutes = 0; + seconds = 0; + fortieth = 0; + +// goblinwarcnt = 0; + treasurescnt = 0; + treasuresfound = 0; + killcnt = 0; + kills = 0; + expgained = 0; + // numinterpolations=0; + + // the new mirror code + floormirrorcnt = 0; + tilesizx[FLOORMIRROR] = 0; + tilesizy[FLOORMIRROR] = 0; + + for (i = 0; i < ARROWCOUNTLIMIT; i++) + arrowsprite[i] = -1; + for (i = 0; i < THROWPIKELIMIT; i++) + throwpikesprite[i] = -1; + + lavadrylandcnt = 0; + aiInit(); + + for (i = 0; i < MAXSPRITES; i++) { // setup sector effect options + if (sprite[i].statnum >= MAXSTATUS) + continue; + + SPRITE& spr = sprite[i]; + + if(!isWh2() && mapon == 5 && i == 0 && spr.lotag == 0 && spr.hitag == 0) { + spr.lotag = 1; + spr.hitag = 34; + } + + if (sprite[i].picnum == CONE) { + sparksx = sprite[i].x; + sparksy = sprite[i].y; + sparksz = sprite[i].z; + for (int j = 0; j < 10; j++) { + makesparks(i, 1); + } + for (int j = 10; j < 20; j++) { + makesparks(i, 2); + } + for (int j = 20; j < 30; j++) { + makesparks(i, 3); + } + sprite[i].cstat &= ~3; + sprite[i].cstat |= 0x8000; + sprite[i].clipdist = 4; + changespritestat(i, (short) 0); + sector[sprite[i].sectnum].lotag = 50; + sector[sprite[i].sectnum].hitag = sprite[i].hitag; + if (sector[sprite[i].sectnum].hitag == 0) + sector[sprite[i].sectnum].hitag = 1; + } + + if ((spr.cstat & (16 + 32)) == (16 + 32)) + spr.cstat &= ~(16 | 32); + +// if (spr.picnum == RAT) { +// ratcnt++; +// if (ratcnt > 10) +// deletesprite((short) i); +// } + + if (spr.picnum == SPAWN) { + deletesprite((short) i); + } + + if (spr.picnum == TORCH) { + spr.cstat &= ~3; + changespritestat(i, TORCHLIGHT); + } + + if (spr.picnum == STANDINTORCH || spr.picnum == BOWLOFFIRE) { + changespritestat(i, TORCHLIGHT); + } + + if (spr.picnum == GLOW) { + changespritestat(i, GLOWLIGHT); + } + + if (spr.picnum == SNDEFFECT) { + sector[spr.sectnum].extra = spr.lotag; + deletesprite((short) i); + } + + if (spr.picnum == SNDLOOP) { // loop on + sector[spr.sectnum].extra = (short) (32768 | (spr.lotag << 1) | 1); + deletesprite((short) i); + } + + if (spr.picnum == SNDLOOPOFF) { // loop off + sector[spr.sectnum].extra = (short) (32768 | (spr.lotag << 1)); + deletesprite((short) i); + } + + if (spr.lotag == 80) { + ironbarsector[ironbarscnt] = spr.sectnum; + ironbarsdone[ironbarscnt] = 0; + ironbarsanim[ironbarscnt] = (short) i; + ironbarsgoal[ironbarscnt] = 0; + ironbarscnt++; + } + + if(isWh2()) { + switch (spr.picnum) { + case WH2HELMET: + spr.detail = HELMETTYPE; + break; + case WH2PLATEARMOR: + spr.detail = PLATEARMORTYPE; + break; + case WH2CHAINMAIL: + spr.detail = CHAINMAILTYPE; + break; + case WH2LEATHERARMOR: + spr.detail = LEATHERARMORTYPE; + break; + case WH2PENTAGRAM: + spr.detail = PENTAGRAMTYPE; + break; + case WH2CRYSTALSTAFF: + spr.detail = CRYSTALSTAFFTYPE; + break; + case WH2AMULETOFTHEMIST: + spr.detail = AMULETOFTHEMISTTYPE; + break; + case WH2HORNEDSKULL: + spr.detail = HORNEDSKULLTYPE; + break; + case WH2THEHORN: + spr.detail = THEHORNTYPE; + break; + case WH2BRASSKEY: + spr.detail = BRASSKEYTYPE; + break; + case WH2BLACKKEY: + spr.detail = BLACKKEYTYPE; + break; + case WH2GLASSKEY: + spr.detail = GLASSKEYTYPE; + break; + case WH2IVORYKEY: + spr.detail = IVORYKEYTYPE; + break; + case WH2SCROLLSCARE: + spr.detail = SCROLLSCARETYPE; + break; + case WH2SCROLLNIGHT: + spr.detail = SCROLLNIGHTTYPE; + break; + case WH2SCROLLFREEZE: + spr.detail = SCROLLFREEZETYPE; + break; + case WH2SCROLLMAGIC: + spr.detail = SCROLLMAGICTYPE; + break; + case WH2SCROLLOPEN: + spr.detail = SCROLLOPENTYPE; + break; + case WH2SCROLLFLY: + spr.detail = SCROLLFLYTYPE; + break; + case WH2SCROLLFIREBALL: + spr.detail = SCROLLFIREBALLTYPE; + break; + case WH2SCROLLNUKE: + spr.detail = SCROLLNUKETYPE; + break; + case WH2QUIVER: + spr.detail = QUIVERTYPE; + break; + case WALLBOW: + case WH2BOW: + spr.detail = BOWTYPE; + break; + case WH2WEAPON1: + spr.detail = WEAPON1TYPE; + break; + case WH2WEAPON1A: + spr.detail = WEAPON1ATYPE; + break; + case WH2GOBWEAPON: + spr.detail = GOBWEAPONTYPE; + break; + case WH2WEAPON2: + spr.detail = WEAPON2TYPE; + break; + case WALLAXE: + case WH2WEAPON4: + spr.detail = WEAPON4TYPE; + break; + case WH2THROWHALBERD: + spr.detail = THROWHALBERDTYPE; + break; + case WH2WEAPON5: + spr.detail = WEAPON5TYPE; + break; + case WH2SHIELD: + spr.detail = SHIELDTYPE; + break; + case WH2WEAPON5B: + spr.detail = WEAPON5BTYPE; + break; + case WALLPIKE: + case WH2THROWPIKE + 1: + spr.detail = WALLPIKETYPE; + break; + case WH2WEAPON6: + spr.detail = WEAPON6TYPE; + break; + case WH2WEAPON7: + spr.detail = WEAPON7TYPE; + break; + case WEAPON8: + spr.detail = WEAPON8TYPE; + break; + } + } else { + switch (spr.picnum) { + case WH1HELMET: + spr.detail = HELMETTYPE; + break; + case WH1PLATEARMOR: + spr.detail = PLATEARMORTYPE; + break; + case WH1CHAINMAIL: + spr.detail = CHAINMAILTYPE; + break; + case WH1LEATHERARMOR: + spr.detail = LEATHERARMORTYPE; + break; + case WH1PENTAGRAM: + spr.detail = PENTAGRAMTYPE; + break; + case WH1CRYSTALSTAFF: + spr.detail = CRYSTALSTAFFTYPE; + break; + case WH1AMULETOFTHEMIST: + spr.detail = AMULETOFTHEMISTTYPE; + break; + case WH1HORNEDSKULL: + spr.detail = HORNEDSKULLTYPE; + break; + case WH1THEHORN: + spr.detail = THEHORNTYPE; + break; + case WH1BRASSKEY: + spr.detail = BRASSKEYTYPE; + break; + case WH1BLACKKEY: + spr.detail = BLACKKEYTYPE; + break; + case WH1GLASSKEY: + spr.detail = GLASSKEYTYPE; + break; + case WH1IVORYKEY: + spr.detail = IVORYKEYTYPE; + break; + case WH1SCROLLSCARE: + spr.detail = SCROLLSCARETYPE; + break; + case WH1SCROLLNIGHT: + spr.detail = SCROLLNIGHTTYPE; + break; + case WH1SCROLLFREEZE: + spr.detail = SCROLLFREEZETYPE; + break; + case WH1SCROLLMAGIC: + spr.detail = SCROLLMAGICTYPE; + break; + case WH1SCROLLOPEN: + spr.detail = SCROLLOPENTYPE; + break; + case WH1SCROLLFLY: + spr.detail = SCROLLFLYTYPE; + break; + case WH1SCROLLFIREBALL: + spr.detail = SCROLLFIREBALLTYPE; + break; + case WH1SCROLLNUKE: + spr.detail = SCROLLNUKETYPE; + break; + case WH1QUIVER: + spr.detail = QUIVERTYPE; + break; + case WALLBOW: + case WH1BOW: + spr.detail = BOWTYPE; + break; + case WH1WEAPON1: + spr.detail = WEAPON1TYPE; + break; + case WH1WEAPON1A: + spr.detail = WEAPON1ATYPE; + break; + case WH1GOBWEAPON: + spr.detail = GOBWEAPONTYPE; + break; + case WH1WEAPON2: + spr.detail = WEAPON2TYPE; + break; + case WALLAXE: + case WH1WEAPON4: + spr.detail = WEAPON4TYPE; + break; + case WH1THROWHALBERD: + spr.detail = THROWHALBERDTYPE; + break; + case WH1WEAPON5: + spr.detail = WEAPON5TYPE; + break; + case WH1SHIELD: + spr.detail = SHIELDTYPE; + break; + case WH1WEAPON5B: + spr.detail = WEAPON5BTYPE; + break; + case WALLPIKE: + case WH1THROWPIKE + 1: + spr.detail = WALLPIKETYPE; + break; + case WH1WEAPON6: + spr.detail = WEAPON6TYPE; + break; + case WH1WEAPON7: + spr.detail = WEAPON7TYPE; + break; + } + } + + switch (spr.picnum) { + case SILVERBAG: + case SILVERCOINS: + spr.detail = SILVERBAGTYPE; + break; + case GOLDBAG: + case GOLDBAG2: + case GOLDCOINS: + case GOLDCOINS2: + spr.detail = GOLDBAGTYPE; + break; + case GIFTBOX: + spr.detail = GIFTBOXTYPE; + break; + case FLASKBLUE: + spr.detail = FLASKBLUETYPE; + break; + case FLASKRED: + spr.detail = FLASKREDTYPE; + break; + case FLASKGREEN: + spr.detail = FLASKGREENTYPE; + break; + case FLASKOCHRE: + spr.detail = FLASKOCHRETYPE; + break; + case FLASKTAN: + spr.detail = FLASKTANTYPE; + break; + case DIAMONDRING: + spr.detail = DIAMONDRINGTYPE; + break; + case SHADOWAMULET: + spr.detail = SHADOWAMULETTYPE; + break; + case GLASSSKULL: + spr.detail = GLASSSKULLTYPE; + break; + case AHNK: + spr.detail = AHNKTYPE; + break; + case BLUESCEPTER: + spr.detail = BLUESCEPTERTYPE; + break; + case YELLOWSCEPTER: + spr.detail = YELLOWSCEPTERTYPE; + break; + case ADAMANTINERING: + spr.detail = ADAMANTINERINGTYPE; + break; + case ONYXRING: + spr.detail = ONYXRINGTYPE; + break; + case SAPHIRERING: + spr.detail = SAPHIRERINGTYPE; + break; + case WALLSWORD: + case WEAPON3A: + spr.detail = WEAPON3ATYPE; + break; + case WEAPON3: + spr.detail = WEAPON3TYPE; + break; + case GONZOBSHIELD: + case GONZOCSHIELD: + case GONZOGSHIELD: + spr.detail = GONZOSHIELDTYPE; + break; + case SPIKEBLADE: + spr.detail = SPIKEBLADETYPE; + break; + case SPIKE: + spr.detail = SPIKETYPE; + break; + case SPIKEPOLE: + spr.detail = SPIKEPOLETYPE; + break; + case MONSTERBALL: + spr.detail = MONSTERBALLTYPE; + break; + case WH1HANGMAN + 1: + case WH2HANGMAN + 1: + if ((spr.picnum == (WH1HANGMAN + 1) && isWh2()) || (spr.picnum == WH2HANGMAN + 1 && !isWh2())) + break; + + spr.xrepeat = 28; + spr.yrepeat = 28; + break; + case GOBLINDEAD: + if (isWh2()) + break; + spr.xrepeat = 36; + spr.yrepeat = 36; + break; + case STONEGONZOBSH: + case STONEGONZOBSW2: + case STONEGONZOCHM: + case STONEGONZOGSH: + case STONEGRONDOVAL: + case STONEGONZOBSW: + spr.xrepeat = 24; + spr.yrepeat = 24; + break; + case GONZOHMJUMP: + case GONZOSHJUMP: + spr.xrepeat = 24; + spr.yrepeat = 24; + spr.clipdist = 32; + spr.extra = spr.lotag; + spr.lotag = 20; + if (spr.extra == 3) { + spr.lotag = 80; + } + spr.cstat |= 0x101; + break; + + case PINE: + spr.xrepeat = treesize = (short) (((krand() % 5) + 3) << 4); + spr.yrepeat = treesize; + break; + + case GYSER: + if (isWh2()) break; + spr.xrepeat = 32; + spr.yrepeat = 18; + spr.shade = -17; + spr.pal = 0; + spr.detail = GYSERTYPE; + // changespritestat(i,DORMANT); + break; + case PATROLPOINT: + spr.xrepeat = 24; + spr.yrepeat = 32; + + spr.cstat &= ~3; + spr.cstat |= 0x8000; + spr.clipdist = 4; + changespritestat(i, APATROLPOINT); + break; + case BARREL: + case VASEA: + case VASEB: + case VASEC: + case STAINGLASS1: + case STAINGLASS2: + case STAINGLASS3: + case STAINGLASS4: + case STAINGLASS5: + case STAINGLASS6: + case STAINGLASS7: + case STAINGLASS8: + case STAINGLASS9: + spr.cstat |= 0x101; + spr.clipdist = 64; + break; + case 2232: // team flags + if (!isWh2()) + break; +// netmarkflag(i); + break; + case 2233: // team flags + if (isWh2()) + break; + // XXX netmarkflag(i); + break; + } + + + if(isItemSprite(i)) { + Item& item = items[(spr.detail & 0xFF) - ITEMSBASE]; + if(item.sizx != -1 && item.sizy != -1) { + spr.xrepeat = (short) item.sizx; + spr.yrepeat = (short) item.sizy; + } + + if(item.treasures) + treasurescnt++; + spr.cstat &= ~1; + if(item.cflag) + spr.cstat &= ~3; + } + + } + + preparesectors(); + + automapping = 1; + + if(isWh2()) { + if(mapon == 5) { + SPRITE& spr = sprite[185]; + if(spr.picnum == 172 && spr.x == -36864 && spr.y == -53504) + deletesprite((short) 185); + } + + if(mapon == 13) { + if(sector[427].floorpicnum == 291) { + int s = insertsprite((short)427, (short)0); + if(s != -1) { + SPRITE& sp = sprite[s]; + sp.x = 27136; + sp.y = 51712; + sp.z = 7168; + sp.picnum = WH2PENTAGRAM; + sp.cstat = 515; + sp.shade = -3; + sp.xrepeat = sp.yrepeat = 64; + } + } + } + } + + if (justteleported) { // next level + plr.hvel = 0; + plr.spritenum = insertsprite(plr.sector, (short) 0); + plr.oldsector = plr.sector; + + sprite[plr.spritenum].x = plr.x; + sprite[plr.spritenum].y = plr.y; + sprite[plr.spritenum].z = sector[plr.sector].floorz; + sprite[plr.spritenum].cstat = 1 + 256; + sprite[plr.spritenum].picnum = isWh2() ? GRONSW : FRED; + sprite[plr.spritenum].shade = 0; + sprite[plr.spritenum].xrepeat = 36; + sprite[plr.spritenum].yrepeat = 36; + sprite[plr.spritenum].ang = (short) plr.ang; + sprite[plr.spritenum].xvel = 0; + sprite[plr.spritenum].yvel = 0; + sprite[plr.spritenum].zvel = 0; + sprite[plr.spritenum].owner = (short) (4096 + myconnectindex); + sprite[plr.spritenum].lotag = 0; + sprite[plr.spritenum].hitag = 0; + sprite[plr.spritenum].pal = (short) (isWh2() ? 10 : 1); + if(isWh2()) + sprite[plr.spritenum].clipdist = 48; + + setsprite(plr.spritenum, plr.x, plr.y, plr.z + (getPlayerHeight() << 8)); + + warpfxsprite(plr.spritenum); + plr.treasure[TBRASSKEY] = plr.treasure[TBLACKKEY] = plr.treasure[TGLASSKEY] = plr.treasure[TIVORYKEY] = 0; + plr.treasure[TBLUESCEPTER] = plr.treasure[TYELLOWSCEPTER] = 0; + + // protection from missile + // anit-missile for level only + // dont forget to cleanup values + plr.treasure[TONYXRING] = 0; + SND_CheckLoops(); + + justteleported = false; + } else { + initplayersprite(plr); + dimension = 3; + SND_Sound(S_SCARYDUDE); + } + + if (nextlevel) { + gAutosaveRequest = true; + nextlevel = false; + } + + if (mUserFlag != UserFlag.UserMap) + startmusic(mapon - 1); + + return true; +} + +END_WH_NS diff --git a/source/games/whaven/src/whobj.cpp b/source/games/whaven/src/whobj.cpp new file mode 100644 index 000000000..3a82c0c6a --- /dev/null +++ b/source/games/whaven/src/whobj.cpp @@ -0,0 +1,1919 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + + +int justwarpedcnt = 0; +byte flashflag = 0x00; + +static const int eg_onyx_effect = 1; + +short torchpattern[] = { 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 4, 4, 6, 6, 4, 4, 6, 6, 4, 4, 6, 6, 4, 4, 6, 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, 2 }; + +// EG 19 Aug 2017 - Try to prevent monsters teleporting back and forth wildly +int monsterwarptime; + +short adjusthp(int hp) { + float factor = (krand() % 20) / 100; + int howhard = difficulty; + + if (krand() % 100 > 50) + return (short) ((hp * (factor + 1)) * howhard); + else + return (short) ((hp - (hp * (factor))) * howhard); +} + +void timerprocess(PLAYER& plr) { + if (justwarpedfx > 0) { + justwarpedfx -= TICSPERFRAME; + justwarpedcnt += TICSPERFRAME << 6; + + if (justwarpedfx <= 0) + justwarpedcnt = 0; + } + + if (plr.poisoned == 1) { + if (plr.poisontime >= 0) { + plr.poisontime -= TICSPERFRAME; + + addhealth(plr, 0); + + if (plr.poisontime < 0) { + startredflash(50); + addhealth(plr, -10); + plr.poisontime = 7200; + } + } + } + + // EG 19 Aug 2017 - Try to prevent monsters teleporting back and forth wildly + if (monsterwarptime > 0) + monsterwarptime -= TICSPERFRAME; + + if (plr.vampiretime > 0) + plr.vampiretime -= TICSPERFRAME; + + if (plr.shockme >= 0) + plr.shockme -= TICSPERFRAME; + + if (plr.helmettime > 0) + plr.helmettime -= TICSPERFRAME; + + if (displaytime > 0) + displaytime -= TICSPERFRAME; + + if (plr.shadowtime >= 0) + plr.shadowtime -= TICSPERFRAME; + + if (plr.nightglowtime >= 0) { + plr.nightglowtime -= TICSPERFRAME; + visibility = 256; + if (plr.nightglowtime < 0) + visibility = 1024; + } + + if (plr.strongtime >= 0) { + plr.strongtime -= TICSPERFRAME; + whitecount = 10; + } + + if (plr.invisibletime >= 0) { + plr.invisibletime -= TICSPERFRAME; + } + + if (plr.invincibletime >= 0) { + plr.invincibletime -= TICSPERFRAME; + whitecount = 10; + } + + if (plr.manatime >= 0) { + plr.manatime -= TICSPERFRAME; + redcount = 20; + } + + if(plr.spiked != 0) + plr.spiketics -= TICSPERFRAME; + + if (displaytime <= 0) { + if (plr.manatime > 0) { + if (plr.manatime < 512) { + if ((plr.manatime % 64) > 32) { + return; + } + } + game.getFont(1).drawText(18,24, toCharArray("FIRE RESISTANCE"), 0, 0, TextAlign.Left, 2, false); + } else if (plr.poisoned == 1) { + game.getFont(1).drawText(18,24, toCharArray("POISONED"), 0, 0, TextAlign.Left, 2, false); + } else if (plr.orbactive[5] > 0) { + if (plr.orbactive[5] < 512) { + if ((plr.orbactive[5] % 64) > 32) { + return; + } + } + game.getFont(1).drawText(18,24, toCharArray("FLYING"), 0, 0, TextAlign.Left, 2, false); + } else if (plr.vampiretime > 0) { + game.getFont(1).drawText(18,24, toCharArray("ORNATE HORN"), 0, 0, TextAlign.Left, 2, false); + } + } +} + +int getPickHeight() { + if (isWh2()) + return PICKHEIGHT2; + else + return PICKHEIGHT; +} + +// see if picked up any objects? +// JSA 4_27 play appropriate sounds pending object picked up + +void processobjs(PLAYER& plr) { + + int dh, dx, dy, dz, i, nexti; + + if (plr.sector < 0 || plr.sector >= numsectors) + return; + + i = headspritesect[plr.sector]; + while (i != -1) { + nexti = nextspritesect[i]; + dx = (int) klabs(plr.x - sprite[i].x); // x distance to sprite + dy = (int) klabs(plr.y - sprite[i].y); // y distance to sprite + dz = (int) klabs((plr.z >> 8) - (sprite[i].z >> 8)); // z distance to sprite + dh = tilesizy[sprite[i].picnum] >> 1; // height of sprite + if (dx + dy < PICKDISTANCE && dz - dh <= getPickHeight()) { + if(isItemSprite(i)) + items[(sprite[i].detail & 0xFF) - ITEMSBASE].pickup(plr, (short)i); + + if (sprite[i].picnum >= EXPLOSTART && sprite[i].picnum <= EXPLOEND && sprite[i].owner != sprite[plr.spritenum].owner) + if (plr.manatime < 1) + addhealth(plr, -1); + } + i = nexti; + } +} + +void newstatus(short sn, int seq) { + switch (seq) { + case AMBUSH: + changespritestat(sn, AMBUSH); + break; + case LAND: + changespritestat(sn, LAND); + break; + case EVILSPIRIT: + changespritestat(sn, EVILSPIRIT); + sprite[sn].lotag = (short) (120 + (krand() & 64)); + break; + case PATROL: + changespritestat(sn, PATROL); + break; + case WARPFX: + changespritestat(sn, WARPFX); + sprite[sn].lotag = 12; + break; + case NUKED: + changespritestat(sn, NUKED); + if (!isWh2()) + sprite[sn].lotag = 24; + break; + case BROKENVASE: + changespritestat(sn, BROKENVASE); + switch (sprite[sn].picnum) { + case VASEA: + playsound_loc(S_GLASSBREAK1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = SHATTERVASE; + break; + case VASEB: + playsound_loc(S_GLASSBREAK1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = SHATTERVASE2; + break; + case VASEC: + playsound_loc(S_GLASSBREAK1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = SHATTERVASE3; + break; + case STAINGLASS1: + case STAINGLASS2: + case STAINGLASS3: + case STAINGLASS4: + case STAINGLASS5: + case STAINGLASS6: + case STAINGLASS7: + case STAINGLASS8: + case STAINGLASS9: + sprite[sn].picnum++; + SND_Sound(S_BIGGLASSBREAK1 + (krand() % 3)); + break; + case FBARRELFALL: + case BARREL: + playsound_loc(S_BARRELBREAK, sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = FSHATTERBARREL; + break; + } + sprite[sn].lotag = 12; + sprite[sn].cstat &= ~3; + break; + case DRAIN: + changespritestat(sn, DRAIN); + sprite[sn].lotag = 24; + sprite[sn].pal = 7; + break; + case ANIMLEVERDN: + playsound_loc(S_PULLCHAIN1, sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = LEVERUP; + changespritestat(sn, ANIMLEVERDN); + sprite[sn].lotag = 24; + break; + case ANIMLEVERUP: + playsound_loc(S_PULLCHAIN1, sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = LEVERDOWN; + changespritestat(sn, ANIMLEVERUP); + sprite[sn].lotag = 24; + break; + case SKULLPULLCHAIN1: + case PULLTHECHAIN: + playsound_loc(S_PULLCHAIN1, sprite[sn].x, sprite[sn].y); + changespritestat(sn, PULLTHECHAIN); + SND_Sound(S_CHAIN1); + sprite[sn].lotag = 24; + break; + case FROZEN: + // JSA_NEW + playsound_loc(S_FREEZE, sprite[sn].x, sprite[sn].y); + changespritestat(sn, FROZEN); + sprite[sn].lotag = 3600; + break; + case DEVILFIRE: + changespritestat(sn, DEVILFIRE); + sprite[sn].lotag = (short) (krand() & 120 + 360); + break; + case DRIP: + changespritestat(sn, DRIP); + break; + case BLOOD: + changespritestat(sn, BLOOD); + break; + case WAR: + changespritestat(sn, WAR); + break; + case PAIN: + sprite[sn].lotag = 36; + switch (sprite[sn].detail) { + case DEMONTYPE: + sprite[sn].lotag = 24; + playsound_loc(S_GUARDIANPAIN1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = DEMON - 1; + changespritestat(sn, PAIN); + break; + case NEWGUYTYPE: + sprite[sn].lotag = 24; + sprite[sn].picnum = NEWGUYPAIN; + changespritestat(sn, PAIN); + playsound_loc(S_AGM_PAIN1, sprite[sn].x, sprite[sn].y); + break; + + case KURTTYPE: + sprite[sn].lotag = 24; + sprite[sn].picnum = GONZOCSWPAIN; + changespritestat(sn, PAIN); + playsound_loc(S_GRONPAINA + (krand() % 3), sprite[sn].x, sprite[sn].y); + break; + + case GONZOTYPE: + sprite[sn].lotag = 24; + switch(sprite[sn].picnum) + { + case KURTSTAND: + case KURTKNEE: + case KURTAT: + case KURTPUNCH: + case KURTREADY: + case KURTREADY + 1: + case GONZOCSW: + sprite[sn].picnum = GONZOCSWPAIN; + playsound_loc(S_GRONPAINA + (krand() % 3), sprite[sn].x, sprite[sn].y); + break; + case GONZOGSW: + sprite[sn].picnum = GONZOGSWPAIN; + playsound_loc(S_GRONPAINA + (krand() % 3), sprite[sn].x, sprite[sn].y); + break; + case GONZOGHM: + sprite[sn].picnum = GONZOGHMPAIN; + playsound_loc(S_GRONPAINA + (krand() % 3), sprite[sn].x, sprite[sn].y); + break; + case GONZOGSH: + sprite[sn].picnum = GONZOGSHPAIN; + playsound_loc(S_GRONPAINA, sprite[sn].x, sprite[sn].y); + break; + default: + changespritestat(sn, FLEE); + break; + } + changespritestat(sn, PAIN); + break; + case KATIETYPE: + sprite[sn].picnum = KATIEPAIN; + changespritestat(sn, PAIN); + break; + case JUDYTYPE: + sprite[sn].lotag = 24; + sprite[sn].picnum = JUDY; + changespritestat(sn, PAIN); + break; + case FATWITCHTYPE: + sprite[sn].lotag = 24; + sprite[sn].picnum = FATWITCHDIE; + changespritestat(sn, PAIN); + break; + case SKULLYTYPE: + sprite[sn].lotag = 24; + sprite[sn].picnum = SKULLYDIE; + changespritestat(sn, PAIN); + break; + case GUARDIANTYPE: + sprite[sn].lotag = 24; + // sprite[sn].picnum=GUARDIANATTACK; + playsound_loc(S_GUARDIANPAIN1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + + if(isWh2()) sprite[sn].picnum = GUARDIAN; + else sprite[sn].picnum = GUARDIANCHAR; + changespritestat(sn, PAIN); + break; + case GRONTYPE: + sprite[sn].lotag = 24; + changespritestat(sn, PAIN); + playsound_loc(S_GRONPAINA + krand() % 3, sprite[sn].x, sprite[sn].y); + + if(sprite[sn].picnum == GRONHAL || sprite[sn].picnum == GRONHALATTACK) + sprite[sn].picnum = GRONHALPAIN; + else if(sprite[sn].picnum == GRONSW || sprite[sn].picnum == GRONSWATTACK) + sprite[sn].picnum = GRONSWPAIN; + else if(sprite[sn].picnum == GRONMU || sprite[sn].picnum == GRONMUATTACK) + sprite[sn].picnum = GRONMUPAIN; + break; + case KOBOLDTYPE: + sprite[sn].picnum = KOBOLDDIE; + changespritestat(sn, PAIN); + playsound_loc(S_KPAIN1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + break; + case DEVILTYPE: + playsound_loc(S_MPAIN1, sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = DEVILPAIN; + changespritestat(sn, PAIN); + break; + case FREDTYPE: + sprite[sn].picnum = FREDPAIN; + changespritestat(sn, PAIN); + // EG: Sounds for Fred (currently copied from ogre) + playsound_loc(S_KPAIN1 + (rand() % 2), sprite[sn].x, sprite[sn].y); + break; + case GOBLINTYPE: + case IMPTYPE: + if (isWh2() && (sprite[sn].picnum == IMP || sprite[sn].picnum == IMPATTACK)) { + sprite[sn].lotag = 24; + sprite[sn].picnum = IMPPAIN; + changespritestat(sn, PAIN); + } else { + sprite[sn].picnum = GOBLINPAIN; + changespritestat(sn, PAIN); + playsound_loc(S_GOBPAIN1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + } + break; + case MINOTAURTYPE: + sprite[sn].picnum = MINOTAURPAIN; + changespritestat(sn, PAIN); + playsound_loc(S_MPAIN1, sprite[sn].x, sprite[sn].y); + break; + default: + changespritestat(sn, FLEE); + break; + } + break; + case FLOCKSPAWN: + sprite[sn].lotag = 36; + sprite[sn].extra = 10; + changespritestat(sn, FLOCKSPAWN); + break; + case FLOCK: + sprite[sn].lotag = 128; + sprite[sn].extra = 0; + sprite[sn].pal = 0; + changespritestat(sn, FLOCK); + break; + case FINDME: + sprite[sn].lotag = 360; + if (sprite[sn].picnum == RAT) { + sprite[sn].ang = (short) (((krand() & 512 - 256) + sprite[sn].ang + 1024) & 2047); // NEW + changespritestat(sn, FLEE); + } else + changespritestat(sn, FINDME); + break; + case SKIRMISH: + sprite[sn].lotag = 60; + if (sprite[sn].picnum == RAT) { + sprite[sn].ang = (short) (((krand() & 512 - 256) + sprite[sn].ang + 1024) & 2047); // NEW + changespritestat(sn, FLEE); + } else + changespritestat(sn, SKIRMISH); + break; + case CHILL: + sprite[sn].lotag = 60; + changespritestat(sn, CHILL); + break; + case WITCHSIT: + sprite[sn].lotag = 12; + changespritestat(sn, WITCHSIT); + break; + case DORMANT: + sprite[sn].lotag = (short) (krand() & 2047 + 2047); + break; + case ACTIVE: + sprite[sn].lotag = 360; + break; + case FLEE: + switch (sprite[sn].detail) { + case GONZOTYPE: + + switch (sprite[sn].picnum) { + case GONZOCSWAT: + case KURTSTAND: + case KURTKNEE: + case KURTAT: + case KURTPUNCH: + sprite[sn].picnum = GONZOCSW; + break; + case GONZOGSWAT: + sprite[sn].picnum = GONZOGSW; + break; + case GONZOGHMAT: + sprite[sn].picnum = GONZOGHM; + break; + case GONZOGSHAT: + sprite[sn].picnum = GONZOGSH; + break; + } + break; + case NEWGUYTYPE: + sprite[sn].picnum = NEWGUY; + break; + case KURTTYPE: + sprite[sn].picnum = GONZOCSW; + break; + case GRONTYPE: + if(sprite[sn].picnum == GRONHALATTACK) + sprite[sn].picnum = GRONHAL; + else if(sprite[sn].picnum == GRONMUATTACK) + sprite[sn].picnum = GRONMU; + else if(sprite[sn].picnum == GRONSWATTACK) + sprite[sn].picnum = GRONSW; + break; + case DEVILTYPE: + sprite[sn].picnum = DEVIL; + break; + case KOBOLDTYPE: + sprite[sn].picnum = KOBOLD; + break; + case MINOTAURTYPE: + sprite[sn].picnum = MINOTAUR; + break; + case SKELETONTYPE: + sprite[sn].picnum = SKELETON; + break; + case FREDTYPE: + sprite[sn].picnum = FRED; + break; + case GOBLINTYPE: + sprite[sn].picnum = GOBLIN; + break; + } + + changespritestat(sn, FLEE); + if (!isWh2() && sprite[sn].picnum == DEVILATTACK && sprite[sn].picnum == DEVIL) + sprite[sn].lotag = (short) (120 + (krand() & 360)); + else + sprite[sn].lotag = 60; + break; + case BOB: + changespritestat(sn, BOB); + break; + case LIFTUP: + if (cartsnd == -1) { + playsound_loc(S_CLUNK, sprite[sn].x, sprite[sn].y); + cartsnd = playsound(S_CHAIN1, sprite[sn].x, sprite[sn].y, 5); + } + + changespritestat(sn, LIFTUP); + break; + case LIFTDN: + if (cartsnd == -1) { + playsound_loc(S_CLUNK, sprite[sn].x, sprite[sn].y); + cartsnd = playsound(S_CHAIN1, sprite[sn].x, sprite[sn].y, 5); + } + + changespritestat(sn, LIFTDN); + break; + case SHOVE: + sprite[sn].lotag = 128; + changespritestat(sn, SHOVE); + break; + case SHATTER: + changespritestat(sn, SHATTER); + switch (sprite[sn].picnum) { + case FBARRELFALL: + sprite[sn].picnum = FSHATTERBARREL; + break; + } + break; + case YELL: + changespritestat(sn, YELL); + sprite[sn].lotag = 12; + break; + case ATTACK2: //WH1 + if(isWh2()) break; + sprite[sn].lotag = 40; + sprite[sn].cstat |= 1; + changespritestat(sn, ATTACK2); + sprite[sn].picnum = DRAGONATTACK2; + playsound_loc(S_DRAGON1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + case ATTACK: + sprite[sn].lotag = 64; + sprite[sn].cstat |= 1; + changespritestat(sn, ATTACK); + switch (sprite[sn].detail) { + case NEWGUYTYPE: + if (sprite[sn].extra > 20) { + sprite[sn].picnum = NEWGUYCAST; + sprite[sn].lotag = 24; + } else if (sprite[sn].extra > 10) + sprite[sn].picnum = NEWGUYBOW; + else if (sprite[sn].extra > 0) + sprite[sn].picnum = NEWGUYMACE; + else + sprite[sn].picnum = NEWGUYPUNCH; + break; + case GONZOTYPE: + case KURTTYPE: + switch(sprite[sn].picnum) + { + case GONZOCSW: + if (sprite[sn].extra > 10) + sprite[sn].picnum = GONZOCSWAT; + else if (sprite[sn].extra > 0) { + sprite[sn].picnum = KURTREADY; + sprite[sn].lotag = 12; + } else + sprite[sn].picnum = KURTPUNCH; + break; + case GONZOGSW: + sprite[sn].picnum = GONZOGSWAT; + break; + case GONZOGHM: + sprite[sn].picnum = GONZOGHMAT; + break; + case GONZOGSH: + sprite[sn].picnum = GONZOGSHAT; + break; + } + break; + case KATIETYPE: + if ((krand() % 10) > 4) { + playsound_loc(S_JUDY1, sprite[sn].x, sprite[sn].y); + } + sprite[sn].picnum = KATIEAT; + break; + case DEMONTYPE: + playsound_loc(S_GUARDIAN1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = DEMON; + break; + case GRONTYPE: + if(sprite[sn].picnum == GRONHAL) + sprite[sn].picnum = GRONHALATTACK; + else if(sprite[sn].picnum == GRONMU) + sprite[sn].picnum = GRONMUATTACK; + else if(sprite[sn].picnum == GRONSW) + sprite[sn].picnum = GRONSWATTACK; + break; + case KOBOLDTYPE: + sprite[sn].picnum = KOBOLDATTACK; + if (krand() % 10 > 4) + playsound_loc(S_KSNARL1 + (krand() % 4), sprite[sn].x, sprite[sn].y); + break; + case DRAGONTYPE: + if ((krand() % 10) > 3) + playsound_loc(S_DRAGON1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + + sprite[sn].picnum = DRAGONATTACK; + break; + case DEVILTYPE: + if ((krand() % 10) > 4) + playsound_loc(S_DEMON1 + (krand() % 5), sprite[sn].x, sprite[sn].y); + + sprite[sn].picnum = DEVILATTACK; + break; + case FREDTYPE: + sprite[sn].picnum = FREDATTACK; + /* EG: Sounds for Fred (currently copied from Ogre) */ + if (rand() % 10 > 4) + playsound_loc(S_KSNARL1 + (rand() % 4), sprite[sn].x, sprite[sn].y); + break; + case SKELETONTYPE: + sprite[sn].picnum = SKELETONATTACK; + break; + case IMPTYPE: + sprite[sn].lotag = 92; + if ((krand() % 10) > 5) + playsound_loc(S_IMPGROWL1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = IMPATTACK; + break; + case GOBLINTYPE: + if ((krand() % 10) > 5) + playsound_loc(S_GOBLIN1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = GOBLINATTACK; + break; + case MINOTAURTYPE: + if ((krand() % 10) > 4) + playsound_loc(S_MSNARL1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + + sprite[sn].picnum = MINOTAURATTACK; + break; + case SKULLYTYPE: + sprite[sn].picnum = SKULLYATTACK; + break; + case FATWITCHTYPE: + if ((krand() % 10) > 4) + playsound_loc(S_FATLAUGH, sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = FATWITCHATTACK; + break; + case JUDYTYPE: + // sprite[sn].cstat=0; + if (krand() % 2 == 0) + sprite[sn].picnum = JUDYATTACK1; + else + sprite[sn].picnum = JUDYATTACK2; + break; + case WILLOWTYPE: + playsound_loc(S_WISP + (krand() % 2), sprite[sn].x, sprite[sn].y); + sprite[sn].pal = 7; + break; + case GUARDIANTYPE: + playsound_loc(S_GUARDIAN1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = GUARDIANATTACK; + break; + } + break; + case FACE: + changespritestat(sn, FACE); + break; + case STAND: + changespritestat(sn, FACE); + sprite[sn].lotag = 0; + break; + case CHASE: + if (sprite[sn].picnum == RAT) + changespritestat(sn, FLEE); + else + changespritestat(sn, CHASE); + sprite[sn].lotag = 256; + switch (sprite[sn].detail) { + case NEWGUYTYPE: + sprite[sn].picnum = NEWGUY; + break; + case KATIETYPE: + sprite[sn].picnum = KATIE; + break; + case DEMONTYPE: + sprite[sn].picnum = DEMON; + break; + case KURTTYPE: + sprite[sn].picnum = GONZOCSW; + break; + case GONZOTYPE: + switch (sprite[sn].picnum) { + case GONZOCSWAT: + case KURTSTAND: + case KURTKNEE: + case KURTAT: + case KURTPUNCH: + sprite[sn].picnum = GONZOCSW; + break; + case GONZOGSWAT: + sprite[sn].picnum = GONZOGSW; + break; + case GONZOGHMAT: + sprite[sn].picnum = GONZOGHM; + break; + case GONZOGSHAT: + sprite[sn].picnum = GONZOGSH; + break; + } + break; + case GRONTYPE: + if(sprite[sn].picnum == GRONHALATTACK) { + if (sprite[sn].extra > 2) + sprite[sn].picnum = GRONHAL; + else + sprite[sn].picnum = GRONMU; + } + else if(sprite[sn].picnum == GRONSWATTACK) + sprite[sn].picnum = GRONSW; + else if(sprite[sn].picnum == GRONMUATTACK) { + if (sprite[sn].extra > 0) + sprite[sn].picnum = GRONMU; + else + sprite[sn].picnum = GRONSW; + } + break; + case KOBOLDTYPE: + sprite[sn].picnum = KOBOLD; + break; + case DRAGONTYPE: + sprite[sn].picnum = DRAGON; + break; + case DEVILTYPE: + sprite[sn].picnum = DEVIL; + break; + case FREDTYPE: + sprite[sn].picnum = FRED; + break; + case SKELETONTYPE: + sprite[sn].picnum = SKELETON; + break; + case GOBLINTYPE: + case IMPTYPE: + if (isWh2() && sprite[sn].picnum == IMPATTACK) { + if (krand() % 10 > 2) + sprite[sn].picnum = IMP; + } else { + if (krand() % 10 > 2) + playsound_loc(S_GOBLIN1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + + sprite[sn].picnum = GOBLIN; + } + break; + case MINOTAURTYPE: + // JSA_DEMO3 + playsound_loc(S_MSNARL1 + (krand() % 4), sprite[sn].x, sprite[sn].y); + sprite[sn].picnum = MINOTAUR; + break; + case SKULLYTYPE: + sprite[sn].picnum = SKULLY; + break; + case FATWITCHTYPE: + sprite[sn].picnum = FATWITCH; + break; + case JUDYTYPE: + sprite[sn].picnum = JUDY; + break; + case GUARDIANTYPE: + sprite[sn].picnum = GUARDIAN; + break; + case WILLOWTYPE: + sprite[sn].pal = 6; + break; + } + break; + case MISSILE: + changespritestat(sn, MISSILE); + break; + case CAST: + changespritestat(sn, CAST); + sprite[sn].lotag = 12; + + if(sprite[sn].picnum == GRONHALATTACK + || sprite[sn].picnum == GONZOCSWAT + || sprite[sn].picnum == NEWGUY) + sprite[sn].lotag = 24; + else if(sprite[sn].picnum == GRONMUATTACK) + sprite[sn].lotag = 36; + break; + case FX: + changespritestat(sn, FX); + break; + case DIE: + if(sprite[sn].statnum == DIE || sprite[sn].statnum == DEAD) //already dying + break; + + if(sprite[sn].detail != GONZOTYPE || sprite[sn].shade != 31) + sprite[sn].cstat &= ~3; + else sprite[sn].cstat &= ~1; + switch (sprite[sn].detail) { + case NEWGUYTYPE: + sprite[sn].lotag = 20; + sprite[sn].picnum = NEWGUYDIE; + playsound_loc(S_AGM_DIE1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + break; + case KURTTYPE: + case GONZOTYPE: + sprite[sn].lotag = 20; + playsound_loc(S_GRONDEATHA + krand() % 3, sprite[sn].x, sprite[sn].y); + switch (sprite[sn].picnum) { + case KURTSTAND: + case KURTKNEE: + case KURTAT: + case KURTPUNCH: + case KURTREADY: + case KURTREADY + 1: + case GONZOCSW: + case GONZOCSWAT: + case GONZOCSWPAIN: + sprite[sn].picnum = GONZOCSWPAIN; + break; + case GONZOGSW: + case GONZOGSWAT: + case GONZOGSWPAIN: + sprite[sn].picnum = GONZOGSWPAIN; + break; + case GONZOGHM: + case GONZOGHMAT: + case GONZOGHMPAIN: + sprite[sn].picnum = GONZOGHMPAIN; + break; + case GONZOGSH: + case GONZOGSHAT: + case GONZOGSHPAIN: + sprite[sn].picnum = GONZOGSHPAIN; + break; + case GONZOBSHPAIN: + sprite[sn].picnum = GONZOBSHPAIN; + if (sprite[sn].shade > 30) { + trailingsmoke(sn, false); + deletesprite((short) sn); + return; + } + break; + default: + sprite[sn].lotag = 20; + sprite[sn].picnum = GONZOGSWPAIN; + System.err.println("die error " + sprite[sn].picnum); + return; + } + break; + case KATIETYPE: + playsound_loc(S_JUDYDIE, sprite[sn].x, sprite[sn].y); + sprite[sn].lotag = 20; + sprite[sn].picnum = KATIEPAIN; + break; + case DEMONTYPE: + playsound_loc(S_GUARDIANDIE, sprite[sn].x, sprite[sn].y); + explosion(sn, sprite[sn].x, sprite[sn].y, sprite[sn].z, sprite[sn].owner); + deletesprite((short) sn); + addscore(aiGetPlayerTarget(sn), 1500); + kills++; + return; + case GRONTYPE: + sprite[sn].lotag = 20; + playsound_loc(S_GRONDEATHA + krand() % 3, sprite[sn].x, sprite[sn].y); + if(sprite[sn].picnum == GRONHAL || sprite[sn].picnum == GRONHALATTACK || sprite[sn].picnum == GRONHALPAIN) + sprite[sn].picnum = GRONHALDIE; + else if(sprite[sn].picnum == GRONSW || sprite[sn].picnum == GRONSWATTACK || sprite[sn].picnum == GRONSWPAIN) + sprite[sn].picnum = GRONSWDIE; + else if(sprite[sn].picnum == GRONMU || sprite[sn].picnum == GRONMUATTACK || sprite[sn].picnum == GRONMUPAIN) + sprite[sn].picnum = GRONMUDIE; + else { + System.err.println("error gron" + sprite[sn].picnum); + sprite[sn].picnum = GRONDIE; + } + break; + case FISHTYPE: + case RATTYPE: + sprite[sn].lotag = 20; + break; + case KOBOLDTYPE: + playsound_loc(S_KDIE1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + sprite[sn].lotag = 20; + sprite[sn].picnum = KOBOLDDIE; + break; + case DRAGONTYPE: + playsound_loc(S_DEMONDIE1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + sprite[sn].lotag = 20; + sprite[sn].picnum = DRAGONDIE; + + break; + case DEVILTYPE: + playsound_loc(S_DEMONDIE1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + sprite[sn].lotag = 20; + sprite[sn].picnum = DEVILDIE; + break; + case FREDTYPE: + sprite[sn].lotag = 20; + sprite[sn].picnum = FREDDIE; + /* EG: Sounds for Fred (currently copied from Ogre) */ + playsound_loc(S_KDIE1 + (rand() % 2), sprite[sn].x, sprite[sn].y); + break; + case SKELETONTYPE: + playsound_loc(S_SKELETONDIE, sprite[sn].x, sprite[sn].y); + sprite[sn].lotag = 20; + sprite[sn].picnum = SKELETONDIE; + break; + case IMPTYPE: + playsound_loc(S_IMPDIE1 + (krand() % 2), sprite[sn].x, sprite[sn].y); + sprite[sn].lotag = 20; + sprite[sn].picnum = IMPDIE; + break; + case GOBLINTYPE: + playsound_loc(S_GOBDIE1 + (krand() % 3), sprite[sn].x, sprite[sn].y); + sprite[sn].lotag = 20; + sprite[sn].picnum = GOBLINDIE; + break; + case MINOTAURTYPE: + playsound_loc(S_MDEATH1, sprite[sn].x, sprite[sn].y); + sprite[sn].lotag = 10; + sprite[sn].picnum = MINOTAURDIE; + break; + case SPIDERTYPE: + sprite[sn].lotag = 10; + sprite[sn].picnum = SPIDERDIE; + break; + case SKULLYTYPE: + sprite[sn].lotag = 20; + sprite[sn].picnum = SKULLYDIE; + playsound_loc(S_SKULLWITCHDIE, sprite[sn].x, sprite[sn].y); + break; + case FATWITCHTYPE: + sprite[sn].lotag = 20; + sprite[sn].picnum = FATWITCHDIE; + playsound_loc(S_FATWITCHDIE, sprite[sn].x, sprite[sn].y); + break; + case JUDYTYPE: + sprite[sn].lotag = 20; + if (mapon < 24) { + for (int j = 0; j < 8; j++) + trailingsmoke(sn, true); + deletesprite((short) sn); + return; + } else { + sprite[sn].picnum = JUDYDIE; + playsound_loc(S_JUDYDIE, sprite[sn].x, sprite[sn].y); + } + break; + case GUARDIANTYPE: + playsound_loc(S_GUARDIANDIE, sprite[sn].x, sprite[sn].y); + for (int j = 0; j < 4; j++) + explosion(sn, sprite[sn].x, sprite[sn].y, sprite[sn].z, sprite[sn].owner); + deletesprite((short) sn); + addscore(aiGetPlayerTarget(sn), 1500); + kills++; + return; + case WILLOWTYPE: + playsound_loc(S_WILLOWDIE, sprite[sn].x, sprite[sn].y); + sprite[sn].pal = 0; + sprite[sn].lotag = 20; + sprite[sn].picnum = WILLOWEXPLO; + break; + } + changespritestat(sn, DIE); + break; + + case RESURECT: + sprite[sn].lotag = 7200; + switch (sprite[sn].picnum) { + case GONZOBSHDEAD: + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 85); + sprite[sn].detail = GONZOTYPE; + break; + case NEWGUYDEAD: + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 55); + sprite[sn].detail = NEWGUYTYPE; + break; + case GONZOCSWDEAD: + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 55); + sprite[sn].detail = GONZOTYPE; + break; + case GONZOGSWDEAD: + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 105); + sprite[sn].detail = GONZOTYPE; + break; + case GONZOGHMDEAD: + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 100); + sprite[sn].detail = GONZOTYPE; + break; + case GONZOGSHDEAD: + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 110); + sprite[sn].detail = GONZOTYPE; + break; + case KATIEDEAD: + trailingsmoke(sn, true); + sprite[sn].picnum = KATIEDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + spawnhornskull(sn); + addscore(aiGetPlayerTarget(sn), 5000); + sprite[sn].detail = KATIETYPE; + break; + case DEVILDEAD: + trailingsmoke(sn, true); + sprite[sn].picnum = DEVILDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 70); + sprite[sn].detail = DEVILTYPE; + break; + case IMPDEAD: + sprite[sn].picnum = IMPDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 115); + sprite[sn].detail = IMPTYPE; + break; + case KOBOLDDEAD: + sprite[sn].picnum = KOBOLDDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + sprite[sn].detail = KOBOLDTYPE; + if(isWh2()) { + switch (sprite[sn].pal) { + case 0: + addscore(aiGetPlayerTarget(sn), 25); + break; + case 7: + addscore(aiGetPlayerTarget(sn), 40); + break; + } + addscore(aiGetPlayerTarget(sn), 10); + break; + } + + + addscore(aiGetPlayerTarget(sn), 10); + break; + case DRAGONDEAD: + sprite[sn].picnum = DRAGONDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 4000); + sprite[sn].detail = DRAGONTYPE; + break; + case FREDDEAD: + sprite[sn].picnum = FREDDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 40); + sprite[sn].detail = FREDTYPE; + break; + case GOBLINDEAD: + sprite[sn].picnum = GOBLINDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 25); + sprite[sn].detail = GOBLINTYPE; + break; + case MINOTAURDEAD: + sprite[sn].picnum = MINOTAURDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), isWh2() ? 95 : 170); + sprite[sn].detail = MINOTAURTYPE; + break; + case SPIDERDEAD: + sprite[sn].picnum = SPIDERDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 5); + sprite[sn].detail = SPIDERTYPE; + break; + case SKULLYDEAD: + sprite[sn].picnum = SKULLYDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 1000); + sprite[sn].detail = SKULLYTYPE; + break; + case FATWITCHDEAD: + sprite[sn].picnum = FATWITCHDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 900); + sprite[sn].detail = FATWITCHTYPE; + break; + case JUDYDEAD: + sprite[sn].picnum = JUDYDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + addscore(aiGetPlayerTarget(sn), 7000); + sprite[sn].detail = JUDYTYPE; + break; + default: + if(sprite[sn].picnum == SKELETONDEAD) { + sprite[sn].picnum = SKELETONDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, RESURECT); + sprite[sn].detail = SKELETONTYPE; + addscore(aiGetPlayerTarget(sn), isWh2() ? 20 : 10); + } else if(sprite[sn].picnum == GRONDEAD) { + sprite[sn].picnum = GRONDEAD; + sprite[sn].cstat &= ~3; + sprite[sn].extra = 3; + sprite[sn].detail = GRONTYPE; + changespritestat(sn, RESURECT); + if(isWh2()) { + switch (sprite[sn].pal) { + case 0: + addscore(aiGetPlayerTarget(sn),125); + break; + case 10: + addscore(aiGetPlayerTarget(sn),90); + break; + case 11: + addscore(aiGetPlayerTarget(sn),115); + break; + case 12: + addscore(aiGetPlayerTarget(sn),65); + break; + } + } else addscore(aiGetPlayerTarget(sn), 200); + } + break; + } + break; + + case DEAD: + sprite[sn].detail = 0; + if(sprite[sn].picnum == SKELETONDEAD) { + sprite[sn].picnum = SKELETONDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + if(isWh2()) { + addscore(aiGetPlayerTarget(sn), 70); + monsterweapon(sn); + } + } else if(sprite[sn].picnum == FISH || sprite[sn].picnum == RAT) { + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), 5); + } else if(sprite[sn].picnum == GRONDEAD) { + sprite[sn].picnum = GRONDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + if(isWh2()) { + switch (sprite[sn].pal) { + case 0: + addscore(aiGetPlayerTarget(sn), 125); + break; + case 10: + addscore(aiGetPlayerTarget(sn), 90); + break; + case 11: + addscore(aiGetPlayerTarget(sn), 115); + break; + case 12: + addscore(aiGetPlayerTarget(sn), 65); + break; + } + } else { + addscore(aiGetPlayerTarget(sn), 200); + } + monsterweapon(sn); + } else { + switch (sprite[sn].picnum) { + case GONZOBSHDEAD: + if (netgame) { + break; + } + sprite[sn].picnum = GONZOBSHDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + if (sprite[sn].pal == 4) { + changespritestat(sn, SHADE); + deaddude(sn); + } else { + changespritestat(sn, DEAD); + if (sprite[sn].shade < 25) + monsterweapon(sn); + } + addscore(aiGetPlayerTarget(sn), 85); + break; + case GONZOCSWDEAD: + if (netgame) { + break; + } + sprite[sn].picnum = GONZOCSWDEAD; + sprite[sn].cstat &= ~3; + if (sprite[sn].pal == 4) { + changespritestat(sn, SHADE); + deaddude(sn); + } else { + changespritestat(sn, DEAD); + monsterweapon(sn); + } + addscore(aiGetPlayerTarget(sn), 55); + break; + case GONZOGSWDEAD: + if (netgame) { + break; + } + sprite[sn].picnum = GONZOGSWDEAD; + sprite[sn].cstat &= ~3; + if (sprite[sn].pal == 4) { + changespritestat(sn, SHADE); + deaddude(sn); + } else { + changespritestat(sn, DEAD); + monsterweapon(sn); + } + addscore(aiGetPlayerTarget(sn), 105); + break; + case GONZOGHMDEAD: + if (netgame) { + break; + } + sprite[sn].picnum = GONZOGHMDEAD; + sprite[sn].cstat &= ~3; + if (sprite[sn].pal == 4) { + changespritestat(sn, SHADE); + deaddude(sn); + } else { + changespritestat(sn, DEAD); + monsterweapon(sn); + } + addscore(aiGetPlayerTarget(sn), 100); + break; + case NEWGUYDEAD: + if (netgame) { + break; + } + sprite[sn].picnum = NEWGUYDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + monsterweapon(sn); + addscore(aiGetPlayerTarget(sn), 50); + break; + case GONZOGSHDEAD: + if (netgame) { + break; + } + sprite[sn].picnum = GONZOGSHDEAD; + if(sprite[sn].shade != 31) + sprite[sn].cstat &= ~3; + else sprite[sn].cstat &= ~1; + if (sprite[sn].pal == 4) { + changespritestat(sn, SHADE); + deaddude(sn); + } else { + changespritestat(sn, DEAD); + monsterweapon(sn); + } + addscore(aiGetPlayerTarget(sn), 110); + break; + case KATIEDEAD: + if (netgame) { + break; + } + trailingsmoke(sn, true); + sprite[sn].picnum = DEVILDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + spawnhornskull(sn); + addscore(aiGetPlayerTarget(sn), 500); + break; + case IMPDEAD: + if (!isWh2()) + break; + sprite[sn].picnum = IMPDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), 115); + monsterweapon(sn); + break; + case KOBOLDDEAD: + sprite[sn].picnum = KOBOLDDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), 10); + break; + case DRAGONDEAD: + sprite[sn].picnum = DRAGONDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), 4000); + break; + case DEVILDEAD: + trailingsmoke(sn, true); + sprite[sn].picnum = DEVILDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), isWh2() ? 70 : 50); + if(isWh2()) + monsterweapon(sn); + break; + case FREDDEAD: + sprite[sn].picnum = FREDDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), 40); + break; + case GOBLINDEAD: + sprite[sn].picnum = GOBLINDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + + PLAYER p = aiGetPlayerTarget(sn); + if(p != null) addscore(p, 25); + + if ((rand() % 100) > 60) + monsterweapon(sn); + break; + case MINOTAURDEAD: + sprite[sn].picnum = MINOTAURDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), isWh2() ? 95 : 70); + if ((rand() % 100) > 60) + monsterweapon(sn); + break; + case SPIDERDEAD: + sprite[sn].picnum = SPIDERDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), 5); + break; + case SKULLYDEAD: + sprite[sn].picnum = SKULLYDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), 100); + break; + case FATWITCHDEAD: + sprite[sn].picnum = FATWITCHDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + addscore(aiGetPlayerTarget(sn), 900); + break; + case JUDYDEAD: + sprite[sn].picnum = JUDYDEAD; + sprite[sn].cstat &= ~3; + changespritestat(sn, DEAD); + spawnapentagram(sn); + addscore(aiGetPlayerTarget(sn), 7000); + break; + case WILLOWEXPLO + 2: + sprite[sn].pal = 0; + sprite[sn].cstat &= ~3; + changespritestat(sn, (short) 0); + deletesprite(sn); + addscore(aiGetPlayerTarget(sn), isWh2() ? 15 : 150); + return; + } + } + + getzrange(sprite[sn].x, sprite[sn].y, sprite[sn].z - 1, sprite[sn].sectnum, + (sprite[sn].clipdist) << 2, CLIPMASK0); + sprite[sn].z = zr_florz; + + if ((zr_florhit & kHitTypeMask) == kHitSector) { + if (sprite[sn].sectnum != MAXSECTORS && (sector[sprite[sn].sectnum].floorpicnum == WATER + || sector[sprite[sn].sectnum].floorpicnum == SLIME)) { + if (sprite[sn].picnum == MINOTAURDEAD) { + sprite[sn].z += (8 << 8); + setsprite(sn, sprite[sn].x, sprite[sn].y, sprite[sn].z); + } + } + if (sprite[sn].sectnum != MAXSECTORS && (sector[sprite[sn].sectnum].floorpicnum == LAVA + || sector[sprite[sn].sectnum].floorpicnum == LAVA1 + || sector[sprite[sn].sectnum].floorpicnum == LAVA2)) { + trailingsmoke(sn, true); + deletesprite((short) sn); + } + } + break; + } + // + // the control variable for monster release + // +} + +void makeafire(int i, int firetype) { + short j = insertsprite(sprite[i].sectnum, FIRE); + //game.pInt.setsprinterpolate(j, sprite[j]); + + sprite[j].x = sprite[i].x + (krand() & 1024) - 512; + sprite[j].y = sprite[i].y + (krand() & 1024) - 512; + sprite[j].z = sprite[i].z; + + sprite[j].cstat = 0; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + + sprite[j].shade = 0; + + sprite[j].clipdist = 64; + sprite[j].owner = sprite[i].owner; + sprite[j].lotag = 2047; + sprite[j].hitag = 0; + changespritestat(j, FIRE); +} + +void explosion(int i, int x, int y, int z, int owner) { + int j = insertsprite(sprite[i].sectnum, EXPLO); + + boolean isWH2 = isWh2(); + + if(!isWH2) { + sprite[j].x = x + (krand() & 1024) - 512; + sprite[j].y = y + (krand() & 1024) - 512; + sprite[j].z = z; + } else { + sprite[j].x = x; + sprite[j].y = y; + sprite[j].z = z + (16 << 8); + } + + //game.pInt.setsprinterpolate(j, sprite[j]); + + sprite[j].cstat = 0; // Hitscan does not hit smoke on wall + sprite[j].cstat &= ~3; + sprite[j].shade = -15; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].ang = (short) (krand() & 2047); + sprite[j].xvel = (short) ((krand() & 511) - 256); + sprite[j].yvel = (short) ((krand() & 511) - 256); + sprite[j].zvel = (short) ((krand() & 511) - 256); + sprite[j].owner = sprite[i].owner; + sprite[j].hitag = 0; + sprite[j].pal = 0; + if(!isWH2) { + sprite[j].picnum = MONSTERBALL; + sprite[j].lotag = 256; + } else { + sprite[j].picnum = EXPLOSTART; + sprite[j].lotag = 12; + } +} + +void explosion2(int i, int x, int y, int z, int owner) { + int j = insertsprite(sprite[i].sectnum, EXPLO); + + boolean isWH2 = isWh2(); + + if(!isWH2) { + sprite[j].x = x + (krand() & 256) - 128; + sprite[j].y = y + (krand() & 256) - 128; + sprite[j].z = z; + } else { + sprite[j].x = x; + sprite[j].y = y; + sprite[j].z = z + (16 << 8); + } + + //game.pInt.setsprinterpolate(j, sprite[j]); + + sprite[j].cstat = 0; + sprite[j].cstat &= ~3; + + sprite[j].shade = -25; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].ang = (short) (krand() & 2047); + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + sprite[j].zvel = (short) ((krand() & 256) - 128); + sprite[j].owner = sprite[i].owner; + sprite[j].hitag = 0; + sprite[j].pal = 0; + + if(!isWH2) { + sprite[j].picnum = MONSTERBALL; + sprite[j].lotag = 128; + } else { + sprite[j].picnum = EXPLOSTART; + sprite[j].lotag = 12; + } + +} + +void trailingsmoke(int i, boolean ball) { + int j = insertsprite(sprite[i].sectnum, SMOKE); + + sprite[j].x = sprite[i].x; + sprite[j].y = sprite[i].y; + sprite[j].z = sprite[i].z; + + //game.pInt.setsprinterpolate(j, sprite[j]); + sprite[j].cstat = 0x03; + sprite[j].cstat &= ~3; + sprite[j].picnum = SMOKEFX; + sprite[j].shade = 0; + if (ball) { + sprite[j].xrepeat = 128; + sprite[j].yrepeat = 128; + } else { + sprite[j].xrepeat = 32; + sprite[j].yrepeat = 32; + } + sprite[j].pal = 0; + + sprite[j].owner = sprite[i].owner; + sprite[j].lotag = 256; + sprite[j].hitag = 0; +} + +void icecubes(int i, int x, int y, int z, int owner) { + int j = insertsprite(sprite[i].sectnum, FX); + + sprite[j].x = x; + sprite[j].y = y; + + sprite[j].z = sector[sprite[i].sectnum].floorz - (getPlayerHeight() << 8) + (krand() & 4096); + + //game.pInt.setsprinterpolate(j, sprite[j]); + + sprite[j].cstat = 0; // Hitscan does not hit smoke on wall + sprite[j].picnum = ICECUBE; + sprite[j].shade = -16; + sprite[j].xrepeat = 16; + sprite[j].yrepeat = 16; + + sprite[j].ang = (short) (((krand() & 1023) - 1024) & 2047); + sprite[j].xvel = (short) ((krand() & 1023) - 512); + sprite[j].yvel = (short) ((krand() & 1023) - 512); + sprite[j].zvel = (short) ((krand() & 1023) - 512); + + sprite[j].pal = 6; + sprite[j].owner = sprite[i].owner; + + if(isWh2()) + sprite[j].lotag = 2048; + else sprite[j].lotag = 999; + sprite[j].hitag = 0; + +} + +boolean damageactor(PLAYER& plr, int hitobject, short i) { + short j = (short) (hitobject & 4095); // j is the spritenum that the bullet (spritenum i) hit + if (j == plr.spritenum && sprite[i].owner == sprite[plr.spritenum].owner) + return false; + + if (j == plr.spritenum && sprite[i].owner != sprite[plr.spritenum].owner) { + if (plr.invincibletime > 0 || plr.godMode) { + deletesprite(i); + return false; + } + // EG 17 Oct 2017: Mass backport of RULES.CFG behavior for resist/onyx ring + // EG 21 Aug 2017: New RULES.CFG behavior in place of the old #ifdef + if (plr.manatime > 0) { + if (/* eg_resist_blocks_traps && */sprite[i].picnum != FATSPANK && sprite[i].picnum != PLASMA) { + deletesprite(i); + return false; + } + // Use "fixed" version: EXPLOSION and MONSTERBALL are the fire attacks, account + // for animation + // FATSPANK is right in the middle of this group of tiles, so still keep an + // exception for it. + else if ((sprite[i].picnum >= EXPLOSION && sprite[i].picnum <= (MONSTERBALL + 2) + && sprite[i].picnum != FATSPANK)) { + deletesprite(i); + return false; + } + } + // EG 21 Aug 2017: onyx ring + else if (plr.treasure[TONYXRING] == 1 /*&& eg_onyx_effect != 0*/ + && ((sprite[i].picnum < EXPLOSION || sprite[i].picnum > MONSTERBALL + 2) + && sprite[i].picnum != PLASMA)) { + +// if (eg_onyx_effect == 1 || (eg_onyx_effect == 2 && ((krand() & 32) > 16))) { + deletesprite(i); + return false; +// } + } + // EG 21 Aug 2017: Move this here so as not to make ouch sounds unless pain is + // happening + if ((krand() & 9) == 0) + playsound_loc(S_PLRPAIN1 + (rand() % 2), sprite[i].x, sprite[i].y); + + if (isWh2() && sprite[i].picnum == DART) { + plr.poisoned = 1; + plr.poisontime = 7200; + showmessage("Poisoned", 360); + } + + if (netgame) { +// netdamageactor(j,i); + } else { + if (sprite[i].picnum == PLASMA) + addhealth(plr, -((krand() & 15) + 15)); + else if (sprite[i].picnum == FATSPANK) { + playsound_loc(S_GORE1A + (krand() % 3), plr.x, plr.y); + addhealth(plr, -((krand() & 10) + 10)); + if ((krand() % 100) > 90) { + plr.poisoned = 1; + plr.poisontime = 7200; + showmessage("Poisoned", 360); + } + } else if (sprite[i].picnum == THROWPIKE) { + addhealth(plr, -((krand() % 10) + 5)); + } else + addhealth(plr, -((krand() & 20) + 5)); + } + + startredflash(10); + /* EG 2017 - Trap fix */ + deletesprite(i); + return true; + } + + if (j != plr.spritenum && !netgame) // Les 08/11/95 + if (sprite[i].owner != j) { + +// final int DEMONTYPE = 1; XXX +// final int DRAGONTYPE = 3; +// final int FISHTYPE = 5; +// final int JUDYTYPE = 12; +// final int RATTYPE = 18; +// final int SKULLYTYPE = 20; + + switch (sprite[j].detail) { + case NEWGUYTYPE: + case KURTTYPE: + case GONZOTYPE: + case KATIETYPE: + case GRONTYPE: + case KOBOLDTYPE: + case DEVILTYPE: + case FREDTYPE: + case GOBLINTYPE: + case IMPTYPE: + case MINOTAURTYPE: + case SPIDERTYPE: + case SKELETONTYPE: + case FATWITCHTYPE: + case WILLOWTYPE: + case GUARDIANTYPE: + if(isBlades(sprite[i].picnum)) { + sprite[j].hitag -= 30; + if(sprite[i].picnum == THROWPIKE) { + if ((krand() % 2) != 0) + playsound_loc(S_GORE1A + krand() % 2, sprite[i].x, sprite[i].y); + } + } else { + switch (sprite[i].picnum) { + case PLASMA: + sprite[j].hitag -= 40; + break; + case FATSPANK: + sprite[j].hitag -= 10; + break; + case MONSTERBALL: + sprite[j].hitag -= 40; + break; + case FIREBALL: + if(!isWh2()) + sprite[j].hitag -= 3; + break; + case BULLET: + sprite[j].hitag -= 10; + break; + case DISTORTIONBLAST: + sprite[j].hitag = 10; + break; + case BARREL: + sprite[j].hitag -= 100; + break; + } + } + + if (sprite[j].hitag <= 0) { + newstatus(j, DIE); + deletesprite(i); + } else + newstatus(j, PAIN); + return true; + } + + switch(sprite[j].detail) { + case GONZOTYPE: + case NEWGUYTYPE: + case KATIETYPE: + case GRONTYPE: + case KOBOLDTYPE: + case DEVILTYPE: + case FREDTYPE: + case GOBLINTYPE: + case MINOTAURTYPE: + case SPIDERTYPE: + case SKELETONTYPE: + case IMPTYPE: + // JSA_NEW //why is this here it's in whplr + // raf because monsters could shatter a guy thats been frozen + if (sprite[j].pal == 6) { + for (int k = 0; k < 32; k++) + icecubes(j, sprite[j].x, sprite[j].y, sprite[j].z, j); + // EG 26 Oct 2017: Move this here from medusa (anti multi-freeze exploit) + addscore(plr, 100); + deletesprite(j); + } + return true; + } + + switch (sprite[j].picnum) { + case BARREL: + case VASEA: + case VASEB: + case VASEC: + case STAINGLASS1: + case STAINGLASS2: + case STAINGLASS3: + case STAINGLASS4: + case STAINGLASS5: + case STAINGLASS6: + case STAINGLASS7: + case STAINGLASS8: + case STAINGLASS9: + sprite[j].hitag = 0; + sprite[j].lotag = 0; + newstatus(j, BROKENVASE); + break; + default: + deletesprite(i); + return true; + } + } + + return false; +} + +enum +{ + NORMALCLIP = 0, + PROJECTILECLIP = 1, + CLIFFCLIP = 2, +}; + +int movesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, int cliptype) { + + int daz, zoffs; + int retval; + short tempshort, dasectnum; + + SPRITE& spr = sprite[spritenum]; + if (spr.statnum == MAXSTATUS) + return (-1); + + //game.pInt.setsprinterpolate(spritenum, spr); + + int dcliptype = 0; + switch (cliptype) { + case NORMALCLIP: + dcliptype = CLIPMASK0; + break; + case PROJECTILECLIP: + dcliptype = CLIPMASK1; + break; + case CLIFFCLIP: + dcliptype = CLIPMASK0; + break; + } + + if ((spr.cstat & 128) == 0) + zoffs = -((tilesizy[spr.picnum] * spr.yrepeat) << 1); + else + zoffs = 0; + + dasectnum = spr.sectnum; // Can't modify sprite sectors directly becuase of linked lists + daz = spr.z + zoffs; // Must do this if not using the new centered centering (of course) + retval = clipmove(spr.x, spr.y, daz, dasectnum, dx, dy, (spr.clipdist) << 2, ceildist, flordist, + dcliptype); + + if (clipmove_sectnum != -1) { + spr.x = clipmove_x; + spr.y = clipmove_y; + daz = clipmove_z; + dasectnum = clipmove_sectnum; + } + + pushmove(spr.x, spr.y, daz, dasectnum, spr.clipdist << 2, ceildist, flordist, CLIPMASK0); + if(pushmove_sectnum != -1) { + spr.x = pushmove_x; + spr.y = pushmove_y; + daz = pushmove_z; + dasectnum = pushmove_sectnum; + } + + if ((dasectnum != spr.sectnum) && (dasectnum >= 0)) + changespritesect(spritenum, dasectnum); + + // Set the blocking bit to 0 temporarly so getzrange doesn't pick up + // its own sprite + tempshort = spr.cstat; + spr.cstat &= ~1; + getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, dcliptype); + spr.cstat = tempshort; + + daz = spr.z + zoffs + dz; + if ((daz <= zr_ceilz) || (daz > zr_florz)) { + if (retval != 0) + return (retval); + return (16384 | dasectnum); + } + spr.z = (daz - zoffs); + return (retval); +} + +void trowajavlin(int s) { + int j = insertsprite(sprite[s].sectnum, JAVLIN); + + sprite[j].x = sprite[s].x; + sprite[j].y = sprite[s].y; + sprite[j].z = sprite[s].z;// - (40 << 8); + + //game.pInt.setsprinterpolate(j, sprite[j]); + + sprite[j].cstat = 21; + + switch (sprite[s].lotag) { + case 91: + sprite[j].picnum = WALLARROW; + sprite[j].ang = (short) (((sprite[s].ang + 2048) - 512) & 2047); + sprite[j].xrepeat = 16; + sprite[j].yrepeat = 48; + sprite[j].clipdist = 24; + break; + case 92: + sprite[j].picnum = DART; + sprite[j].ang = (short) (((sprite[s].ang + 2048) - 512) & 2047); + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].clipdist = 16; + break; + case 93: + sprite[j].picnum = HORIZSPIKEBLADE; + sprite[j].ang = (short) (((sprite[s].ang + 2048) - 512) & 2047); + sprite[j].xrepeat = 16; + sprite[j].yrepeat = 48; + sprite[j].clipdist = 32; + break; + case 94: + sprite[j].picnum = THROWPIKE; + sprite[j].ang = (short) (((sprite[s].ang + 2048) - 512) & 2047); + sprite[j].xrepeat = 24; + sprite[j].yrepeat = 24; + sprite[j].clipdist = 32; + break; + } + + sprite[j].extra = sprite[s].ang; + sprite[j].shade = -15; + sprite[j].xvel = (short) ((krand() & 256) - 128); + sprite[j].yvel = (short) ((krand() & 256) - 128); + sprite[j].zvel = (short) ((krand() & 256) - 128); + + sprite[j].owner = 0; + sprite[j].lotag = 0; + sprite[j].hitag = 0; + sprite[j].pal = 0; +} + +void spawnhornskull(short i) { + short j = insertsprite(sprite[i].sectnum, (short) 0); + sprite[j].x = sprite[i].x; + sprite[j].y = sprite[i].y; + sprite[j].z = sprite[i].z - (24 << 8); + + //game.pInt.setsprinterpolate(j, sprite[j]); + + sprite[j].shade = -15; + sprite[j].cstat = 0; + sprite[j].cstat &= ~3; + sprite[j].pal = 0; + sprite[j].picnum = HORNEDSKULL; + sprite[j].detail = HORNEDSKULLTYPE; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; +} + +void spawnapentagram(int sn) { + short j = insertsprite(sprite[sn].sectnum, (short) 0); + + sprite[j].x = sprite[sn].x; + sprite[j].y = sprite[sn].y; + sprite[j].z = sprite[sn].z - (8 << 8); + + //game.pInt.setsprinterpolate(j, sprite[j]); + + sprite[j].xrepeat = sprite[j].yrepeat = 64; + sprite[j].pal = 0; + sprite[j].shade = -15; + sprite[j].cstat = 0; + sprite[j].clipdist = 64; + sprite[j].lotag = 0; + sprite[j].hitag = 0; + sprite[j].extra = 0; + sprite[j].picnum = PENTAGRAM; + sprite[j].detail = PENTAGRAMTYPE; + + setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z); +} + +END_WH_NS \ No newline at end of file diff --git a/source/games/whaven/src/whplr.cpp b/source/games/whaven/src/whplr.cpp new file mode 100644 index 000000000..fe8276b0d --- /dev/null +++ b/source/games/whaven/src/whplr.cpp @@ -0,0 +1,601 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + + PLAYER player[MAXPLAYERS]; + PLOCATION gPrevPlayerLoc[MAXPLAYERS]; + + short monsterangle[MAXSPRITESONSCREEN], monsterlist[MAXSPRITESONSCREEN]; + int shootgunzvel; + + boolean justteleported; + + int victor = 0; + int autohoriz = 0; // XXX NOT FOR MULTIPLAYER + + int pyrn; + int mapon; + int damage_vel, damage_svel, damage_angvel; + + void viewBackupPlayerLoc( int nPlayer ) + { + SPRITE& pSprite = sprite[player[nPlayer].spritenum]; + PLOCATION pPLocation = gPrevPlayerLoc[nPlayer]; + pPLocation.x = pSprite.x; + pPLocation.y = pSprite.y; + pPLocation.z = player[nPlayer].z; + pPLocation.ang = player[nPlayer].ang; + pPLocation.horiz = player[nPlayer].horiz + player[nPlayer].jumphoriz; + } + + void playerdead(PLAYER& plr) { + if (plr.dead) + return; + + if (plr.potion[0] > 0 && plr.spiked == 0) { + int i = plr.currentpotion; + plr.currentpotion = 0; + usapotion(plr); + plr.currentpotion = i; + return; + } + + plr.currspikeframe = 0; + + if (plr.spiked == 1) { + plr.spiketics = spikeanimtics[0].daweapontics; + playsound_loc(S_GORE1, plr.x, plr.y); + SND_Sound(S_HEARTBEAT); + } + + SND_Sound(S_PLRDIE1); + +// netsendmove(); + plr.dead = true; + } + + void initplayersprite(PLAYER& plr) { + if (difficulty > 1) { + plr.currweapon = 1; + plr.selectedgun = 1; + } else { + plr.currweapon = 4; + plr.selectedgun = 4; + } + plr.currentpotion = 0; + plr.helmettime = -1; + plr.shadowtime = -1; + plr.nightglowtime = -1; + plr.strongtime = -1; + plr.invisibletime = -1; + plr.manatime = -1; + plr.currentorb = 0; + plr.currweaponfired = 3; + plr.currweaponanim = 0; + plr.currweaponattackstyle = 0; + plr.currweaponflip = 0; + + plr.vampiretime = 0; + plr.shieldpoints = 0; + plr.shieldtype = 0; + plr.dead = false; + plr.spiked = 0; + plr.shockme = -1; + plr.poisoned = 0; + plr.poisontime = -1; + + plr.oldsector = plr.sector; + plr.horiz = 100; + plr.height = getPlayerHeight(); + plr.z = sector[plr.sector].floorz - (plr.height << 8); + + plr.spritenum = (short) insertsprite(plr.sector, (short) 0); + + plr.onsomething = 1; + + sprite[plr.spritenum].x = plr.x; + sprite[plr.spritenum].y = plr.y; + sprite[plr.spritenum].z = plr.z + (plr.height << 8); + sprite[plr.spritenum].cstat = 1 + 256; + sprite[plr.spritenum].picnum = isWh2() ? GRONSW : FRED; + sprite[plr.spritenum].shade = 0; + sprite[plr.spritenum].xrepeat = 36; + sprite[plr.spritenum].yrepeat = 36; + sprite[plr.spritenum].ang = (short) plr.ang; + sprite[plr.spritenum].xvel = 0; + sprite[plr.spritenum].yvel = 0; + sprite[plr.spritenum].zvel = 0; + sprite[plr.spritenum].owner = (short) (4096 + myconnectindex); + sprite[plr.spritenum].lotag = 0; + sprite[plr.spritenum].hitag = 0; + sprite[plr.spritenum].pal = (short) (isWh2() ? 10 : 1); + if(isWh2()) + sprite[plr.spritenum].clipdist = 48; + + plr.selectedgun = 0; + + if(isWh2()) { + for (int i = 0; i <= 9; i++) { + if (i < 5) { + plr.ammo[i] = 40; + plr.weapon[i] = 1; + } else { + plr.ammo[i] = 0; + plr.weapon[i] = 0; + } + if (i < 8) { + plr.orb[i] = 0; + plr.orbammo[i] = 0; + } + } + + if (difficulty > 1) { + plr.weapon[0] = plr.weapon[1] = 1; + plr.ammo[0] = 32000; + plr.ammo[1] = 45; + } + + } else { + + if (difficulty > 1) { + for (int i = 0; i <= 9; i++) { + plr.ammo[i] = 0; + plr.weapon[i] = 0; + if (i < 8) { + plr.orb[i] = 0; + plr.orbammo[i] = 0; + } + } + plr.weapon[0] = plr.weapon[1] = 1; + plr.ammo[0] = 32000; + plr.ammo[1] = 45; + } else { + for (int i = 0; i <= 9; i++) { + plr.ammo[i] = 0; + plr.weapon[i] = 0; + if (i < 5) { + plr.ammo[i] = 40; + plr.weapon[i] = 1; + } + if (i < 8) { + plr.orb[i] = 0; + plr.orbammo[i] = 0; + } + } + } + } + + for (int i = 0; i < MAXPOTIONS; i++) + plr.potion[i] = 0; + for (int i = 0; i < MAXTREASURES; i++) + plr.treasure[i] = 0; + + plr.lvl = 1; + plr.score = 0; + plr.health = 100; + plr.maxhealth = 100; + plr.armor = 0; + plr.armortype = 0; + plr.currentorb = 0; + plr.currentpotion = 0; + + if (difficulty > 1) + plr.currweapon = plr.selectedgun = 1; + else + plr.currweapon = plr.selectedgun = 4; + + if (isWh2()) { + plr.potion[0] = 3; + plr.potion[3] = 1; + plr.currweapon = plr.selectedgun = 4; + } + + plr.currweaponfired = 3; + plr.currweaponflip = 0; + + for (int i = 0; i < MAXNUMORBS; i++) + plr.orbactive[i] = -1; + + lockclock = totalclock; + playertorch = 0; + + plr.spellbookflip = 0; + + plr.invincibletime = plr.manatime = -1; + plr.hasshot = 0; + plr.orbshot = 0; + displaytime = -1; + plr.shadowtime = -1; + plr.helmettime = -1; + plr.nightglowtime = -1; + plr.strongtime = -1; + plr.invisibletime = -1; + } + + void updateviewmap(PLAYER& plr) { + int i; + if ((i = plr.sector) > -1) { + int wallid = sector[i].wallptr; + show2dsector[i >> 3] |= (1 << (i & 7)); + for (int j = sector[i].wallnum; j > 0; j--) { + WALL wal = wall[wallid++]; + i = wal.nextsector; + if (i < 0) + continue; + if ((wal.cstat & 0x0071) != 0) + continue; + if (wall[wal.nextwall] != nullptr && (wall[wal.nextwall].cstat & 0x0071) != 0) + continue; + if (sector[i] != nullptr && sector[i].ceilingz >= sector[i].floorz) + continue; + show2dsector[i >> 3] |= (1 << (i & 7)); + } + } + } + + void plruse(PLAYER& plr) { + neartag(plr.x, plr.y, plr.z, (short) plr.sector, (short) plr.ang, neartag, 1024, 3); + + if (neartag.tagsector >= 0) { + if (sector[neartag.tagsector].hitag == 0) { + operatesector(plr, neartag.tagsector); + } else { + short daang = (short) plr.ang; + int daz2 = (int) (100 - plr.horiz) * 2000; + hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position + sintable[(daang + 2560) & 2047], // X vector of 3D ang + sintable[(daang + 2048) & 2047], // Y vector of 3D ang + daz2, // Z vector of 3D ang + pHitInfo, CLIPMASK1); + + if (pHitInfo.hitwall >= 0) { + if ((klabs(plr.x - pHitInfo.hitx) + klabs(plr.y - pHitInfo.hity) < 512) + && (klabs((plr.z >> 8) - ((pHitInfo.hitz >> 8) - (64))) <= (512 >> 3))) { + int pic = wall[pHitInfo.hitwall].picnum; + if(pic == PENTADOOR1 || pic == PENTADOOR2 || (pic >= PENTADOOR3 && pic <= PENTADOOR7)) + showmessage("find door trigger", 360); + } + } + playsound_loc(S_PUSH1 + (krand() % 2), plr.x, plr.y); + } + } + if (neartag.tagsprite >= 0) { + if (sprite[neartag.tagsprite].lotag == 1) { + if(sprite[neartag.tagsprite].picnum == PULLCHAIN1 || sprite[neartag.tagsprite].picnum == SKULLPULLCHAIN1) { + sprite[neartag.tagsprite].lotag = 0; + newstatus(neartag.tagsprite, PULLTHECHAIN); + } else if(sprite[neartag.tagsprite].picnum == LEVERUP) { + sprite[neartag.tagsprite].lotag = 0; + newstatus(neartag.tagsprite, ANIMLEVERUP); + } + for (int i = 0; i < numsectors; i++) + if (sector[i].hitag == sprite[neartag.tagsprite].hitag) + operatesector(plr, i); + } else + operatesprite(plr, neartag.tagsprite); + } + } + + void chunksofmeat(PLAYER& plr, int hitsprite, int hitx, int hity, int hitz, short hitsect, int daang) { + + int j; + short k; + short zgore = 0; + int chunk = REDCHUNKSTART; + int newchunk; + + if (!whcfg.gGameGore) + return; + + if (sprite[hitsprite].picnum == JUDY || sprite[hitsprite].picnum == JUDYATTACK1 + || sprite[hitsprite].picnum == JUDYATTACK2) + return; + + switch (plr.selectedgun) { + case 1: + case 2: + zgore = 1; + break; + case 3: + case 4: + zgore = 2; + break; + case 5: + zgore = 3; + break; + case 6: + zgore = 1; + break; + case 7: + zgore = 2; + break; + case 8: + case 9: + zgore = 3; + break; + } + + if (sprite[hitsprite].statnum == NUKED) { + zgore = 32; + } + + if (sprite[hitsprite].picnum == RAT) + zgore = 1; + + if (sprite[hitsprite].picnum == WILLOW || sprite[hitsprite].picnum == WILLOWEXPLO + || sprite[hitsprite].picnum == WILLOWEXPLO + 1 || sprite[hitsprite].picnum == WILLOWEXPLO + 2 + || sprite[hitsprite].picnum == GUARDIAN || sprite[hitsprite].picnum == GUARDIANATTACK + || sprite[hitsprite].picnum == DEMON) + return; + + if (sprite[hitsprite].picnum == SKELETON || sprite[hitsprite].picnum == SKELETONATTACK + || sprite[hitsprite].picnum == SKELETONDIE) { + playsound_loc(S_SKELHIT1 + (krand() % 2), sprite[hitsprite].x, sprite[hitsprite].y); + } else { + if (krand() % 100 > 60) + playsound_loc(S_GORE1 + (krand() % 4), sprite[hitsprite].x, sprite[hitsprite].y); + } + + if ((hitsprite >= 0) && (sprite[hitsprite].statnum < MAXSTATUS)) { + for (k = 0; k < zgore; k++) { + newchunk = 0; + + j = insertsprite(hitsect, CHUNKOMEAT); + if(j == -1) + return; + sprite[j].x = hitx; + sprite[j].y = hity; + sprite[j].z = hitz; + sprite[j].cstat = 0; + if (krand() % 100 > 50) { + switch (sprite[hitsprite].detail) { + case GRONTYPE: + chunk = REDCHUNKSTART + (krand() % 8); + break; + case KOBOLDTYPE: + if (sprite[hitsprite].pal == 0) + chunk = BROWNCHUNKSTART + (krand() % 8); + if (sprite[hitsprite].pal == 4) + chunk = GREENCHUNKSTART + (krand() % 8); + if (sprite[hitsprite].pal == 7) + chunk = REDCHUNKSTART + (krand() % 8); + break; + case DRAGONTYPE: + chunk = GREENCHUNKSTART + (krand() % 8); + break; + case DEVILTYPE: + chunk = REDCHUNKSTART + (krand() % 8); + break; + case FREDTYPE: + chunk = BROWNCHUNKSTART + (krand() % 8); + break; + case GOBLINTYPE: + case IMPTYPE: + if(isWh2() && (sprite[hitsprite].picnum == IMP || sprite[hitsprite].picnum == IMPATTACK)) { + if (sprite[hitsprite].pal == 0) + chunk = GREENCHUNKSTART + (krand() % 8); + } else { + if (sprite[hitsprite].pal == 0) + chunk = GREENCHUNKSTART + (krand() % 8); + if (sprite[hitsprite].pal == 4) + chunk = BROWNCHUNKSTART + (krand() % 8); + if (sprite[hitsprite].pal == 5) + chunk = TANCHUNKSTART + (krand() % 8); + } + break; + case MINOTAURTYPE: + chunk = TANCHUNKSTART + (krand() % 8); + break; + case SPIDERTYPE: + chunk = GREYCHUNKSTART + (krand() % 8); + break; + case SKULLYTYPE: + case FATWITCHTYPE: + case JUDYTYPE: + chunk = REDCHUNKSTART + (krand() % 8); + break; + } + } else { + newchunk = 1; + if (!isWh2()) + chunk = NEWCHUNK + (krand() % 9); + else + chunk = REDCHUNKSTART + (krand() % 8); + } + + if (sprite[hitsprite].detail == SKELETONTYPE) + chunk = BONECHUNK1 + (krand() % 9); + + if (plr.weapon[2] == 3 && plr.currweapon == 2) { + sprite[j].picnum = ARROWFLAME; + } else { + sprite[j].picnum = (short) chunk; // = REDCHUNKSTART + (rand() % 8); + } + + sprite[j].shade = -16; + sprite[j].xrepeat = 64; + sprite[j].yrepeat = 64; + sprite[j].clipdist = 16; + sprite[j].ang = (short) (((krand() & 1023) - 1024) & 2047); + sprite[j].xvel = (short) ((krand() & 1023) - 512); + sprite[j].yvel = (short) ((krand() & 1023) - 512); + sprite[j].zvel = (short) ((krand() & 1023) - 512); + if (newchunk == 1) + sprite[j].zvel <<= 1; + sprite[j].owner = sprite[plr.spritenum].owner; + sprite[j].lotag = 512; + sprite[j].hitag = 0; + sprite[j].pal = 0; + movesprite((short) j, ((sintable[(sprite[j].ang + 512) & 2047]) * TICSPERFRAME) << 3, + ((sintable[sprite[j].ang & 2047]) * TICSPERFRAME) << 3, 0, 4 << 8, 4 << 8, 0); + } + } + + } + + void addhealth(PLAYER& plr, int hp) { + if (plr.godMode && hp < 0) + return; + + plr.health += hp; + + if (plr.health < 0) + plr.health = 0; + } + + void addarmor(PLAYER& plr, int arm) { + plr.armor += arm; + + if (plr.armor < 0) { + plr.armor = 0; + plr.armortype = 0; + } + } + + void addscore(PLAYER& plr, int score) { + if(plr == nullptr) return; + + plr.score += score; + expgained += score; + + goesupalevel(plr); + } + + void goesupalevel(PLAYER& plr) { + if (isWh2()) + goesupalevel2(plr); + else + goesupalevel1(plr); + } + + void goesupalevel2(PLAYER& plr) { + switch (plr.lvl) { + case 0: + case 1: + if (plr.score > 9999) { + showmessage("thou art a warrior", 360); + plr.lvl = 2; + plr.maxhealth = 120; + } + break; + case 2: + if (plr.score > 19999) { + showmessage("thou art a swordsman", 360); + plr.lvl = 3; + plr.maxhealth = 140; + } + break; + case 3: + if (plr.score > 29999) { + showmessage("thou art a hero", 360); + plr.lvl = 4; + plr.maxhealth = 160; + } + break; + case 4: + if (plr.score > 39999) { + showmessage("thou art a champion", 360); + plr.lvl = 5; + plr.maxhealth = 180; + } + break; + case 5: + if (plr.score > 49999) { + showmessage("thou art a superhero", 360); + plr.lvl = 6; + plr.maxhealth = 200; + } + break; + case 6: + if (plr.score > 59999) { + showmessage("thou art a lord", 360); + plr.lvl = 7; + } + } + } + + void goesupalevel1(PLAYER& plr) { + if (plr.score > 2250 && plr.score < 4499 && plr.lvl < 2) { + showmessage("thou art 2nd level", 360); + plr.lvl = 2; + plr.maxhealth = 120; + } else if (plr.score > 4500 && plr.score < 8999 && plr.lvl < 3) { + showmessage("thou art 3rd level", 360); + plr.lvl = 3; + plr.maxhealth = 140; + } else if (plr.score > 9000 && plr.score < 17999 && plr.lvl < 4) { + showmessage("thou art 4th level", 360); + plr.lvl = 4; + plr.maxhealth = 160; + } else if (plr.score > 18000 && plr.score < 35999 && plr.lvl < 5) { + showmessage("thou art 5th level", 360); + plr.lvl = 5; + plr.maxhealth = 180; + } else if (plr.score > 36000 && plr.score < 74999 && plr.lvl < 6) { + showmessage("thou art 6th level", 360); + plr.lvl = 6; + plr.maxhealth = 200; + } else if (plr.score > 75000 && plr.score < 179999 && plr.lvl < 7) { + showmessage("thou art 7th level", 360); + plr.lvl = 7; + } else if (plr.score > 180000 && plr.score < 279999 && plr.lvl < 8) { + showmessage("thou art 8th level", 360); + plr.lvl = 8; + } else if (plr.score > 280000 && plr.score < 379999 && plr.lvl < 9) { + showmessage("thou art hero", 360); + plr.lvl = 9; + } + } + + void lockon(PLAYER& plr, int numshots, int shootguntype) { + short daang, i, k, n = 0, s; + SPRITE spr; + + for (i = 0; i < tspritelistcnt && n < numshots; i++) { + spr = tspritelist[i]; + + if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7), + spr.sectnum)) { + switch (spr.detail) { + case KOBOLDTYPE: + case DEVILTYPE: + case IMPTYPE: + case MINOTAURTYPE: + case SKELETONTYPE: + case GRONTYPE: + case DEMONTYPE: + case GUARDIANTYPE: + case WILLOWTYPE: + case NEWGUYTYPE: + case KURTTYPE: + case GONZOTYPE: + case KATIETYPE: + monsterangle[n] = getangle(tspritelist[i].x - plr.x, tspritelist[i].y - plr.y); + monsterlist[n] = i; + n++; + break; + } + } + } + + daang = (short) (plr.ang - ((numshots * (128 / numshots)) >> 1)); + for (k = 0, s = 0; k < numshots; k++) { + if (n > 0) { + spr = tspritelist[monsterlist[s]]; + daang = monsterangle[s]; + shootgunzvel = ((spr.z - (48 << 8) - plr.z) << 8) + / ksqrt((spr.x - plr.x) * (spr.x - plr.x) + (spr.y - plr.y) * (spr.y - plr.y)); + s = (short) ((s + 1) % n); + } else { + daang += (128 / numshots); + } + shootgun(plr, daang, shootguntype); + } + } + + int getPlayerHeight() + { + return isWh2() ? WH2PLAYERHEIGHT : PLAYERHEIGHT; + } +} diff --git a/source/games/whaven/src/whtag.cpp b/source/games/whaven/src/whtag.cpp new file mode 100644 index 000000000..ba59cdadb --- /dev/null +++ b/source/games/whaven/src/whtag.cpp @@ -0,0 +1,1037 @@ +#include "ns.h" +#include "wh.h" + +BEGIN_WH_NS + +int d_soundplayed = 0; +int delaycnt; +Delayitem delayitem[MAXSECTORS]; + +short ironbarsector[16]; +short ironbarscnt; +int ironbarsgoal1[16], ironbarsgoal2[16]; +short ironbarsdone[16], ironbarsanim[16]; +int ironbarsgoal[16]; + +short warpsectorlist[64], warpsectorcnt; +short xpanningsectorlist[16], xpanningsectorcnt; +short ypanningwalllist[128], ypanningwallcnt; +short floorpanninglist[64], floorpanningcnt; +SwingDoor swingdoor[MAXSWINGDOORS]; +short swingcnt; + +short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt; +int dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16]; + + +void operatesprite(PLAYER& plr, short s) { + if (sprite[s].picnum == SPAWNFIREBALL) + newstatus(s, DEVILFIRE); + if (sprite[s].picnum == SPAWNJAVLIN) + trowajavlin(s); + + switch (sprite[s].picnum) { + case STONEGONZOCHM: + case STONEGONZOGSH: + case STONEGRONDOVAL: + case STONEGONZOBSW: + sprite[s].lotag *= 120; + changespritestat((short) s, STONETOFLESH); + break; + case GONZOHMJUMP: + case GONZOSHJUMP: + newstatus((short) s, AMBUSH); + break; + case STAINGLASS1: + case STAINGLASS2: + case STAINGLASS3: + case STAINSKULL: + case STAINHEAD: + case STAINSNAKE: + case STAINCIRCLE: + case STAINQ: + case STAINSCENE: + switch (sprite[s].lotag) { + case 2: + playsound_loc(S_GLASSBREAK1 + (rand() % 3), sprite[s].x, sprite[s].y); + for (int j = 0; j < 20; j++) { + shards(s, 2); + } + deletesprite((short) s); + break; + } + break; + } + + if ((sprite[s].lotag == 1800 || sprite[s].lotag == 1810 || sprite[s].lotag == 1820) + && sprite[s].sectnum == plr.sector) { + for (short j = 0; j < MAXSPRITES; j++) { + if (sprite[s].sectnum == sprite[j].sectnum && (sprite[j].lotag >= 1800 && sprite[j].lotag <= 1899)) + newstatus(j, LIFTDN); + } + } + if ((sprite[s].lotag == 1801 || sprite[s].lotag == 1811 || sprite[s].lotag == 1821) + && sprite[s].sectnum == plr.sector) { + for (short j = 0; j < MAXSPRITES; j++) { + if (sprite[s].sectnum == sprite[j].sectnum && (sprite[j].lotag >= 1800 && sprite[j].lotag <= 1899)) + newstatus(j, LIFTUP); + } + } +} + + +void operatesector(PLAYER& plr, int s) { + int botz, dax2, day2, goalz, i, j, size, topz; + int daz; + int doorantic, doorkey, doortype; + + int temp1, temp2, temp3; + short k; + + int keysok = 0; + int datag = sector[s].lotag; + int startwall = sector[s].wallptr; + int endwall = startwall + sector[s].wallnum - 1; + int centx = 0, centy = 0; + int opwallfind[2] = {}; + + for (i = startwall; i <= endwall; i++) { + centx += wall[i].x; + centy += wall[i].y; + } + centx /= (endwall - startwall + 1); + centy /= (endwall - startwall + 1); + + switch (datag) { + case 61: + case 131: + // check for proper key + if (plr.treasure[TBRASSKEY] == 0) { + keysok = 0; + showmessage("BRASS KEY NEEDED", 360); + } else + keysok = 1; + break; + case 62: + case 132: + // check for proper key + if (plr.treasure[TBLACKKEY] == 0) { + keysok = 0; + showmessage("Black KEY NEEDED", 360); + } else + keysok = 1; + break; + case 63: + case 133: + // check for proper key + if (plr.treasure[TGLASSKEY] == 0) { + keysok = 0; + showmessage("glass KEY NEEDED", 360); + } else + keysok = 1; + break; + case 64: + case 134: + if (plr.treasure[TIVORYKEY] == 0) { + keysok = 0; + showmessage("ivory KEY NEEDED", 360); + } else + keysok = 1; + break; + case 71: + // check for proper key + if (plr.treasure[TBRASSKEY] == 0) { + keysok = 0; + showmessage("BRASS KEY NEEDED", 360); + } else + keysok = 1; + break; + case 72: + // check for proper key + if (plr.treasure[TBLACKKEY] == 0) { + keysok = 0; + showmessage("black KEY NEEDED", 360); + } else + keysok = 1; + break; + case 73: + // check for proper key + if (plr.treasure[TGLASSKEY] == 0) { + keysok = 0; + showmessage("glass KEY NEEDED", 360); + } else + keysok = 1; + break; + case 74: + if (plr.treasure[TIVORYKEY] == 0) { + keysok = 0; + showmessage("Ivory KEY NEEDED", 360); + } else + keysok = 1; + break; + } + + switch (datag) { + case DOORBOX: + opwallfind[0] = -1; + opwallfind[1] = -1; + for (i = startwall; i <= endwall; i++) { + if (wall[i].lotag == 6) { + if (opwallfind[0] == -1) + opwallfind[0] = i; + else + opwallfind[1] = i; + } + } + + for (j = 0; j < 2; j++) { + if(opwallfind[j] == -1) + break; + + if ((((wall[opwallfind[j]].x + wall[wall[opwallfind[j]].point2].x) >> 1) == centx) + && (((wall[opwallfind[j]].y + wall[wall[opwallfind[j]].point2].y) >> 1) == centy)) { + i = opwallfind[j] - 1; + if (i < startwall) + i = endwall; + dax2 = wall[i].x - wall[opwallfind[j]].x; + day2 = wall[i].y - wall[opwallfind[j]].y; + if (dax2 != 0) { + dax2 = wall[wall[wall[wall[opwallfind[j]].point2].point2].point2].x; + dax2 -= wall[wall[wall[opwallfind[j]].point2].point2].x; + setanimation(opwallfind[j], wall[opwallfind[j]].x + dax2, 4, 0, WALLX); + setanimation(i, wall[i].x + dax2, 4, 0, WALLX); + setanimation(wall[opwallfind[j]].point2, wall[wall[opwallfind[j]].point2].x + dax2, 4, 0, + WALLX); + setanimation(wall[wall[opwallfind[j]].point2].point2, + wall[wall[wall[opwallfind[j]].point2].point2].x + dax2, 4, 0, WALLX); + } else if (day2 != 0) { + day2 = wall[wall[wall[wall[opwallfind[j]].point2].point2].point2].y; + day2 -= wall[wall[wall[opwallfind[j]].point2].point2].y; + setanimation(opwallfind[j], wall[opwallfind[j]].y + day2, 4, 0, WALLY); + setanimation(i, wall[i].y + day2, 4, 0, WALLY); + setanimation(wall[opwallfind[j]].point2, wall[wall[opwallfind[j]].point2].y + day2, 4, 0, + WALLY); + setanimation(wall[wall[opwallfind[j]].point2].point2, + wall[wall[wall[opwallfind[j]].point2].point2].y + day2, 4, 0, WALLY); + } + } else { + i = opwallfind[j] - 1; + if (i < startwall) + i = endwall; + dax2 = wall[i].x - wall[opwallfind[j]].x; + day2 = wall[i].y - wall[opwallfind[j]].y; + if (dax2 != 0) { + setanimation(opwallfind[j], centx, 4, 0, WALLX); + setanimation(i, centx + dax2, 4, 0, WALLX); + setanimation(wall[opwallfind[j]].point2, centx, 4, 0, WALLX); + setanimation(wall[wall[opwallfind[j]].point2].point2, centx + dax2, 4, 0, WALLX); + } else if (day2 != 0) { + setanimation(opwallfind[j], centy, 4, 0, WALLY); + setanimation(i, centy + day2, 4, 0, WALLY); + setanimation(wall[opwallfind[j]].point2, centy, 4, 0, WALLY); + setanimation(wall[wall[opwallfind[j]].point2].point2, centy + day2, 4, 0, WALLY); + } + } + } + + SND_Sound(S_DOOR2); + + break; + case DOORUPTAG: // a door that opens up + i = getanimationgoal(sector[s], 2); + if (i >= 0) { + goalz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + if (gAnimationData[i].goal == goalz) { + gAnimationData[i].goal = sector[s].floorz; + } else { + gAnimationData[i].goal = goalz; + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + goalz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + + } else { + goalz = sector[s].floorz; + + } + setanimation(s, goalz, DOORSPEED, 0, CEILZ); + } + SND_Sound(S_DOOR2); + break; + + case DOORDOWNTAG: // a door that opens down + i = getanimationgoal(sector[s], 1); + if (i >= 0) { + goalz = sector[nextsectorneighborz(s, sector[s].ceilingz, 1, 1)].floorz; + if (gAnimationData[i].goal == goalz) { + gAnimationData[i].goal = sector[s].ceilingz; + } else { + gAnimationData[i].goal = goalz; + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + goalz = sector[nextsectorneighborz(s, sector[s].ceilingz, 1, 1)].floorz; + } else { + goalz = sector[s].ceilingz; + } + setanimation(s, goalz, DOORSPEED, 0, FLOORZ); + } + SND_Sound(S_DOOR1); + break; + + case PLATFORMELEVTAG: + i = getanimationgoal(sector[s], 1); + goalz = sector[plr.sector].floorz; + if (i >= 0) { + gAnimationData[i].goal = goalz; + } else { + setanimation(s, goalz, ELEVSPEED, 0, FLOORZ); + } + break; + case BOXELEVTAG: + i = getanimationgoal(sector[s], 1); + j = getanimationgoal(sector[s], 2); + size = sector[s].ceilingz - sector[s].floorz; + goalz = sector[plr.sector].floorz; + if (i >= 0) { + + gAnimationData[i].goal = goalz; + } else { + setanimation(s, goalz, ELEVSPEED, 0, FLOORZ); + } + goalz = goalz + size; + if (j >= 0) { + gAnimationData[j].goal = goalz; + } else { + setanimation(s, goalz, ELEVSPEED, 0, CEILZ); + } + break; + case DOORSPLITHOR: + i = getanimationgoal(sector[s], 1); + j = getanimationgoal(sector[s], 2); + if (i >= 0) { + botz = sector[nextsectorneighborz(s, sector[s].ceilingz, 1, 1)].floorz; + if (gAnimationData[i].goal == botz) { + gAnimationData[i].goal = (sector[s].ceilingz + sector[s].floorz) >> 1; + } else { + gAnimationData[i].goal = botz; + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + botz = sector[nextsectorneighborz(s, sector[s].ceilingz, 1, 1)].floorz; + + } else { + botz = (sector[s].ceilingz + sector[s].floorz) >> 1; + + } + setanimation(s, botz, ELEVSPEED, 0, FLOORZ); + } + if (j >= 0) { + topz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + if (gAnimationData[j].goal == topz) { + gAnimationData[j].goal = (sector[s].ceilingz + sector[s].floorz) >> 1; + } else { + gAnimationData[j].goal = topz; + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + topz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + } else { + topz = (sector[s].ceilingz + sector[s].floorz) >> 1; + } + setanimation(s, topz, ELEVSPEED, 0, CEILZ); + } + SND_Sound(S_DOOR1 + (krand() % 3)); + break; + case DOORSPLITVER: + + opwallfind[0] = -1; + opwallfind[1] = -1; + for (i = startwall; i <= endwall; i++) + if ((wall[i].x == centx) || (wall[i].y == centy)) { + if (opwallfind[0] == -1) + opwallfind[0] = i; + else + opwallfind[1] = i; + } + + for (j = 0; j < 2; j++) { + if ((wall[opwallfind[j]].x == centx) && (wall[opwallfind[j]].y == centy)) { + i = opwallfind[j] - 1; + if (i < startwall) + i = endwall; + dax2 = ((wall[i].x + wall[wall[opwallfind[j]].point2].x) >> 1) - wall[opwallfind[j]].x; + day2 = ((wall[i].y + wall[wall[opwallfind[j]].point2].y) >> 1) - wall[opwallfind[j]].y; + if (dax2 != 0) { + dax2 = wall[wall[wall[opwallfind[j]].point2].point2].x; + dax2 -= wall[wall[opwallfind[j]].point2].x; + setanimation(opwallfind[j], wall[opwallfind[j]].x + dax2, 4, 0, WALLX); + setanimation(i, wall[i].x + dax2, 4, 0, WALLX); + setanimation(wall[opwallfind[j]].point2, wall[wall[opwallfind[j]].point2].x + dax2, 4, 0, + WALLX); + } else if (day2 != 0) { + day2 = wall[wall[wall[opwallfind[j]].point2].point2].y; + day2 -= wall[wall[opwallfind[j]].point2].y; + setanimation(opwallfind[j], wall[opwallfind[j]].y + day2, 4, 0, WALLY); + setanimation(i, wall[i].y + day2, 4, 0, WALLY); + setanimation(wall[opwallfind[j]].point2, wall[wall[opwallfind[j]].point2].y + day2, 4, 0, + WALLY); + } + } else { + i = opwallfind[j] - 1; + if (i < startwall) + i = endwall; + dax2 = ((wall[i].x + wall[wall[opwallfind[j]].point2].x) >> 1) - wall[opwallfind[j]].x; + day2 = ((wall[i].y + wall[wall[opwallfind[j]].point2].y) >> 1) - wall[opwallfind[j]].y; + if (dax2 != 0) { + setanimation(opwallfind[j], centx, 4, 0, WALLX); + setanimation(i, centx + dax2, 4, 0, WALLX); + setanimation(wall[opwallfind[j]].point2, centx + dax2, 4, 0, WALLX); + } else if (day2 != 0) { + setanimation(opwallfind[j], centy, 4, 0, WALLY); + setanimation(i, centy + day2, 4, 0, WALLY); + setanimation(wall[opwallfind[j]].point2, centy + day2, 4, 0, WALLY); + } + } + } + break; + + case 131: + if (keysok == 0) + break; + else { + playsound(S_CREAKDOOR2, 0, 0, 0); + d_soundplayed = 1; + } + + case 132: + if (keysok == 0) + break; + else { + playsound(S_CREAKDOOR2, 0, 0, 0); + d_soundplayed = 1; + } + + case 133: + if (keysok == 0) + break; + else { + playsound(S_CREAKDOOR2, 0, 0, 0); + d_soundplayed = 1; + } + + case 134: + if (keysok == 0) + break; + else { + playsound(S_CREAKDOOR2, 0, 0, 0); + d_soundplayed = 1; + } + + case DOORSWINGTAG: + if (isWh2() && d_soundplayed == 0) + playsound(S_SWINGDOOR, 0, 0, 0); + else d_soundplayed = 1; + + for (i = 0; i < swingcnt; i++) { + if (swingdoor[i].sector == s) { + if (swingdoor[i].anginc == 0) { + if (swingdoor[i].ang == swingdoor[i].angclosed) { + swingdoor[i].anginc = swingdoor[i].angopendir; + } else { + swingdoor[i].anginc = -swingdoor[i].angopendir; + } + } else { + swingdoor[i].anginc = -swingdoor[i].anginc; + } + } + } + break; + } // switch + // + // LOWER FLOOR ANY AMOUNT + // + if (datag >= 1100 && datag <= 1199) { + + int speed = 32; + if (sector[s].hitag > 100) + speed = 64; + + sector[s].hitag = 0; + + daz = sector[s].floorz + (1024 * (sector[s].lotag - 1100)); + + if ((j = setanimation(s, daz, speed, 0, FLOORZ)) >= 0) { + playsound(S_STONELOOP1, 0, 0, (sector[s].lotag - 1100) / 10); + } + sector[s].lotag = 0; + } + + // + // RAISE FLOOR 1-99 + // + if (datag >= 1200 && datag <= 1299) { + int speed = 32; + if (sector[s].hitag > 100) + speed = 64; + + sector[s].hitag = 0; + + switch (sector[s].floorpicnum) { + case LAVA: + case ANILAVA: + case LAVA1: + sector[s].floorpicnum = COOLLAVA; + break; + case SLIME: + sector[s].floorpicnum = DRYSLIME; + break; + case WATER: + case HEALTHWATER: + sector[s].floorpicnum = DRYWATER; + break; + case LAVA2: + sector[s].floorpicnum = COOLLAVA2; + break; + } + // XXX + daz = sector[s].floorz - (1024 * (sector[s].lotag - 1200)); + + if ((j = setanimation(s, daz, speed, 0, FLOORZ)) >= 0) { + playsound(S_STONELOOP1, 0, 0, (sector[s].lotag - 1200) / 10); + } + sector[s].lotag = 0; + } + + if (datag >= 1300 && datag <= 1399) { + int speed = 32; + if (sector[s].hitag > 100) + speed = 64; + + sector[s].hitag = 0; + + daz = sector[s].ceilingz + (1024 * (sector[s].lotag - 1300)); + + if ((j = setanimation(s, daz, speed, 0, CEILZ)) >= 0) { + playsound(S_STONELOOP1, 0, 0, (sector[s].lotag - 1300) / 10); + } + sector[s].lotag = 0; + } + + // RAISE CEILING ANY AMOUNT + if (datag >= 1400 && datag <= 1499) { + sector[s].hitag = 0; + int speed = 32; + if (sector[s].hitag > 100) + speed = 64; + + daz = sector[s].ceilingz - (1024 * (sector[s].lotag - 1400)); + + if ((j = setanimation(s, daz, speed, 0, CEILZ)) >= 0) { + playsound(S_STONELOOP1, 0, 0, (sector[s].lotag - 1400) / 10); + } + sector[s].lotag = 0; + } + + /********* + * LOWER FLOOR AND CEILING ANY AMOUNT + *********/ + + if (datag >= 1500 && datag <= 1599) { + int speed = 32; + if (sector[s].hitag > 100) + speed = 64; + + sector[s].hitag = 0; + + daz = sector[s].floorz + (1024 * (sector[s].lotag - 1500)); + + setanimation(s, daz, speed, 0, FLOORZ); + + daz = sector[s].ceilingz + (1024 * (sector[s].lotag - 1500)); + + if ((j = setanimation(s, daz, speed, 0, CEILZ)) >= 0) { + playsound(S_STONELOOP1, 0, 0, (sector[s].lotag - 1500) / 10); + } + sector[s].lotag = 0; + } + + // + // RAISE FLOOR AND CEILING ANY AMOUNT + // + if (datag >= 1600 && datag <= 1699) { + + int speed = 32; + if (sector[s].hitag > 100) + speed = 64; + + sector[s].hitag = 0; + + daz = sector[s].floorz - (1024 * (sector[s].lotag - 1600)); + + setanimation(s, daz, speed, 0, FLOORZ); + + daz = sector[s].ceilingz - (1024 * (sector[s].lotag - 1600)); + + if ((j = setanimation(s, daz, speed, 0, CEILZ)) >= 0) { + playsound(S_STONELOOP1, 0, 0, (sector[s].lotag - 1600) / 10); + } + sector[s].lotag = 0; + } + + if (datag >= 1800 && datag <= 1899) { + i = getanimationgoal(sector[s], 1); + if (i >= 0) { + daz = sector[s].ceilingz + (1024 * 16); + + if (gAnimationData[i].goal == daz) + gAnimationData[i].goal = sector[nextsectorneighborz(s, sector[s].ceilingz - (1024 * 16), -1, + -1)].floorz; + else + gAnimationData[i].goal = daz; + } else { + if (sector[s].floorz == sector[s].ceilingz + (1024 * 16)) + daz = sector[nextsectorneighborz(s, sector[s].ceilingz - (1024 * 16), -1, -1)].floorz; + else { + daz = sector[s].ceilingz + (1024 * 16); + } + if ((j = setanimation(s, daz, 32, 0, FLOORZ)) >= 0) { + playsound(S_STONELOOP1, 0, 0, (sector[s].lotag - 1800) / 10); + } + } + } + + if (datag >= 1900 && datag <= 1999) { + + sector[s].hitag = 0; + temp1 = sector[s].lotag - 1900; + temp2 = temp1 / 10; + temp3 = temp1 - temp2; + + SND_Sound(S_STONELOOP1); + + switch (temp3) { // type of crush + case 0: + sector[s].lotag = DOORDOWNTAG; + setanimation(s, sector[s].ceilingz, 64, 0, FLOORZ); + break; + case 1: + daz = sector[s].ceilingz; + setanimation(s, daz, 64, 0, FLOORZ); + sector[s].lotag = 0; +// crushsectoranim[s]=0; +// crushsectordone[s]=0; + break; + case 2: + daz = sector[s].floorz; + setanimation(s, daz, 64, 0, CEILZ); + sector[s].lotag = 0; +// crushsectoranim[s]=0; +// crushsectordone[s]=0; + break; + case 3: + sector[s].lotag = 0; +// crushsectoranim[s]=1; +// crushsectordone[s]=1; + break; + case 4: + sector[s].lotag = 0; +// crushsectoranim[s]=2; +// crushsectordone[s]=1; + break; + case 5: + daz = (sector[s].ceilingz + sector[s].floorz) >> 1; + setanimation(s, daz, 64, 0, FLOORZ); + setanimation(s, daz, 64, 0, CEILZ); + break; + case 6: + sector[s].lotag = 0; +// crushsectoranim[s]=3; +// crushsectordone[s]=1; + break; + } + } + + // BRASS KEY + // BLACK KEY + // GLASS KEY + // IVORY KEY + + if (datag >= 2000 && datag <= 2999) { + Printf("WHTAG.java: 683 check this place keychecking"); //XXX + doorkey = (sector[s].lotag - 2000) / 100; + doorantic = (sector[s].lotag - (2000 + (doorkey * 100))) / 10; + doortype = sector[s].lotag - (2000 + (doorkey * 100) + (doorantic * 10)); + boolean checkforkey = false; + for (i = 0; i < MAXKEYS; i++) { + if (plr.treasure[i] == doorkey) + checkforkey = true; + } + if (checkforkey) { + if (doorantic == 0) + sector[s].lotag = 0; + switch (doortype) { + case 0: // up + i = getanimationgoal(sector[s], 2); + if (i >= 0) { + goalz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + if (gAnimationData[i].goal == goalz) { + gAnimationData[i].goal = sector[s].floorz; + if (doorantic == 2 || doorantic == 3) + setdelayfunc(s, 0); + } else { + gAnimationData[i].goal = goalz; + if (doorantic == 2) + setdelayfunc(s, DOORDELAY); + else if (doorantic == 3) + setdelayfunc(s, DOORDELAY << 3); + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + goalz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + if (doorantic == 2) + setdelayfunc(s, DOORDELAY); + else if (doorantic == 3) + setdelayfunc(s, DOORDELAY << 3); + } else { + goalz = sector[s].floorz; + if (doorantic == 2 || doorantic == 3) + setdelayfunc(s, 0); + } + setanimation(s, goalz, DOORSPEED, 0, CEILZ); + } + break; + case 1: // dn + i = getanimationgoal(sector[s], 1); + if (i >= 0) { + goalz = sector[nextsectorneighborz(s, sector[s].ceilingz, 1, 1)].floorz; + if (gAnimationData[i].goal == goalz) { + gAnimationData[i].goal = sector[s].ceilingz; + if (doorantic == 2 || doorantic == 3) + setdelayfunc(s, 0); + } else { + gAnimationData[i].goal = goalz; + if (doorantic == 2) + setdelayfunc(s, DOORDELAY); + else if (doorantic == 3) + setdelayfunc(s, DOORDELAY << 3); + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + goalz = sector[nextsectorneighborz(s, sector[s].ceilingz, 1, 1)].floorz; + if (doorantic == 2) + setdelayfunc(s, DOORDELAY); + else if (doorantic == 3) + setdelayfunc(s, DOORDELAY << 3); + } else { + goalz = sector[s].ceilingz; + if (doorantic == 2 || doorantic == 3) + setdelayfunc(s, 0); + } + setanimation(s, goalz, DOORSPEED, 0, FLOORZ); + } + break; + case 2: // middle + i = getanimationgoal(sector[s], 1); + j = getanimationgoal(sector[s], 2); + if (i >= 0) { + botz = sector[nextsectorneighborz(s, sector[s].ceilingz, 1, 1)].floorz; + if (gAnimationData[i].goal == botz) { + gAnimationData[i].goal = (sector[s].ceilingz + sector[s].floorz) >> 1; + if (doorantic == 2 || doorantic == 3) + setdelayfunc(s, 0); + } else { + gAnimationData[i].goal = botz; + if (doorantic == 2) + setdelayfunc(s, DOORDELAY); + else if (doorantic == 3) + setdelayfunc(s, DOORDELAY << 3); + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + botz = sector[nextsectorneighborz(s, sector[s].ceilingz, 1, 1)].floorz; + if (doorantic == 2) + setdelayfunc(s, DOORDELAY); + else if (doorantic == 3) + setdelayfunc(s, DOORDELAY << 3); + } else { + botz = (sector[s].ceilingz + sector[s].floorz) >> 1; + if (doorantic == 2 || doorantic == 3) + setdelayfunc(s, 0); + } + setanimation(s, botz, DOORSPEED, 0, FLOORZ); + } + if (j >= 0) { + topz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + if (gAnimationData[j].goal == topz) { + gAnimationData[j].goal = (sector[s].ceilingz + sector[s].floorz) >> 1; + } else { + gAnimationData[j].goal = topz; + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + topz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + } else { + topz = (sector[s].ceilingz + sector[s].floorz) >> 1; + } + setanimation(s, topz, DOORSPEED, 0, CEILZ); + } + break; + case 3: // vert + case 4: // swing + break; + } + } + } // end of complexdoors + + if (datag == 3000) { + for (k = 0; k < ironbarscnt; k++) { + if (ironbarsector[k] == s) { + ironbarsdone[k] = 1; + + switch (sprite[ironbarsanim[k]].picnum) { + + case SwingDoor: + + case SWINGDOOR2: + + case SWINGDOOR3: + + case TALLSWING: + + case TALLSWING2: + SND_Sound(S_CREAKDOOR2); + break; + + case SWINGGATE: + SND_Sound(S_CREAKDOOR3); + break; + + case SWINGHOLE: + + case SWINGGATE2: + + case ROPEDOOR: + + case GEARSSTART: + + case WOODGEARSSTART: + SND_Sound(S_CREAKDOOR1); + break; + } + + int pic = sprite[ironbarsanim[k]].picnum; + if(pic == SWINGGATE3 || pic == SWINGGATE4 || pic == SWINGGATE5 || pic == GEARS2START) + SND_Sound(S_CREAKDOOR1); + } + } + } + + if (datag == 4000) { +// sector[s].lotag=0; + for (k = 0; k < MAXSPRITES; k++) { + if (sector[s].hitag == sprite[k].hitag && sprite[k].extra < 1) { + newstatus(k, FLOCKSPAWN); + if (batsnd == -1) + batsnd = playsound(S_BATSLOOP, sprite[k].x, sprite[k].y, -1); +// sector[s].lotag = sector[s].hitag = 0; + } + } + } + if (datag == 4001) { +// sector[s].lotag=0; + for (k = 0; k < MAXSPRITES; k++) { + if (sector[s].hitag == sprite[k].hitag && sprite[k].picnum == GOBLIN) + newstatus(k, WAR); + } + } + + switch (datag) { + case 61: + case 62: + case 63: + case 64: + if (keysok == 0) + break; + else { + i = getanimationgoal(sector[s], 2); + if (i >= 0) { + goalz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + if (gAnimationData[i].goal == goalz) { + gAnimationData[i].goal = sector[s].floorz; + } else { + gAnimationData[i].goal = goalz; + } + } else { + if (sector[s].ceilingz == sector[s].floorz) { + goalz = sector[nextsectorneighborz(s, sector[s].floorz, -1, -1)].ceilingz; + } else { + goalz = sector[s].floorz; + } + setanimation(s, goalz, DOORSPEED, 0, CEILZ); + } + SND_Sound(S_DOOR2); + } + } +} + +void animatetags(int nPlayer) { + + int endwall, good, j, k, oldang, startwall; + short i, nexti; + int dasector; + + PLAYER& plr = player[nPlayer]; + + if (plr.sector != -1) { + if (sector[plr.sector].lotag == 2) { + for (i = 0; i < numsectors; i++) + if (sector[i].hitag == sector[plr.sector].hitag) + if (sector[i].lotag != 2) + operatesector(plr, i); + i = headspritestat[0]; + while (i != -1) { + nexti = nextspritestat[i]; + if (sprite[i].hitag == sector[plr.sector].hitag) + operatesprite(plr, i); + i = nexti; + } + + sector[plr.sector].lotag = 0; + sector[plr.sector].hitag = 0; + } + if ((sector[plr.sector].lotag == 1) && (plr.sector != plr.oldsector)) { + for (i = 0; i < numsectors; i++) + if (sector[i].hitag == sector[plr.sector].hitag) + if (sector[i].lotag != 2) + operatesector(plr, i); + i = headspritestat[0]; + while (i != -1) { + nexti = nextspritestat[i]; + if (sprite[i].hitag == sector[plr.sector].hitag) + operatesprite(plr, i); + i = nexti; + } + } + } + + for (i = 0; i < dragsectorcnt; i++) { + + dasector = dragsectorlist[i]; + + startwall = sector[dasector].wallptr; + endwall = startwall + sector[dasector].wallnum - 1; + + if (wall[startwall].x + dragxdir[i] < dragx1[i]) + dragxdir[i] = 16; + if (wall[startwall].y + dragydir[i] < dragy1[i]) + dragydir[i] = 16; + if (wall[startwall].x + dragxdir[i] > dragx2[i]) + dragxdir[i] = -16; + if (wall[startwall].y + dragydir[i] > dragy2[i]) + dragydir[i] = -16; + + for (j = startwall; j <= endwall; j++) + dragpoint((short) j, wall[j].x + dragxdir[i], wall[j].y + dragydir[i]); + j = sector[dasector].floorz; + + game.pInt.setceilinterpolate(dasector, sector[dasector]); + sector[dasector].floorz = dragfloorz[i] + (sintable[(lockclock << 4) & 2047] >> 3); + + if (plr.sector == dasector) { + + viewBackupPlayerLoc(nPlayer); + + plr.x += dragxdir[i]; + plr.y += dragydir[i]; + plr.z += (sector[dasector].floorz - j); + + // Update sprite representation of player + + game.pInt.setsprinterpolate(plr.spritenum, sprite[plr.spritenum]); + setsprite(plr.spritenum, plr.x, plr.y, plr.z + (plr.height)); + sprite[plr.spritenum].ang = (short) plr.ang; + } + } + + for (i = 0; i < swingcnt; i++) { + if (swingdoor[i].anginc != 0) { + oldang = swingdoor[i].ang; + for (j = 0; j < ((TICSPERFRAME) << 2); j++) { + swingdoor[i].ang = ((swingdoor[i].ang + 2048 + swingdoor[i].anginc) & 2047); + if (swingdoor[i].ang == swingdoor[i].angclosed) { + swingdoor[i].anginc = 0; + } + if (swingdoor[i].ang == swingdoor[i].angopen) { + swingdoor[i].anginc = 0; + } + } + for (k = 1; k <= 3; k++) { + Point out = rotatepoint(swingdoor[i].x[0], swingdoor[i].y[0], swingdoor[i].x[k], + swingdoor[i].y[k], (short) swingdoor[i].ang); + + dragpoint((short)swingdoor[i].wall[k], out.getX(), out.getY()); + } + if (swingdoor[i].anginc != 0) { + if (plr.sector == swingdoor[i].sector) { + good = 1; + for (k = 1; k <= 3; k++) { + if (clipinsidebox(plr.x, plr.y, (short) swingdoor[i].wall[k], 512) != 0) { + good = 0; + break; + } + } + if (good == 0) { + swingdoor[i].ang = oldang; + for (k = 1; k <= 3; k++) { + Point out = rotatepoint(swingdoor[i].x[0], swingdoor[i].y[0], swingdoor[i].x[k], + swingdoor[i].y[k], (short) swingdoor[i].ang); + + dragpoint((short)swingdoor[i].wall[k], out.getX(), out.getY()); + } + swingdoor[i].anginc = -swingdoor[i].anginc; + break; + } + } + } + } + } +} + +void dodelayitems(int tics) { + int cnt = delaycnt; + for (int i = 0; i < cnt; i++) { + if (!delayitem[i].func) { + int j = delaycnt - 1; + delayitem[i].memmove(delayitem[j]); + delaycnt = j; + } + if (delayitem[i].timer > 0) { + if ((delayitem[i].timer -= tics) <= 0) { + delayitem[i].timer = 0; + operatesector(player[pyrn], delayitem[i].item); + delayitem[i].func = false; + } + } + } +} + +void setdelayfunc(int item, int delay) { + for (int i = 0; i < delaycnt; i++) { + if (delayitem[i].item == item && delayitem[i].func) { + if (delay == 0) + delayitem[i].func = false; + delayitem[i].timer = delay; + return; + } + } + if (delay > 0) { + delayitem[delaycnt].func = true; + delayitem[delaycnt].item = item; + delayitem[delaycnt].timer = delay; + delaycnt++; + } +} + + +END_WH_NS