Advertisement
Guest User

Diff Spell System

a guest
Feb 17th, 2018
344
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 101.19 KB | None | 0 0
  1. From e38301b5a0ac148ea55adf63ce89484d5c546c7d Mon Sep 17 00:00:00 2001
  2. From: eduardovicente <dudugt500@gmail.com>
  3. Date: Wed, 14 Feb 2018 02:30:32 -0200
  4. Subject: [PATCH] Summon Spells 1.0
  5.  
  6. ---
  7. .../data/actions/scripts/tools/emptyPokeball.lua   |  14 +
  8.  .../data/monster/Dragons/dragon.xml                |  45 +-
  9.  forgottenserver-1.2/data/monster/monsters.xml      |   3 -
  10.  .../data/spells/scripts/energy_beam.lua            |  20 +
  11.  forgottenserver-1.2/data/spells/spells.xml         |   1 +
  12.  .../data/talkactions/scripts/summonspell.lua       |   7 +
  13.  forgottenserver-1.2/src/combat.cpp                 | 264 +++++++----
  14.  forgottenserver-1.2/src/combat.h                   |  12 +
  15.  forgottenserver-1.2/src/creature.cpp               | 116 +++--
  16.  forgottenserver-1.2/src/creature.h                 |   2 +-
  17.  forgottenserver-1.2/src/enums.h                    | 121 +++--
  18.  forgottenserver-1.2/src/game.cpp                   | 142 +-----
  19.  forgottenserver-1.2/src/game.h                     |   2 +-
  20.  forgottenserver-1.2/src/items.cpp                  |  48 +-
  21.  forgottenserver-1.2/src/luascript.cpp              |  77 +++-
  22.  forgottenserver-1.2/src/monster.cpp                | 271 ++++++------
  23.  forgottenserver-1.2/src/monster.h                  |  26 +-
  24.  forgottenserver-1.2/src/monsters.cpp               | 491 ++++++---------------
  25.  forgottenserver-1.2/src/monsters.h                 |  18 +-
  26.  forgottenserver-1.2/src/player.cpp                 |   7 +-
  27.  forgottenserver-1.2/src/player.h                   |   2 +-
  28.  forgottenserver-1.2/src/spells.h                   |  21 +-
  29.  forgottenserver-1.2/src/tools.cpp                  |  37 +-
  30.  forgottenserver-1.2/src/weapons.cpp                |  19 +-
  31.  24 files changed, 820 insertions(+), 946 deletions(-)
  32.  create mode 100644 forgottenserver-1.2/data/actions/scripts/tools/emptyPokeball.lua
  33.  create mode 100644 forgottenserver-1.2/data/spells/scripts/energy_beam.lua
  34.  create mode 100644 forgottenserver-1.2/data/talkactions/scripts/summonspell.lua
  35.  
  36. diff --git a/forgottenserver-1.2/data/actions/scripts/tools/emptyPokeball.lua b/forgottenserver-1.2/data/actions/scripts/tools/emptyPokeball.lua
  37. new file mode 100644
  38. index 0000000..d3fdd91
  39. --- /dev/null
  40. +++ b/forgottenserver-1.2/data/actions/scripts/tools/emptyPokeball.lua
  41. @@ -0,0 +1,14 @@
  42. +function onUse(player, pokeball, fromPosition, target, toPosition, isHotkey)
  43. +    if not target:isMonster() then
  44. +        return false
  45. +    end
  46. +
  47. +    local pokeball = player:addItem(2467, 1)
  48. +    pokeball:setPokemonName(target:getName())
  49. +    pokeball:setLevel(target:getLevel())
  50. +    pokeball:setExperience(target:getExperience())
  51. +    pokeball:setMaxHealth(target:getMaxHealth())
  52. +    pokeball:setHealth(target:getHealth())
  53. +
  54. +    target:remove()
  55. +end
  56. \ No newline at end of file
  57. diff --git a/forgottenserver-1.2/data/monster/Dragons/dragon.xml b/forgottenserver-1.2/data/monster/Dragons/dragon.xml
  58. index 5437025..ed54145 100644
  59. --- a/forgottenserver-1.2/data/monster/Dragons/dragon.xml
  60. +++ b/forgottenserver-1.2/data/monster/Dragons/dragon.xml
  61. @@ -2,7 +2,25 @@
  62.  <monster name="Dragon" nameDescription="a dragon" race="blood" experience="700" speed="185" manacost="0">
  63.     <health now="1000" max="1000" />
  64.     <look type="34" corpse="5973" />
  65. -   <targetchange interval="4000" chance="10" />
  66. +  
  67. +   <level min="10" max="20" />
  68. +   <basestatus hp="150" attack="50" defense="20" specialattack="10" specialdefense="10" speed="25"  />
  69. +   <statusperlevel hp="2" attack="5" defense="1" specialattack="1.5" specialdefense="0.5" speed="3" />
  70. +   <targetchange interval="4000" chance="20" />
  71. +
  72. +   <attacks>
  73. +       <spell name="Energy Beam" word="m1" level="1" cooldown="2500" chance="10"/>
  74. +   </attacks>
  75. +   <passives>
  76. +   </passives>
  77. +
  78. +   <elements>
  79. +       <element icePercent="-80" />
  80. +       <element firePercent="30" />
  81. +   </elements>
  82. +   <immunities>
  83. +   </immunities>
  84. +
  85.     <flags>
  86.         <flag summonable="0" />
  87.         <flag attackable="1" />
  88. @@ -16,31 +34,6 @@
  89.         <flag staticattack="80" />
  90.         <flag runonhealth="300" />
  91.     </flags>
  92. -   <attacks>
  93. -       <attack name="melee" interval="2000" min="0" max="-120" />
  94. -       <attack name="fire" interval="2000" chance="15" range="7" radius="4" target="1" min="-60" max="-140">
  95. -           <attribute key="shootEffect" value="fire" />
  96. -           <attribute key="areaEffect" value="firearea" />
  97. -       </attack>
  98. -       <attack name="fire" interval="2000" chance="10" length="8" spread="3" min="-100" max="-170">
  99. -           <attribute key="areaEffect" value="firearea" />
  100. -       </attack>
  101. -   </attacks>
  102. -   <defenses armor="30" defense="30">
  103. -       <defense name="healing" interval="2000" chance="15" min="40" max="70">
  104. -           <attribute key="areaEffect" value="blueshimmer" />
  105. -       </defense>
  106. -   </defenses>
  107. -   <elements>
  108. -       <element earthPercent="80" />
  109. -       <element energyPercent="20" />
  110. -       <element icePercent="-10" />
  111. -   </elements>
  112. -   <immunities>
  113. -       <immunity paralyze="1" />
  114. -       <immunity invisible="1" />
  115. -       <immunity fire="1" />
  116. -   </immunities>
  117.     <voices interval="5000" chance="10">
  118.         <voice sentence="GROOAAARRR" yell="1" />
  119.         <voice sentence="FCHHHHH" yell="1" />
  120. diff --git a/forgottenserver-1.2/data/monster/monsters.xml b/forgottenserver-1.2/data/monster/monsters.xml
  121. index 8aa1bd3..352773e 100644
  122. --- a/forgottenserver-1.2/data/monster/monsters.xml
  123. +++ b/forgottenserver-1.2/data/monster/monsters.xml
  124. @@ -2,7 +2,4 @@
  125.  <monsters>
  126.     <!-- Dragons -->
  127.     <monster name="Dragon Lord" file="Dragons/dragon_lord.xml" />
  128. -   <monster name="Dragon Lord Hatchling" file="Dragons/dragon_lord_hatchling.xml" />
  129. -   <monster name="Dragon" file="Dragons/dragon.xml" />
  130. -   <monster name="Dragon Hatchling" file="Dragons/dragon_hatchling.xml" />
  131.  </monsters>
  132. diff --git a/forgottenserver-1.2/data/spells/scripts/energy_beam.lua b/forgottenserver-1.2/data/spells/scripts/energy_beam.lua
  133. new file mode 100644
  134. index 0000000..0c21c72
  135. --- /dev/null
  136. +++ b/forgottenserver-1.2/data/spells/scripts/energy_beam.lua
  137. @@ -0,0 +1,20 @@
  138. +local combat = Combat()
  139. +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE)
  140. +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_WATERSPLASH)
  141. +combat:setArea(createCombatArea(AREA_SQUARE1X1))
  142. +combat:setCondition(condition)
  143. +
  144. +function onMonsterCombat(monster, hp, attack, defense, specialattack, specialdefense, speed)
  145. +    local chance = math.random(1, 5)
  146. +    print(hp, attack, defense, specialattack, specialdefense, speed)
  147. +    
  148. +    local min = (attack * 1.5)/ chance
  149. +    local max = (attack * 2) / chance
  150. +    return -min, -max
  151. +end
  152. +
  153. +combat:setCallback(CALLBACK_PARAM_MONSTER, "onMonsterCombat")
  154. +
  155. +function onCastSpell(creature, variant)
  156. +    return combat:execute(creature, variant)
  157. +end
  158. diff --git a/forgottenserver-1.2/data/spells/spells.xml b/forgottenserver-1.2/data/spells/spells.xml
  159. index cc793e2..342d1fc 100644
  160. --- a/forgottenserver-1.2/data/spells/spells.xml
  161. +++ b/forgottenserver-1.2/data/spells/spells.xml
  162. @@ -1,3 +1,4 @@
  163.  <?xml version="1.0" encoding="UTF-8"?>
  164.  <spells>
  165. +        <instant name="Energy Beam" words="m1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="energy_beam.lua" />
  166.  </spells>
  167. diff --git a/forgottenserver-1.2/data/talkactions/scripts/summonspell.lua b/forgottenserver-1.2/data/talkactions/scripts/summonspell.lua
  168. new file mode 100644
  169. index 0000000..ace81b2
  170. --- /dev/null
  171. +++ b/forgottenserver-1.2/data/talkactions/scripts/summonspell.lua
  172. @@ -0,0 +1,7 @@
  173. +function onSay(player, words, param)
  174. +    if (#player:getSummons() <= 0) then
  175. +        return
  176. +    end
  177. +    
  178. +    player:getSummons()[1]:castSpell(words)
  179. +end
  180. \ No newline at end of file
  181. diff --git a/forgottenserver-1.2/src/combat.cpp b/forgottenserver-1.2/src/combat.cpp
  182. index 6c48f54..1b8f820 100644
  183. --- a/forgottenserver-1.2/src/combat.cpp
  184. +++ b/forgottenserver-1.2/src/combat.cpp
  185. @@ -25,6 +25,7 @@
  186.  #include "weapons.h"
  187.  #include "configmanager.h"
  188.  #include "events.h"
  189. +#include "monster.h"
  190.  
  191.  extern Game g_game;
  192.  extern Weapons* g_weapons;
  193. @@ -36,50 +37,37 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const
  194.     CombatDamage damage;
  195.     damage.origin = params.origin;
  196.     damage.primary.type = params.combatType;
  197. -   if (formulaType == COMBAT_FORMULA_DAMAGE) {
  198. +
  199. +   if (!creature) {
  200.         damage.primary.value = normal_random(
  201.             static_cast<int32_t>(mina),
  202.             static_cast<int32_t>(maxa)
  203. -       );
  204. -   } else if (creature) {
  205. -       int32_t min, max;
  206. -       if (creature->getCombatValues(min, max)) {
  207. -           damage.primary.value = normal_random(min, max);
  208. -       } else if (Player* player = creature->getPlayer()) {
  209. -           if (params.valueCallback) {
  210. -               params.valueCallback->getMinMaxValues(player, damage, params.useCharges);
  211. -           } else if (formulaType == COMBAT_FORMULA_LEVELMAGIC) {
  212. -               int32_t levelFormula = player->getLevel() * 2 + player->getMagicLevel() * 3;
  213. -               damage.primary.value = normal_random(
  214. -                   static_cast<int32_t>(levelFormula * mina + minb),
  215. -                   static_cast<int32_t>(levelFormula * maxa + maxb)
  216. +           );
  217. +
  218. +       return damage;
  219. +   }
  220. +
  221. +   int32_t min, max;
  222. +   if (creature->getCombatValues(min, max)) {
  223. +       damage.primary.value = normal_random(min, max);
  224. +   } else if (Monster* monster = creature->getMonster()) {
  225. +       if (params.monsterCallback) {
  226. +           params.monsterCallback->onMonsterCombat(monster, damage);
  227. +       } else if (formulaType == COMBAT_FORMULA_DAMAGE) {
  228. +           //TODO REVISAR ATTACK FORMULAS
  229. +           int32_t attackFormula;
  230. +           if (params.spellType == COMBATSPELL_SPECIALATTACK)
  231. +               attackFormula = monster->getStatus().getSpecialAttack();
  232. +           else
  233. +               attackFormula = monster->getStatus().getAttack();
  234. +
  235. +           damage.primary.value = normal_random(
  236. +               static_cast<int32_t>(mina - attackFormula),
  237. +               static_cast<int32_t>(maxa - attackFormula)
  238.                 );
  239. -           } else if (formulaType == COMBAT_FORMULA_SKILL) {
  240. -               Item* tool = player->getWeapon();
  241. -               const Weapon* weapon = g_weapons->getWeapon(tool);
  242. -               if (weapon) {
  243. -                   damage.primary.value = normal_random(
  244. -                       static_cast<int32_t>(minb),
  245. -                       static_cast<int32_t>(weapon->getWeaponDamage(player, target, tool, true) * maxa + maxb)
  246. -                   );
  247. -
  248. -                   damage.secondary.type = weapon->getElementType();
  249. -                   damage.secondary.value = weapon->getElementDamage(player, target, tool);
  250. -                   if (params.useCharges) {
  251. -                       uint16_t charges = tool->getCharges();
  252. -                       if (charges != 0) {
  253. -                           g_game.transformItem(tool, tool->getID(), charges - 1);
  254. -                       }
  255. -                   }
  256. -               } else {
  257. -                   damage.primary.value = normal_random(
  258. -                       static_cast<int32_t>(minb),
  259. -                       static_cast<int32_t>(maxb)
  260. -                   );
  261. -               }
  262. -           }
  263.         }
  264.     }
  265. +
  266.     return damage;
  267.  }
  268.  
  269. @@ -104,32 +92,43 @@ void Combat::getCombatArea(const Position& centerPos, const Position& targetPos,
  270.  CombatType_t Combat::ConditionToDamageType(ConditionType_t type)
  271.  {
  272.     switch (type) {
  273. -       case CONDITION_FIRE:
  274. -           return COMBAT_FIREDAMAGE;
  275. -
  276. -       case CONDITION_ENERGY:
  277. -           return COMBAT_ENERGYDAMAGE;
  278. -
  279. -       case CONDITION_BLEEDING:
  280. -           return COMBAT_PHYSICALDAMAGE;
  281. -
  282. -       case CONDITION_DROWN:
  283. -           return COMBAT_DROWNDAMAGE;
  284. -
  285. -       case CONDITION_POISON:
  286. -           return COMBAT_EARTHDAMAGE;
  287. -
  288. -       case CONDITION_FREEZING:
  289. -           return COMBAT_ICEDAMAGE;
  290. -
  291. -       case CONDITION_DAZZLED:
  292. -           return COMBAT_HOLYDAMAGE;
  293. -
  294. -       case CONDITION_CURSED:
  295. -           return COMBAT_DEATHDAMAGE;
  296. -
  297. -       default:
  298. -           break;
  299. +   case CONDITION_BUG:
  300. +       return COMBAT_BUGDAMAGE;
  301. +   case CONDITION_DRAGON:
  302. +       return COMBAT_DRAGONDAMAGE;
  303. +   case CONDITION_FAIRY:
  304. +       return COMBAT_FAIRYDAMAGE;
  305. +   case CONDITION_FIRE:
  306. +       return COMBAT_FIREDAMAGE;
  307. +   case CONDITION_GHOST:
  308. +       return COMBAT_GHOSTDAMAGE;
  309. +   case CONDITION_GROUND:
  310. +       return COMBAT_GROUNDDAMAGE;
  311. +   case CONDITION_NORMAL:
  312. +       return COMBAT_NORMALDAMAGE;
  313. +   case CONDITION_STEEL:
  314. +       return COMBAT_STEELDAMAGE;
  315. +   case CONDITION_DARK:
  316. +       return COMBAT_DARKDAMAGE;
  317. +   case CONDITION_ELECTRIC:
  318. +       return COMBAT_ELECTRICDAMAGE;
  319. +   case CONDITION_FIGHTING:
  320. +       return COMBAT_FIGHTINGDAMAGE;
  321. +   case CONDITION_FLYING:
  322. +       return COMBAT_FLYINGDAMAGE;
  323. +   case CONDITION_GRASS:
  324. +       return COMBAT_GRASSDAMAGE;
  325. +   case CONDITION_ICE:
  326. +       return COMBAT_ICEDAMAGE;
  327. +   case CONDITION_POISON:
  328. +       return COMBAT_POISONDAMAGE;
  329. +   case CONDITION_ROCK:
  330. +       return COMBAT_ROCKDAMAGE;
  331. +   case CONDITION_WATER:
  332. +       return COMBAT_WATERDAMAGE;
  333. +
  334. +   default:
  335. +       break;
  336.     }
  337.  
  338.     return COMBAT_NONE;
  339. @@ -138,32 +137,42 @@ CombatType_t Combat::ConditionToDamageType(ConditionType_t type)
  340.  ConditionType_t Combat::DamageToConditionType(CombatType_t type)
  341.  {
  342.     switch (type) {
  343. -       case COMBAT_FIREDAMAGE:
  344. -           return CONDITION_FIRE;
  345. -
  346. -       case COMBAT_ENERGYDAMAGE:
  347. -           return CONDITION_ENERGY;
  348. -
  349. -       case COMBAT_DROWNDAMAGE:
  350. -           return CONDITION_DROWN;
  351. -
  352. -       case COMBAT_EARTHDAMAGE:
  353. -           return CONDITION_POISON;
  354. -
  355. -       case COMBAT_ICEDAMAGE:
  356. -           return CONDITION_FREEZING;
  357. -
  358. -       case COMBAT_HOLYDAMAGE:
  359. -           return CONDITION_DAZZLED;
  360. -
  361. -       case COMBAT_DEATHDAMAGE:
  362. -           return CONDITION_CURSED;
  363. -
  364. -       case COMBAT_PHYSICALDAMAGE:
  365. -           return CONDITION_BLEEDING;
  366. -
  367. -       default:
  368. -           return CONDITION_NONE;
  369. +   case COMBAT_BUGDAMAGE:
  370. +       return CONDITION_BUG;
  371. +   case COMBAT_DRAGONDAMAGE:
  372. +       return CONDITION_DRAGON;
  373. +   case COMBAT_FAIRYDAMAGE:
  374. +       return CONDITION_FAIRY;
  375. +   case COMBAT_FIREDAMAGE:
  376. +       return CONDITION_FIRE;
  377. +   case COMBAT_GHOSTDAMAGE:
  378. +       return CONDITION_GHOST;
  379. +   case COMBAT_GROUNDDAMAGE:
  380. +       return CONDITION_GROUND;
  381. +   case COMBAT_NORMALDAMAGE:
  382. +       return CONDITION_NORMAL;
  383. +   case COMBAT_STEELDAMAGE:
  384. +       return CONDITION_STEEL;
  385. +   case COMBAT_DARKDAMAGE:
  386. +       return CONDITION_DARK;
  387. +   case COMBAT_ELECTRICDAMAGE:
  388. +       return CONDITION_ELECTRIC;
  389. +   case COMBAT_FIGHTINGDAMAGE:
  390. +       return CONDITION_FIGHTING;
  391. +   case COMBAT_FLYINGDAMAGE:
  392. +       return CONDITION_FLYING;
  393. +   case COMBAT_GRASSDAMAGE:
  394. +       return CONDITION_GRASS;
  395. +   case COMBAT_ICEDAMAGE:
  396. +       return CONDITION_ICE;
  397. +   case COMBAT_POISONDAMAGE:
  398. +       return CONDITION_POISON;
  399. +   case COMBAT_ROCKDAMAGE:
  400. +       return CONDITION_ROCK;
  401. +   case COMBAT_WATERDAMAGE:
  402. +       return CONDITION_WATER;
  403. +   default:
  404. +       return CONDITION_NONE;
  405.     }
  406.  }
  407.  
  408. @@ -459,6 +468,11 @@ bool Combat::setCallback(CallBackParam_t key)
  409.             params.targetCallback.reset(new TargetCallback());
  410.             return true;
  411.         }
  412. +
  413. +       case CALLBACK_PARAM_MONSTER: {
  414. +           params.monsterCallback.reset(new MonsterCallback());
  415. +           return true;
  416. +       }
  417.     }
  418.     return false;
  419.  }
  420. @@ -478,6 +492,10 @@ CallBack* Combat::getCallback(CallBackParam_t key)
  421.         case CALLBACK_PARAM_TARGETCREATURE: {
  422.             return params.targetCallback.get();
  423.         }
  424. +
  425. +       case CALLBACK_PARAM_MONSTER: {
  426. +           return params.monsterCallback.get();
  427. +       }
  428.     }
  429.     return nullptr;
  430.  }
  431. @@ -486,10 +504,11 @@ void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatPa
  432.  {
  433.     assert(data);
  434.     CombatDamage damage = *data;
  435. -   if (g_game.combatBlockHit(damage, caster, target, params.blockedByShield, params.blockedByArmor, params.itemId != 0)) {
  436. +   if (g_game.combatBlockHit(damage, caster, target, params.blockedByShield, params.blockedByArmor, params.itemId != 0, params.spellType)) {
  437.         return;
  438.     }
  439.  
  440. +   //Todo: Rever Isso
  441.     if ((damage.primary.value < 0 || damage.secondary.value < 0) && caster) {
  442.         Player* targetPlayer = target->getPlayer();
  443.         if (targetPlayer && caster->getPlayer() && targetPlayer->getSkull() != SKULL_BLACK) {
  444. @@ -741,12 +760,11 @@ void Combat::doCombat(Creature* caster, Creature* target) const
  445.     //target combat callback function
  446.     if (params.combatType != COMBAT_NONE) {
  447.         CombatDamage damage = getCombatDamage(caster, target);
  448. -       if (damage.primary.type != COMBAT_MANADRAIN) {
  449. +       if (damage.primary.type) {
  450.             doCombatHealth(caster, target, damage, params);
  451. -       } else {
  452. -           doCombatMana(caster, target, damage, params);
  453.         }
  454. -   } else {
  455. +   }
  456. +   else {
  457.         doCombatDefault(caster, target, params);
  458.     }
  459.  }
  460. @@ -756,10 +774,8 @@ void Combat::doCombat(Creature* caster, const Position& position) const
  461.     //area combat callback function
  462.     if (params.combatType != COMBAT_NONE) {
  463.         CombatDamage damage = getCombatDamage(caster, nullptr);
  464. -       if (damage.primary.type != COMBAT_MANADRAIN) {
  465. +       if (damage.primary.type) {
  466.             doCombatHealth(caster, position, area.get(), damage, params);
  467. -       } else {
  468. -           doCombatMana(caster, position, area.get(), damage, params);
  469.         }
  470.     } else {
  471.         CombatFunc(caster, position, area.get(), params, CombatNullFunc, nullptr);
  472. @@ -1054,6 +1070,58 @@ void TargetCallback::onTargetCombat(Creature* creature, Creature* target) const
  473.     scriptInterface->resetScriptEnv();
  474.  }
  475.  
  476. +void MonsterCallback::onMonsterCombat(Monster* monster, CombatDamage& damage) const
  477. +{
  478. +   //onMonsterCombat(monster, level, hp, attack, defense, specialattack, specialdefense, speed)
  479. +   if (!scriptInterface->reserveScriptEnv()) {
  480. +       std::cout << "[Error - MonsterCallback::onMonsterCombat] Call stack overflow" << std::endl;
  481. +       return;
  482. +   }
  483. +
  484. +   ScriptEnvironment* env = scriptInterface->getScriptEnv();
  485. +   if (!env->setCallbackId(scriptId, scriptInterface)) {
  486. +       scriptInterface->resetScriptEnv();
  487. +       return;
  488. +   }
  489. +
  490. +   lua_State* L = scriptInterface->getLuaState();
  491. +
  492. +   scriptInterface->pushFunction(scriptId);
  493. +
  494. +   if (monster) {
  495. +       LuaScriptInterface::pushUserdata<Monster>(L, monster);
  496. +       LuaScriptInterface::setCreatureMetatable(L, -1, monster);
  497. +
  498. +       lua_pushnumber(L, monster->getStatus().getHealth());
  499. +       lua_pushnumber(L, monster->getStatus().getAttack());
  500. +       lua_pushnumber(L, monster->getStatus().getDefense());
  501. +       lua_pushnumber(L, monster->getStatus().getSpecialAttack());
  502. +       lua_pushnumber(L, monster->getStatus().getSpecialDefense());
  503. +       lua_pushnumber(L, monster->getStatus().getSpeed());
  504. +   }
  505. +   else {
  506. +       lua_pushnil(L);
  507. +   }
  508. +
  509. +   int size0 = lua_gettop(L);
  510. +   if (lua_pcall(L, 7, 2, 0) != 0) {
  511. +       LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L));
  512. +   }
  513. +   else {
  514. +       damage.primary.value = normal_random(
  515. +           LuaScriptInterface::getNumber<int32_t>(L, -2),
  516. +           LuaScriptInterface::getNumber<int32_t>(L, -1)
  517. +           );
  518. +       lua_pop(L, 2);
  519. +   }
  520. +
  521. +   if ((lua_gettop(L) + 7 + 1) != size0) {
  522. +       LuaScriptInterface::reportError(nullptr, "Stack size changed!");
  523. +   }
  524. +
  525. +   scriptInterface->resetScriptEnv();
  526. +}
  527. +
  528.  //**********************************************************//
  529.  
  530.  void AreaCombat::clear()
  531. diff --git a/forgottenserver-1.2/src/combat.h b/forgottenserver-1.2/src/combat.h
  532. index 8f9b373..87cfca5 100644
  533. --- a/forgottenserver-1.2/src/combat.h
  534. +++ b/forgottenserver-1.2/src/combat.h
  535. @@ -60,18 +60,30 @@ class TargetCallback final : public CallBack
  536.         formulaType_t type;
  537.  };
  538.  
  539. +class MonsterCallback final : public CallBack
  540. +{
  541. +public:
  542. +   void onMonsterCombat(Monster* monster, CombatDamage& damage) const;
  543. +
  544. +protected:
  545. +   formulaType_t type;
  546. +
  547. +};
  548. +
  549.  struct CombatParams {
  550.     std::forward_list<std::unique_ptr<const Condition>> conditionList;
  551.  
  552.     std::unique_ptr<ValueCallback> valueCallback;
  553.     std::unique_ptr<TileCallback> tileCallback;
  554.     std::unique_ptr<TargetCallback> targetCallback;
  555. +   std::unique_ptr<MonsterCallback> monsterCallback;
  556.  
  557.     uint16_t itemId = 0;
  558.  
  559.     ConditionType_t dispelType = CONDITION_NONE;
  560.     CombatType_t combatType = COMBAT_NONE;
  561.     CombatOrigin origin = ORIGIN_SPELL;
  562. +   CombatSpellType_t spellType = COMBATSPELL_NONE;
  563.  
  564.     uint8_t impactEffect = CONST_ME_NONE;
  565.     uint8_t distanceEffect = CONST_ANI_NONE;
  566. diff --git a/forgottenserver-1.2/src/creature.cpp b/forgottenserver-1.2/src/creature.cpp
  567. index 318380b..44dfccb 100644
  568. --- a/forgottenserver-1.2/src/creature.cpp
  569. +++ b/forgottenserver-1.2/src/creature.cpp
  570. @@ -800,48 +800,13 @@ void Creature::drainMana(Creature* attacker, int32_t manaLoss)
  571.  }
  572.  
  573.  BlockType_t Creature::blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
  574. -                               bool checkDefense /* = false */, bool checkArmor /* = false */, bool /* field  = false */)
  575. +                               bool checkDefense /* = false */, bool checkArmor /* = false */, bool /* field  = false */, CombatSpellType_t spellType)
  576.  {
  577.     BlockType_t blockType = BLOCK_NONE;
  578.  
  579.     if (isImmune(combatType)) {
  580.         damage = 0;
  581.         blockType = BLOCK_IMMUNITY;
  582. -   } else if (checkDefense || checkArmor) {
  583. -       bool hasDefense = false;
  584. -
  585. -       if (blockCount > 0) {
  586. -           --blockCount;
  587. -           hasDefense = true;
  588. -       }
  589. -
  590. -       if (checkDefense && hasDefense) {
  591. -           int32_t defense = getDefense();
  592. -           damage -= uniform_random(defense / 2, defense);
  593. -           if (damage <= 0) {
  594. -               damage = 0;
  595. -               blockType = BLOCK_DEFENSE;
  596. -               checkArmor = false;
  597. -           }
  598. -       }
  599. -
  600. -       if (checkArmor) {
  601. -           int32_t armor = getArmor();
  602. -           if (armor > 3) {
  603. -               damage -= uniform_random(armor / 2, armor - (armor % 2 + 1));
  604. -           } else if (armor > 0) {
  605. -               --damage;
  606. -           }
  607. -
  608. -           if (damage <= 0) {
  609. -               damage = 0;
  610. -               blockType = BLOCK_ARMOR;
  611. -           }
  612. -       }
  613. -
  614. -       if (hasDefense && blockType != BLOCK_NONE) {
  615. -           onBlockHit();
  616. -       }
  617.     }
  618.  
  619.     if (attacker) {
  620. @@ -1036,32 +1001,59 @@ void Creature::onTickCondition(ConditionType_t type, bool& bRemove)
  621.     }
  622.  
  623.     switch (type) {
  624. -       case CONDITION_FIRE:
  625. -           bRemove = (field->getCombatType() != COMBAT_FIREDAMAGE);
  626. -           break;
  627. -       case CONDITION_ENERGY:
  628. -           bRemove = (field->getCombatType() != COMBAT_ENERGYDAMAGE);
  629. -           break;
  630. -       case CONDITION_POISON:
  631. -           bRemove = (field->getCombatType() != COMBAT_EARTHDAMAGE);
  632. -           break;
  633. -       case CONDITION_FREEZING:
  634. -           bRemove = (field->getCombatType() != COMBAT_ICEDAMAGE);
  635. -           break;
  636. -       case CONDITION_DAZZLED:
  637. -           bRemove = (field->getCombatType() != COMBAT_HOLYDAMAGE);
  638. -           break;
  639. -       case CONDITION_CURSED:
  640. -           bRemove = (field->getCombatType() != COMBAT_DEATHDAMAGE);
  641. -           break;
  642. -       case CONDITION_DROWN:
  643. -           bRemove = (field->getCombatType() != COMBAT_DROWNDAMAGE);
  644. -           break;
  645. -       case CONDITION_BLEEDING:
  646. -           bRemove = (field->getCombatType() != COMBAT_PHYSICALDAMAGE);
  647. -           break;
  648. -       default:
  649. -           break;
  650. +   case CONDITION_BUG:
  651. +       bRemove = (field->getCombatType() != COMBAT_BUGDAMAGE);
  652. +       break;
  653. +   case CONDITION_DRAGON:
  654. +       bRemove = (field->getCombatType() != COMBAT_DRAGONDAMAGE);
  655. +       break;
  656. +   case CONDITION_FAIRY:
  657. +       bRemove = (field->getCombatType() != COMBAT_FAIRYDAMAGE);
  658. +       break;
  659. +   case CONDITION_FIRE:
  660. +       bRemove = (field->getCombatType() != COMBAT_FIREDAMAGE);
  661. +       break;
  662. +   case CONDITION_GHOST:
  663. +       bRemove = (field->getCombatType() != COMBAT_GHOSTDAMAGE);
  664. +       break;
  665. +   case CONDITION_GROUND:
  666. +       bRemove = (field->getCombatType() != COMBAT_GROUNDDAMAGE);
  667. +       break;
  668. +   case CONDITION_NORMAL:
  669. +       bRemove = (field->getCombatType() != COMBAT_NORMALDAMAGE);
  670. +       break;
  671. +   case CONDITION_PSYCHIC:
  672. +       bRemove = (field->getCombatType() != COMBAT_PSYCHICDAMAGE);
  673. +       break;
  674. +   case CONDITION_STEEL:
  675. +       bRemove = (field->getCombatType() != COMBAT_STEELDAMAGE);
  676. +       break;
  677. +   case CONDITION_ELECTRIC:
  678. +       bRemove = (field->getCombatType() != COMBAT_ELECTRICDAMAGE);
  679. +       break;
  680. +   case CONDITION_FIGHTING:
  681. +       bRemove = (field->getCombatType() != COMBAT_FIGHTINGDAMAGE);
  682. +       break;
  683. +   case CONDITION_FLYING:
  684. +       bRemove = (field->getCombatType() != COMBAT_FLYINGDAMAGE);
  685. +       break;
  686. +   case CONDITION_GRASS:
  687. +       bRemove = (field->getCombatType() != COMBAT_GRASSDAMAGE);
  688. +       break;
  689. +   case CONDITION_ICE:
  690. +       bRemove = (field->getCombatType() != COMBAT_ICEDAMAGE);
  691. +       break;
  692. +   case CONDITION_POISON:
  693. +       bRemove = (field->getCombatType() != COMBAT_POISONDAMAGE);
  694. +       break;
  695. +   case CONDITION_ROCK:
  696. +       bRemove = (field->getCombatType() != COMBAT_ROCKDAMAGE);
  697. +       break;
  698. +   case CONDITION_WATER:
  699. +       bRemove = (field->getCombatType() != COMBAT_WATERDAMAGE);
  700. +       break;
  701. +   default:
  702. +       break;
  703.     }
  704.  }
  705.  
  706. diff --git a/forgottenserver-1.2/src/creature.h b/forgottenserver-1.2/src/creature.h
  707. index 583fa80..3f02c99 100644
  708. --- a/forgottenserver-1.2/src/creature.h
  709. +++ b/forgottenserver-1.2/src/creature.h
  710. @@ -274,7 +274,7 @@ class Creature : virtual public Thing
  711.         }
  712.         virtual bool setAttackedCreature(Creature* creature);
  713.         virtual BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
  714. -                                    bool checkDefense = false, bool checkArmor = false, bool field = false);
  715. +                                    bool checkDefense = false, bool checkArmor = false, bool field = false, CombatSpellType_t spellType = COMBATSPELL_NONE);
  716.  
  717.         void setMaster(Creature* creature) {
  718.             master = creature;
  719. diff --git a/forgottenserver-1.2/src/enums.h b/forgottenserver-1.2/src/enums.h
  720. index 2613586..91bd00e 100644
  721. --- a/forgottenserver-1.2/src/enums.h
  722. +++ b/forgottenserver-1.2/src/enums.h
  723. @@ -138,23 +138,36 @@ enum RaceType_t : uint8_t {
  724.     RACE_ENERGY,
  725.  };
  726.  
  727. -enum CombatType_t : uint16_t {
  728. +enum CombatType_t {
  729.     COMBAT_NONE = 0,
  730.  
  731. -   COMBAT_PHYSICALDAMAGE = 1 << 0,
  732. -   COMBAT_ENERGYDAMAGE = 1 << 1,
  733. -   COMBAT_EARTHDAMAGE = 1 << 2,
  734. +   COMBAT_BUGDAMAGE = 1 << 0,
  735. +   COMBAT_DRAGONDAMAGE = 1 << 1,
  736. +   COMBAT_FAIRYDAMAGE = 1 << 2,
  737.     COMBAT_FIREDAMAGE = 1 << 3,
  738. -   COMBAT_UNDEFINEDDAMAGE = 1 << 4,
  739. -   COMBAT_LIFEDRAIN = 1 << 5,
  740. -   COMBAT_MANADRAIN = 1 << 6,
  741. -   COMBAT_HEALING = 1 << 7,
  742. -   COMBAT_DROWNDAMAGE = 1 << 8,
  743. -   COMBAT_ICEDAMAGE = 1 << 9,
  744. -   COMBAT_HOLYDAMAGE = 1 << 10,
  745. -   COMBAT_DEATHDAMAGE = 1 << 11,
  746. -
  747. -   COMBAT_COUNT = 12
  748. +   COMBAT_GHOSTDAMAGE = 1 << 4,
  749. +   COMBAT_GROUNDDAMAGE = 1 << 5,
  750. +   COMBAT_NORMALDAMAGE = 1 << 6,
  751. +   COMBAT_PSYCHICDAMAGE = 1 << 7,
  752. +   COMBAT_STEELDAMAGE = 1 << 8,
  753. +   COMBAT_DARKDAMAGE = 1 << 9,
  754. +   COMBAT_ELECTRICDAMAGE = 1 << 10,
  755. +   COMBAT_FIGHTINGDAMAGE = 1 << 11,
  756. +   COMBAT_FLYINGDAMAGE = 1 << 12,
  757. +   COMBAT_GRASSDAMAGE = 1 << 13,
  758. +   COMBAT_ICEDAMAGE = 1 << 14,
  759. +   COMBAT_POISONDAMAGE = 1 << 15,
  760. +   COMBAT_ROCKDAMAGE = 1 << 16,
  761. +   COMBAT_WATERDAMAGE = 1 << 17,
  762. +   COMBAT_HEALING = 1 << 18,
  763. +
  764. +   COMBAT_COUNT = 18
  765. +};
  766. +
  767. +enum CombatSpellType_t {
  768. +   COMBATSPELL_NONE = 0,
  769. +   COMBATSPELL_ATTACK = 1 << 0,
  770. +   COMBATSPELL_SPECIALATTACK = 2 << 0,
  771.  };
  772.  
  773.  enum CombatParam_t {
  774. @@ -175,6 +188,7 @@ enum CallBackParam_t {
  775.     CALLBACK_PARAM_SKILLVALUE,
  776.     CALLBACK_PARAM_TARGETTILE,
  777.     CALLBACK_PARAM_TARGETCREATURE,
  778. +   CALLBACK_PARAM_MONSTER,
  779.  };
  780.  
  781.  enum ConditionParam_t {
  782. @@ -229,7 +243,7 @@ enum ConditionParam_t {
  783.  enum BlockType_t : uint8_t {
  784.     BLOCK_NONE,
  785.     BLOCK_DEFENSE,
  786. -   BLOCK_ARMOR,
  787. +   BLOCK_SPECIALDEFENSE,
  788.     BLOCK_IMMUNITY
  789.  };
  790.  
  791. @@ -269,34 +283,51 @@ enum formulaType_t {
  792.  enum ConditionType_t {
  793.     CONDITION_NONE,
  794.  
  795. -   CONDITION_POISON = 1 << 0,
  796. -   CONDITION_FIRE = 1 << 1,
  797. -   CONDITION_ENERGY = 1 << 2,
  798. -   CONDITION_BLEEDING = 1 << 3,
  799. -   CONDITION_HASTE = 1 << 4,
  800. -   CONDITION_PARALYZE = 1 << 5,
  801. -   CONDITION_OUTFIT = 1 << 6,
  802. -   CONDITION_INVISIBLE = 1 << 7,
  803. -   CONDITION_LIGHT = 1 << 8,
  804. -   CONDITION_MANASHIELD = 1 << 9,
  805. -   CONDITION_INFIGHT = 1 << 10,
  806. -   CONDITION_DRUNK = 1 << 11,
  807. -   CONDITION_EXHAUST_WEAPON = 1 << 12, // unused
  808. -   CONDITION_REGENERATION = 1 << 13,
  809. -   CONDITION_SOUL = 1 << 14,
  810. -   CONDITION_DROWN = 1 << 15,
  811. -   CONDITION_MUTED = 1 << 16,
  812. -   CONDITION_CHANNELMUTEDTICKS = 1 << 17,
  813. -   CONDITION_YELLTICKS = 1 << 18,
  814. -   CONDITION_ATTRIBUTES = 1 << 19,
  815. -   CONDITION_FREEZING = 1 << 20,
  816. -   CONDITION_DAZZLED = 1 << 21,
  817. -   CONDITION_CURSED = 1 << 22,
  818. -   CONDITION_EXHAUST_COMBAT = 1 << 23, // unused
  819. -   CONDITION_EXHAUST_HEAL = 1 << 24, // unused
  820. -   CONDITION_PACIFIED = 1 << 25,
  821. -   CONDITION_SPELLCOOLDOWN = 1 << 26,
  822. -   CONDITION_SPELLGROUPCOOLDOWN = 1 << 27,
  823. +   CONDITION_POISON = 1,
  824. +   CONDITION_FIRE = 2,
  825. +   CONDITION_ENERGY = 3,
  826. +   CONDITION_BLEEDING = 4,
  827. +   CONDITION_HASTE = 5,
  828. +   CONDITION_PARALYZE = 6,
  829. +   CONDITION_OUTFIT = 7,
  830. +   CONDITION_INVISIBLE = 8,
  831. +   CONDITION_LIGHT = 9,
  832. +   CONDITION_MANASHIELD = 10,
  833. +   CONDITION_INFIGHT = 11,
  834. +   CONDITION_DRUNK = 12,
  835. +   CONDITION_EXHAUST_WEAPON = 13, // unused
  836. +   CONDITION_REGENERATION = 14,
  837. +   CONDITION_SOUL = 15,
  838. +   CONDITION_DROWN = 16,
  839. +   CONDITION_MUTED = 17,
  840. +   CONDITION_CHANNELMUTEDTICKS = 18,
  841. +   CONDITION_YELLTICKS = 19,
  842. +   CONDITION_ATTRIBUTES = 20,
  843. +   CONDITION_FREEZING = 21,
  844. +   CONDITION_DAZZLED = 22,
  845. +   CONDITION_CURSED = 23,
  846. +   CONDITION_EXHAUST_COMBAT = 24, // unused
  847. +   CONDITION_EXHAUST_HEAL = 25, // unused
  848. +   CONDITION_PACIFIED = 26,
  849. +   CONDITION_SPELLCOOLDOWN = 27,
  850. +   CONDITION_SPELLGROUPCOOLDOWN = 28,
  851. +   CONDITION_BUG = 29,
  852. +   CONDITION_DRAGON = 30,
  853. +   CONDITION_FAIRY = 31,
  854. +   CONDITION_GHOST = 32,
  855. +   CONDITION_GROUND = 33,
  856. +   CONDITION_NORMAL = 34,
  857. +   CONDITION_PSYCHIC = 35,
  858. +   CONDITION_STEEL = 36,
  859. +   CONDITION_DARK = 38,
  860. +   CONDITION_ELECTRIC = 39,
  861. +   CONDITION_FIGHTING = 40,
  862. +   CONDITION_FLYING = 41,
  863. +   CONDITION_GRASS = 42,
  864. +   CONDITION_ICE = 43,
  865. +   CONDITION_ROCK = 44,
  866. +   CONDITION_WATER = 45,
  867. +
  868.  };
  869.  
  870.  enum ConditionId_t : int8_t {
  871. @@ -564,7 +595,7 @@ public:
  872.         attack += nStatus.getAttack();
  873.         defense += nStatus.getDefense();
  874.         health += nStatus.getHealth();
  875. -       specialAttack += nStatus.getSpeciaAttack();
  876. +       specialAttack += nStatus.getSpecialAttack();
  877.         specialDefense += nStatus.getSpecialDefense();
  878.         speed += nStatus.getSpeed();
  879.     }
  880. @@ -600,7 +631,7 @@ public:
  881.     {
  882.         specialAttack = value;
  883.     }
  884. -   double getSpeciaAttack()
  885. +   double getSpecialAttack()
  886.     {
  887.         return specialAttack;
  888.     }
  889. diff --git a/forgottenserver-1.2/src/game.cpp b/forgottenserver-1.2/src/game.cpp
  890. index cf3014b..efc77e7 100644
  891. --- a/forgottenserver-1.2/src/game.cpp
  892. +++ b/forgottenserver-1.2/src/game.cpp
  893. @@ -3595,7 +3595,7 @@ void Game::changeLight(const Creature* creature)
  894.     }
  895.  }
  896.  
  897. -bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field)
  898. +bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field, CombatSpellType_t spellType)
  899.  {
  900.     if (damage.primary.type == COMBAT_NONE && damage.secondary.type == COMBAT_NONE) {
  901.         return true;
  902. @@ -3610,37 +3610,15 @@ bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* ta
  903.     }
  904.  
  905.     static const auto sendBlockEffect = [this](BlockType_t blockType, CombatType_t combatType, const Position& targetPos) {
  906. -       if (blockType == BLOCK_DEFENSE) {
  907. +       if (blockType == BLOCK_SPECIALDEFENSE) {
  908.             addMagicEffect(targetPos, CONST_ME_POFF);
  909. -       } else if (blockType == BLOCK_ARMOR) {
  910. +       }
  911. +       else if (blockType == BLOCK_DEFENSE) {
  912.             addMagicEffect(targetPos, CONST_ME_BLOCKHIT);
  913. -       } else if (blockType == BLOCK_IMMUNITY) {
  914. +       }
  915. +       else if (blockType == BLOCK_IMMUNITY) {
  916.             uint8_t hitEffect = 0;
  917. -           switch (combatType) {
  918. -               case COMBAT_UNDEFINEDDAMAGE: {
  919. -                   return;
  920. -               }
  921. -               case COMBAT_ENERGYDAMAGE:
  922. -               case COMBAT_FIREDAMAGE:
  923. -               case COMBAT_PHYSICALDAMAGE:
  924. -               case COMBAT_ICEDAMAGE:
  925. -               case COMBAT_DEATHDAMAGE: {
  926. -                   hitEffect = CONST_ME_BLOCKHIT;
  927. -                   break;
  928. -               }
  929. -               case COMBAT_EARTHDAMAGE: {
  930. -                   hitEffect = CONST_ME_GREEN_RINGS;
  931. -                   break;
  932. -               }
  933. -               case COMBAT_HOLYDAMAGE: {
  934. -                   hitEffect = CONST_ME_HOLYDAMAGE;
  935. -                   break;
  936. -               }
  937. -               default: {
  938. -                   hitEffect = CONST_ME_POFF;
  939. -                   break;
  940. -               }
  941. -           }
  942. +           hitEffect = CONST_ME_POFF;
  943.             addMagicEffect(targetPos, hitEffect);
  944.         }
  945.     };
  946. @@ -3648,116 +3626,34 @@ bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* ta
  947.     BlockType_t primaryBlockType, secondaryBlockType;
  948.     if (damage.primary.type != COMBAT_NONE) {
  949.         damage.primary.value = -damage.primary.value;
  950. -       primaryBlockType = target->blockHit(attacker, damage.primary.type, damage.primary.value, checkDefense, checkArmor, field);
  951. +       primaryBlockType = target->blockHit(attacker, damage.primary.type, damage.primary.value, checkDefense, checkArmor, field, spellType);
  952.  
  953.         damage.primary.value = -damage.primary.value;
  954.         sendBlockEffect(primaryBlockType, damage.primary.type, target->getPosition());
  955. -   } else {
  956. +   }
  957. +   else {
  958.         primaryBlockType = BLOCK_NONE;
  959.     }
  960.  
  961.     if (damage.secondary.type != COMBAT_NONE) {
  962.         damage.secondary.value = -damage.secondary.value;
  963. -       secondaryBlockType = target->blockHit(attacker, damage.secondary.type, damage.secondary.value, false, false, field);
  964. +       secondaryBlockType = target->blockHit(attacker, damage.secondary.type, damage.secondary.value, false, false, field, spellType);
  965.  
  966.         damage.secondary.value = -damage.secondary.value;
  967.         sendBlockEffect(secondaryBlockType, damage.secondary.type, target->getPosition());
  968. -   } else {
  969. +   }
  970. +   else {
  971.         secondaryBlockType = BLOCK_NONE;
  972.     }
  973. +
  974.     return (primaryBlockType != BLOCK_NONE) && (secondaryBlockType != BLOCK_NONE);
  975.  }
  976.  
  977.  void Game::combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColor_t& color, uint8_t& effect)
  978.  {
  979. -   switch (combatType) {
  980. -       case COMBAT_PHYSICALDAMAGE: {
  981. -           Item* splash = nullptr;
  982. -           switch (target->getRace()) {
  983. -               case RACE_VENOM:
  984. -                   color = TEXTCOLOR_LIGHTGREEN;
  985. -                   effect = CONST_ME_HITBYPOISON;
  986. -                   splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_GREEN);
  987. -                   break;
  988. -               case RACE_BLOOD:
  989. -                   color = TEXTCOLOR_RED;
  990. -                   effect = CONST_ME_DRAWBLOOD;
  991. -                   splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_BLOOD);
  992. -                   break;
  993. -               case RACE_UNDEAD:
  994. -                   color = TEXTCOLOR_LIGHTGREY;
  995. -                   effect = CONST_ME_HITAREA;
  996. -                   break;
  997. -               case RACE_FIRE:
  998. -                   color = TEXTCOLOR_ORANGE;
  999. -                   effect = CONST_ME_DRAWBLOOD;
  1000. -                   break;
  1001. -               case RACE_ENERGY:
  1002. -                   color = TEXTCOLOR_PURPLE;
  1003. -                   effect = CONST_ME_ENERGYHIT;
  1004. -                   break;
  1005. -               default:
  1006. -                   color = TEXTCOLOR_NONE;
  1007. -                   effect = CONST_ME_NONE;
  1008. -                   break;
  1009. -           }
  1010. -
  1011. -           if (splash) {
  1012. -               internalAddItem(target->getTile(), splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
  1013. -               startDecay(splash);
  1014. -           }
  1015. -
  1016. -           break;
  1017. -       }
  1018. -
  1019. -       case COMBAT_ENERGYDAMAGE: {
  1020. -           color = TEXTCOLOR_PURPLE;
  1021. -           effect = CONST_ME_ENERGYHIT;
  1022. -           break;
  1023. -       }
  1024. -
  1025. -       case COMBAT_EARTHDAMAGE: {
  1026. -           color = TEXTCOLOR_LIGHTGREEN;
  1027. -           effect = CONST_ME_GREEN_RINGS;
  1028. -           break;
  1029. -       }
  1030. -
  1031. -       case COMBAT_DROWNDAMAGE: {
  1032. -           color = TEXTCOLOR_LIGHTBLUE;
  1033. -           effect = CONST_ME_LOSEENERGY;
  1034. -           break;
  1035. -       }
  1036. -       case COMBAT_FIREDAMAGE: {
  1037. -           color = TEXTCOLOR_ORANGE;
  1038. -           effect = CONST_ME_HITBYFIRE;
  1039. -           break;
  1040. -       }
  1041. -       case COMBAT_ICEDAMAGE: {
  1042. -           color = TEXTCOLOR_SKYBLUE;
  1043. -           effect = CONST_ME_ICEATTACK;
  1044. -           break;
  1045. -       }
  1046. -       case COMBAT_HOLYDAMAGE: {
  1047. -           color = TEXTCOLOR_YELLOW;
  1048. -           effect = CONST_ME_HOLYDAMAGE;
  1049. -           break;
  1050. -       }
  1051. -       case COMBAT_DEATHDAMAGE: {
  1052. -           color = TEXTCOLOR_DARKRED;
  1053. -           effect = CONST_ME_SMALLCLOUDS;
  1054. -           break;
  1055. -       }
  1056. -       case COMBAT_LIFEDRAIN: {
  1057. -           color = TEXTCOLOR_RED;
  1058. -           effect = CONST_ME_MAGIC_RED;
  1059. -           break;
  1060. -       }
  1061. -       default: {
  1062. -           color = TEXTCOLOR_NONE;
  1063. -           effect = CONST_ME_NONE;
  1064. -           break;
  1065. -       }
  1066. -   }
  1067. +   //Todo: Arrumar os Combat Type
  1068. +   color = TEXTCOLOR_LIGHTGREEN;
  1069. +   effect = CONST_ME_HITBYPOISON;
  1070.  }
  1071.  
  1072.  bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage)
  1073. @@ -3873,7 +3769,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage
  1074.         message.position = targetPos;
  1075.  
  1076.         SpectatorVec list;
  1077. -       if (target->hasCondition(CONDITION_MANASHIELD) && damage.primary.type != COMBAT_UNDEFINEDDAMAGE) {
  1078. +       if (target->hasCondition(CONDITION_MANASHIELD)) {
  1079.             int32_t manaDamage = std::min<int32_t>(target->getMana(), healthChange);
  1080.             if (manaDamage != 0) {
  1081.                 if (damage.origin != ORIGIN_NONE) {
  1082. @@ -4087,7 +3983,7 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, int32_t manaCh
  1083.         }
  1084.  
  1085.         int32_t manaLoss = std::min<int32_t>(target->getMana(), -manaChange);
  1086. -       BlockType_t blockType = target->blockHit(attacker, COMBAT_MANADRAIN, manaLoss);
  1087. +       BlockType_t blockType = target->blockHit(attacker, COMBAT_NONE, manaLoss);
  1088.         if (blockType != BLOCK_NONE) {
  1089.             addMagicEffect(targetPos, CONST_ME_POFF);
  1090.             return false;
  1091. diff --git a/forgottenserver-1.2/src/game.h b/forgottenserver-1.2/src/game.h
  1092. index 06e4f21..8050020 100644
  1093. --- a/forgottenserver-1.2/src/game.h
  1094. +++ b/forgottenserver-1.2/src/game.h
  1095. @@ -435,7 +435,7 @@ class Game
  1096.         void checkCreatures(size_t index);
  1097.         void checkLight();
  1098.  
  1099. -       bool combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field);
  1100. +       bool combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field, CombatSpellType_t spellType = COMBATSPELL_NONE);
  1101.  
  1102.         void combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColor_t& color, uint8_t& effect);
  1103.  
  1104. diff --git a/forgottenserver-1.2/src/items.cpp b/forgottenserver-1.2/src/items.cpp
  1105. index 37a1201..790f037 100644
  1106. --- a/forgottenserver-1.2/src/items.cpp
  1107. +++ b/forgottenserver-1.2/src/items.cpp
  1108. @@ -376,6 +376,8 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
  1109.             continue;
  1110.         }
  1111.  
  1112. +
  1113. +       //Todo: Arrumar fields
  1114.         std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string());
  1115.         if (tmpStrValue == "type") {
  1116.             tmpStrValue = asLowerCaseString(valueAttribute.as_string());
  1117. @@ -657,11 +659,11 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
  1118.         } else if (tmpStrValue == "magicpointspercent") {
  1119.             it.getAbilities().statsPercent[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
  1120.         } else if (tmpStrValue == "fieldabsorbpercentenergy") {
  1121. -           it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1122. +           //it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1123.         } else if (tmpStrValue == "fieldabsorbpercentfire") {
  1124.             it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1125.         } else if (tmpStrValue == "fieldabsorbpercentpoison" || tmpStrValue == "fieldabsorpercentearth") {
  1126. -           it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1127. +           //it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1128.         } else if (tmpStrValue == "absorbpercentall" || tmpStrValue == "absorbpercentallelements") {
  1129.             int16_t value = pugi::cast<int16_t>(valueAttribute.value());
  1130.             Abilities& abilities = it.getAbilities();
  1131. @@ -671,43 +673,43 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
  1132.         } else if (tmpStrValue == "absorbpercentelements") {
  1133.             int16_t value = pugi::cast<int16_t>(valueAttribute.value());
  1134.             Abilities& abilities = it.getAbilities();
  1135. -           abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
  1136. +           //abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
  1137.             abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
  1138. -           abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
  1139. +           //abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
  1140.             abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value;
  1141.         } else if (tmpStrValue == "absorbpercentmagic") {
  1142.             int16_t value = pugi::cast<int16_t>(valueAttribute.value());
  1143.             Abilities& abilities = it.getAbilities();
  1144. -           abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
  1145. +           //abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
  1146.             abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
  1147. -           abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
  1148. +           //abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
  1149.             abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value;
  1150. -           abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value;
  1151. -           abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value;
  1152. +           //abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value;
  1153. +           //abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value;
  1154.         } else if (tmpStrValue == "absorbpercentenergy") {
  1155. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1156. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1157.         } else if (tmpStrValue == "absorbpercentfire") {
  1158.             it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1159.         } else if (tmpStrValue == "absorbpercentpoison" ||  tmpStrValue == "absorbpercentearth") {
  1160. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1161. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1162.         } else if (tmpStrValue == "absorbpercentice") {
  1163.             it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1164.         } else if (tmpStrValue == "absorbpercentholy") {
  1165. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1166. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1167.         } else if (tmpStrValue == "absorbpercentdeath") {
  1168. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1169. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1170.         } else if (tmpStrValue == "absorbpercentlifedrain") {
  1171. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
  1172. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
  1173.         } else if (tmpStrValue == "absorbpercentmanadrain") {
  1174. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
  1175. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
  1176.         } else if (tmpStrValue == "absorbpercentdrown") {
  1177. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1178. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1179.         } else if (tmpStrValue == "absorbpercentphysical") {
  1180. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1181. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1182.         } else if (tmpStrValue == "absorbpercenthealing") {
  1183.             it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value());
  1184.         } else if (tmpStrValue == "absorbpercentundefined") {
  1185. -           it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1186. +           //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
  1187.         } else if (tmpStrValue == "suppressdrunk") {
  1188.             if (valueAttribute.as_bool()) {
  1189.                 it.getAbilities().conditionSuppressions |= CONDITION_DRUNK;
  1190. @@ -757,16 +759,16 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
  1191.                 combatType = COMBAT_FIREDAMAGE;
  1192.             } else if (tmpStrValue == "energy") {
  1193.                 conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY);
  1194. -               combatType = COMBAT_ENERGYDAMAGE;
  1195. +               combatType = COMBAT_FIREDAMAGE;
  1196.             } else if (tmpStrValue == "poison") {
  1197.                 conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON);
  1198. -               combatType = COMBAT_EARTHDAMAGE;
  1199. +               combatType = COMBAT_FIREDAMAGE;
  1200.             } else if (tmpStrValue == "drown") {
  1201.                 conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_DROWN);
  1202. -               combatType = COMBAT_DROWNDAMAGE;
  1203. +               combatType = COMBAT_FIREDAMAGE;
  1204.             } else if (tmpStrValue == "physical") {
  1205.                 conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_BLEEDING);
  1206. -               combatType = COMBAT_PHYSICALDAMAGE;
  1207. +               combatType = COMBAT_FIREDAMAGE;
  1208.             } else {
  1209.                 std::cout << "[Warning - Items::parseItemNode] Unknown field value: " << valueAttribute.as_string() << std::endl;
  1210.             }
  1211. @@ -860,7 +862,7 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
  1212.         } else if (tmpStrValue == "elementearth") {
  1213.             Abilities& abilities = it.getAbilities();
  1214.             abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
  1215. -           abilities.elementType = COMBAT_EARTHDAMAGE;
  1216. +           abilities.elementType = COMBAT_FIREDAMAGE;
  1217.         } else if (tmpStrValue == "elementfire") {
  1218.             Abilities& abilities = it.getAbilities();
  1219.             abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
  1220. @@ -868,7 +870,7 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
  1221.         } else if (tmpStrValue == "elementenergy") {
  1222.             Abilities& abilities = it.getAbilities();
  1223.             abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
  1224. -           abilities.elementType = COMBAT_ENERGYDAMAGE;
  1225. +           abilities.elementType = COMBAT_FIREDAMAGE;
  1226.         } else if (tmpStrValue == "walkstack") {
  1227.             it.walkStack = valueAttribute.as_bool();
  1228.         } else if (tmpStrValue == "blocking") {
  1229. diff --git a/forgottenserver-1.2/src/luascript.cpp b/forgottenserver-1.2/src/luascript.cpp
  1230. index 351e19a..542dd0e 100644
  1231. --- a/forgottenserver-1.2/src/luascript.cpp
  1232. +++ b/forgottenserver-1.2/src/luascript.cpp
  1233. @@ -1058,6 +1058,7 @@ void LuaScriptInterface::registerFunctions()
  1234.     registerEnum(CALLBACK_PARAM_SKILLVALUE)
  1235.     registerEnum(CALLBACK_PARAM_TARGETTILE)
  1236.     registerEnum(CALLBACK_PARAM_TARGETCREATURE)
  1237. +   registerEnum(CALLBACK_PARAM_MONSTER)
  1238.  
  1239.     registerEnum(COMBAT_FORMULA_UNDEFINED)
  1240.     registerEnum(COMBAT_FORMULA_LEVELMAGIC)
  1241. @@ -1074,18 +1075,25 @@ void LuaScriptInterface::registerFunctions()
  1242.     registerEnum(DIRECTION_NORTHEAST)
  1243.  
  1244.     registerEnum(COMBAT_NONE)
  1245. -   registerEnum(COMBAT_PHYSICALDAMAGE)
  1246. -   registerEnum(COMBAT_ENERGYDAMAGE)
  1247. -   registerEnum(COMBAT_EARTHDAMAGE)
  1248. +   registerEnum(COMBAT_BUGDAMAGE)
  1249. +   registerEnum(COMBAT_DRAGONDAMAGE)
  1250. +   registerEnum(COMBAT_FAIRYDAMAGE)
  1251.     registerEnum(COMBAT_FIREDAMAGE)
  1252. -   registerEnum(COMBAT_UNDEFINEDDAMAGE)
  1253. -   registerEnum(COMBAT_LIFEDRAIN)
  1254. -   registerEnum(COMBAT_MANADRAIN)
  1255. -   registerEnum(COMBAT_HEALING)
  1256. -   registerEnum(COMBAT_DROWNDAMAGE)
  1257. +   registerEnum(COMBAT_GHOSTDAMAGE)
  1258. +   registerEnum(COMBAT_GROUNDDAMAGE)
  1259. +   registerEnum(COMBAT_NORMALDAMAGE)
  1260. +   registerEnum(COMBAT_PSYCHICDAMAGE)
  1261. +   registerEnum(COMBAT_STEELDAMAGE)
  1262. +   registerEnum(COMBAT_DARKDAMAGE)
  1263. +   registerEnum(COMBAT_ELECTRICDAMAGE)
  1264. +   registerEnum(COMBAT_FIGHTINGDAMAGE)
  1265. +   registerEnum(COMBAT_FLYINGDAMAGE)
  1266. +   registerEnum(COMBAT_GRASSDAMAGE)
  1267.     registerEnum(COMBAT_ICEDAMAGE)
  1268. -   registerEnum(COMBAT_HOLYDAMAGE)
  1269. -   registerEnum(COMBAT_DEATHDAMAGE)
  1270. +   registerEnum(COMBAT_POISONDAMAGE)
  1271. +   registerEnum(COMBAT_ROCKDAMAGE)
  1272. +   registerEnum(COMBAT_WATERDAMAGE)
  1273. +   registerEnum(COMBAT_HEALING)
  1274.  
  1275.     registerEnum(COMBAT_PARAM_TYPE)
  1276.     registerEnum(COMBAT_PARAM_EFFECT)
  1277. @@ -1128,6 +1136,25 @@ void LuaScriptInterface::registerFunctions()
  1278.     registerEnum(CONDITION_SPELLCOOLDOWN)
  1279.     registerEnum(CONDITION_SPELLGROUPCOOLDOWN)
  1280.  
  1281. +   registerEnum(CONDITION_BUG)
  1282. +   registerEnum(CONDITION_DRAGON)
  1283. +   registerEnum(CONDITION_FAIRY)
  1284. +   registerEnum(CONDITION_FIRE)
  1285. +   registerEnum(CONDITION_GHOST)
  1286. +   registerEnum(CONDITION_GROUND)
  1287. +   registerEnum(CONDITION_NORMAL)
  1288. +   registerEnum(CONDITION_PSYCHIC)
  1289. +   registerEnum(CONDITION_STEEL)
  1290. +   registerEnum(CONDITION_DARK)
  1291. +   registerEnum(CONDITION_ELECTRIC)
  1292. +   registerEnum(CONDITION_FIGHTING)
  1293. +   registerEnum(CONDITION_FLYING)
  1294. +   registerEnum(CONDITION_GRASS)
  1295. +   registerEnum(CONDITION_ICE)
  1296. +   registerEnum(CONDITION_POISON)
  1297. +   registerEnum(CONDITION_ROCK)
  1298. +   registerEnum(CONDITION_WATER)
  1299. +
  1300.     registerEnum(CONDITIONID_DEFAULT)
  1301.     registerEnum(CONDITIONID_COMBAT)
  1302.     registerEnum(CONDITIONID_HEAD)
  1303. @@ -2280,6 +2307,7 @@ void LuaScriptInterface::registerFunctions()
  1304.     registerMetaMethod("Monster", "__eq", LuaScriptInterface::luaUserdataCompare);
  1305.  
  1306.     registerMethod("Monster", "isMonster", LuaScriptInterface::luaMonsterIsMonster);
  1307. +   registerMethod("Monster", "castSpell", LuaScriptInterface::luaMonsterCastSpell);
  1308.  
  1309.     registerMethod("Monster", "getType", LuaScriptInterface::luaMonsterGetType);
  1310.  
  1311. @@ -3167,7 +3195,7 @@ int LuaScriptInterface::luaDoAreaCombatMana(lua_State* L)
  1312.  
  1313.         CombatDamage damage;
  1314.         damage.origin = getNumber<CombatOrigin>(L, 7, ORIGIN_SPELL);
  1315. -       damage.primary.type = COMBAT_MANADRAIN;
  1316. +       damage.primary.type = COMBAT_NONE;
  1317.         damage.primary.value = normal_random(getNumber<int32_t>(L, 4), getNumber<int32_t>(L, 5));
  1318.  
  1319.         Position pos = getPosition(L, 2);
  1320. @@ -3202,7 +3230,7 @@ int LuaScriptInterface::luaDoTargetCombatMana(lua_State* L)
  1321.  
  1322.     CombatDamage damage;
  1323.     damage.origin = getNumber<CombatOrigin>(L, 6, ORIGIN_SPELL);
  1324. -   damage.primary.type = COMBAT_MANADRAIN;
  1325. +   damage.primary.type = COMBAT_NONE;
  1326.     damage.primary.value = normal_random(getNumber<int32_t>(L, 3), getNumber<int32_t>(L, 4));
  1327.  
  1328.     Combat::doCombatMana(creature, target, damage, params);
  1329. @@ -7246,12 +7274,13 @@ int LuaScriptInterface::luaCreatureAddHealth(lua_State* L)
  1330.     if (damage.primary.value >= 0) {
  1331.         damage.primary.type = COMBAT_HEALING;
  1332.     } else {
  1333. -       damage.primary.type = COMBAT_UNDEFINEDDAMAGE;
  1334. +       damage.primary.type = COMBAT_NONE;
  1335.     }
  1336.     pushBoolean(L, g_game.combatChangeHealth(nullptr, creature, damage));
  1337.     return 1;
  1338.  }
  1339.  
  1340. +
  1341.  int LuaScriptInterface::luaCreatureGetMaxHealth(lua_State* L)
  1342.  {
  1343.     // creature:getMaxHealth()
  1344. @@ -9522,6 +9551,18 @@ int LuaScriptInterface::luaMonsterIsMonster(lua_State* L)
  1345.     return 1;
  1346.  }
  1347.  
  1348. +int LuaScriptInterface::luaMonsterCastSpell(lua_State* L)
  1349. +{
  1350. +   // monster:castSpell(word)
  1351. +   Monster* monster = getUserdata<Monster>(L, 1);
  1352. +   if (monster) {
  1353. +       std::string word = getString(L, 2);
  1354. +       monster->castSpell(word);
  1355. +   }
  1356. +
  1357. +   return 1;
  1358. +}
  1359. +
  1360.  int LuaScriptInterface::luaMonsterGetType(lua_State* L)
  1361.  {
  1362.     // monster:getType()
  1363. @@ -9902,7 +9943,7 @@ int LuaScriptInterface::luaMonsterGetSpecialAttack(lua_State* L)
  1364.     // monster:getSpecialAttack()
  1365.     Monster* monster = getUserdata<Monster>(L, 1);
  1366.     if (monster) {
  1367. -       lua_pushnumber(L, monster->getStatus().getSpeciaAttack());
  1368. +       lua_pushnumber(L, monster->getStatus().getSpecialAttack());
  1369.     }
  1370.     else {
  1371.         lua_pushnumber(L, 0);
  1372. @@ -11939,7 +11980,7 @@ int LuaScriptInterface::luaMonsterTypeGetAttackList(lua_State* L)
  1373.         setField(L, "minCombatValue", spellBlock.minCombatValue);
  1374.         setField(L, "maxCombatValue", spellBlock.maxCombatValue);
  1375.         setField(L, "range", spellBlock.range);
  1376. -       setField(L, "speed", spellBlock.speed);
  1377. +       setField(L, "speed", spellBlock.cooldown);
  1378.         pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
  1379.         lua_setfield(L, -2, "spell");
  1380.  
  1381. @@ -11957,11 +11998,11 @@ int LuaScriptInterface::luaMonsterTypeGetDefenseList(lua_State* L)
  1382.         return 1;
  1383.     }
  1384.  
  1385. -   lua_createtable(L, monsterType->info.defenseSpells.size(), 0);
  1386. +   lua_createtable(L, monsterType->info.passiveSpells.size(), 0);
  1387.  
  1388.  
  1389.     int index = 0;
  1390. -   for (const auto& spellBlock : monsterType->info.defenseSpells) {
  1391. +   for (const auto& spellBlock : monsterType->info.passiveSpells) {
  1392.         lua_createtable(L, 0, 8);
  1393.  
  1394.         setField(L, "chance", spellBlock.chance);
  1395. @@ -11970,7 +12011,7 @@ int LuaScriptInterface::luaMonsterTypeGetDefenseList(lua_State* L)
  1396.         setField(L, "minCombatValue", spellBlock.minCombatValue);
  1397.         setField(L, "maxCombatValue", spellBlock.maxCombatValue);
  1398.         setField(L, "range", spellBlock.range);
  1399. -       setField(L, "speed", spellBlock.speed);
  1400. +       setField(L, "speed", spellBlock.cooldown);
  1401.         pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
  1402.         lua_setfield(L, -2, "spell");
  1403.  
  1404. diff --git a/forgottenserver-1.2/src/monster.cpp b/forgottenserver-1.2/src/monster.cpp
  1405. index 5272fac..c698753 100644
  1406. --- a/forgottenserver-1.2/src/monster.cpp
  1407. +++ b/forgottenserver-1.2/src/monster.cpp
  1408. @@ -64,6 +64,15 @@ Monster::Monster(MonsterType* mtype) :
  1409.     // Adiciona a experiencia ao pokemon com base no level gerado
  1410.     experience = getExpForLevel(level);
  1411.  
  1412. +   // Adicona as magias no pokemon
  1413. +   for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
  1414. +       attackSpells.push_back(MonsterSpell(spellBlock));
  1415. +   }
  1416. +
  1417. +   for (const spellBlock_t& spellBlock : mType->info.passiveSpells) {
  1418. +       passiveSpells.push_back(MonsterSpell(spellBlock));
  1419. +   }
  1420. +
  1421.     defaultOutfit = mType->info.outfit;
  1422.     currentOutfit = mType->info.outfit;
  1423.     skull = mType->info.skull;
  1424. @@ -104,6 +113,58 @@ bool Monster::canSee(const Position& pos) const
  1425.     return Creature::canSee(getPosition(), pos, 9, 9);
  1426.  }
  1427.  
  1428. +//Todo: Talvez trocar os returns
  1429. +void Monster::castSpell(std::string word)
  1430. +{
  1431. +   for (MonsterSpell& spell : attackSpells) {
  1432. +       const spellBlock_t& spellBlock = *spell.spellBlock;
  1433. +       if (spellBlock.word != word) {
  1434. +           continue;
  1435. +       }
  1436. +
  1437. +       int64_t castTime = OTSYS_TIME();
  1438. +
  1439. +       Player* playerMaster = getMaster()->getPlayer();
  1440. +       if (level < spellBlock.level) {
  1441. +           if (playerMaster)
  1442. +               playerMaster->sendCancelMessage("Your Summon dont have level to cast this spell.");
  1443. +           return;
  1444. +       } else if ((castTime - spell.lastCooldown) < spellBlock.cooldown) {
  1445. +           if (playerMaster) {
  1446. +               std::stringstream msg;
  1447. +               msg << "This spell is in cooldown (" << ((spellBlock.cooldown - (castTime - spell.lastCooldown)) / 1000) << " sec).";
  1448. +               playerMaster->sendCancelMessage(msg.str());
  1449. +           }
  1450. +           return;
  1451. +       }
  1452. +
  1453. +       bool needTarget = spellBlock.spell->getNeedTarget();
  1454. +       if (needTarget && (!attackedCreature || attackedCreature == this)) {
  1455. +           if (playerMaster)
  1456. +               playerMaster->sendCancelMessage("You need a target to cast this spell.");
  1457. +           return;
  1458. +       }
  1459. +
  1460. +       updateLookDirection();
  1461. +
  1462. +       if (needTarget)
  1463. +           spellBlock.spell->castSpell(this, attackedCreature);
  1464. +       else
  1465. +           spellBlock.spell->castSpell(this);
  1466. +
  1467. +       const std::string& spellName = spellBlock.spell->getName();
  1468. +       if (spellName.size() > 0) {
  1469. +           g_game.internalCreatureSay(this, TALKTYPE_MONSTER_YELL, spellName, false);
  1470. +
  1471. +           if (playerMaster)
  1472. +               g_game.internalCreatureSay(playerMaster, TALKTYPE_MONSTER_YELL, getName() + " use " + spellName + "!", false);
  1473. +       }
  1474. +
  1475. +       spell.lastCooldown = castTime;
  1476. +       return;
  1477. +   }
  1478. +}
  1479. +
  1480.  void Monster::onAttackedCreatureDisappear(bool)
  1481.  {
  1482.     attackTicks = 0;
  1483. @@ -588,7 +649,7 @@ void Monster::onFollowCreatureComplete(const Creature* creature)
  1484.  }
  1485.  
  1486.  BlockType_t Monster::blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
  1487. -                              bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool /* field = false */)
  1488. +                              bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool /* field = false */, CombatSpellType_t spellType)
  1489.  {
  1490.     BlockType_t blockType = Creature::blockHit(attacker, combatType, damage, checkDefense, checkArmor);
  1491.  
  1492. @@ -600,11 +661,16 @@ BlockType_t Monster::blockHit(Creature* attacker, CombatType_t combatType, int32
  1493.         }
  1494.  
  1495.         if (elementMod != 0) {
  1496. -           damage = static_cast<int32_t>(std::round(damage * ((100 - elementMod) / 100.)));
  1497. -           if (damage <= 0) {
  1498. -               damage = 0;
  1499. -               blockType = BLOCK_ARMOR;
  1500. -           }
  1501. +           damage = static_cast<int32_t>(std::ceil(damage * ((100 - elementMod) / 100.)));
  1502. +       }
  1503. +
  1504. +       if (spellType == COMBATSPELL_ATTACK) {
  1505. +           blockType = BLOCK_DEFENSE;
  1506. +           damage -= status.getDefense();
  1507. +       }
  1508. +       else if (spellType == COMBATSPELL_SPECIALATTACK) {
  1509. +           blockType = BLOCK_SPECIALDEFENSE;
  1510. +           damage -= status.getSpecialDefense();
  1511.         }
  1512.     }
  1513.  
  1514. @@ -758,7 +824,7 @@ void Monster::onThink(uint32_t interval)
  1515.  
  1516.             onThinkTarget(interval);
  1517.             onThinkYell(interval);
  1518. -           onThinkDefense(interval);
  1519. +           onThinkPassive(interval);
  1520.         }
  1521.     }
  1522.  }
  1523. @@ -769,94 +835,89 @@ void Monster::doAttacking(uint32_t interval)
  1524.         return;
  1525.     }
  1526.  
  1527. -   bool updateLook = true;
  1528. -   bool resetTicks = interval != 0;
  1529. -   attackTicks += interval;
  1530. +   if (!isSummon()) {
  1531. +       const Position& myPos = getPosition();
  1532. +       const Position& targetPos = attackedCreature->getPosition();
  1533.  
  1534. -   const Position& myPos = getPosition();
  1535. -   const Position& targetPos = attackedCreature->getPosition();
  1536. +       for (MonsterSpell& spell : attackSpells) {
  1537. +           tryToUseSpell(myPos, targetPos, spell);
  1538. +       }
  1539. +   }
  1540. +}
  1541.  
  1542. -   for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
  1543. -       bool inRange = false;
  1544. +bool Monster::tryToUseSpell(const Position& myPos, const Position& targetPos, MonsterSpell& spell) {
  1545.  
  1546. -       if (canUseSpell(myPos, targetPos, spellBlock, interval, inRange, resetTicks)) {
  1547. -           if (spellBlock.chance >= static_cast<uint32_t>(uniform_random(1, 100))) {
  1548. -               if (updateLook) {
  1549. -                   updateLookDirection();
  1550. -                   updateLook = false;
  1551. -               }
  1552. +   const spellBlock_t& spellBlock = *spell.spellBlock;
  1553. +
  1554. +   bool inRange = true;
  1555. +   if (!canUseSpell(myPos, targetPos, spell, inRange))
  1556. +       return false;
  1557.  
  1558. -               minCombatValue = spellBlock.minCombatValue;
  1559. -               maxCombatValue = spellBlock.maxCombatValue;
  1560. -               spellBlock.spell->castSpell(this, attackedCreature);
  1561. +   if (!inRange)
  1562. +       return false;
  1563.  
  1564. -               if (spellBlock.isMelee) {
  1565. -                   extraMeleeAttack = false;
  1566. -               }
  1567. -           }
  1568. -       }
  1569. +   if (spellBlock.chance < static_cast<uint32_t>(uniform_random(1, 100)))
  1570. +       return false;
  1571.  
  1572. -       if (!inRange && spellBlock.isMelee) {
  1573. -           //melee swing out of reach
  1574. -           extraMeleeAttack = true;
  1575. -       }
  1576. -   }
  1577. +   updateLookDirection();
  1578.  
  1579. -   if (updateLook) {
  1580. -       updateLookDirection();
  1581. -   }
  1582. +   if (spellBlock.spell) {
  1583. +       spellBlock.spell->castSpell(this, attackedCreature);
  1584. +
  1585. +       const std::string& spellName = spellBlock.spell->getName();
  1586. +       if (spellName.size() > 0)
  1587. +           g_game.internalCreatureSay(this, TALKTYPE_MONSTER_YELL, spellName, false);
  1588.  
  1589. -   if (resetTicks) {
  1590. -       attackTicks = 0;
  1591. +       spell.lastCooldown = OTSYS_TIME();
  1592.     }
  1593. +
  1594. +   return true;
  1595.  }
  1596.  
  1597.  bool Monster::canUseAttack(const Position& pos, const Creature* target) const
  1598.  {
  1599. -   if (isHostile()) {
  1600. -       const Position& targetPos = target->getPosition();
  1601. -       uint32_t distance = std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos));
  1602. -       for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
  1603. -           if (spellBlock.range != 0 && distance <= spellBlock.range) {
  1604. -               return g_game.isSightClear(pos, targetPos, true);
  1605. -           }
  1606. +   if (!isHostile())
  1607. +       return true;
  1608. +
  1609. +   const Position& targetPos = target->getPosition();
  1610. +   uint32_t distance = std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos));
  1611. +
  1612. +   for (const MonsterSpell& spell : attackSpells) {
  1613. +
  1614. +       const spellBlock_t& spellBlock = *spell.spellBlock;
  1615. +       if (level < spellBlock.level) {
  1616. +           continue;
  1617. +       }
  1618. +       else if ((OTSYS_TIME() - spell.lastCooldown) < spellBlock.cooldown) {
  1619. +           continue;
  1620. +       }
  1621. +
  1622. +       if (spellBlock.range != 0 && distance <= spellBlock.range) {
  1623. +           return g_game.isSightClear(pos, targetPos, true);
  1624.         }
  1625. -       return false;
  1626.     }
  1627. -   return true;
  1628. +
  1629. +   return false;
  1630.  }
  1631.  
  1632. -bool Monster::canUseSpell(const Position& pos, const Position& targetPos,
  1633. -                          const spellBlock_t& sb, uint32_t interval, bool& inRange, bool& resetTicks)
  1634. +bool Monster::canUseSpell(const Position& pos, const Position& targetPos, const MonsterSpell& spell, bool& inRange)
  1635.  {
  1636. -   inRange = true;
  1637. +   const spellBlock_t& sb = *spell.spellBlock;
  1638.  
  1639.     if (sb.isMelee && isFleeing()) {
  1640.         return false;
  1641.     }
  1642. -
  1643. -   if (extraMeleeAttack) {
  1644. -       lastMeleeAttack = OTSYS_TIME();
  1645. -   } else if (sb.isMelee && (OTSYS_TIME() - lastMeleeAttack) < 1500) {
  1646. +   else if (level < sb.level) {
  1647.         return false;
  1648.     }
  1649. -
  1650. -   if (!sb.isMelee || !extraMeleeAttack) {
  1651. -       if (sb.speed > attackTicks) {
  1652. -           resetTicks = false;
  1653. -           return false;
  1654. -       }
  1655. -
  1656. -       if (attackTicks % sb.speed >= interval) {
  1657. -           //already used this spell for this round
  1658. -           return false;
  1659. -       }
  1660. +   else if ((OTSYS_TIME() - spell.lastCooldown) < sb.cooldown) {
  1661. +       return false;
  1662.     }
  1663. -
  1664. -   if (sb.range != 0 && std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos)) > sb.range) {
  1665. +   else if (sb.range != 0 && std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos)) > sb.range) {
  1666.         inRange = false;
  1667.         return false;
  1668.     }
  1669. +
  1670.     return true;
  1671.  }
  1672.  
  1673. @@ -897,78 +958,16 @@ void Monster::onThinkTarget(uint32_t interval)
  1674.     }
  1675.  }
  1676.  
  1677. -void Monster::onThinkDefense(uint32_t interval)
  1678. +void Monster::onThinkPassive(uint32_t interval)
  1679.  {
  1680. -   bool resetTicks = true;
  1681. -   defenseTicks += interval;
  1682. -
  1683. -   for (const spellBlock_t& spellBlock : mType->info.defenseSpells) {
  1684. -       if (spellBlock.speed > defenseTicks) {
  1685. -           resetTicks = false;
  1686. -           continue;
  1687. -       }
  1688. -
  1689. -       if (defenseTicks % spellBlock.speed >= interval) {
  1690. -           //already used this spell for this round
  1691. -           continue;
  1692. -       }
  1693. -
  1694. -       if ((spellBlock.chance >= static_cast<uint32_t>(uniform_random(1, 100)))) {
  1695. -           minCombatValue = spellBlock.minCombatValue;
  1696. -           maxCombatValue = spellBlock.maxCombatValue;
  1697. -           spellBlock.spell->castSpell(this, this);
  1698. -       }
  1699. -   }
  1700. -
  1701. -   if (!isSummon() && summons.size() < mType->info.maxSummons && hasFollowPath) {
  1702. -       for (const summonBlock_t& summonBlock : mType->info.summons) {
  1703. -           if (summonBlock.speed > defenseTicks) {
  1704. -               resetTicks = false;
  1705. -               continue;
  1706. -           }
  1707. -
  1708. -           if (summons.size() >= mType->info.maxSummons) {
  1709. -               continue;
  1710. -           }
  1711. -
  1712. -           if (defenseTicks % summonBlock.speed >= interval) {
  1713. -               //already used this spell for this round
  1714. -               continue;
  1715. -           }
  1716. -
  1717. -           uint32_t summonCount = 0;
  1718. -           for (Creature* summon : summons) {
  1719. -               if (summon->getName() == summonBlock.name) {
  1720. -                   ++summonCount;
  1721. -               }
  1722. -           }
  1723. -
  1724. -           if (summonCount >= summonBlock.max) {
  1725. -               continue;
  1726. -           }
  1727. -
  1728. -           if (summonBlock.chance < static_cast<uint32_t>(uniform_random(1, 100))) {
  1729. -               continue;
  1730. -           }
  1731. -
  1732. -           Monster* summon = Monster::createMonster(summonBlock.name);
  1733. -           if (summon) {
  1734. -               const Position& summonPos = getPosition();
  1735. -
  1736. -               addSummon(summon);
  1737. +   if ((attackedCreature && attackedCreature == this) || !attackedCreature)
  1738. +       return;
  1739.  
  1740. -               if (!g_game.placeCreature(summon, summonPos, false, summonBlock.force)) {
  1741. -                   removeSummon(summon);
  1742. -               } else {
  1743. -                   g_game.addMagicEffect(getPosition(), CONST_ME_MAGIC_BLUE);
  1744. -                   g_game.addMagicEffect(summon->getPosition(), CONST_ME_TELEPORT);
  1745. -               }
  1746. -           }
  1747. -       }
  1748. -   }
  1749. +   const Position& myPos = getPosition();
  1750. +   const Position& targetPos = attackedCreature->getPosition();
  1751.  
  1752. -   if (resetTicks) {
  1753. -       defenseTicks = 0;
  1754. +   for (MonsterSpell& spell : passiveSpells) {
  1755. +       tryToUseSpell(myPos, targetPos, spell);
  1756.     }
  1757.  }
  1758.  
  1759. diff --git a/forgottenserver-1.2/src/monster.h b/forgottenserver-1.2/src/monster.h
  1760. index e22971b..feef705 100644
  1761. --- a/forgottenserver-1.2/src/monster.h
  1762. +++ b/forgottenserver-1.2/src/monster.h
  1763. @@ -37,6 +37,17 @@ enum TargetSearchType_t {
  1764.     TARGETSEARCH_NEAREST,
  1765.  };
  1766.  
  1767. +struct MonsterSpell {
  1768. +   MonsterSpell() {};
  1769. +   MonsterSpell(const spellBlock_t& spell) {
  1770. +       spellBlock = &spell;
  1771. +   }
  1772. +
  1773. +   const spellBlock_t* spellBlock = nullptr;
  1774. +   int64_t lastCooldown = 0;
  1775. +};
  1776. +
  1777. +
  1778.  class Monster final : public Creature
  1779.  {
  1780.     public:
  1781. @@ -124,6 +135,8 @@ class Monster final : public Creature
  1782.             this->spawn = spawn;
  1783.         }
  1784.  
  1785. +       void castSpell(std::string word);
  1786. +
  1787.         void onAttackedCreatureDisappear(bool isLogout) final;
  1788.  
  1789.         void onCreatureAppear(Creature* creature, bool isLogin) final;
  1790. @@ -171,7 +184,7 @@ class Monster final : public Creature
  1791.         }
  1792.  
  1793.         BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
  1794. -                            bool checkDefense = false, bool checkArmor = false, bool field = false);
  1795. +                            bool checkDefense = false, bool checkArmor = false, bool field = false, CombatSpellType_t spellType = COMBATSPELL_NONE);
  1796.  
  1797.         uint64_t getExperience();
  1798.         void setExperience(uint64_t exp);
  1799. @@ -217,6 +230,8 @@ class Monster final : public Creature
  1800.         PokemonStatus status;
  1801.  
  1802.         int64_t lastMeleeAttack = 0;
  1803. +       std::vector<MonsterSpell> attackSpells;
  1804. +       std::vector<MonsterSpell> passiveSpells;
  1805.  
  1806.         uint32_t attackTicks = 0;
  1807.         uint32_t targetTicks = 0;
  1808. @@ -262,12 +277,11 @@ class Monster final : public Creature
  1809.         void onEndCondition(ConditionType_t type) final;
  1810.         void onCreatureConvinced(const Creature* convincer, const Creature* creature) final;
  1811.  
  1812. +       bool tryToUseSpell(const Position& myPos, const Position& targetPos, MonsterSpell& spell);
  1813.         bool canUseAttack(const Position& pos, const Creature* target) const;
  1814. -       bool canUseSpell(const Position& pos, const Position& targetPos,
  1815. -                        const spellBlock_t& sb, uint32_t interval, bool& inRange, bool& resetTicks);
  1816. +       bool canUseSpell(const Position& pos, const Position& targetPos, const MonsterSpell& spell, bool& inRange);
  1817.         bool getRandomStep(const Position& creaturePos, Direction& direction) const;
  1818. -       bool getDanceStep(const Position& creaturePos, Direction& direction,
  1819. -                         bool keepAttack = true, bool keepDistance = true);
  1820. +       bool getDanceStep(const Position& creaturePos, Direction& direction, bool keepAttack = true, bool keepDistance = true);
  1821.         bool isInSpawnRange(const Position& pos) const;
  1822.         bool canWalkTo(Position pos, Direction direction) const;
  1823.  
  1824. @@ -278,7 +292,7 @@ class Monster final : public Creature
  1825.  
  1826.         void onThinkTarget(uint32_t interval);
  1827.         void onThinkYell(uint32_t interval);
  1828. -       void onThinkDefense(uint32_t interval);
  1829. +       void onThinkPassive(uint32_t interval);
  1830.  
  1831.         bool isFriend(const Creature* creature) const;
  1832.         bool isOpponent(const Creature* creature) const;
  1833. diff --git a/forgottenserver-1.2/src/monsters.cpp b/forgottenserver-1.2/src/monsters.cpp
  1834. index 960af30..206d9a8 100644
  1835. --- a/forgottenserver-1.2/src/monsters.cpp
  1836. +++ b/forgottenserver-1.2/src/monsters.cpp
  1837. @@ -1,21 +1,21 @@
  1838.  /**
  1839. - * The Forgotten Server - a free and open-source MMORPG server emulator
  1840. - * Copyright (C) 2016  Mark Samman <mark.samman@gmail.com>
  1841. - *
  1842. - * This program is free software; you can redistribute it and/or modify
  1843. - * it under the terms of the GNU General Public License as published by
  1844. - * the Free Software Foundation; either version 2 of the License, or
  1845. - * (at your option) any later version.
  1846. - *
  1847. - * This program is distributed in the hope that it will be useful,
  1848. - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1849. - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1850. - * GNU General Public License for more details.
  1851. - *
  1852. - * You should have received a copy of the GNU General Public License along
  1853. - * with this program; if not, write to the Free Software Foundation, Inc.,
  1854. - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  1855. - */
  1856. +* The Forgotten Server - a free and open-source MMORPG server emulator
  1857. +* Copyright (C) 2016  Mark Samman <mark.samman@gmail.com>
  1858. +*
  1859. +* This program is free software; you can redistribute it and/or modify
  1860. +* it under the terms of the GNU General Public License as published by
  1861. +* the Free Software Foundation; either version 2 of the License, or
  1862. +* (at your option) any later version.
  1863. +*
  1864. +* This program is distributed in the hope that it will be useful,
  1865. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  1866. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1867. +* GNU General Public License for more details.
  1868. +*
  1869. +* You should have received a copy of the GNU General Public License along
  1870. +* with this program; if not, write to the Free Software Foundation, Inc.,
  1871. +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  1872. +*/
  1873.  
  1874.  #include "otpch.h"
  1875.  
  1876. @@ -214,7 +214,7 @@ bool Monsters::reload()
  1877.  }
  1878.  
  1879.  ConditionDamage* Monsters::getDamageCondition(ConditionType_t conditionType,
  1880. -        int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval)
  1881. +   int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval)
  1882.  {
  1883.     ConditionDamage* condition = static_cast<ConditionDamage*>(Condition::createCondition(CONDITIONID_COMBAT, conditionType, 0, 0));
  1884.     condition->setParam(CONDITION_PARAM_TICKINTERVAL, tickInterval);
  1885. @@ -242,8 +242,20 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
  1886.         return false;
  1887.     }
  1888.  
  1889. -   if ((attr = node.attribute("speed")) || (attr = node.attribute("interval"))) {
  1890. -       sb.speed = std::max<int32_t>(1, pugi::cast<int32_t>(attr.value()));
  1891. +   if (auto spell = g_spells->getSpellByName(name)) {
  1892. +       sb.spell = spell;
  1893. +   }
  1894. +
  1895. +   if ((attr = node.attribute("cooldown"))) {
  1896. +       sb.cooldown = std::max<int32_t>(1, pugi::cast<int32_t>(attr.value()));
  1897. +   }
  1898. +
  1899. +   if ((attr = node.attribute("word"))) {
  1900. +       sb.word = attr.as_string();
  1901. +   }
  1902. +
  1903. +   if ((attr = node.attribute("level"))) {
  1904. +       sb.level = pugi::cast<uint32_t>(attr.value());
  1905.     }
  1906.  
  1907.     if ((attr = node.attribute("chance"))) {
  1908. @@ -277,12 +289,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
  1909.         }
  1910.     }
  1911.  
  1912. -   if (auto spell = g_spells->getSpellByName(name)) {
  1913. -       sb.spell = spell;
  1914. -       return true;
  1915. -   }
  1916. -
  1917. -   CombatSpell* combatSpell = nullptr;
  1918. +   /*CombatSpell* combatSpell = nullptr;
  1919.     bool needTarget = false;
  1920.     bool needDirection = false;
  1921.  
  1922. @@ -307,6 +314,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
  1923.         combatSpell = combatSpellPtr.release();
  1924.         combatSpell->getCombat()->setPlayerCombatValues(COMBAT_FORMULA_DAMAGE, sb.minCombatValue, 0, sb.maxCombatValue, 0);
  1925.     } else {
  1926. +
  1927.         Combat* combat = new Combat;
  1928.         if ((attr = node.attribute("length"))) {
  1929.             int32_t length = pugi::cast<int32_t>(attr.value());
  1930. @@ -350,103 +358,12 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
  1931.                 sb.maxCombatValue = -Weapons::getMaxMeleeDamage(pugi::cast<int32_t>(skillAttribute.value()), pugi::cast<int32_t>(attackAttribute.value()));
  1932.             }
  1933.  
  1934. -           ConditionType_t conditionType = CONDITION_NONE;
  1935. -           int32_t minDamage = 0;
  1936. -           int32_t maxDamage = 0;
  1937. -           uint32_t tickInterval = 2000;
  1938. -
  1939. -           if ((attr = node.attribute("fire"))) {
  1940. -               conditionType = CONDITION_FIRE;
  1941. -
  1942. -               minDamage = pugi::cast<int32_t>(attr.value());
  1943. -               maxDamage = minDamage;
  1944. -               tickInterval = 9000;
  1945. -           } else if ((attr = node.attribute("poison"))) {
  1946. -               conditionType = CONDITION_POISON;
  1947. -
  1948. -               minDamage = pugi::cast<int32_t>(attr.value());
  1949. -               maxDamage = minDamage;
  1950. -               tickInterval = 5000;
  1951. -           } else if ((attr = node.attribute("energy"))) {
  1952. -               conditionType = CONDITION_ENERGY;
  1953. -
  1954. -               minDamage = pugi::cast<int32_t>(attr.value());
  1955. -               maxDamage = minDamage;
  1956. -               tickInterval = 10000;
  1957. -           } else if ((attr = node.attribute("drown"))) {
  1958. -               conditionType = CONDITION_DROWN;
  1959. -
  1960. -               minDamage = pugi::cast<int32_t>(attr.value());
  1961. -               maxDamage = minDamage;
  1962. -               tickInterval = 5000;
  1963. -           } else if ((attr = node.attribute("freeze"))) {
  1964. -               conditionType = CONDITION_FREEZING;
  1965. -
  1966. -               minDamage = pugi::cast<int32_t>(attr.value());
  1967. -               maxDamage = minDamage;
  1968. -               tickInterval = 8000;
  1969. -           } else if ((attr = node.attribute("dazzle"))) {
  1970. -               conditionType = CONDITION_DAZZLED;
  1971. -
  1972. -               minDamage = pugi::cast<int32_t>(attr.value());
  1973. -               maxDamage = minDamage;
  1974. -               tickInterval = 10000;
  1975. -           } else if ((attr = node.attribute("curse"))) {
  1976. -               conditionType = CONDITION_CURSED;
  1977. -
  1978. -               minDamage = pugi::cast<int32_t>(attr.value());
  1979. -               maxDamage = minDamage;
  1980. -               tickInterval = 4000;
  1981. -           } else if ((attr = node.attribute("bleed")) || (attr = node.attribute("physical"))) {
  1982. -               conditionType = CONDITION_BLEEDING;
  1983. -               tickInterval = 5000;
  1984. -           }
  1985. -
  1986. -           if ((attr = node.attribute("tick"))) {
  1987. -               int32_t value = pugi::cast<int32_t>(attr.value());
  1988. -               if (value > 0) {
  1989. -                   tickInterval = value;
  1990. -               }
  1991. -           }
  1992. -
  1993. -           if (conditionType != CONDITION_NONE) {
  1994. -               Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, 0, tickInterval);
  1995. -               combat->setCondition(condition);
  1996. -           }
  1997. -
  1998.             sb.range = 1;
  1999. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE);
  2000. -           combat->setParam(COMBAT_PARAM_BLOCKARMOR, 1);
  2001. -           combat->setParam(COMBAT_PARAM_BLOCKSHIELD, 1);
  2002. +           //Todo: Editar o COmbat Type
  2003. +           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_NONE);
  2004.             combat->setOrigin(ORIGIN_MELEE);
  2005. -       } else if (tmpName == "physical") {
  2006. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE);
  2007. -           combat->setParam(COMBAT_PARAM_BLOCKARMOR, 1);
  2008. -           combat->setOrigin(ORIGIN_RANGED);
  2009. -       } else if (tmpName == "bleed") {
  2010. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE);
  2011. -       } else if (tmpName == "poison" || tmpName == "earth") {
  2012. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE);
  2013. -       } else if (tmpName == "fire") {
  2014. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE);
  2015. -       } else if (tmpName == "energy") {
  2016. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE);
  2017. -       } else if (tmpName == "drown") {
  2018. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE);
  2019. -       } else if (tmpName == "ice") {
  2020. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE);
  2021. -       } else if (tmpName == "holy") {
  2022. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE);
  2023. -       } else if (tmpName == "death") {
  2024. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE);
  2025. -       } else if (tmpName == "lifedrain") {
  2026. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN);
  2027. -       } else if (tmpName == "manadrain") {
  2028. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_MANADRAIN);
  2029. -       } else if (tmpName == "healing") {
  2030. -           combat->setParam(COMBAT_PARAM_TYPE, COMBAT_HEALING);
  2031. -           combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0);
  2032. -       } else if (tmpName == "speed") {
  2033. +       }
  2034. +       else if (tmpName == "speed") {
  2035.             int32_t speedChange = 0;
  2036.             int32_t duration = 10000;
  2037.  
  2038. @@ -473,115 +390,6 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
  2039.             ConditionSpeed* condition = static_cast<ConditionSpeed*>(Condition::createCondition(CONDITIONID_COMBAT, conditionType, duration, 0));
  2040.             condition->setFormulaVars(speedChange / 1000.0, 0, speedChange / 1000.0, 0);
  2041.             combat->setCondition(condition);
  2042. -       } else if (tmpName == "outfit") {
  2043. -           int32_t duration = 10000;
  2044. -
  2045. -           if ((attr = node.attribute("duration"))) {
  2046. -               duration = pugi::cast<int32_t>(attr.value());
  2047. -           }
  2048. -
  2049. -           if ((attr = node.attribute("monster"))) {
  2050. -               MonsterType* mType = g_monsters.getMonsterType(attr.as_string());
  2051. -               if (mType) {
  2052. -                   ConditionOutfit* condition = static_cast<ConditionOutfit*>(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0));
  2053. -                   condition->setOutfit(mType->info.outfit);
  2054. -                   combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0);
  2055. -                   combat->setCondition(condition);
  2056. -               }
  2057. -           } else if ((attr = node.attribute("item"))) {
  2058. -               Outfit_t outfit;
  2059. -               outfit.lookTypeEx = pugi::cast<uint16_t>(attr.value());
  2060. -
  2061. -               ConditionOutfit* condition = static_cast<ConditionOutfit*>(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0));
  2062. -               condition->setOutfit(outfit);
  2063. -               combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0);
  2064. -               combat->setCondition(condition);
  2065. -           }
  2066. -       } else if (tmpName == "invisible") {
  2067. -           int32_t duration = 10000;
  2068. -
  2069. -           if ((attr = node.attribute("duration"))) {
  2070. -               duration = pugi::cast<int32_t>(attr.value());
  2071. -           }
  2072. -
  2073. -           Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0);
  2074. -           combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0);
  2075. -           combat->setCondition(condition);
  2076. -       } else if (tmpName == "drunk") {
  2077. -           int32_t duration = 10000;
  2078. -
  2079. -           if ((attr = node.attribute("duration"))) {
  2080. -               duration = pugi::cast<int32_t>(attr.value());
  2081. -           }
  2082. -
  2083. -           Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, 0);
  2084. -           combat->setCondition(condition);
  2085. -       } else if (tmpName == "firefield") {
  2086. -           combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL);
  2087. -       } else if (tmpName == "poisonfield") {
  2088. -           combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_POISONFIELD_PVP);
  2089. -       } else if (tmpName == "energyfield") {
  2090. -           combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_ENERGYFIELD_PVP);
  2091. -       } else if (tmpName == "firecondition" || tmpName == "energycondition" ||
  2092. -                  tmpName == "earthcondition" || tmpName == "poisoncondition" ||
  2093. -                  tmpName == "icecondition" || tmpName == "freezecondition" ||
  2094. -                  tmpName == "deathcondition" || tmpName == "cursecondition" ||
  2095. -                  tmpName == "holycondition" || tmpName == "dazzlecondition" ||
  2096. -                  tmpName == "drowncondition" || tmpName == "bleedcondition" ||
  2097. -                  tmpName == "physicalcondition") {
  2098. -           ConditionType_t conditionType = CONDITION_NONE;
  2099. -           uint32_t tickInterval = 2000;
  2100. -
  2101. -           if (tmpName == "firecondition") {
  2102. -               conditionType = CONDITION_FIRE;
  2103. -               tickInterval = 10000;
  2104. -           } else if (tmpName == "poisoncondition" || tmpName == "earthcondition") {
  2105. -               conditionType = CONDITION_POISON;
  2106. -               tickInterval = 5000;
  2107. -           } else if (tmpName == "energycondition") {
  2108. -               conditionType = CONDITION_ENERGY;
  2109. -               tickInterval = 10000;
  2110. -           } else if (tmpName == "drowncondition") {
  2111. -               conditionType = CONDITION_DROWN;
  2112. -               tickInterval = 5000;
  2113. -           } else if (tmpName == "freezecondition" || tmpName == "icecondition") {
  2114. -               conditionType = CONDITION_FREEZING;
  2115. -               tickInterval = 10000;
  2116. -           } else if (tmpName == "cursecondition" || tmpName == "deathcondition") {
  2117. -               conditionType = CONDITION_CURSED;
  2118. -               tickInterval = 4000;
  2119. -           } else if (tmpName == "dazzlecondition" || tmpName == "holycondition") {
  2120. -               conditionType = CONDITION_DAZZLED;
  2121. -               tickInterval = 10000;
  2122. -           } else if (tmpName == "physicalcondition" || tmpName == "bleedcondition") {
  2123. -               conditionType = CONDITION_BLEEDING;
  2124. -               tickInterval = 5000;
  2125. -           }
  2126. -
  2127. -           if ((attr = node.attribute("tick"))) {
  2128. -               int32_t value = pugi::cast<int32_t>(attr.value());
  2129. -               if (value > 0) {
  2130. -                   tickInterval = value;
  2131. -               }
  2132. -           }
  2133. -
  2134. -           int32_t minDamage = std::abs(sb.minCombatValue);
  2135. -           int32_t maxDamage = std::abs(sb.maxCombatValue);
  2136. -           int32_t startDamage = 0;
  2137. -
  2138. -           if ((attr = node.attribute("start"))) {
  2139. -               int32_t value = std::abs(pugi::cast<int32_t>(attr.value()));
  2140. -               if (value <= minDamage) {
  2141. -                   startDamage = value;
  2142. -               }
  2143. -           }
  2144. -
  2145. -           Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval);
  2146. -           combat->setCondition(condition);
  2147. -       } else if (tmpName == "strength") {
  2148. -           //
  2149. -       } else if (tmpName == "effect") {
  2150. -           //
  2151.         } else {
  2152.             std::cout << "[Error - Monsters::deserializeSpell] - " << description << " - Unknown spell name: " << name << std::endl;
  2153.             delete combat;
  2154. @@ -608,7 +416,8 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
  2155.                         MagicEffectClasses effect = getMagicEffect(attr.as_string());
  2156.                         if (effect != CONST_ME_NONE) {
  2157.                             combat->setParam(COMBAT_PARAM_EFFECT, effect);
  2158. -                       } else {
  2159. +                       }
  2160. +                       else {
  2161.                             std::cout << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown areaEffect: " << attr.as_string() << std::endl;
  2162.                         }
  2163.                     }
  2164. @@ -622,7 +431,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
  2165.     sb.spell = combatSpell;
  2166.     if (combatSpell) {
  2167.         sb.combatSpell = true;
  2168. -   }
  2169. +   }*/
  2170.     return true;
  2171.  }
  2172.  
  2173. @@ -824,7 +633,7 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
  2174.             mType->info.lookcorpse = pugi::cast<uint16_t>(attr.value());
  2175.         }
  2176.     }
  2177. -  
  2178. +
  2179.     if ((node = monsterNode.child("level"))) {
  2180.         if ((attr = node.attribute("min"))) {
  2181.             mType->info.spawnLevel.min = pugi::cast<uint32_t>(attr.value());
  2182. @@ -928,21 +737,13 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
  2183.         }
  2184.     }
  2185.  
  2186. -   if ((node = monsterNode.child("defenses"))) {
  2187. -       if ((attr = node.attribute("defense"))) {
  2188. -           mType->info.defense = pugi::cast<int32_t>(attr.value());
  2189. -       }
  2190. -
  2191. -       if ((attr = node.attribute("armor"))) {
  2192. -           mType->info.armor = pugi::cast<int32_t>(attr.value());
  2193. -       }
  2194. -
  2195. -       for (auto defenseNode : node.children()) {
  2196. +   if ((node = monsterNode.child("passives"))) {
  2197. +       for (auto passiveNode : node.children()) {
  2198.             spellBlock_t sb;
  2199. -           if (deserializeSpell(defenseNode, sb, monsterName)) {
  2200. -               mType->info.defenseSpells.emplace_back(std::move(sb));
  2201. +           if (deserializeSpell(passiveNode, sb, monsterName)) {
  2202. +               mType->info.passiveSpells.emplace_back(std::move(sb));
  2203.             } else {
  2204. -               std::cout << "[Warning - Monsters::loadMonster] Cant load spell. " << file << std::endl;
  2205. +               std::cout << "[Warning - Monsters::loadMonster] Cant load passive spell. " << file << std::endl;
  2206.             }
  2207.         }
  2208.     }
  2209. @@ -951,116 +752,48 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
  2210.         for (auto immunityNode : node.children()) {
  2211.             if ((attr = immunityNode.attribute("name"))) {
  2212.                 std::string tmpStrValue = asLowerCaseString(attr.as_string());
  2213. -               if (tmpStrValue == "physical") {
  2214. -                   mType->info.damageImmunities |= COMBAT_PHYSICALDAMAGE;
  2215. -                   mType->info.conditionImmunities |= CONDITION_BLEEDING;
  2216. +               /*if (tmpStrValue == "physical") {
  2217. +               mType->info.damageImmunities |= COMBAT_PHYSICALDAMAGE;
  2218. +               mType->info.conditionImmunities |= CONDITION_BLEEDING;
  2219.                 } else if (tmpStrValue == "energy") {
  2220. -                   mType->info.damageImmunities |= COMBAT_ENERGYDAMAGE;
  2221. -                   mType->info.conditionImmunities |= CONDITION_ENERGY;
  2222. +               mType->info.damageImmunities |= COMBAT_ENERGYDAMAGE;
  2223. +               mType->info.conditionImmunities |= CONDITION_ENERGY;
  2224.                 } else if (tmpStrValue == "fire") {
  2225. -                   mType->info.damageImmunities |= COMBAT_FIREDAMAGE;
  2226. -                   mType->info.conditionImmunities |= CONDITION_FIRE;
  2227. +               mType->info.damageImmunities |= COMBAT_FIREDAMAGE;
  2228. +               mType->info.conditionImmunities |= CONDITION_FIRE;
  2229.                 } else if (tmpStrValue == "poison" ||
  2230. -                           tmpStrValue == "earth") {
  2231. -                   mType->info.damageImmunities |= COMBAT_EARTHDAMAGE;
  2232. -                   mType->info.conditionImmunities |= CONDITION_POISON;
  2233. +               tmpStrValue == "earth") {
  2234. +               mType->info.damageImmunities |= COMBAT_EARTHDAMAGE;
  2235. +               mType->info.conditionImmunities |= CONDITION_POISON;
  2236.                 } else if (tmpStrValue == "drown") {
  2237. -                   mType->info.damageImmunities |= COMBAT_DROWNDAMAGE;
  2238. -                   mType->info.conditionImmunities |= CONDITION_DROWN;
  2239. +               mType->info.damageImmunities |= COMBAT_DROWNDAMAGE;
  2240. +               mType->info.conditionImmunities |= CONDITION_DROWN;
  2241.                 } else if (tmpStrValue == "ice") {
  2242. -                   mType->info.damageImmunities |= COMBAT_ICEDAMAGE;
  2243. -                   mType->info.conditionImmunities |= CONDITION_FREEZING;
  2244. +               mType->info.damageImmunities |= COMBAT_ICEDAMAGE;
  2245. +               mType->info.conditionImmunities |= CONDITION_FREEZING;
  2246.                 } else if (tmpStrValue == "holy") {
  2247. -                   mType->info.damageImmunities |= COMBAT_HOLYDAMAGE;
  2248. -                   mType->info.conditionImmunities |= CONDITION_DAZZLED;
  2249. +               mType->info.damageImmunities |= COMBAT_HOLYDAMAGE;
  2250. +               mType->info.conditionImmunities |= CONDITION_DAZZLED;
  2251.                 } else if (tmpStrValue == "death") {
  2252. -                   mType->info.damageImmunities |= COMBAT_DEATHDAMAGE;
  2253. -                   mType->info.conditionImmunities |= CONDITION_CURSED;
  2254. +               mType->info.damageImmunities |= COMBAT_DEATHDAMAGE;
  2255. +               mType->info.conditionImmunities |= CONDITION_CURSED;
  2256.                 } else if (tmpStrValue == "lifedrain") {
  2257. -                   mType->info.damageImmunities |= COMBAT_LIFEDRAIN;
  2258. +               mType->info.damageImmunities |= COMBAT_LIFEDRAIN;
  2259.                 } else if (tmpStrValue == "manadrain") {
  2260. -                   mType->info.damageImmunities |= COMBAT_MANADRAIN;
  2261. +               mType->info.damageImmunities |= COMBAT_MANADRAIN;
  2262.                 } else if (tmpStrValue == "paralyze") {
  2263. -                   mType->info.conditionImmunities |= CONDITION_PARALYZE;
  2264. +               mType->info.conditionImmunities |= CONDITION_PARALYZE;
  2265.                 } else if (tmpStrValue == "outfit") {
  2266. -                   mType->info.conditionImmunities |= CONDITION_OUTFIT;
  2267. +               mType->info.conditionImmunities |= CONDITION_OUTFIT;
  2268.                 } else if (tmpStrValue == "drunk") {
  2269. -                   mType->info.conditionImmunities |= CONDITION_DRUNK;
  2270. +               mType->info.conditionImmunities |= CONDITION_DRUNK;
  2271.                 } else if (tmpStrValue == "invisible" || tmpStrValue == "invisibility") {
  2272. -                   mType->info.conditionImmunities |= CONDITION_INVISIBLE;
  2273. +               mType->info.conditionImmunities |= CONDITION_INVISIBLE;
  2274.                 } else if (tmpStrValue == "bleed") {
  2275. -                   mType->info.conditionImmunities |= CONDITION_BLEEDING;
  2276. +               mType->info.conditionImmunities |= CONDITION_BLEEDING;
  2277.                 } else {
  2278. -                   std::cout << "[Warning - Monsters::loadMonster] Unknown immunity name " << attr.as_string() << ". " << file << std::endl;
  2279. -               }
  2280. -           } else if ((attr = immunityNode.attribute("physical"))) {
  2281. -               if (attr.as_bool()) {
  2282. -                   mType->info.damageImmunities |= COMBAT_PHYSICALDAMAGE;
  2283. -                   mType->info.conditionImmunities |= CONDITION_BLEEDING;
  2284. -               }
  2285. -           } else if ((attr = immunityNode.attribute("energy"))) {
  2286. -               if (attr.as_bool()) {
  2287. -                   mType->info.damageImmunities |= COMBAT_ENERGYDAMAGE;
  2288. -                   mType->info.conditionImmunities |= CONDITION_ENERGY;
  2289. -               }
  2290. -           } else if ((attr = immunityNode.attribute("fire"))) {
  2291. -               if (attr.as_bool()) {
  2292. -                   mType->info.damageImmunities |= COMBAT_FIREDAMAGE;
  2293. -                   mType->info.conditionImmunities |= CONDITION_FIRE;
  2294. -               }
  2295. -           } else if ((attr = immunityNode.attribute("poison")) || (attr = immunityNode.attribute("earth"))) {
  2296. -               if (attr.as_bool()) {
  2297. -                   mType->info.damageImmunities |= COMBAT_EARTHDAMAGE;
  2298. -                   mType->info.conditionImmunities |= CONDITION_POISON;
  2299. -               }
  2300. -           } else if ((attr = immunityNode.attribute("drown"))) {
  2301. -               if (attr.as_bool()) {
  2302. -                   mType->info.damageImmunities |= COMBAT_DROWNDAMAGE;
  2303. -                   mType->info.conditionImmunities |= CONDITION_DROWN;
  2304. -               }
  2305. -           } else if ((attr = immunityNode.attribute("ice"))) {
  2306. -               if (attr.as_bool()) {
  2307. -                   mType->info.damageImmunities |= COMBAT_ICEDAMAGE;
  2308. -                   mType->info.conditionImmunities |= CONDITION_FREEZING;
  2309. -               }
  2310. -           } else if ((attr = immunityNode.attribute("holy"))) {
  2311. -               if (attr.as_bool()) {
  2312. -                   mType->info.damageImmunities |= COMBAT_HOLYDAMAGE;
  2313. -                   mType->info.conditionImmunities |= CONDITION_DAZZLED;
  2314. -               }
  2315. -           } else if ((attr = immunityNode.attribute("death"))) {
  2316. -               if (attr.as_bool()) {
  2317. -                   mType->info.damageImmunities |= COMBAT_DEATHDAMAGE;
  2318. -                   mType->info.conditionImmunities |= CONDITION_CURSED;
  2319. -               }
  2320. -           } else if ((attr = immunityNode.attribute("lifedrain"))) {
  2321. -               if (attr.as_bool()) {
  2322. -                   mType->info.damageImmunities |= COMBAT_LIFEDRAIN;
  2323. -               }
  2324. -           } else if ((attr = immunityNode.attribute("manadrain"))) {
  2325. -               if (attr.as_bool()) {
  2326. -                   mType->info.damageImmunities |= COMBAT_MANADRAIN;
  2327. -               }
  2328. -           } else if ((attr = immunityNode.attribute("paralyze"))) {
  2329. -               if (attr.as_bool()) {
  2330. -                   mType->info.conditionImmunities |= CONDITION_PARALYZE;
  2331. -               }
  2332. -           } else if ((attr = immunityNode.attribute("outfit"))) {
  2333. -               if (attr.as_bool()) {
  2334. -                   mType->info.conditionImmunities |= CONDITION_OUTFIT;
  2335. -               }
  2336. -           } else if ((attr = immunityNode.attribute("bleed"))) {
  2337. -               if (attr.as_bool()) {
  2338. -                   mType->info.conditionImmunities |= CONDITION_BLEEDING;
  2339. -               }
  2340. -           } else if ((attr = immunityNode.attribute("drunk"))) {
  2341. -               if (attr.as_bool()) {
  2342. -                   mType->info.conditionImmunities |= CONDITION_DRUNK;
  2343. -               }
  2344. -           } else if ((attr = immunityNode.attribute("invisible")) || (attr = immunityNode.attribute("invisibility"))) {
  2345. -               if (attr.as_bool()) {
  2346. -                   mType->info.conditionImmunities |= CONDITION_INVISIBLE;
  2347. -               }
  2348. +               std::cout << "[Warning - Monsters::loadMonster] Unknown immunity name " << attr.as_string() << ". " << file << std::endl;
  2349. +               }*/
  2350.             } else {
  2351.                 std::cout << "[Warning - Monsters::loadMonster] Unknown immunity. " << file << std::endl;
  2352.             }
  2353. @@ -1110,27 +843,61 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
  2354.  
  2355.     if ((node = monsterNode.child("elements"))) {
  2356.         for (auto elementNode : node.children()) {
  2357. -           if ((attr = elementNode.attribute("physicalPercent"))) {
  2358. -               mType->info.elementMap[COMBAT_PHYSICALDAMAGE] = pugi::cast<int32_t>(attr.value());
  2359. -           } else if ((attr = elementNode.attribute("icePercent"))) {
  2360. -               mType->info.elementMap[COMBAT_ICEDAMAGE] = pugi::cast<int32_t>(attr.value());
  2361. -           } else if ((attr = elementNode.attribute("poisonPercent")) || (attr = elementNode.attribute("earthPercent"))) {
  2362. -               mType->info.elementMap[COMBAT_EARTHDAMAGE] = pugi::cast<int32_t>(attr.value());
  2363. -           } else if ((attr = elementNode.attribute("firePercent"))) {
  2364. +           if ((attr = elementNode.attribute("bugPercent"))) {
  2365. +               mType->info.elementMap[COMBAT_BUGDAMAGE] = pugi::cast<int32_t>(attr.value());
  2366. +           }
  2367. +           else if ((attr = elementNode.attribute("dragonPercent"))) {
  2368. +               mType->info.elementMap[COMBAT_DRAGONDAMAGE] = pugi::cast<int32_t>(attr.value());
  2369. +           }
  2370. +           else if ((attr = elementNode.attribute("fairyPercent"))) {
  2371. +               mType->info.elementMap[COMBAT_FAIRYDAMAGE] = pugi::cast<int32_t>(attr.value());
  2372. +           }
  2373. +           else if ((attr = elementNode.attribute("firePercent"))) {
  2374.                 mType->info.elementMap[COMBAT_FIREDAMAGE] = pugi::cast<int32_t>(attr.value());
  2375. -           } else if ((attr = elementNode.attribute("energyPercent"))) {
  2376. -               mType->info.elementMap[COMBAT_ENERGYDAMAGE] = pugi::cast<int32_t>(attr.value());
  2377. -           } else if ((attr = elementNode.attribute("holyPercent"))) {
  2378. -               mType->info.elementMap[COMBAT_HOLYDAMAGE] = pugi::cast<int32_t>(attr.value());
  2379. -           } else if ((attr = elementNode.attribute("deathPercent"))) {
  2380. -               mType->info.elementMap[COMBAT_DEATHDAMAGE] = pugi::cast<int32_t>(attr.value());
  2381. -           } else if ((attr = elementNode.attribute("drownPercent"))) {
  2382. -               mType->info.elementMap[COMBAT_DROWNDAMAGE] = pugi::cast<int32_t>(attr.value());
  2383. -           } else if ((attr = elementNode.attribute("lifedrainPercent"))) {
  2384. -               mType->info.elementMap[COMBAT_LIFEDRAIN] = pugi::cast<int32_t>(attr.value());
  2385. -           } else if ((attr = elementNode.attribute("manadrainPercent"))) {
  2386. -               mType->info.elementMap[COMBAT_MANADRAIN] = pugi::cast<int32_t>(attr.value());
  2387. -           } else {
  2388. +           }
  2389. +           else if ((attr = elementNode.attribute("ghostPercent"))) {
  2390. +               mType->info.elementMap[COMBAT_GHOSTDAMAGE] = pugi::cast<int32_t>(attr.value());
  2391. +           }
  2392. +           else if ((attr = elementNode.attribute("groundPercent"))) {
  2393. +               mType->info.elementMap[COMBAT_GROUNDDAMAGE] = pugi::cast<int32_t>(attr.value());
  2394. +           }
  2395. +           else if ((attr = elementNode.attribute("normalPercent"))) {
  2396. +               mType->info.elementMap[COMBAT_NORMALDAMAGE] = pugi::cast<int32_t>(attr.value());
  2397. +           }
  2398. +           else if ((attr = elementNode.attribute("psychicPercent"))) {
  2399. +               mType->info.elementMap[COMBAT_PSYCHICDAMAGE] = pugi::cast<int32_t>(attr.value());
  2400. +           }
  2401. +           else if ((attr = elementNode.attribute("steelPercent"))) {
  2402. +               mType->info.elementMap[COMBAT_STEELDAMAGE] = pugi::cast<int32_t>(attr.value());
  2403. +           }
  2404. +           else if ((attr = elementNode.attribute("darkPercent"))) {
  2405. +               mType->info.elementMap[COMBAT_DARKDAMAGE] = pugi::cast<int32_t>(attr.value());
  2406. +           }
  2407. +           else if ((attr = elementNode.attribute("electricPercent"))) {
  2408. +               mType->info.elementMap[COMBAT_ELECTRICDAMAGE] = pugi::cast<int32_t>(attr.value());
  2409. +           }
  2410. +           else if ((attr = elementNode.attribute("fightingPercent"))) {
  2411. +               mType->info.elementMap[COMBAT_FIGHTINGDAMAGE] = pugi::cast<int32_t>(attr.value());
  2412. +           }
  2413. +           else if ((attr = elementNode.attribute("flyingPercent"))) {
  2414. +               mType->info.elementMap[COMBAT_FLYINGDAMAGE] = pugi::cast<int32_t>(attr.value());
  2415. +           }
  2416. +           else if ((attr = elementNode.attribute("grassPercent"))) {
  2417. +               mType->info.elementMap[COMBAT_GRASSDAMAGE] = pugi::cast<int32_t>(attr.value());
  2418. +           }
  2419. +           else if ((attr = elementNode.attribute("icePercent"))) {
  2420. +               mType->info.elementMap[COMBAT_ICEDAMAGE] = pugi::cast<int32_t>(attr.value());
  2421. +           }
  2422. +           else if ((attr = elementNode.attribute("poisonPercent"))) {
  2423. +               mType->info.elementMap[COMBAT_POISONDAMAGE] = pugi::cast<int32_t>(attr.value());
  2424. +           }
  2425. +           else if ((attr = elementNode.attribute("rockPercent"))) {
  2426. +               mType->info.elementMap[COMBAT_ROCKDAMAGE] = pugi::cast<int32_t>(attr.value());
  2427. +           }
  2428. +           else if ((attr = elementNode.attribute("waterPercent"))) {
  2429. +               mType->info.elementMap[COMBAT_WATERDAMAGE] = pugi::cast<int32_t>(attr.value());
  2430. +           }
  2431. +           else {
  2432.                 std::cout << "[Warning - Monsters::loadMonster] Unknown element percent. " << file << std::endl;
  2433.             }
  2434.         }
  2435. @@ -1192,7 +959,7 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
  2436.     mType->info.summons.shrink_to_fit();
  2437.     mType->info.lootItems.shrink_to_fit();
  2438.     mType->info.attackSpells.shrink_to_fit();
  2439. -   mType->info.defenseSpells.shrink_to_fit();
  2440. +   mType->info.passiveSpells.shrink_to_fit();
  2441.     mType->info.voiceVector.shrink_to_fit();
  2442.     mType->info.scripts.shrink_to_fit();
  2443.     return true;
  2444. diff --git a/forgottenserver-1.2/src/monsters.h b/forgottenserver-1.2/src/monsters.h
  2445. index 43357cf..3e7731e 100644
  2446. --- a/forgottenserver-1.2/src/monsters.h
  2447. +++ b/forgottenserver-1.2/src/monsters.h
  2448. @@ -62,9 +62,11 @@ struct spellBlock_t {
  2449.     spellBlock_t(const spellBlock_t& other) = delete;
  2450.     spellBlock_t& operator=(const spellBlock_t& other) = delete;
  2451.     spellBlock_t(spellBlock_t&& other) :
  2452. +       word(other.word),
  2453. +       level(other.level),
  2454.         spell(other.spell),
  2455.         chance(other.chance),
  2456. -       speed(other.speed),
  2457. +       cooldown(other.cooldown),
  2458.         range(other.range),
  2459.         minCombatValue(other.minCombatValue),
  2460.         maxCombatValue(other.maxCombatValue),
  2461. @@ -73,9 +75,11 @@ struct spellBlock_t {
  2462.         other.spell = nullptr;
  2463.     }
  2464.  
  2465. +   std::string word = "";
  2466. +   uint32_t level = 1;
  2467.     BaseSpell* spell = nullptr;
  2468.     uint32_t chance = 100;
  2469. -   uint32_t speed = 2000;
  2470. +   uint32_t cooldown = 2000;
  2471.     uint32_t range = 0;
  2472.     int32_t minCombatValue = 0;
  2473.     int32_t maxCombatValue = 0;
  2474. @@ -105,17 +109,17 @@ class MonsterType
  2475.         std::vector<LootBlock> lootItems;
  2476.         std::vector<std::string> scripts;
  2477.         std::vector<spellBlock_t> attackSpells;
  2478. -       std::vector<spellBlock_t> defenseSpells;
  2479. +       std::vector<spellBlock_t> passiveSpells;
  2480.         std::vector<summonBlock_t> summons;
  2481.  
  2482.         Skulls_t skull = SKULL_NONE;
  2483.         Outfit_t outfit = {};
  2484.         RaceType_t race = RACE_BLOOD;
  2485.  
  2486. -       spawnLevel_t spawnLevel;
  2487. +       spawnLevel_t spawnLevel = {};
  2488.  
  2489. -       PokemonStatus baseStatus;
  2490. -       PokemonStatus statusPerLevel;
  2491. +       PokemonStatus baseStatus = {};
  2492. +       PokemonStatus statusPerLevel = {};
  2493.  
  2494.         LightInfo light = {};
  2495.         uint16_t lookcorpse = 0;
  2496. @@ -141,7 +145,7 @@ class MonsterType
  2497.         int32_t runAwayHealth = 0;
  2498.         int32_t health = 100;
  2499.         int32_t healthMax = 100;
  2500. -       int32_t changeTargetChance =0;
  2501. +       int32_t changeTargetChance = 0;
  2502.         int32_t defense = 0;
  2503.         int32_t armor = 0;
  2504.  
  2505. diff --git a/forgottenserver-1.2/src/player.cpp b/forgottenserver-1.2/src/player.cpp
  2506. index 04ae2d5..492b6b0 100644
  2507. --- a/forgottenserver-1.2/src/player.cpp
  2508. +++ b/forgottenserver-1.2/src/player.cpp
  2509. @@ -1780,8 +1780,7 @@ void Player::onAttackedCreatureBlockHit(BlockType_t blockType)
  2510.             break;
  2511.         }
  2512.  
  2513. -       case BLOCK_DEFENSE:
  2514. -       case BLOCK_ARMOR: {
  2515. +       case BLOCK_DEFENSE: {
  2516.             //need to draw blood every 30 hits
  2517.             if (bloodHitCount > 0) {
  2518.                 addAttackSkillPoint = true;
  2519. @@ -1814,7 +1813,7 @@ bool Player::hasShield() const
  2520.  }
  2521.  
  2522.  BlockType_t Player::blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
  2523. -                             bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool field /* = false*/)
  2524. +                             bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool field /* = false*/, CombatSpellType_t spellType)
  2525.  {
  2526.     BlockType_t blockType = Creature::blockHit(attacker, combatType, damage, checkDefense, checkArmor, field);
  2527.  
  2528. @@ -1865,7 +1864,7 @@ BlockType_t Player::blockHit(Creature* attacker, CombatType_t combatType, int32_
  2529.  
  2530.         if (damage <= 0) {
  2531.             damage = 0;
  2532. -           blockType = BLOCK_ARMOR;
  2533. +           blockType = BLOCK_DEFENSE;
  2534.         }
  2535.     }
  2536.     return blockType;
  2537. diff --git a/forgottenserver-1.2/src/player.h b/forgottenserver-1.2/src/player.h
  2538. index a9f346a..395d3cb 100644
  2539. --- a/forgottenserver-1.2/src/player.h
  2540. +++ b/forgottenserver-1.2/src/player.h
  2541. @@ -603,7 +603,7 @@ class Player final : public Creature, public Cylinder
  2542.             return pzLocked;
  2543.         }
  2544.         BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
  2545. -                                    bool checkDefense = false, bool checkArmor = false, bool field = false) final;
  2546. +                                    bool checkDefense = false, bool checkArmor = false, bool field = false, CombatSpellType_t spellType = COMBATSPELL_NONE) final;
  2547.         void doAttacking(uint32_t interval) final;
  2548.         bool hasExtraSwing() final {
  2549.             return lastAttack > 0 && ((OTSYS_TIME() - lastAttack) >= getAttackSpeed());
  2550. diff --git a/forgottenserver-1.2/src/spells.h b/forgottenserver-1.2/src/spells.h
  2551. index 2aea3b3..abb553c 100644
  2552. --- a/forgottenserver-1.2/src/spells.h
  2553. +++ b/forgottenserver-1.2/src/spells.h
  2554. @@ -82,6 +82,12 @@ class BaseSpell
  2555.  
  2556.         virtual bool castSpell(Creature* creature) = 0;
  2557.         virtual bool castSpell(Creature* creature, Creature* target) = 0;
  2558. +
  2559. +       virtual bool getNeedTarget() {
  2560. +           return false;
  2561. +       }
  2562. +
  2563. +       virtual const std::string& getName() const = 0;
  2564.  };
  2565.  
  2566.  class CombatSpell final : public Event, public BaseSpell
  2567. @@ -100,6 +106,14 @@ class CombatSpell final : public Event, public BaseSpell
  2568.             return true;
  2569.         }
  2570.  
  2571. +       bool getNeedTarget() final {
  2572. +           return needTarget;
  2573. +       }
  2574. +
  2575. +       const std::string& getName() const final {
  2576. +           return name;
  2577. +       }
  2578. +
  2579.         //scripting
  2580.         bool executeCastSpell(Creature* creature, const LuaVariant& var);
  2581.  
  2582. @@ -117,6 +131,7 @@ class CombatSpell final : public Event, public BaseSpell
  2583.  
  2584.         bool needDirection;
  2585.         bool needTarget;
  2586. +       std::string name = "";
  2587.  };
  2588.  
  2589.  class Spell : public BaseSpell
  2590. @@ -125,7 +140,7 @@ class Spell : public BaseSpell
  2591.         Spell() = default;
  2592.  
  2593.         bool configureSpell(const pugi::xml_node& node);
  2594. -       const std::string& getName() const {
  2595. +       const std::string& getName() const final {
  2596.             return name;
  2597.         }
  2598.  
  2599. @@ -154,6 +169,10 @@ class Spell : public BaseSpell
  2600.             return learnable;
  2601.         }
  2602.  
  2603. +       bool getNeedTarget() final {
  2604. +           return needTarget;
  2605. +       }
  2606. +
  2607.         static ReturnValue CreateIllusion(Creature* creature, const Outfit_t& outfit, int32_t time);
  2608.         static ReturnValue CreateIllusion(Creature* creature, const std::string& name, int32_t time);
  2609.         static ReturnValue CreateIllusion(Creature* creature, uint32_t itemId, int32_t time);
  2610. diff --git a/forgottenserver-1.2/src/tools.cpp b/forgottenserver-1.2/src/tools.cpp
  2611. index 6c86d46..80f261d 100644
  2612. --- a/forgottenserver-1.2/src/tools.cpp
  2613. +++ b/forgottenserver-1.2/src/tools.cpp
  2614. @@ -665,18 +665,24 @@ ShootTypeNames shootTypeNames[] = {
  2615.  };
  2616.  
  2617.  CombatTypeNames combatTypeNames[] = {
  2618. -   {"physical",        COMBAT_PHYSICALDAMAGE},
  2619. -   {"energy",      COMBAT_ENERGYDAMAGE},
  2620. -   {"earth",       COMBAT_EARTHDAMAGE},
  2621. -   {"fire",        COMBAT_FIREDAMAGE},
  2622. -   {"undefined",       COMBAT_UNDEFINEDDAMAGE},
  2623. -   {"lifedrain",       COMBAT_LIFEDRAIN},
  2624. -   {"manadrain",       COMBAT_MANADRAIN},
  2625. -   {"healing",     COMBAT_HEALING},
  2626. -   {"drown",       COMBAT_DROWNDAMAGE},
  2627. -   {"ice",         COMBAT_ICEDAMAGE},
  2628. -   {"holy",        COMBAT_HOLYDAMAGE},
  2629. -   {"death",       COMBAT_DEATHDAMAGE},
  2630. +   { "bug",        COMBAT_BUGDAMAGE },
  2631. +   { "dragon",     COMBAT_DRAGONDAMAGE },
  2632. +   { "fairy",      COMBAT_FAIRYDAMAGE },
  2633. +   { "fire",       COMBAT_FIREDAMAGE },
  2634. +   { "ghost",      COMBAT_GHOSTDAMAGE },
  2635. +   { "ground",     COMBAT_GROUNDDAMAGE },
  2636. +   { "normal",     COMBAT_NORMALDAMAGE },
  2637. +   { "psychic",    COMBAT_PSYCHICDAMAGE },
  2638. +   { "steel",      COMBAT_STEELDAMAGE },
  2639. +   { "dark",       COMBAT_DARKDAMAGE },
  2640. +   { "electric",   COMBAT_ELECTRICDAMAGE },
  2641. +   { "fighthing",  COMBAT_FIGHTINGDAMAGE },
  2642. +   { "flying",     COMBAT_FLYINGDAMAGE },
  2643. +   { "grass",      COMBAT_GRASSDAMAGE },
  2644. +   { "ice",        COMBAT_ICEDAMAGE },
  2645. +   { "poison",     COMBAT_POISONDAMAGE },
  2646. +   { "rock",       COMBAT_ROCKDAMAGE },
  2647. +   { "water",      COMBAT_WATERDAMAGE },
  2648.  };
  2649.  
  2650.  AmmoTypeNames ammoTypeNames[] = {
  2651. @@ -905,7 +911,8 @@ std::string getWeaponName(WeaponType_t weaponType)
  2652.  
  2653.  size_t combatTypeToIndex(CombatType_t combatType)
  2654.  {
  2655. -   switch (combatType) {
  2656. +   //Todo: Arrumar Types
  2657. +   /*switch (combatType) {
  2658.         case COMBAT_PHYSICALDAMAGE:
  2659.             return 0;
  2660.         case COMBAT_ENERGYDAMAGE:
  2661. @@ -932,7 +939,9 @@ size_t combatTypeToIndex(CombatType_t combatType)
  2662.             return 11;
  2663.         default:
  2664.             return 0;
  2665. -   }
  2666. +   }*/
  2667. +
  2668. +   return 0;
  2669.  }
  2670.  
  2671.  CombatType_t indexToCombatType(size_t v)
  2672. diff --git a/forgottenserver-1.2/src/weapons.cpp b/forgottenserver-1.2/src/weapons.cpp
  2673. index f401112..badff1f 100644
  2674. --- a/forgottenserver-1.2/src/weapons.cpp
  2675. +++ b/forgottenserver-1.2/src/weapons.cpp
  2676. @@ -343,7 +343,7 @@ bool Weapon::useFist(Player* player, Creature* target)
  2677.     int32_t maxDamage = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
  2678.  
  2679.     CombatParams params;
  2680. -   params.combatType = COMBAT_PHYSICALDAMAGE;
  2681. +   params.combatType = COMBAT_NONE;
  2682.     params.blockedByArmor = true;
  2683.     params.blockedByShield = true;
  2684.  
  2685. @@ -496,7 +496,7 @@ WeaponMelee::WeaponMelee(LuaScriptInterface* interface) :
  2686.  {
  2687.     params.blockedByArmor = true;
  2688.     params.blockedByShield = true;
  2689. -   params.combatType = COMBAT_PHYSICALDAMAGE;
  2690. +   params.combatType = COMBAT_NONE;
  2691.  }
  2692.  
  2693.  void WeaponMelee::configureWeapon(const ItemType& it)
  2694. @@ -588,7 +588,7 @@ WeaponDistance::WeaponDistance(LuaScriptInterface* interface) :
  2695.     Weapon(interface)
  2696.  {
  2697.     params.blockedByArmor = true;
  2698. -   params.combatType = COMBAT_PHYSICALDAMAGE;
  2699. +   params.combatType = COMBAT_NONE;
  2700.  }
  2701.  
  2702.  void WeaponDistance::configureWeapon(const ItemType& it)
  2703. @@ -840,8 +840,7 @@ bool WeaponDistance::getSkillType(const Player* player, const Item*, skills_t& s
  2704.                 break;
  2705.             }
  2706.  
  2707. -           case BLOCK_DEFENSE:
  2708. -           case BLOCK_ARMOR: {
  2709. +           case BLOCK_DEFENSE: {
  2710.                 skillpoint = 1;
  2711.                 break;
  2712.             }
  2713. @@ -874,17 +873,7 @@ bool WeaponWand::configureEvent(const pugi::xml_node& node)
  2714.     if ((attr = node.attribute("type"))) {
  2715.         std::string tmpStrValue = asLowerCaseString(attr.as_string());
  2716.         if (tmpStrValue == "earth") {
  2717. -           params.combatType = COMBAT_EARTHDAMAGE;
  2718. -       } else if (tmpStrValue == "ice") {
  2719.             params.combatType = COMBAT_ICEDAMAGE;
  2720. -       } else if (tmpStrValue == "energy") {
  2721. -           params.combatType = COMBAT_ENERGYDAMAGE;
  2722. -       } else if (tmpStrValue == "fire") {
  2723. -           params.combatType = COMBAT_FIREDAMAGE;
  2724. -       } else if (tmpStrValue == "death") {
  2725. -           params.combatType = COMBAT_DEATHDAMAGE;
  2726. -       } else if (tmpStrValue == "holy") {
  2727. -           params.combatType = COMBAT_HOLYDAMAGE;
  2728.         } else {
  2729.             std::cout << "[Warning - WeaponWand::configureEvent] Type \"" << attr.as_string() << "\" does not exist." << std::endl;
  2730.         }
  2731. --
  2732. 2.7.4.1.g5468f9e
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement