From 4f7c565d22b04eaef078ade1488f09cd92b2a970 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 1 Oct 2022 12:15:13 -0700 Subject: [PATCH] MM: MM1: Beginning to implement monster spells --- devtools/create_mm/files/mm1/strings_en.yml | 13 ++++ engines/mm/mm1/game/combat.h | 2 +- engines/mm/mm1/game/encounter.h | 3 +- engines/mm/mm1/game/spells_monsters.cpp | 77 +++++++++++++++++++-- engines/mm/mm1/game/spells_monsters.h | 20 +++++- 5 files changed, 105 insertions(+), 10 deletions(-) diff --git a/devtools/create_mm/files/mm1/strings_en.yml b/devtools/create_mm/files/mm1/strings_en.yml index e9b6403668d..d7fd29c0868 100644 --- a/devtools/create_mm/files/mm1/strings_en.yml +++ b/devtools/create_mm/files/mm1/strings_en.yml @@ -739,6 +739,7 @@ monster_spells: of_damage: "OF DAMAGE!" goes_down: "GOES DOWN!!!" dies: "DIES!" + breathes: "BREATHES" a_curse: "A CURSE" energy_blast: "ENERGY BLAST" blindles: "BLINDNESS" @@ -770,6 +771,18 @@ monster_spells: energy: "ENERGY" swarm: "SWARM" breathes: "BREATHES " + effects: + 0: "IS SLEPT" + 1: "IS BLINDED" + 2: "IS SILENCED" + 3: "IS DISEASED" + 4: "IS POISONED" + 5: "IS PARALYZED" + 6: "IS RENDERED UNCONSCIOUS" + 7: "IS KILLED" + 8: "IS TURNED TO STONE" + 9: "IS ERADICATED" + 10: "IS AFFECTED" maps: map00: diff --git a/engines/mm/mm1/game/combat.h b/engines/mm/mm1/game/combat.h index e9b00332ae1..3261ae63bd5 100644 --- a/engines/mm/mm1/game/combat.h +++ b/engines/mm/mm1/game/combat.h @@ -139,7 +139,7 @@ protected: /** * Get the monster index */ - int getMonsterIndex() const { + int getMonsterIndex() const override { return _monsterIndex; } diff --git a/engines/mm/mm1/game/encounter.h b/engines/mm/mm1/game/encounter.h index d3c6aa5bbc9..0676e245fd4 100644 --- a/engines/mm/mm1/game/encounter.h +++ b/engines/mm/mm1/game/encounter.h @@ -45,7 +45,6 @@ private: int _monsterNum16 = 0; int _totalLevels = 0; int _monsterNum = 0; - byte _arr1[MAX_COMBAT_MONSTERS]; byte _monsIndexes[MAX_COMBAT_MONSTERS]; void randomAdjust(); @@ -59,6 +58,8 @@ public: int _highestLevel = 0; EncounterType _encounterType = NORMAL_SURPRISED; byte _fleeThreshold = 0; + byte _arr1[MAX_COMBAT_MONSTERS]; + public: /** * Start an encounter diff --git a/engines/mm/mm1/game/spells_monsters.cpp b/engines/mm/mm1/game/spells_monsters.cpp index b2651149e12..30247ea28ba 100644 --- a/engines/mm/mm1/game/spells_monsters.cpp +++ b/engines/mm/mm1/game/spells_monsters.cpp @@ -64,7 +64,8 @@ const SpellMonstersSpell SpellsMonsters::SPELLS[MONSTER_SPELLS_COUNT] = { }; void SpellsMonsters::castMonsterSpell(const Common::String &monsterName, int spellNum) { - _mmVal1 = _mmVal2 = _resistanceType = _mmVal4 = 0; + _mmVal1 = _mmVal2 = _newCondition = 0; + _resistanceType = RESISTANCE_MAGIC; // All spell messages start with the monster who casts it _lines.clear(); @@ -85,14 +86,39 @@ void SpellsMonsters::spell02_energyBlast() { if (casts()) { add(STRING["monster_spells.energy_blast"]); ++_mmVal1; - _mmVal4 = getRandomNumber(16) + 4; + _newCondition = getRandomNumber(16) + 4; damageRandomChar(); } } -void SpellsMonsters::spell03_fire() {} +void SpellsMonsters::spell03_fire() { + add(Common::String::format("%s %s", + STRING["monster_spells.breathes"].c_str(), + STRING["monster_spells.fire"].c_str())); + ++_mmVal2; + _resistanceType = RESISTANCE_FIRE; -void SpellsMonsters::spell04_blindness() {} + int count = g_globals->_encounters._arr1[getMonsterIndex()]; + _newCondition += count * 6; + + damageRandomChar(); +} + +void SpellsMonsters::spell04_blindness() { + if (casts()) { + add(STRING["monster_spells.blindness"]); + ++_mmVal1; + ++_mmVal2; + _newCondition = 2; + + add(':'); + + for (uint i = 0; i < g_globals->_party.size(); ++i) { + g_globals->_currCharacter = &g_globals->_party[i]; + writeConditionEffect(); + } + } +} void SpellsMonsters::spell05_sprayPoison() {} @@ -192,7 +218,7 @@ bool SpellsMonsters::isCharAffected() const { void SpellsMonsters::handleDamage() { _mmVal5 = 1; - _damage = _mmVal4; + _damage = _newCondition; if (charAffected()) { if (isEffective()) { @@ -370,6 +396,47 @@ bool SpellsMonsters::damageType7() { } } +void SpellsMonsters::writeConditionEffect() { + _mmVal5 = 0; + int effectNum; + + if (!charAffected() || !isEffective() || !testElementalResistance()) + return; + + if (_newCondition == 0) { + effectNum = 10; + } else if (_newCondition & BAD_CONDITION) { + if (!(_newCondition & (BAD_CONDITION | DEAD))) + effectNum = 7; + else if (!(_newCondition & (BAD_CONDITION | STONE))) + effectNum = 8; + else if (_newCondition == ERADICATED) + effectNum = 9; + else + effectNum = 10; + } else { + effectNum = 0; + + for (byte bitset = _newCondition; bitset & 1; + ++effectNum, bitset >>= 1) { + } + } + + add(STRING[Common::String::format("monster_spells.effects.%d", + effectNum)]); + add('!'); +} + +void SpellsMonsters::setCondition(byte newCondition) { + Character &c = *g_globals->_currCharacter; + + if (!(c._condition & BAD_CONDITION)) { + c._condition |= newCondition; + } else if (newCondition & BAD_CONDITION) { + c._condition = newCondition; + } +} + } // namespace Game } // namespace MM1 } // namespace MM diff --git a/engines/mm/mm1/game/spells_monsters.h b/engines/mm/mm1/game/spells_monsters.h index 90bfb30ae68..0b0a5dccf96 100644 --- a/engines/mm/mm1/game/spells_monsters.h +++ b/engines/mm/mm1/game/spells_monsters.h @@ -23,6 +23,7 @@ #define MM1_GAME_SPELLS_MONSTERS #include "mm/mm1/game/game_logic.h" +#include "mm/mm1/data/character.h" #include "mm/mm1/messages.h" #include "common/str.h" @@ -40,9 +41,11 @@ private: static const SpellMonstersSpell SPELLS[MONSTER_SPELLS_COUNT]; LineArray _lines; int _mmVal1 = 0, _mmVal2 = 0; - int _resistanceType = 0, _mmVal4 = 0; - int _mmVal5 = 0, _damage = 0; + byte _newCondition = 0; + int _mmVal5 = 0; int _mmVal7 = 0; + Resistance _resistanceType = RESISTANCE_MAGIC; + int _damage = 0; void spell01_curse(); void spell02_energyBlast(); @@ -142,8 +145,10 @@ private: void subtractDamage(); bool testElementalResistance(); - void proc9(); + /** + * Test whether character resists different damage types + */ bool damageType1(); bool damageType2(); bool damageType3(); @@ -152,8 +157,17 @@ private: bool damageType6(); bool damageType7(); + /** + * Writes different spell effects + */ + void writeConditionEffect(); + + void setCondition(byte newCondition); + void proc9(); + protected: virtual bool canMonsterCast() const = 0; + virtual int getMonsterIndex() const = 0; public: /**