From 1119c2d2d94a5d49ad0cafc684c8419d5ea34ea0 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Thu, 24 Jun 2021 02:03:49 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8FCleanup=20missiles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/missiles.cpp | 721 ++++++++++++++++++++++---------------------- 1 file changed, 354 insertions(+), 367 deletions(-) diff --git a/Source/missiles.cpp b/Source/missiles.cpp index e23eb3754..e525fade7 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -32,14 +32,12 @@ const int CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, 885, void GetDamageAmt(int i, int *mind, int *maxd) { - int k, sl; - assert(myplr >= 0 && myplr < MAX_PLRS); assert(i >= 0 && i < 64); auto &myPlayer = plr[myplr]; - sl = myPlayer._pSplLvl[i] + myPlayer._pISplLvlAdd; + int sl = myPlayer._pSplLvl[i] + myPlayer._pISplLvlAdd; switch (i) { case SPL_FIREBOLT: @@ -54,10 +52,10 @@ void GetDamageAmt(int i, int *mind, int *maxd) *mind += *mind / 2; } *maxd = 10; - for (k = 0; k < myPlayer._pLevel; k++) { + for (int k = 0; k < myPlayer._pLevel; k++) { *maxd += 4; } - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *maxd += 6; } if (myPlayer._pClass == HeroClass::Warrior || myPlayer._pClass == HeroClass::Monk || myPlayer._pClass == HeroClass::Barbarian) { @@ -75,7 +73,7 @@ void GetDamageAmt(int i, int *mind, int *maxd) break; case SPL_FLASH: *mind = myPlayer._pLevel; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *mind += *mind / 8; } *mind += *mind / 2; @@ -116,21 +114,21 @@ void GetDamageAmt(int i, int *mind, int *maxd) case SPL_FIREBALL: case SPL_RUNEFIRE: *mind = 2 * myPlayer._pLevel + 4; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *mind += *mind / 8; } *maxd = 2 * myPlayer._pLevel + 40; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *maxd += *maxd / 8; } break; case SPL_GUARDIAN: *mind = (myPlayer._pLevel / 2) + 1; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *mind += *mind / 8; } *maxd = (myPlayer._pLevel / 2) + 10; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *maxd += *maxd / 8; } break; @@ -147,12 +145,12 @@ void GetDamageAmt(int i, int *mind, int *maxd) case SPL_RUNEIMMOLAT: case SPL_RUNENOVA: *mind = (myPlayer._pLevel + 5) / 2; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *mind += *mind / 8; } *mind *= 5; *maxd = (myPlayer._pLevel + 30) / 2; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *maxd += *maxd / 8; } *maxd *= 5; @@ -168,22 +166,22 @@ void GetDamageAmt(int i, int *mind, int *maxd) break; case SPL_APOCA: *mind = 0; - for (k = 0; k < myPlayer._pLevel; k++) { + for (int k = 0; k < myPlayer._pLevel; k++) { *mind += 1; } *maxd = 0; - for (k = 0; k < myPlayer._pLevel; k++) { + for (int k = 0; k < myPlayer._pLevel; k++) { *maxd += 6; } break; case SPL_ELEMENT: *mind = 2 * myPlayer._pLevel + 4; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *mind += *mind / 8; } /// BUGFIX: add here '*mind /= 2;' *maxd = 2 * myPlayer._pLevel + 40; - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *maxd += *maxd / 8; } /// BUGFIX: add here '*maxd /= 2;' @@ -205,10 +203,10 @@ void GetDamageAmt(int i, int *mind, int *maxd) *mind += *mind / 2; } *maxd = 10; - for (k = 0; k < myPlayer._pLevel; k++) { + for (int k = 0; k < myPlayer._pLevel; k++) { *maxd += 4; } - for (k = 0; k < sl; k++) { + for (int k = 0; k < sl; k++) { *maxd += 6; } if (myPlayer._pClass == HeroClass::Warrior || myPlayer._pClass == HeroClass::Monk || myPlayer._pClass == HeroClass::Barbarian) { @@ -264,21 +262,14 @@ static int FindClosest(Point source, int rad) return -1; } -int GetSpellLevel(int id, spell_id sn) +int GetSpellLevel(int playerId, spell_id sn) { - int result; - - auto &player = plr[id]; - - if (id == myplr) - result = player._pISplLvlAdd + player._pSplLvl[sn]; - else - result = 1; + auto &player = plr[playerId]; - if (result < 0) - result = 0; + if (playerId != myplr) + return 1; // BUGFIX spell level will be wrong in multiplayer - return result; + return std::max(player._pISplLvlAdd + player._pSplLvl[sn], 0); } constexpr Direction16 Direction16Flip(Direction16 x, Direction16 pivot) @@ -548,10 +539,9 @@ bool MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, bool shift) bool MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, bool shift) { - int hit, hper, dam, mor; - bool resist, ret; + int dam; - resist = false; + bool resist = false; if (monster[m].mtalkmsg != TEXT_NONE || monster[m]._mhitpoints >> 6 <= 0 || (t == MIS_HBOLT && monster[m].MType->mtype != MT_DIABLO && monster[m].MData->mMonstClass != MC_UNDEAD)) { @@ -562,7 +552,7 @@ bool MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, bool if (monster[m]._mmode == MM_CHARGE) return false; - mor = monster[m].mMagicRes; + uint8_t mor = monster[m].mMagicRes; missile_resistance mir = missiledata[t].mResist; if ((mor & IMMUNE_MAGIC && mir == MISR_MAGIC) @@ -579,7 +569,8 @@ bool MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, bool if (gbIsHellfire && t == MIS_HBOLT && (monster[m].MType->mtype == MT_DIABLO || monster[m].MType->mtype == MT_BONEDEMN)) resist = true; - hit = GenerateRnd(100); + int hit = GenerateRnd(100); + int hper = 0; if (pnum != -1) { const auto &player = plr[pnum]; if (missiledata[t].mType == 0) { @@ -605,77 +596,83 @@ bool MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, bool hper = GenerateRnd(75) - monster[m].mLevel * 2; } - if (hper < 5) - hper = 5; - if (hper > 95) - hper = 95; + hper = clamp(hper, 5, 95); + if (monster[m]._mmode == MM_STONE) hit = 0; + + bool ret = false; if (CheckMonsterHit(m, &ret)) return ret; + #ifdef _DEBUG - if (hit < hper || debug_mode_key_inverted_v || debug_mode_dollar_sign) { + if (hit >= hper && !debug_mode_key_inverted_v && !debug_mode_dollar_sign) + return false; #else - if (hit < hper) { + if (hit >= hper) + return false; #endif - if (t == MIS_BONESPIRIT) { - dam = monster[m]._mhitpoints / 3 >> 6; + + if (t == MIS_BONESPIRIT) { + dam = monster[m]._mhitpoints / 3 >> 6; + } else { + dam = mindam + GenerateRnd(maxdam - mindam + 1); + } + + if (missiledata[t].mType == 0) { + const auto &player = plr[pnum]; + dam = player._pIBonusDamMod + dam * player._pIBonusDam / 100 + dam; + if (player._pClass == HeroClass::Rogue) + dam += player._pDamageMod; + else + dam += player._pDamageMod / 2; + } + + if (!shift) + dam <<= 6; + if (resist) + dam >>= 2; + + if (pnum == myplr) + monster[m]._mhitpoints -= dam; + + if ((gbIsHellfire && plr[pnum]._pIFlags & ISPL_NOHEALMON) || (!gbIsHellfire && plr[pnum]._pIFlags & ISPL_FIRE_ARROWS)) + monster[m]._mFlags |= MFLAG_NOHEAL; + + if (monster[m]._mhitpoints >> 6 <= 0) { + if (monster[m]._mmode == MM_STONE) { + M_StartKill(m, pnum); + monster[m]._mmode = MM_STONE; } else { - dam = mindam + GenerateRnd(maxdam - mindam + 1); + M_StartKill(m, pnum); } - if (missiledata[t].mType == 0) { - const auto &player = plr[pnum]; - dam = player._pIBonusDamMod + dam * player._pIBonusDam / 100 + dam; - if (player._pClass == HeroClass::Rogue) - dam += player._pDamageMod; - else - dam += (player._pDamageMod / 2); - } - if (!shift) - dam <<= 6; - if (resist) - dam >>= 2; - if (pnum == myplr) - monster[m]._mhitpoints -= dam; - if ((gbIsHellfire && plr[pnum]._pIFlags & ISPL_NOHEALMON) || (!gbIsHellfire && plr[pnum]._pIFlags & ISPL_FIRE_ARROWS)) - monster[m]._mFlags |= MFLAG_NOHEAL; - - if (monster[m]._mhitpoints >> 6 <= 0) { - if (monster[m]._mmode == MM_STONE) { - M_StartKill(m, pnum); - monster[m]._mmode = MM_STONE; - } else { - M_StartKill(m, pnum); - } + } else { + if (resist) { + PlayEffect(m, 1); + } else if (monster[m]._mmode == MM_STONE) { + if (m > MAX_PLRS - 1) + M_StartHit(m, pnum, dam); + monster[m]._mmode = MM_STONE; } else { - if (resist) { - PlayEffect(m, 1); - } else if (monster[m]._mmode == MM_STONE) { - if (m > MAX_PLRS - 1) - M_StartHit(m, pnum, dam); - monster[m]._mmode = MM_STONE; - } else { - if (missiledata[t].mType == 0 && plr[pnum]._pIFlags & ISPL_KNOCKBACK) { - M_GetKnockback(m); - } - if (m > MAX_PLRS - 1) - M_StartHit(m, pnum, dam); + if (missiledata[t].mType == 0 && plr[pnum]._pIFlags & ISPL_KNOCKBACK) { + M_GetKnockback(m); } + if (m > MAX_PLRS - 1) + M_StartHit(m, pnum, dam); } + } - if (monster[m]._msquelch == 0) { - monster[m]._msquelch = UINT8_MAX; - monster[m].position.last = plr[pnum].position.tile; - } - return true; + if (monster[m]._msquelch == 0) { + monster[m]._msquelch = UINT8_MAX; + monster[m].position.last = plr[pnum].position.tile; } - return false; + return true; } bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool shift, int earflag, bool *blocked) { - int hit, hper, tac, dam, blk, blkper, resper; + int hper, dam, resper; *blocked = false; auto &player = plr[pnum]; @@ -688,17 +685,17 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s return false; } - if (player._pSpellFlags & 1 && missiledata[mtype].mType == 0) { + if ((player._pSpellFlags & 1) && missiledata[mtype].mType == 0) { return false; } - hit = GenerateRnd(100); + int hit = GenerateRnd(100); #ifdef _DEBUG if (debug_mode_dollar_sign || debug_mode_key_inverted_v) hit = 1000; #endif if (missiledata[mtype].mType == 0) { - tac = player._pIAC + player._pIBonusAC + player._pDexterity / 5; + int tac = player._pIAC + player._pIBonusAC + player._pDexterity / 5; if (m != -1) { hper = monster[m].mHit + ((monster[m].mLevel - player._pLevel) * 2) @@ -708,10 +705,9 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s hper = 100 - (tac / 2) - (dist * 2); } } else { + hper = 40; if (m != -1) { - hper = +40 - (player._pLevel * 2) - (dist * 2) + (monster[m].mLevel * 2); - } else { - hper = 40; + hper += (monster[m].mLevel * 2) - (player._pLevel * 2) - (dist * 2); } } @@ -727,20 +723,20 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s hper = 30; } + int blk = 100; if ((player._pmode == PM_STAND || player._pmode == PM_ATTACK) && player._pBlockFlag) { blk = GenerateRnd(100); - } else { - blk = 100; } if (shift) blk = 100; if (mtype == MIS_ACIDPUD) blk = 100; + + int blkper = player._pBaseToBlk + player._pDexterity; if (m != -1) - blkper = player._pBaseToBlk + player._pDexterity - ((monster[m].mLevel - player._pLevel) * 2); - else - blkper = player._pBaseToBlk + player._pDexterity; + blkper -= (monster[m].mLevel - player._pLevel) * 2; + if (blkper < 0) blkper = 0; if (blkper > 100) @@ -762,63 +758,66 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s break; } - if (hit < hper) { - if (mtype == MIS_BONESPIRIT) { - dam = player._pHitPoints / 3; - } else { - if (!shift) { - - dam = (mind << 6) + GenerateRnd((maxd - mind + 1) << 6); - if (m == -1) - if ((player._pIFlags & ISPL_ABSHALFTRAP) != 0) - dam /= 2; - dam += (player._pIGetHit << 6); - } else { - dam = mind + GenerateRnd(maxd - mind + 1); - if (m == -1) - if ((player._pIFlags & ISPL_ABSHALFTRAP) != 0) - dam /= 2; - dam += player._pIGetHit; - } + if (hit >= hper) { + return false; + } - if (dam < 64) - dam = 64; - } - if ((resper <= 0 || gbIsHellfire) && blk < blkper) { - Direction dir = player._pdir; - if (m != -1) { - dir = GetDirection(player.position.tile, monster[m].position.tile); - } - *blocked = true; - StartPlrBlock(pnum, dir); - return true; + if (mtype == MIS_BONESPIRIT) { + dam = player._pHitPoints / 3; + } else { + if (!shift) { + dam = (mind << 6) + GenerateRnd((maxd - mind + 1) << 6); + if (m == -1) + if ((player._pIFlags & ISPL_ABSHALFTRAP) != 0) + dam /= 2; + dam += (player._pIGetHit << 6); + } else { + dam = mind + GenerateRnd(maxd - mind + 1); + if (m == -1) + if ((player._pIFlags & ISPL_ABSHALFTRAP) != 0) + dam /= 2; + dam += player._pIGetHit; } - if (resper > 0) { - dam = dam - dam * resper / 100; - if (pnum == myplr) { - ApplyPlrDamage(pnum, 0, 0, dam, earflag); - } + dam = std::max(dam, 64); + } - if (player._pHitPoints >> 6 > 0) { - player.Say(HeroSpeech::ArghClang); - } - return true; + if ((resper <= 0 || gbIsHellfire) && blk < blkper) { + Direction dir = player._pdir; + if (m != -1) { + dir = GetDirection(player.position.tile, monster[m].position.tile); } + *blocked = true; + StartPlrBlock(pnum, dir); + return true; + } + + if (resper > 0) { + dam = dam - dam * resper / 100; if (pnum == myplr) { ApplyPlrDamage(pnum, 0, 0, dam, earflag); } + if (player._pHitPoints >> 6 > 0) { - StartPlrHit(pnum, dam, false); + player.Say(HeroSpeech::ArghClang); } return true; } - return false; + + if (pnum == myplr) { + ApplyPlrDamage(pnum, 0, 0, dam, earflag); + } + + if (player._pHitPoints >> 6 > 0) { + StartPlrHit(pnum, dam, false); + } + + return true; } bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, bool shift, bool *blocked) { - int dam, blk, blkper, hper, hit, resper; + int dam, hit, resper; if (!sgGameInitInfo.bFriendlyFire && gbFriendlyMode) return false; @@ -836,7 +835,7 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b return false; } - if (target._pSpellFlags & 1 && missiledata[mtype].mType == 0) { + if ((target._pSpellFlags & 1) && missiledata[mtype].mType == 0) { return false; } @@ -855,7 +854,9 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b resper = 0; break; } - hper = GenerateRnd(100); + + int hper = GenerateRnd(100); + if (missiledata[mtype].mType == 0) { hit = player._pIBonusToHit + player._pLevel @@ -878,56 +879,50 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b else if (player._pClass == HeroClass::Bard) hit += 10; } - if (hit < 5) - hit = 5; - if (hit > 95) - hit = 95; - if (hper < hit) { - if ((target._pmode == PM_STAND || target._pmode == PM_ATTACK) && target._pBlockFlag) { - blkper = GenerateRnd(100); - } else { - blkper = 100; - } - if (shift) - blkper = 100; - blk = target._pDexterity + target._pBaseToBlk + (target._pLevel * 2) - (player._pLevel * 2); - if (blk < 0) { - blk = 0; - } - if (blk > 100) { - blk = 100; - } + hit = clamp(hit, 5, 95); - if (mtype == MIS_BONESPIRIT) { - dam = target._pHitPoints / 3; - } else { - dam = mindam + GenerateRnd(maxdam - mindam + 1); - if (missiledata[mtype].mType == 0) - dam += player._pIBonusDamMod + player._pDamageMod + dam * player._pIBonusDam / 100; - if (!shift) - dam <<= 6; - } - if (missiledata[mtype].mType != 0) - dam /= 2; - if (resper > 0) { - dam -= (dam * resper) / 100; - if (pnum == myplr) - NetSendCmdDamage(true, p, dam); - player.Say(HeroSpeech::ArghClang); - return true; - } - if (blkper < blk) { - StartPlrBlock(p, GetDirection(target.position.tile, player.position.tile)); - *blocked = true; - } else { - if (pnum == myplr) - NetSendCmdDamage(true, p, dam); - StartPlrHit(p, dam, false); - } + if (hper >= hit) { + return false; + } + + int blkper = 100; + if (!shift && (target._pmode == PM_STAND || target._pmode == PM_ATTACK) && target._pBlockFlag) { + blkper = GenerateRnd(100); + } + + int blk = target._pDexterity + target._pBaseToBlk + (target._pLevel * 2) - (player._pLevel * 2); + blk = clamp(blk, 0, 100); + + if (mtype == MIS_BONESPIRIT) { + dam = target._pHitPoints / 3; + } else { + dam = mindam + GenerateRnd(maxdam - mindam + 1); + if (missiledata[mtype].mType == 0) + dam += player._pIBonusDamMod + player._pDamageMod + dam * player._pIBonusDam / 100; + if (!shift) + dam <<= 6; + } + if (missiledata[mtype].mType != 0) + dam /= 2; + if (resper > 0) { + dam -= (dam * resper) / 100; + if (pnum == myplr) + NetSendCmdDamage(true, p, dam); + player.Say(HeroSpeech::ArghClang); return true; } - return false; + + if (blkper < blk) { + StartPlrBlock(p, GetDirection(target.position.tile, player.position.tile)); + *blocked = true; + } else { + if (pnum == myplr) + NetSendCmdDamage(true, p, dam); + StartPlrHit(p, dam, false); + } + + return true; } void CheckMissileCol(int i, int mindam, int maxdam, bool shift, Point position, bool nodel) @@ -1208,19 +1203,17 @@ void FreeMissiles2() void InitMissiles() { - int mi, src, i, j; - auto &myPlayer = plr[myplr]; AutoMapShowItems = false; myPlayer._pSpellFlags &= ~0x1; if (myPlayer._pInfraFlag) { - for (i = 0; i < nummissiles; ++i) { - mi = missileactive[i]; + for (int i = 0; i < nummissiles; ++i) { + int mi = missileactive[i]; if (missile[mi]._mitype == MIS_INFRA) { - src = missile[mi]._misource; + int src = missile[mi]._misource; if (src == myplr) - CalcPlrItemVals(src, true); + CalcPlrItemVals(myplr, true); } } } @@ -1228,8 +1221,8 @@ void InitMissiles() if ((myPlayer._pSpellFlags & 2) == 2 || (myPlayer._pSpellFlags & 4) == 4) { myPlayer._pSpellFlags &= ~0x2; myPlayer._pSpellFlags &= ~0x4; - for (i = 0; i < nummissiles; ++i) { - mi = missileactive[i]; + for (int i = 0; i < nummissiles; ++i) { + int mi = missileactive[i]; if (missile[mi]._mitype == MIS_BLODBOIL) { if (missile[mi]._misource == myplr) { int missingHP = myPlayer._pMaxHP - myPlayer._pHitPoints; @@ -1241,18 +1234,18 @@ void InitMissiles() } nummissiles = 0; - for (i = 0; i < MAXMISSILES; i++) { + for (int i = 0; i < MAXMISSILES; i++) { missileavail[i] = i; missileactive[i] = 0; } numchains = 0; - for (i = 0; i < MAXMISSILES; i++) { + for (int i = 0; i < MAXMISSILES; i++) { chain[i].idx = -1; chain[i]._mitype = 0; chain[i]._mirange = 0; } - for (j = 0; j < MAXDUNY; j++) { - for (i = 0; i < MAXDUNX; i++) { + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { dFlags[i][j] &= ~BFLAG_MISSILE; } } @@ -1380,16 +1373,16 @@ void AddStoneRune(int mi, Point src, Point dst, int midir, int8_t mienemy, int i void AddReflection(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam) { - int lvl; - if (id >= 0) { + int lvl = 2; if (missile[mi]._mispllvl) lvl = missile[mi]._mispllvl; - else - lvl = 2; + plr[id].wReflections += lvl * plr[id]._pLevel; + UseMana(id, SPL_REFLECT); } + missile[mi]._mirange = 0; missile[mi]._miDelFlag = false; } @@ -1552,7 +1545,7 @@ void AddStealPotions(int mi, Point src, Point dst, int midir, int8_t mienemy, in SetPlrHandItem(&player.HoldItem, ii); GetPlrHandSeed(&player.HoldItem); player.HoldItem._iStatFlag = true; - player.SpdList[si] = plr[pnum].HoldItem; + player.SpdList[si] = player.HoldItem; } if (!hasPlayedSFX) { PlaySfxLoc(IS_POPPOP2, tx, ty); @@ -1568,17 +1561,15 @@ void AddStealPotions(int mi, Point src, Point dst, int midir, int8_t mienemy, in void AddManaTrap(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam) { - int i, pn, k, j, tx, ty, pid; - missile[mi]._misource = id; - for (i = 0; i < 3; i++) { - k = CrawlNum[i]; - pn = k + 2; - for (j = CrawlTable[k]; j > 0; j--) { - tx = src.x + CrawlTable[pn - 1]; - ty = src.y + CrawlTable[pn]; + for (int i = 0; i < 3; i++) { + int k = CrawlNum[i]; + int pn = k + 2; + for (int j = CrawlTable[k]; j > 0; j--) { + int tx = src.x + CrawlTable[pn - 1]; + int ty = src.y + CrawlTable[pn]; if (0 < tx && tx < MAXDUNX && 0 < ty && ty < MAXDUNY) { - pid = dPlayer[tx][ty]; + int pid = dPlayer[tx][ty]; if (pid != 0) { auto &player = plr[(pid > 0) ? pid - 1 : -(pid + 1)]; @@ -1598,9 +1589,8 @@ void AddManaTrap(int mi, Point src, Point dst, int midir, int8_t mienemy, int id void AddSpecArrow(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam) { - int av; + int av = 0; - av = 0; if (mienemy == TARGET_MONSTERS) { auto &player = plr[id]; @@ -1618,6 +1608,7 @@ void AddSpecArrow(int mi, Point src, Point dst, int midir, int8_t mienemy, int i if ((player._pIFlags & ISPL_FASTESTATTACK) != 0) av += 8; } + missile[mi]._mirange = 1; missile[mi]._miVar1 = dst.x; missile[mi]._miVar2 = dst.y; @@ -1760,15 +1751,13 @@ void AddLightningArrow(int mi, Point src, Point dst, int midir, int8_t mienemy, void AddMana(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam) { - int i, ManaAmount; - auto &player = plr[id]; - ManaAmount = (GenerateRnd(10) + 1) << 6; - for (i = 0; i < player._pLevel; i++) { + int ManaAmount = (GenerateRnd(10) + 1) << 6; + for (int i = 0; i < player._pLevel; i++) { ManaAmount += (GenerateRnd(4) + 1) << 6; } - for (i = 0; i < missile[mi]._mispllvl; i++) { + for (int i = 0; i < missile[mi]._mispllvl; i++) { ManaAmount += (GenerateRnd(6) + 1) << 6; } if (player._pClass == HeroClass::Sorcerer) @@ -1915,6 +1904,7 @@ void AddArrow(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, i int av = 32; if (mienemy == TARGET_MONSTERS) { auto &player = plr[id]; + if ((player._pIFlags & ISPL_RNDARROWVEL) != 0) { av = GenerateRnd(32) + 16; } @@ -2621,12 +2611,10 @@ void AddGolem(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, i void AddEtherealize(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam) { - int i; - auto &player = plr[id]; missile[mi]._mirange = 16 * player._pLevel / 2; - for (i = missile[mi]._mispllvl; i > 0; i--) { + for (int i = missile[mi]._mispllvl; i > 0; i--) { missile[mi]._mirange += missile[mi]._mirange / 8; } missile[mi]._mirange += missile[mi]._mirange * player._pISplDur / 128; @@ -2667,31 +2655,24 @@ void AddBoom(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, in void AddHeal(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam) { - int i; - int HealAmount; - auto &player = plr[id]; - HealAmount = (GenerateRnd(10) + 1) << 6; - for (i = 0; i < player._pLevel; i++) { - HealAmount += (GenerateRnd(4) + 1) << 6; + int hp = (GenerateRnd(10) + 1) << 6; + for (int i = 0; i < player._pLevel; i++) { + hp += (GenerateRnd(4) + 1) << 6; } - for (i = 0; i < missile[mi]._mispllvl; i++) { - HealAmount += (GenerateRnd(6) + 1) << 6; + for (int i = 0; i < missile[mi]._mispllvl; i++) { + hp += (GenerateRnd(6) + 1) << 6; } - if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Barbarian || player._pClass == HeroClass::Monk) - HealAmount *= 2; - else if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Bard) - HealAmount += HealAmount / 2; - - player._pHitPoints += HealAmount; - if (player._pHitPoints > player._pMaxHP) - player._pHitPoints = player._pMaxHP; + if (player._pClass == HeroClass::Warrior || player._pClass == HeroClass::Barbarian || player._pClass == HeroClass::Monk) { + hp *= 2; + } else if (player._pClass == HeroClass::Rogue || player._pClass == HeroClass::Bard) { + hp += hp / 2; + } - player._pHPBase += HealAmount; - if (player._pHPBase > player._pMaxHPBase) - player._pHPBase = player._pMaxHPBase; + player._pHitPoints = std::min(player._pHitPoints + hp, player._pMaxHP); + player._pHPBase = std::min(player._pHPBase + hp, player._pMaxHPBase); UseMana(id, SPL_HEAL); missile[mi]._miDelFlag = true; @@ -2839,19 +2820,20 @@ void AddBlodboil(int mi, Point src, Point dst, int midir, int8_t mienemy, int id if (player._pSpellFlags & 6 || player._pHitPoints <= player._pLevel << 6) { missile[mi]._miDelFlag = true; - } else { - UseMana(id, SPL_BLODBOIL); - missile[mi]._miVar1 = id; - int tmp = 3 * player._pLevel; - tmp <<= 7; - player._pSpellFlags |= 2U; - missile[mi]._miVar2 = tmp; - int lvl = player._pLevel * 2; - missile[mi]._mirange = lvl + 10 * missile[mi]._mispllvl + 245; - CalcPlrItemVals(id, true); - force_redraw = 255; - player.Say(HeroSpeech::Aaaaargh); + return; } + + UseMana(id, SPL_BLODBOIL); + missile[mi]._miVar1 = id; + int tmp = 3 * player._pLevel; + tmp <<= 7; + player._pSpellFlags |= 2; + missile[mi]._miVar2 = tmp; + int lvl = player._pLevel * 2; + missile[mi]._mirange = lvl + 10 * missile[mi]._mispllvl + 245; + CalcPlrItemVals(id, true); + force_redraw = 255; + player.Say(HeroSpeech::Aaaaargh); } void AddRepair(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam) @@ -2968,10 +2950,7 @@ void AddCbolt(int mi, Point src, Point dst, int midir, int8_t micaster, int id, assert((DWORD)mi < MAXMISSILES); missile[mi]._mirnd = GenerateRnd(15) + 1; - missile[mi]._midam = 15; - if (micaster == 0) { - missile[mi]._midam = GenerateRnd(plr[id]._pMagic / 4) + 1; - } + missile[mi]._midam = (micaster == 0) ? (GenerateRnd(plr[id]._pMagic / 4) + 1) : 15; if (src == dst) { dst += (Direction)midir; @@ -2991,10 +2970,12 @@ void AddHbolt(int mi, Point src, Point dst, int midir, int8_t micaster, int id, if (src == dst) { dst += (Direction)midir; } + int sp = 16; if (id != -1) { sp += std::min(missile[mi]._mispllvl * 2, 47); } + GetMissileVel(mi, src, dst, sp); SetMissDir(mi, GetDirection16(src, dst)); missile[mi]._mirange = 256; @@ -3065,24 +3046,21 @@ void AddRportal(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, void AddDiabApoca(int mi, Point src, Point dst, int midir, int8_t mienemy, int id, int dam) { - int pnum; - int players = gbIsMultiplayer ? MAX_PLRS : 1; - for (pnum = 0; pnum < players; pnum++) { + for (int pnum = 0; pnum < players; pnum++) { auto &player = plr[pnum]; if (!player.plractive) continue; - if (LineClearMissile(src, player.position.future)) { - AddMissile({ 0, 0 }, player.position.future, 0, MIS_BOOM2, mienemy, id, dam, 0); - } + if (!LineClearMissile(src, player.position.future)) + continue; + + AddMissile({ 0, 0 }, player.position.future, 0, MIS_BOOM2, mienemy, id, dam, 0); } missile[mi]._miDelFlag = true; } int AddMissile(Point src, Point dst, int midir, int mitype, int8_t micaster, int id, int midam, int spllvl) { - int i, mi; - if (nummissiles >= MAXMISSILES - 1) return -1; @@ -3090,14 +3068,14 @@ int AddMissile(Point src, Point dst, int midir, int mitype, int8_t micaster, int if (currlevel != plr[id].plrlevel) return -1; - for (i = 0; i < nummissiles; i++) { - mi = missileactive[i]; + for (int i = 0; i < nummissiles; i++) { + int mi = missileactive[i]; if (missile[mi]._mitype == MIS_MANASHIELD && missile[mi]._misource == id) return -1; } } - mi = missileavail[0]; + int mi = missileavail[0]; missileavail[0] = missileavail[MAXMISSILES - nummissiles - 1]; missileactive[nummissiles] = mi; @@ -3789,6 +3767,7 @@ static void MI_Ring(int i, int type) int k = CrawlNum[3] + 1; uint8_t lvl = src > 0 ? plr[src]._pLevel : currlevel; int dmg = 16 * (GenerateRnd(10) + GenerateRnd(10) + lvl + 2) / 2; + for (int j = CrawlTable[b]; j > 0; j--, k += 2) { int tx = missile[i]._miVar1 + CrawlTable[k - 1]; int ty = missile[i]._miVar2 + CrawlTable[k]; @@ -3801,10 +3780,12 @@ static void MI_Ring(int i, int type) continue; if (!LineClearMissile(missile[i].position.tile, { tx, ty })) continue; - if (nMissileTable[dp] || missile[i]._miVar8) + if (nMissileTable[dp] || missile[i]._miVar8) { missile[i]._miVar8 = 1; - else - AddMissile({ tx, ty }, { tx, ty }, 0, type, TARGET_BOTH, src, dmg, missile[i]._mispllvl); + continue; + } + + AddMissile({ tx, ty }, { tx, ty }, 0, type, TARGET_BOTH, src, dmg, missile[i]._mispllvl); } } @@ -3821,44 +3802,48 @@ void MI_LightningRing(int i) void MI_Search(int i) { missile[i]._mirange--; - if (missile[i]._mirange == 0) { - missile[i]._miDelFlag = true; - PlaySfxLoc(IS_CAST7, plr[missile[i]._miVar1].position.tile.x, plr[missile[i]._miVar1].position.tile.y); - AutoMapShowItems = false; - } + if (missile[i]._mirange != 0) + return; + + missile[i]._miDelFlag = true; + PlaySfxLoc(IS_CAST7, plr[missile[i]._miVar1].position.tile.x, plr[missile[i]._miVar1].position.tile.y); + AutoMapShowItems = false; } void MI_LightningWallC(int i) { + int tx, ty; + missile[i]._mirange--; int id = missile[i]._misource; - int lvl = 0; - if (id > -1) - lvl = plr[id]._pLevel; + int lvl = (id > -1) ? plr[id]._pLevel : 0; + int dmg = 16 * (GenerateRnd(10) + GenerateRnd(10) + lvl + 2); if (missile[i]._mirange == 0) { missile[i]._miDelFlag = true; + return; + } + + int dp = dPiece[missile[i]._miVar1][missile[i]._miVar2]; + assert(dp <= MAXTILES && dp >= 0); + Point t = Point { missile[i]._miVar1, missile[i]._miVar2 } + (Direction)missile[i]._miVar3; + if (!nMissileTable[dp] && missile[i]._miVar8 == 0 && InDungeonBounds(t)) { + AddMissile({ missile[i]._miVar1, missile[i]._miVar2 }, { missile[i]._miVar1, missile[i]._miVar2 }, plr[id]._pdir, MIS_LIGHTWALL, TARGET_BOTH, id, dmg, missile[i]._mispllvl); + missile[i]._miVar1 = t.x; + missile[i]._miVar2 = t.y; } else { - int dp = dPiece[missile[i]._miVar1][missile[i]._miVar2]; - assert(dp <= MAXTILES && dp >= 0); - Point t = Point { missile[i]._miVar1, missile[i]._miVar2 } + (Direction)missile[i]._miVar3; - if (!nMissileTable[dp] && missile[i]._miVar8 == 0 && InDungeonBounds(t)) { - AddMissile({ missile[i]._miVar1, missile[i]._miVar2 }, { missile[i]._miVar1, missile[i]._miVar2 }, plr[id]._pdir, MIS_LIGHTWALL, TARGET_BOTH, id, dmg, missile[i]._mispllvl); - missile[i]._miVar1 = t.x; - missile[i]._miVar2 = t.y; - } else { - missile[i]._miVar8 = 1; - } - dp = dPiece[missile[i]._miVar5][missile[i]._miVar6]; - assert(dp <= MAXTILES && dp >= 0); - t = Point { missile[i]._miVar5, missile[i]._miVar6 } + (Direction)missile[i]._miVar4; - if (!nMissileTable[dp] && missile[i]._miVar7 == 0 && InDungeonBounds(t)) { - AddMissile({ missile[i]._miVar5, missile[i]._miVar6 }, { missile[i]._miVar5, missile[i]._miVar6 }, plr[id]._pdir, MIS_LIGHTWALL, TARGET_BOTH, id, dmg, missile[i]._mispllvl); - missile[i]._miVar5 = t.x; - missile[i]._miVar6 = t.y; - } else { - missile[i]._miVar7 = 1; - } + missile[i]._miVar8 = 1; + } + + dp = dPiece[missile[i]._miVar5][missile[i]._miVar6]; + assert(dp <= MAXTILES && dp >= 0); + t = Point { missile[i]._miVar5, missile[i]._miVar6 } + (Direction)missile[i]._miVar4; + if (!nMissileTable[dp] && missile[i]._miVar7 == 0 && InDungeonBounds(t)) { + AddMissile({ missile[i]._miVar5, missile[i]._miVar6 }, { missile[i]._miVar5, missile[i]._miVar6 }, plr[id]._pdir, MIS_LIGHTWALL, TARGET_BOTH, id, dmg, missile[i]._mispllvl); + missile[i]._miVar5 = t.x; + missile[i]._miVar6 = t.y; + } else { + missile[i]._miVar7 = 1; } } @@ -4028,7 +4013,6 @@ void MI_Lightning(int i) void MI_Town(int i) { int ExpLight[17] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }; - int p; if (missile[i]._mirange > 1) missile[i]._mirange--; @@ -4041,7 +4025,7 @@ void MI_Town(int i) missile[i]._miVar2++; } - for (p = 0; p < MAX_PLRS; p++) { + for (int p = 0; p < MAX_PLRS; p++) { auto &player = plr[p]; if (player.plractive && currlevel == player.plrlevel && !player._pLvlChanging && player._pmode == PM_STAND && player.position.tile == missile[i].position.tile) { ClrPlrPath(player); @@ -4379,31 +4363,30 @@ void MI_Acidsplat(int i) void MI_Teleport(int i) { - int id; - - id = missile[i]._misource; missile[i]._mirange--; if (missile[i]._mirange <= 0) { missile[i]._miDelFlag = true; - } else { - auto &player = plr[id]; + return; + } - dPlayer[player.position.tile.x][player.position.tile.y] = 0; - PlrClrTrans(player.position.tile); - player.position.tile = { missile[i].position.tile.x, missile[i].position.tile.y }; - player.position.future = player.position.tile; - player.position.old = player.position.tile; - PlrDoTrans(player.position.tile); - missile[i]._miVar1 = 1; - dPlayer[player.position.tile.x][player.position.tile.y] = id + 1; - if (leveltype != DTYPE_TOWN) { - ChangeLightXY(player._plid, player.position.tile); - ChangeVisionXY(player._pvid, player.position.tile); - } - if (id == myplr) { - ViewX = player.position.tile.x - ScrollInfo.tile.x; - ViewY = player.position.tile.y - ScrollInfo.tile.y; - } + int id = missile[i]._misource; + auto &player = plr[id]; + + dPlayer[player.position.tile.x][player.position.tile.y] = 0; + PlrClrTrans(player.position.tile); + player.position.tile = { missile[i].position.tile.x, missile[i].position.tile.y }; + player.position.future = player.position.tile; + player.position.old = player.position.tile; + PlrDoTrans(player.position.tile); + missile[i]._miVar1 = 1; + dPlayer[player.position.tile.x][player.position.tile.y] = id + 1; + if (leveltype != DTYPE_TOWN) { + ChangeLightXY(player._plid, player.position.tile); + ChangeVisionXY(player._pvid, player.position.tile); + } + if (id == myplr) { + ViewX = player.position.tile.x - ScrollInfo.tile.x; + ViewY = player.position.tile.y - ScrollInfo.tile.y; } } @@ -4521,31 +4504,35 @@ void MI_Fireman(int i) void MI_FirewallC(int i) { + int dp, tx, ty; + missile[i]._mirange--; int id = missile[i]._misource; if (missile[i]._mirange == 0) { missile[i]._miDelFlag = true; + return; + } + + int dp = dPiece[missile[i]._miVar1][missile[i]._miVar2]; + assert(dp <= MAXTILES && dp >= 0); + Point t = Point { missile[i]._miVar1, missile[i]._miVar2 } + (Direction)missile[i]._miVar3; + if (!nMissileTable[dp] && missile[i]._miVar8 == 0 && InDungeonBounds(t)) { + AddMissile({ missile[i]._miVar1, missile[i]._miVar2 }, { missile[i]._miVar1, missile[i]._miVar2 }, plr[id]._pdir, MIS_FIREWALL, TARGET_BOTH, id, 0, missile[i]._mispllvl); + missile[i]._miVar1 = t.x; + missile[i]._miVar2 = t.y; } else { - int dp = dPiece[missile[i]._miVar1][missile[i]._miVar2]; - assert(dp <= MAXTILES && dp >= 0); - Point t = Point { missile[i]._miVar1, missile[i]._miVar2 } + (Direction)missile[i]._miVar3; - if (!nMissileTable[dp] && missile[i]._miVar8 == 0 && InDungeonBounds(t)) { - AddMissile({ missile[i]._miVar1, missile[i]._miVar2 }, { missile[i]._miVar1, missile[i]._miVar2 }, plr[id]._pdir, MIS_FIREWALL, TARGET_BOTH, id, 0, missile[i]._mispllvl); - missile[i]._miVar1 = t.x; - missile[i]._miVar2 = t.y; - } else { - missile[i]._miVar8 = 1; - } - dp = dPiece[missile[i]._miVar5][missile[i]._miVar6]; - assert(dp <= MAXTILES && dp >= 0); - t = Point { missile[i]._miVar5, missile[i]._miVar6 } + (Direction)missile[i]._miVar4; - if (!nMissileTable[dp] && missile[i]._miVar7 == 0 && InDungeonBounds(t)) { - AddMissile({ missile[i]._miVar5, missile[i]._miVar6 }, { missile[i]._miVar5, missile[i]._miVar6 }, plr[id]._pdir, MIS_FIREWALL, TARGET_BOTH, id, 0, missile[i]._mispllvl); - missile[i]._miVar5 = t.x; - missile[i]._miVar6 = t.y; - } else { - missile[i]._miVar7 = 1; - } + missile[i]._miVar8 = 1; + } + + dp = dPiece[missile[i]._miVar5][missile[i]._miVar6]; + assert(dp <= MAXTILES && dp >= 0); + t = Point { missile[i]._miVar5, missile[i]._miVar6 } + (Direction)missile[i]._miVar4; + if (!nMissileTable[dp] && missile[i]._miVar7 == 0 && InDungeonBounds(t)) { + AddMissile({ missile[i]._miVar5, missile[i]._miVar6 }, { missile[i]._miVar5, missile[i]._miVar6 }, plr[id]._pdir, MIS_FIREWALL, TARGET_BOTH, id, 0, missile[i]._mispllvl); + missile[i]._miVar5 = t.x; + missile[i]._miVar6 = t.y; + } else { + missile[i]._miVar7 = 1; } } @@ -4627,6 +4614,7 @@ void MI_Wave(int i) } } } + missile[i]._mirange--; if (missile[i]._mirange == 0) missile[i]._miDelFlag = true; @@ -4662,33 +4650,32 @@ void MI_Nova(int i) void MI_Blodboil(int i) { - int id, hpdif; - missile[i]._mirange--; - if (missile[i]._mirange == 0) { - id = missile[i]._miVar1; - auto &player = plr[id]; - if ((player._pSpellFlags & 2) == 2) { - player._pSpellFlags &= ~0x2; - player._pSpellFlags |= 4; - int lvl = player._pLevel * 2; - missile[i]._mirange = lvl + 10 * missile[i]._mispllvl + 245; - hpdif = player._pMaxHP - player._pHitPoints; - CalcPlrItemVals(id, true); - ApplyPlrDamage(id, 0, 1, hpdif); - force_redraw = 255; - player.Say(HeroSpeech::HeavyBreathing); - } else { - missile[i]._miDelFlag = true; - player._pSpellFlags &= ~0x4; - hpdif = player._pMaxHP - player._pHitPoints; - CalcPlrItemVals(id, true); - ApplyPlrDamage(id, 0, 1, hpdif + missile[i]._miVar2); - force_redraw = 255; - player.Say(HeroSpeech::HeavyBreathing); - } + if (missile[i]._mirange != 0) { + return; + } + + int id = missile[i]._miVar1; + auto &player = plr[id]; + + int hpdif = player._pMaxHP - player._pHitPoints; + + if ((player._pSpellFlags & 2) != 0) { + player._pSpellFlags &= ~0x2; + player._pSpellFlags |= 4; + int lvl = player._pLevel * 2; + missile[i]._mirange = lvl + 10 * missile[i]._mispllvl + 245; + } else { + player._pSpellFlags &= ~0x4; + missile[i]._miDelFlag = true; + hpdif += missile[i]._miVar2; } + + CalcPlrItemVals(id, true); + ApplyPlrDamage(id, 0, 1, hpdif); + force_redraw = 255; + player.Say(HeroSpeech::HeavyBreathing); } void MI_Flame(int i)