Mercurial > mm7
diff Engine/Spells/Spells.cpp @ 2499:68cdef6879a0
engine folder
author | Ritor1 |
---|---|
date | Fri, 19 Sep 2014 02:57:42 +0600 |
parents | |
children | a77c34acdbc9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Engine/Spells/Spells.cpp Fri Sep 19 02:57:42 2014 +0600 @@ -0,0 +1,741 @@ +#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> + +#define _CRT_SECURE_NO_WARNINGS +#include <stdlib.h> +#include "../ErrorHandling.h" + +#include "Spells.h" +#include "Engine/Graphics/Overlays.h" +#include "../LOD.h" +#include "../texts.h" + +#include "../Party.h" +#include "../OurMath.h" +#include "Engine/Objects/SpriteObject.h" +#include "Engine/Objects/ObjectList.h" +#include "Engine/Graphics/Indoor.h" +#include "AudioPlayer.h" +#include "Engine/Objects/Actor.h" +#include "../Game.h" +#include "stru6.h" + + +std::array<TownPortalData, 6> TownPortalList = //4ECBB8 +{{ + {Vec3_int_(-5121, 2107, 1), 1536, 0, 21, 0}, + {Vec3_int_(-15148, -10240, 1473), 0, 0, 4, 0}, + {Vec3_int_(-10519, 5375, 753), 512, 0, 3, 0}, + {Vec3_int_(3114, -11055, 513), 0, 0, 10, 0}, + {Vec3_int_(-158, 7624, 1), 512, 0, 7, 0}, + {Vec3_int_(-1837, -4247, 65), 65, 0, 8, 0} +}} ; + +struct SpellStats *pSpellStats; + + +std::array<stru324_spell, 103> stru_4E3ACC = +{{ + {10, 0}, + {1000, 0}, {1010, 0}, {1020, 0}, {1030, 0}, {1040, 0}, {1050, 0}, {1060, 0}, {1070, 0}, {1080, 0}, {1090, 0}, {1100, 0}, + {2000, 0}, {2010, 0}, {2020, 0}, {2030, 0}, {2040, 0}, {2050, 0}, {2060, 0}, {2070, 0}, {2080, 0}, {2090, 0}, {2100, 0}, + {3000, 0}, {3010, 0}, {3020, 0}, {3030, 0}, {3040, 0}, {3050, 0}, {3060, 0}, {3070, 0}, {3080, 0}, {3090, 0}, {3100, 0}, + {4000, 0}, {4010, 0}, {4020, 0}, {4030, 0}, {4040, 0}, {4050, 0}, {4060, 0}, {4070, 0}, {4080, 0}, {4090, 0}, {4100, 0}, + {5000, 0}, {5010, 0}, {5020, 0}, {5030, 0}, {5040, 0}, {5050, 0}, {5060, 0}, {5070, 0}, {5080, 0}, {5090, 0}, {5100, 0}, + {6000, 0}, {6010, 0}, {6020, 0}, {6030, 0}, {6040, 0}, {6050, 0}, {6060, 0}, {6070, 0}, {6080, 0}, {6090, 0}, {6100, 0}, + {7000, 0}, {7010, 0}, {7020, 0}, {7030, 0}, {7040, 0}, {7050, 0}, {7060, 0}, {7070, 0}, {7080, 0}, {7090, 0}, {7100, 0}, + {8000, 0}, {8010, 0}, {8020, 0}, {8030, 0}, {8040, 0}, {8050, 0}, {8060, 0}, {8070, 0}, {8080, 0}, {8090, 0}, {8100, 0}, + {9000, 0}, {9010, 0}, {9020, 0}, {9030, 0}, {9040, 0}, {9050, 0}, {9060, 0}, {9070, 0}, {9080, 0}, {9090, 0}, {9100, 0}, + {545, 0}, + {545, 0}, + {555, 0} +}}; + + + +SpellData::SpellData( __int16 innormalMana, __int16 inExpertLevelMana, __int16 inMasterLevelMana, __int16 inMagisterLevelMana, + __int16 inNormalLevelRecovery, __int16 inExpertLevelRecovery, __int16 inMasterLevelRecovery, __int16 inMagisterLevelRecovery, + __int8 inbaseDamage, __int8 inbonusSkillDamage, __int16 instats ): +uNormalLevelMana(innormalMana), +uExpertLevelMana(inExpertLevelMana), +uMasterLevelMana(inMasterLevelMana), +uMagisterLevelMana(inMagisterLevelMana), +uNormalLevelRecovery(inNormalLevelRecovery), +uExpertLevelRecovery(inExpertLevelRecovery), +uMasterLevelRecovery(inMasterLevelRecovery), +uMagisterLevelRecovery(inMagisterLevelRecovery), +baseDamage(inbaseDamage), +bonusSkillDamage(inbonusSkillDamage), +stats(instats) +{ + +} + + //9 spellbook pages 11 spells per page 9*11 =99 +1 zero struct at 0. It counted from 1! +std::array<SpellData, 100> pSpellDatas={{ + SpellData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + + SpellData(1, 1, 1, 1, 60, 60, 60, 40, 0, 0, 0),//0 fire + SpellData(2, 2, 2, 2, 110, 110, 100, 90, 3, 3, 0), + SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0), + SpellData(4, 4, 4, 4, 120, 120, 120, 120, 0, 0, 0), + SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0), + SpellData(8, 8, 8, 8, 100, 100, 90, 80, 0, 6, 0), + SpellData(10, 10, 10, 10, 150, 150, 150, 150, 0, 6, 0), + SpellData(15, 15, 15, 15, 120, 120, 120, 120, 0, 6, 0), + SpellData(20, 20, 20, 20, 100, 100, 100, 90, 8, 1, 0), + SpellData(25, 25, 25, 25, 100, 100, 100, 90, 12, 1, 0), + SpellData(30, 30, 30, 30, 90, 90, 90, 90, 15, 15, 0), + + SpellData(1, 1, 1, 0, 60, 60, 60, 60, 0, 0, 0), //1 air + SpellData(2, 2, 2, 2, 120, 120, 120, 100, 0, 0, 0), + SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0), + SpellData(4, 4, 4, 4, 110, 100, 90, 80, 2, 1, 0), + SpellData(5, 5, 5, 5, 90, 90, 70, 50, 0, 0, 0), + SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0), + SpellData(10, 10, 10, 10, 100, 100, 90, 70, 0, 8, 0), + SpellData(15, 15, 15, 15, 200, 200, 200, 200, 0, 0, 0), + SpellData(20, 20, 20, 20, 100, 100, 100, 90, 10, 10, 0), + SpellData(25, 25, 25, 25, 250, 250, 250, 250, 0, 0, 0), + SpellData(30, 30, 30, 30, 90, 90, 90, 90, 20, 1, 0), + + SpellData(1, 1, 1, 1, 60, 60, 60, 20, 0, 0, 0), //2 water + SpellData(2, 2, 2, 2, 110, 100, 90, 70, 2, 2, 0), + SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0), + SpellData(4, 4, 4, 4, 110, 100, 90, 80, 0, 4, 0), + SpellData(5, 5, 5, 5, 150, 150, 150, 150, 0, 0, 0), + SpellData(8, 8, 8, 8, 200, 200, 200, 200, 0, 0, 0), + SpellData(10, 10, 10, 10, 100, 100, 90, 80, 9, 9, 0), + SpellData(15, 15, 15, 15, 140, 140, 140, 140, 0, 0, 0), + SpellData(20, 20, 20, 20, 200, 200, 200, 200, 0, 0, 0), + SpellData(25, 25, 25, 25, 80, 80, 80, 80, 12, 3, 0), + SpellData(30, 30, 30, 30, 250, 250, 250, 250, 0, 0, 0), + + SpellData(1, 1, 1, 1, 80, 80, 80, 80, 0, 0, 0), //3 earth + SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0), + SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0), + SpellData(4, 4, 4, 4, 110, 100, 90, 80, 5, 3, 0), + SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0), + SpellData(8, 8, 8, 8, 100, 100, 90, 80, 0, 9, 0), + SpellData(10, 10, 10, 10, 140, 140, 140, 140, 0, 0, 0), + SpellData(15, 15, 15, 15, 90, 90, 90, 80, 0, 8, 0), + SpellData(20, 20, 20, 20, 150, 150, 150, 150, 0, 0, 0), + SpellData(25, 25, 25, 25, 100, 100, 100, 90, 20, 1, 0), + SpellData(30, 30, 30, 30, 90, 90, 90, 90, 25, 0, 0), + + SpellData(1, 1, 1, 1, 100, 100, 100, 100, 0, 0, 0), //4 spirit + SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0), + SpellData(3, 3, 3, 3, 90, 90, 90, 90, 0, 0, 0), + SpellData(4, 4, 4, 4, 120, 120, 120, 120, 0, 0, 0), + SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0), + SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0), + SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0), + SpellData(15, 15, 15, 15, 100, 100, 100, 100, 10, 8, 0), + SpellData(20, 20, 20, 20, 240, 240, 240, 240, 0, 0, 0), + SpellData(25, 25, 25, 25, 150, 150, 150, 150, 0, 0, 0), + SpellData(30, 30, 30, 30, 1000, 1000, 1000, 1000, 0, 0, 0), + + SpellData(1, 1, 1, 1, 120, 120, 120, 120, 0, 0, 0), //5 mind + SpellData(2, 2, 2, 2, 110, 110, 110, 110, 3, 3, 0), + SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0), + SpellData(4, 4, 4, 4, 110, 100, 90, 80, 0, 0, 0), + SpellData(5, 5, 5, 5, 100, 100, 100, 100, 0, 0, 0), + SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0), + SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0), + SpellData(15, 15, 15, 15, 80, 80, 80, 80, 0, 0, 0), + SpellData(20, 20, 20, 20, 120, 120, 120, 120, 0, 0, 0), + SpellData(25, 25, 25, 25, 110, 110, 110, 100, 12, 12, 0), + SpellData(30, 30, 30, 30, 120, 120, 120, 120, 0, 0, 0), + + SpellData(1, 1, 1, 1, 120, 120, 120, 120, 0, 0, 0), //6 body + SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0), + SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0), + SpellData(4, 4, 4, 4, 110, 100, 90, 80, 8, 2, 0), + SpellData(5, 5, 5, 5, 110, 110, 110, 110, 0, 0, 0), + SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0), + SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0), + SpellData(15, 15, 15, 15, 120, 120, 120, 120, 0, 0, 0), + SpellData(20, 20, 20, 20, 120, 120, 120, 120, 0, 0, 0), + SpellData(25, 25, 25, 25, 110, 110, 110, 100, 30, 5, 0), + SpellData(30, 30, 30, 30, 100, 100, 100, 100, 0, 0, 0), + + SpellData(5, 5, 5, 5, 110, 100, 90, 80, 0, 4, 0), //7 light + SpellData(10, 10, 10, 10, 120, 110, 100, 90, 16, 16, 0), + SpellData(15, 15, 15, 15, 120, 110, 100, 90, 0, 0, 0), + SpellData(20, 20, 20, 20, 160, 140, 120, 100, 0, 0, 0), + SpellData(25, 25, 25, 25, 140, 140, 140, 140, 0, 0, 0), + SpellData(30, 30, 30, 30, 500, 500, 500, 500, 0, 0, 0), + SpellData(35, 35, 35, 35, 135, 135, 120, 100, 25, 1, 0), + SpellData(40, 40, 40, 40, 500, 500, 500, 500, 0, 0, 0), + SpellData(45, 45, 45, 45, 250, 250, 250, 250, 0, 0, 0), + SpellData(50, 50, 50, 50, 150, 150, 150, 135, 20, 20, 0), + SpellData(55, 55, 55, 55, 300, 300, 300, 300, 0, 0, 0), + + SpellData(10, 10, 10, 10, 140, 140, 140, 140, 0, 0, 0), //8 dark + SpellData(15, 15, 15, 15, 120, 110, 100, 90, 25, 10, 0), + SpellData(20, 20, 20, 20, 120, 100, 90, 120, 0, 0, 0), + SpellData(25, 25, 25, 25, 120, 120, 120, 120, 0, 0, 0), + SpellData(30, 30, 30, 30, 90, 90, 80, 70, 6, 6, 0), + SpellData(35, 35, 35, 35, 120, 120, 100, 80, 0, 0, 0), + SpellData(40, 40, 40, 40, 110, 110, 110, 110, 0, 0, 0), + SpellData(45, 45, 45, 45, 200, 200, 200, 150, 0, 0, 0), + SpellData(50, 50, 50, 50, 120, 120, 120, 100, 0, 25, 0), + SpellData(55, 55, 55, 55, 250, 250, 250, 250, 50, 1, 0), + SpellData(60, 60, 60, 60, 300, 300, 300, 300, 25, 8, 0) + }}; + +std::array<unsigned int, 25> wand_spell_ids = +{ +// 135 Wand of Fire 136 Wand of Sparks 137 Wand of Poison 138 Wand of Stunning 139 Wand of Harm + SPELL_FIRE_FIRE_BOLT, SPELL_AIR_SPARKS, SPELL_WATER_POISON_SPRAY, SPELL_EARTH_STUN, SPELL_BODY_HARM, +// 140 Fairy Wand of Light 141 Fairy Wand of Ice 142 Fairy Wand of Lashing 143 Fairy Wand of Mind 144 Fairy Wand of Swarms + SPELL_LIGHT_LIGHT_BOLT, SPELL_WATER_ICE_BOLT, SPELL_SPIRIT_SPIRIT_LASH, SPELL_MIND_MIND_BLAST, SPELL_EARTH_DEADLY_SWARM, +// 145 Alacorn Wand of Fireballs 146 Alacorn Wand of Acid 147 Alacorn Wand of Lightning 148 Alacorn Wand of Blades 149 Alacorn Wand of Charms + SPELL_FIRE_FIREBALL, SPELL_WATER_ACID_BURST, SPELL_AIR_LIGHNING_BOLT, SPELL_EARTH_BLADES, SPELL_MIND_CHARM, +// 150 Arcane Wand of Blasting 151 Arcane Wand of The Fist 152 Arcane Wand of Rocks 153 Arcane Wand of Paralyzing 154 Arcane Wand of Clouds + SPELL_WATER_ICE_BLAST, SPELL_BODY_FLYING_FIST, SPELL_EARTH_ROCK_BLAST, SPELL_LIGHT_PARALYZE, SPELL_DARK_TOXIC_CLOUD, +// 155 Mystic Wand of Implosion 156 Mystic Wand of Distortion 157 Mystic Wand of Sharpmetal 158 Mystic Wand of Shrinking 159 Mystic Wand of Incineration + SPELL_AIR_IMPLOSION, SPELL_EARTH_MASS_DISTORTION, SPELL_DARK_SHARPMETAL, SPELL_DARK_SHRINKING_RAY, SPELL_FIRE_INCINERATE +}; + + +std::array<std::array<unsigned char, 12>, 9> pSpellbookSpellIndices = // 4E2430 + {{ //0 1 2 3 4 5 6 7 8 9 10 11 + {0, 3, 1, 8, 11, 7, 4, 10, 6, 2, 5, 9}, + {0, 11, 2, 9, 6, 8, 5, 10, 3, 7, 1, 4}, + {0, 4, 8, 9, 1, 10, 3, 11, 7, 6, 2, 5}, + {0, 7, 10, 8, 2, 11, 1, 5, 3, 6, 4, 9}, + {0, 5, 10, 11, 7, 2, 8, 1, 4, 9, 3, 6}, + {0, 5, 9, 8, 3, 7, 6, 4, 1, 11, 2, 10}, + {0, 1, 6, 9, 3, 5, 8, 11, 7, 10, 4, 2}, + {0, 1, 10, 11, 9, 4, 3, 6, 5, 7, 8, 2}, + {0, 9, 3, 7, 1, 5, 2, 10, 11, 8, 6, 4} +}}; + + std::array<std::array<struct SpellBookIconPos, 12>, 9> pIconPos={{ + + { 0, 0, 17, 13, 115, 2, 217, 15, + 299, 6, 28, 125, 130, 133, 294, 114, + 11, 232, 134, 233, 237, 171, 296, 231}, + + { 0, 0, 19, 9, 117, 3, 206, 13, + 285, 7, 16, 123, 113, 101, 201, 118, + 317, 110, 11, 230, 149, 236, 296, 234}, + + { 0, 0, 17, 9, 140, 0, 210, 34, + 293, 5, 15, 98, 78, 121, 175, 136, + 301, 115, 15, 226, 154, 225, 272, 220}, + + { 0, 0, 7, 9, 156, 2, 277, 9, + 11, 117, 111, 82, 180, 102, 303, 108, + 10, 229, 120, 221, 201, 217, 296, 225}, + + { 0, 0, 18, 8, 89, 15, 192, 14, + 292, 7, 22, 129, 125, 146, 217, 136, + 305, 115, 22, 226, 174, 237, 290, 231}, + + { 0, 0, 18, 12, 148, 9, 292, 7, + 17, 122, 121, 99, 220, 87, 293, 112, + 13, 236, 128, 213, 220, 223, 315, 223}, + + { 0, 0, 23, 14, 127, 8, 204, 0, + 306, 8, 14, 115, 122, 132, 200, 116, + 293, 122, 20, 228, 154, 228, 294, 239}, + + { 0, 0, 19, 14, 124, 10, 283, 12, + 8, 105, 113, 89, 190, 82, 298, 108, + 18, 181, 101, 204, 204, 203, 285, 218}, + + { 0, 0, 18, 17, 110, 16, 201, 15, + 307, 15, 18, 148, 125, 166, 201, 123, + 275, 120, 28, 235, 217, 222, 324, 216}}}; + + +//----- (0042EB31) -------------------------------------------------------- +bool SpellBuff::NotExpired() +{ + return (signed __int64)this->uExpireTime > 0 ? true:false; +} + + +//----- (00458585) -------------------------------------------------------- +void SpellBuff::Reset() +{ + uSkill = 0; + uPower = 0; + uExpireTime = 0i64; + uCaster = 0; + uFlags = 0; + if (uOverlayID) + { + pOtherOverlayList->pOverlays[uOverlayID - 1].Reset(); + pOtherOverlayList->bRedraw = true; + uOverlayID = 0; + } +} + +//----- (004585CA) -------------------------------------------------------- +bool SpellBuff::IsBuffExpiredToTime( __int64 time_end ) + { + if (uExpireTime && (uExpireTime < time_end)) + { + uExpireTime = 0; + uPower = 0; + uSkill = 0; + uOverlayID = 0; + return true; + } + return false; +} + +//----- (004584E0) -------------------------------------------------------- +bool SpellBuff::Apply( signed __int64 uExpireTime, unsigned __int16 uSkillLevel, unsigned __int16 uPower, int uOverlayID, unsigned __int8 caster ) + { + if (this->uExpireTime && (uExpireTime < this->uExpireTime)) + return false; + + this->uSkill = uSkillLevel; + this->uPower = uPower; + this->uExpireTime = uExpireTime; + if (this->uOverlayID && this->uOverlayID != uOverlayID) + { + pOtherOverlayList->pOverlays[this->uOverlayID - 1].Reset(); + pOtherOverlayList->bRedraw = true; + this->uOverlayID = 0; + } + this->uOverlayID = uOverlayID; + this->uCaster = caster; + + return true; +} + +//----- (0045384A) -------------------------------------------------------- +void SpellStats::Initialize() +{ + std::map<std::string, SPELL_SCHOOL, ci_less> spellSchoolMaps; + spellSchoolMaps["fire"] = SPELL_SCHOOL_FIRE; + spellSchoolMaps["air"] = SPELL_SCHOOL_AIR; + spellSchoolMaps["water"] = SPELL_SCHOOL_WATER; + spellSchoolMaps["earth"] = SPELL_SCHOOL_EARTH; + spellSchoolMaps["spirit"] = SPELL_SCHOOL_SPIRIT; + spellSchoolMaps["mind"] = SPELL_SCHOOL_MIND; + spellSchoolMaps["body"] = SPELL_SCHOOL_BODY; + spellSchoolMaps["light"] = SPELL_SCHOOL_LIGHT; + spellSchoolMaps["dark"] = SPELL_SCHOOL_DARK; + spellSchoolMaps["magic"] = SPELL_SCHOOL_MAGIC; + + char* test_string; + + free(pSpellsTXT_Raw); + pSpellsTXT_Raw = (char *)pEvents_LOD->LoadRaw("spells.txt", 0); + + strtok(pSpellsTXT_Raw, "\r"); + for(int i=1; i<100; ++i) + { + if (((i % 11) - 1 )==0) + strtok(NULL, "\r"); + test_string=strtok(NULL, "\r")+1; + auto tokens = Tokenize(test_string, '\t'); + pInfos[i].pName=RemoveQuotes(tokens[2]); + auto findResult = spellSchoolMaps.find(tokens[3]); + pInfos[i].uSchool = findResult == spellSchoolMaps.end() ? SPELL_SCHOOL_NONE : findResult->second; + pInfos[i].pShortName=RemoveQuotes(tokens[4]); + pInfos[i].pDescription=RemoveQuotes(tokens[5]); + pInfos[i].pBasicSkillDesc=RemoveQuotes(tokens[6]); + pInfos[i].pExpertSkillDesc=RemoveQuotes(tokens[7]); + pInfos[i].pMasterSkillDesc=RemoveQuotes(tokens[8]); + pInfos[i].pGrandmasterSkillDesc=RemoveQuotes(tokens[9]); + pSpellDatas[i].stats |= strchr(tokens[10], 'm') || strchr(tokens[10], 'M') ? 1 : 0; + pSpellDatas[i].stats |= strchr(tokens[10], 'e') || strchr(tokens[10], 'E') ? 2 : 0; + pSpellDatas[i].stats |= strchr(tokens[10], 'c') || strchr(tokens[10], 'C') ? 4 : 0; + pSpellDatas[i].stats |= strchr(tokens[10], 'x') || strchr(tokens[10], 'X') ? 8 : 0; + } +} +//----- (00448DF8) -------------------------------------------------------- +void __fastcall EventCastSpell(int uSpellID, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz)//sub_448DF8 +{ + int v9; // esi@1 + signed __int64 v10; // st7@4 + signed __int64 v11; // st6@4 + signed __int64 v12; // st5@4 + double v13; // st7@6 + int v14; // ST44_4@7 + uint skillMasteryPlusOne; // ebx@9 + uint v16; // edx@15 + int i; // esi@42 + int j; // esi@60 + unsigned __int64 v36; // qax@99 +// SpellBuff *v37; // ecx@99 + int v38; // esi@103 + signed __int64 v39; // qax@105 + int v42; // esi@111 + int v43; // ebx@111 + int v47; // [sp-4h] [bp-B8h]@35 + int v49; // [sp+0h] [bp-B4h]@35 + int v55; // [sp+28h] [bp-8Ch]@7 + unsigned int yaw; // [sp+30h] [bp-84h]@7 + int pitch; // [sp+34h] [bp-80h]@7 + int v60; // [sp+ACh] [bp-8h]@1 + int a6_4; // [sp+C8h] [bp+14h]@117 + int a7c; // [sp+CCh] [bp+18h]@29 + int a7d; // [sp+CCh] [bp+18h]@55 + signed __int64 xSquared; // [sp+D0h] [bp+1Ch]@6 + int a8b; // [sp+D0h] [bp+1Ch]@37 + int a8c; // [sp+D0h] [bp+1Ch]@55 + signed __int64 ySquared; // [sp+D4h] [bp+20h]@6 + + v9 = 0; + skillMasteryPlusOne = uSkillLevel + 1; + //spellnum_ = uSpellID; + v60 = 0; + if ( tox || toy || toz ) + { + v10 = tox - fromx; + v11 = toy - fromy; + v12 = toz - fromz; + } + else + { + v10 = pParty->vPosition.x - fromx; + v11 = pParty->vPosition.y - fromy; + v12 = (pParty->vPosition.z + pParty->sEyelevel) - fromz; + } + v13 = sqrt(long double(v10 * v10 + v11 * v11 + v12 * v12)); + if ( v13 <= 1.0 ) + { + v55 = 1; + yaw = 0; + pitch = 0; + } + else + { + v55 = (int)v13; + ySquared = v11 * v11; + xSquared = v10 * v10; + v14 = (int)sqrt(long double(xSquared + ySquared)); + yaw = stru_5C6E00->Atan2((int)v10, (int)v11); + pitch = stru_5C6E00->Atan2(v14, (int)v12); + } + Assert(skillMasteryPlusOne > 0 && skillMasteryPlusOne <= 4, "Invalid mastery level"); + + SpriteObject a1; // [sp+38h] [bp-7Ch]@12 + //SpriteObject::SpriteObject(&a1); + + switch ( uSpellID ) + { + case SPELL_FIRE_FIRE_BOLT: + case SPELL_FIRE_FIREBALL: + case SPELL_AIR_LIGHNING_BOLT: + case SPELL_WATER_ICE_BOLT: + case SPELL_WATER_ACID_BURST: + case SPELL_WATER_ICE_BLAST: + case SPELL_EARTH_BLADES: + case SPELL_EARTH_ROCK_BLAST: + case SPELL_WATER_POISON_SPRAY: + case SPELL_AIR_SPARKS: + case SPELL_EARTH_DEATH_BLOSSOM: + a1.uType = stru_4E3ACC[uSpellID].uType; + a1.stru_24.Reset(); + a1.spell_id = uSpellID; + a1.spell_level = uSkill; + a1.spell_skill = skillMasteryPlusOne; + v16 = 0; + while (v16 < pObjectList->uNumObjects) + { + if ( a1.uType == pObjectList->pObjects[v16].uObjectID) + { + break; + } + v16++; + } + a1.uObjectDescID = v16; + a1.vPosition.x = fromx; + a1.vPosition.y = fromy; + a1.vPosition.z = fromz; + a1.uAttributes = 16; + a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz); + a1.field_60_distance_related_prolly_lod = v55; + a1.uSpriteFrameID = 0; + a1.spell_caster_pid = 8000 | OBJECT_Item; + a1.uSoundID = 0; + break; + } + + switch ( uSpellID ) + { + case SPELL_FIRE_FIRE_BOLT: + case SPELL_FIRE_FIREBALL: + case SPELL_AIR_LIGHNING_BOLT: + case SPELL_WATER_ICE_BOLT: + case SPELL_WATER_ACID_BURST: + case SPELL_WATER_ICE_BLAST: + case SPELL_EARTH_BLADES: + case SPELL_EARTH_ROCK_BLAST: + //v20 = yaw; + a1.spell_target_pid = 0; + a1.uFacing = yaw; + a1.uSoundID = 0; + v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed; + a1.Create(yaw, pitch, v49, 0); + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0); + return; + case SPELL_WATER_POISON_SPRAY: + switch ( skillMasteryPlusOne ) + { + case 1: + v60 = 1; + break; + case 2: + v60 = 3; + break; + case 3: + v60 = 5; + break; + case 4: + v60 = 7; + break; + } + a1.spell_target_pid = 0; + a1.uFacing = yaw; + if ( v60 == 1 ) + { + v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed; + a1.Create(yaw, pitch, v49, 0); + } + else + { + a7c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360; + a8b = a7c / (v60 - 1); + for ( i = a7c / -2; i <= a7c / 2; i += a8b ) + { + a1.uFacing = i + yaw; + a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0); + } + } + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0); + return; + case SPELL_AIR_SPARKS: + switch ( skillMasteryPlusOne ) + { + case 1: + v60 = 3; + break; + case 2: + v60 = 5; + break; + case 3: + v60 = 7; + break; + case 4: + v60 = 9; + break; + } + a7d = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360; + a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1); + a1.spell_target_pid = 4; + for ( j = a7d / -2; j <= a7d / 2; j += a8c ) + { + a1.uFacing = j + yaw; + a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0); + } + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0); + return; + case SPELL_EARTH_DEATH_BLOSSOM: + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + return; + a1.spell_target_pid = 4; + v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed; + v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2; + a1.Create(yaw, v47, v49, 0); + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0); + return; + + case SPELL_FIRE_HASTE: + if ( skillMasteryPlusOne > 0 ) + { + if ( skillMasteryPlusOne <= 2 ) + v9 = 60 * (uSkill + 60); + else if ( skillMasteryPlusOne == 3 ) + v9 = 180 * (uSkill + 20); + else if ( skillMasteryPlusOne == 4 ) + v9 = 240 * (uSkill + 15); + } + for (uint i = 0; i < 4; ++i) + if (pParty->pPlayers[i].IsWeak()) + return; + pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 * 128) * 0.033333335), skillMasteryPlusOne, 0, 0, 0); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3); + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);//звук алтаря + return; + case SPELL_AIR_SHIELD: + case SPELL_EARTH_STONESKIN: + case SPELL_SPIRIT_HEROISM: + switch ( skillMasteryPlusOne ) + { + case 1: + case 2: + v9 = 300 * (uSkill + 12); + break; + case 3: + v9 = 900 * (uSkill + 4); + break; + case 4: + v9 = 3600 * (uSkill + 1); + break; + } + switch ( uSpellID ) + { + case SPELL_AIR_SHIELD: + v60 = 0; + uSkill = 14; + break; + case SPELL_EARTH_STONESKIN: + v60 = uSkill + 5; + uSkill = 15; + break; + case SPELL_SPIRIT_HEROISM: + v60 = uSkill + 5; + uSkill = 9; + break; + } + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3); + v36 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335); + pParty->pPartyBuffs[uSkill].Apply(v36, skillMasteryPlusOne, v60, 0, 0); + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0); + return; + case SPELL_FIRE_IMMOLATION: + if (skillMasteryPlusOne == 4) + v38 = 600 * uSkill; + else + v38 = 60 * uSkill; + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3); + v39 = (signed __int64)((double)(v38 << 7) * 0.033333335); + v36 = pParty->uTimePlayed + v39; + pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(v36, skillMasteryPlusOne, uSkill, 0, 0); + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0); + return; + case SPELL_FIRE_PROTECTION_FROM_FIRE: + case SPELL_AIR_PROTECTION_FROM_AIR: + case SPELL_WATER_PROTECTION_FROM_WATER: + case SPELL_EARTH_PROTECTION_FROM_EARTH: + case SPELL_MIND_PROTECTION_FROM_MIND: + case SPELL_BODY_PROTECTION_FROM_BODY: + a6_4 = 3600 * uSkill; + switch (skillMasteryPlusOne) + { + case 1: + v60 = uSkill; + break; + case 2: + v60 = 2 * uSkill; + break; + case 3: + v60 = 3 * uSkill; + break; + case 4: + v60 = 4 * uSkill; + break; + } + switch ( uSpellID ) + { + case SPELL_FIRE_PROTECTION_FROM_FIRE: + uSkill = PARTY_BUFF_RESIST_FIRE; + break; + case SPELL_AIR_PROTECTION_FROM_AIR: + uSkill = PARTY_BUFF_RESIST_AIR; + break; + case SPELL_WATER_PROTECTION_FROM_WATER: + uSkill = PARTY_BUFF_RESIST_WATER; + break; + case SPELL_EARTH_PROTECTION_FROM_EARTH: + uSkill = PARTY_BUFF_RESIST_EARTH; + break; + case SPELL_MIND_PROTECTION_FROM_MIND: + uSkill = PARTY_BUFF_RESIST_MIND; + break; + case SPELL_BODY_PROTECTION_FROM_BODY: + uSkill = PARTY_BUFF_RESIST_BODY; + break; + } + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3); + pParty->pPartyBuffs[uSkill].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)a6_4 * 4.2666669), skillMasteryPlusOne, v60, 0, 0); + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0); + return; + case SPELL_LIGHT_DAY_OF_THE_GODS : + switch (skillMasteryPlusOne) + { + case 2: + v42 = 10800 * uSkill; + v43 = 3 * uSkill + 10; + break; + case 3: + v42 = 18000 * uSkill; + v43 = 5 * uSkill + 10; + break; + case 4: + v42 = 14400 * uSkill; + v43 = 4 * uSkill + 10; + break; + } + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2); + pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3); + v39 = (signed __int64)((double)(v42 << 7) * 0.033333335); + v36 = pParty->uTimePlayed + v39; + pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(v36, skillMasteryPlusOne, v43, 0, 0); + pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0); + return; + default: + return; + } +} +//----- (00427769) -------------------------------------------------------- +bool sub_427769_isSpellQuickCastableOnShiftClick(unsigned int uSpellID) +{ + return ( pSpellDatas[uSpellID].stats & 0xC ) != 0; +} +//----- (0043AFE3) -------------------------------------------------------- +int _43AFE3_calc_spell_damage(int spellId, int spellLevel, signed int skillMastery, int currentHp) +{ + int result; // eax@1 + unsigned int v5; // [sp-4h] [bp-8h]@9 + + result = 0; + if ( spellId == SPELL_FIRE_FIRE_SPIKE ) + { + switch (skillMastery) + { + case 1: + case 2: + v5 = 6; + case 3: + v5 = 8; + case 4: + v5 = 10; + default: + return 0; + } + result = GetDiceResult(spellLevel, v5); + } + else if ( spellId == SPELL_EARTH_MASS_DISTORTION ) + result = currentHp * (pSpellDatas[SPELL_EARTH_MASS_DISTORTION].baseDamage + 2 * spellLevel) / 100; + else + result = pSpellDatas[spellId].baseDamage + + GetDiceResult(spellLevel, pSpellDatas[spellId].bonusSkillDamage); + + return result; +} \ No newline at end of file