diff --git a/Source/misdat.cpp b/Source/misdat.cpp index fcbca78fb..5a663e65d 100644 --- a/Source/misdat.cpp +++ b/Source/misdat.cpp @@ -18,7 +18,7 @@ MissileData MissilesData[] = { // clang-format off // mAddProc, mProc, name, mDraw, mType, damageType, mFileNum, mlSFX, miSFX, MovementDistribution; { &AddArrow, &MI_Arrow, MissileID::Arrow, true, 0, DamageType::Physical, MFILE_ARROWS, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, -{ &AddFirebolt, &MI_Firebolt, MissileID::Firebolt, true, 1, DamageType::Fire, MFILE_FIREBA, LS_FBOLT1, LS_FIRIMP2, MissileMovementDistribution::Blockable }, +{ &AddFirebolt, &MI_Projectile, MissileID::Firebolt, true, 1, DamageType::Fire, MFILE_FIREBA, LS_FBOLT1, LS_FIRIMP2, MissileMovementDistribution::Blockable }, { &AddGuardian, &MI_Guardian, MissileID::Guardian, true, 1, DamageType::Physical, MFILE_GUARD, LS_GUARD, LS_GUARDLAN, MissileMovementDistribution::Disabled }, { &AddRndTeleport, &MI_Teleport, MissileID::Phasing, false, 1, DamageType::Physical, MFILE_NONE, LS_TELEPORT, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddLightball, &MI_Lightball, MissileID::NovaBall, true, 1, DamageType::Lightning, MFILE_LGHNING, SFX_NONE, SFX_NONE, MissileMovementDistribution::Unblockable }, @@ -38,10 +38,10 @@ MissileData MissilesData[] = { { nullptr, nullptr, MissileID::BoneHit, true, 2, DamageType::Physical, MFILE_BONE, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, { nullptr, nullptr, MissileID::MetalHit, true, 2, DamageType::Physical, MFILE_METLHIT, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddRhino, &MI_Rhino, MissileID::Rhino, true, 2, DamageType::Physical, MFILE_NONE, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, -{ &AddMagmaball, &MI_Firebolt, MissileID::MagmaBall, true, 1, DamageType::Fire, MFILE_MAGBALL, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, +{ &AddMagmaball, &MI_Projectile, MissileID::MagmaBall, true, 1, DamageType::Fire, MFILE_MAGBALL, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, { &AddLightctrl, &MI_Lightctrl, MissileID::ThinLightningControl, false, 1, DamageType::Lightning, MFILE_THINLGHT, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddLightning, &MI_Lightning, MissileID::ThinLightning, true, 1, DamageType::Lightning, MFILE_THINLGHT, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, -{ &AddFlare, &MI_Firebolt, MissileID::BloodStar, true, 1, DamageType::Magic, MFILE_FLARE, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, +{ &AddFlare, &MI_Projectile, MissileID::BloodStar, true, 1, DamageType::Magic, MFILE_FLARE, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, { &AddMisexp, &MI_Misexp, MissileID::BloodStarExplosion, true, 2, DamageType::Magic, MFILE_FLAREEXP, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddTeleport, &MI_Teleport, MissileID::Teleport, false, 1, DamageType::Physical, MFILE_NONE, LS_ELEMENTL, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddLArrow, &MI_LArrow, MissileID::FireArrow, true, 0, DamageType::Fire, MFILE_FARROW, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, @@ -74,7 +74,7 @@ MissileData MissilesData[] = { { &AddResurrect, nullptr, MissileID::Resurrect, false, 1, DamageType::Magic, MFILE_NONE, SFX_NONE, LS_RESUR, MissileMovementDistribution::Disabled }, { &AddTelekinesis, nullptr, MissileID::Telekinesis, false, 1, DamageType::Physical, MFILE_NONE, LS_ETHEREAL, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddLArrow, &MI_LArrow, MissileID::LightningArrow, true, 0, DamageType::Lightning, MFILE_LARROW, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, -{ &AddAcid, &MI_Firebolt, MissileID::Acid, true, 1, DamageType::Acid, MFILE_ACIDBF, LS_ACID, SFX_NONE, MissileMovementDistribution::Blockable }, +{ &AddAcid, &MI_Projectile, MissileID::Acid, true, 1, DamageType::Acid, MFILE_ACIDBF, LS_ACID, SFX_NONE, MissileMovementDistribution::Blockable }, { &AddMisexp, &MI_Acidsplat, MissileID::AcidSplat, true, 2, DamageType::Acid, MFILE_ACIDSPLA, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddAcidpud, &MI_Acidpud, MissileID::AcidPuddle, true, 2, DamageType::Acid, MFILE_ACIDPUD, LS_PUDDLE, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddHealOther, nullptr, MissileID::HealOther, false, 1, DamageType::Physical, MFILE_NONE, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, @@ -115,11 +115,11 @@ MissileData MissilesData[] = { { &AddHorkSpawn, &MI_HorkSpawn, MissileID::HorkSpawn, false, 2, DamageType::Physical, MFILE_NONE, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddJester, nullptr, MissileID::Jester, false, 2, DamageType::Physical, MFILE_NONE, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddHiveExplosion, nullptr, MissileID::OpenNest, false, 2, DamageType::Physical, MFILE_NONE, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled }, -{ &AddFlare, &MI_Firebolt, MissileID::OrangeFlare, true, 1, DamageType::Magic, MFILE_LICH, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, -{ &AddFlare, &MI_Firebolt, MissileID::BlueFlare, true, 1, DamageType::Magic, MFILE_BONEDEMON, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, -{ &AddFlare, &MI_Firebolt, MissileID::RedFlare, true, 1, DamageType::Magic, MFILE_NECROMORB, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, -{ &AddFlare, &MI_Firebolt, MissileID::YellowFlare, true, 1, DamageType::Magic, MFILE_ARCHLICH, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, -{ &AddFlare, &MI_Firebolt, MissileID::BlueFlare2, true, 1, DamageType::Magic, MFILE_BONEDEMON, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, +{ &AddFlare, &MI_Projectile, MissileID::OrangeFlare, true, 1, DamageType::Magic, MFILE_LICH, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, +{ &AddFlare, &MI_Projectile, MissileID::BlueFlare, true, 1, DamageType::Magic, MFILE_BONEDEMON, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, +{ &AddFlare, &MI_Projectile, MissileID::RedFlare, true, 1, DamageType::Magic, MFILE_NECROMORB, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, +{ &AddFlare, &MI_Projectile, MissileID::YellowFlare, true, 1, DamageType::Magic, MFILE_ARCHLICH, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, +{ &AddFlare, &MI_Projectile, MissileID::BlueFlare2, true, 1, DamageType::Magic, MFILE_BONEDEMON, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable }, { &AddMisexp, &MI_Misexp, MissileID::YellowExplosion, true, 2, DamageType::Physical, MFILE_EXYEL2, LS_FIRIMP2, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddMisexp, &MI_Misexp, MissileID::RedExplosion, true, 2, DamageType::Physical, MFILE_EXRED3, LS_FIRIMP2, SFX_NONE, MissileMovementDistribution::Disabled }, { &AddMisexp, &MI_Misexp, MissileID::BlueExplosion, true, 2, DamageType::Physical, MFILE_EXBL2, LS_FIRIMP2, SFX_NONE, MissileMovementDistribution::Disabled }, diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 23331bce6..c5385cb07 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -189,6 +189,17 @@ void MoveMissilePos(Missile &missile) } } +int ProjectileMonsterDamage(Missile &missile) +{ + const Monster &monster = *missile.sourceMonster(); + return monster.minDamage + GenerateRnd(monster.maxDamage - monster.minDamage + 1); +} + +int ProjectileTrapDamage(Missile &missile) +{ + return currlevel + GenerateRnd(2 * currlevel); +} + bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, MissileID t, bool shift) { auto &monster = Monsters[monsterId]; @@ -648,7 +659,7 @@ bool GuardianTryFireAt(Missile &missile, Point target) return false; Direction dir = GetDirection(position, target); - AddMissile(position, target, dir, MissileID::Firebolt, TARGET_MONSTERS, missile._misource, missile._midam, missile.sourcePlayer()->GetSpellLevel(SPL_FIREBOLT), &missile); + AddMissile(position, target, dir, MissileID::Firebolt, TARGET_MONSTERS, missile._misource, missile._midam, missile.sourcePlayer()->GetSpellLevel(SPL_GUARDIAN), &missile); SetMissDir(missile, 2); missile.var2 = 3; @@ -1763,6 +1774,21 @@ void AddFirebolt(Missile &missile, AddMissileParameter ¶meter) missile.var1 = missile.position.start.x; missile.var2 = missile.position.start.y; missile._mlid = AddLight(missile.position.start, 8); + switch (missile.sourceType()) { + case MissileSource::Player: + if (missile._midam == 0) { + const Player &player = *missile.sourcePlayer(); + missile._midam = GenerateRnd(10) + (player._pMagic / 8) + missile._mispllvl + 1; + } + break; + + case MissileSource::Monster: + missile._midam = ProjectileMonsterDamage(missile); + break; + case MissileSource::Trap: + missile._midam = ProjectileTrapDamage(missile); + break; + } } void AddMagmaball(Missile &missile, AddMissileParameter ¶meter) @@ -1778,6 +1804,18 @@ void AddMagmaball(Missile &missile, AddMissileParameter ¶meter) missile.var1 = missile.position.start.x; missile.var2 = missile.position.start.y; missile._mlid = AddLight(missile.position.start, 8); + switch (missile.sourceType()) { + case MissileSource::Player: + // Not typically created by Players + missile._midam = 0; + break; + case MissileSource::Monster: + missile._midam = ProjectileMonsterDamage(missile); + break; + case MissileSource::Trap: + missile._midam = ProjectileTrapDamage(missile); + break; + } } void AddTeleport(Missile &missile, AddMissileParameter ¶meter) @@ -2160,6 +2198,20 @@ void AddFlare(Missile &missile, AddMissileParameter ¶meter) if (MissileSpriteData[missile._miAnimType].animFAmt == 16) { SetMissDir(missile, GetDirection16(missile.position.start, dst)); } + + switch (missile.sourceType()) { + case MissileSource::Player: { + const Player &player = *missile.sourcePlayer(); + missile._midam = 3 * missile._mispllvl - (player._pMagic / 8) + (player._pMagic / 2); + break; + } + case MissileSource::Monster: + missile._midam = ProjectileMonsterDamage(missile); + break; + case MissileSource::Trap: + missile._midam = ProjectileTrapDamage(missile); + break; + } } void AddAcid(Missile &missile, AddMissileParameter ¶meter) @@ -2173,6 +2225,18 @@ void AddAcid(Missile &missile, AddMissileParameter ¶meter) missile._mlid = NO_LIGHT; missile.var1 = missile.position.start.x; missile.var2 = missile.position.start.y; + switch (missile.sourceType()) { + case MissileSource::Player: + // Not typically used by Players + missile._midam = 0; + break; + case MissileSource::Monster: + missile._midam = ProjectileMonsterDamage(missile); + break; + case MissileSource::Trap: + missile._midam = ProjectileTrapDamage(missile); + break; + } PutMissile(missile); } @@ -2791,42 +2855,12 @@ void MI_Arrow(Missile &missile) PutMissile(missile); } -void MI_Firebolt(Missile &missile) +void MI_Projectile(Missile &missile) { - int d = 0; - missile._mirange--; - if (missile._mitype != MissileID::BoneSpirit || missile._mimfnum != 8) { - switch (missile.sourceType()) { - case MissileSource::Player: { - const Player &player = *missile.sourcePlayer(); - switch (missile._mitype) { - case MissileID::Firebolt: - // BUGFIX: damage of missile should be encoded in missile struct; player can be dead/have left the game before missile arrives. - d = GenerateRnd(10) + (player._pMagic / 8) + missile._mispllvl + 1; - break; - case MissileID::BloodStar: - // BUGFIX: damage of missile should be encoded in missile struct; player can be dead/have left the game before missile arrives. - d = 3 * missile._mispllvl - (player._pMagic / 8) + (player._pMagic / 2); - break; - case MissileID::BoneSpirit: - d = 0; - break; - default: - break; - } - } break; - case MissileSource::Monster: { - const Monster &monster = *missile.sourceMonster(); - // BUGFIX: damage of missile should be encoded in missile struct; monster can be dead before missile arrives. - d = monster.minDamage + GenerateRnd(monster.maxDamage - monster.minDamage + 1); - } break; - case MissileSource::Trap: - d = currlevel + GenerateRnd(2 * currlevel); - break; - } - MoveMissileAndCheckMissileCol(missile, d, d, true, true); + if (missile._mimfnum != 8) { + MoveMissileAndCheckMissileCol(missile, missile._midam, missile._midam, true, true); if (missile._mirange == 0) { missile._miDelFlag = true; Point dst = { 0, 0 }; @@ -2842,12 +2876,12 @@ void MI_Firebolt(Missile &missile) case MissileID::Acid: AddMissile(missile.position.tile, dst, dir, MissileID::AcidSplat, missile._micaster, missile._misource, 0, 0, &missile); break; - case MissileID::BoneSpirit: + /*case MissileID::BoneSpirit: SetMissDir(missile, 8); missile._mirange = 7; missile._miDelFlag = false; PutMissile(missile); - return; + return;*/ case MissileID::OrangeFlare: AddMissile(missile.position.tile, dst, dir, MissileID::OrangeExplosion, missile._micaster, missile._misource, 0, 0, &missile); break; diff --git a/Source/missiles.h b/Source/missiles.h index 52a336476..23962397a 100644 --- a/Source/missiles.h +++ b/Source/missiles.h @@ -388,7 +388,7 @@ void AddDiabApoca(Missile &missile, AddMissileParameter ¶meter); Missile *AddMissile(Point src, Point dst, Direction midir, MissileID mitype, mienemy_type micaster, int id, int midam, int spllvl, Missile *pParent = nullptr); void MI_LArrow(Missile &missile); void MI_Arrow(Missile &missile); -void MI_Firebolt(Missile &missile); +void MI_Projectile(Missile &missile); void MI_Lightball(Missile &missilei); void MI_Acidpud(Missile &missile); void MI_Firewall(Missile &missile);