Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From e38301b5a0ac148ea55adf63ce89484d5c546c7d Mon Sep 17 00:00:00 2001
- From: eduardovicente <dudugt500@gmail.com>
- Date: Wed, 14 Feb 2018 02:30:32 -0200
- Subject: [PATCH] Summon Spells 1.0
- ---
- .../data/actions/scripts/tools/emptyPokeball.lua | 14 +
- .../data/monster/Dragons/dragon.xml | 45 +-
- forgottenserver-1.2/data/monster/monsters.xml | 3 -
- .../data/spells/scripts/energy_beam.lua | 20 +
- forgottenserver-1.2/data/spells/spells.xml | 1 +
- .../data/talkactions/scripts/summonspell.lua | 7 +
- forgottenserver-1.2/src/combat.cpp | 264 +++++++----
- forgottenserver-1.2/src/combat.h | 12 +
- forgottenserver-1.2/src/creature.cpp | 116 +++--
- forgottenserver-1.2/src/creature.h | 2 +-
- forgottenserver-1.2/src/enums.h | 121 +++--
- forgottenserver-1.2/src/game.cpp | 142 +-----
- forgottenserver-1.2/src/game.h | 2 +-
- forgottenserver-1.2/src/items.cpp | 48 +-
- forgottenserver-1.2/src/luascript.cpp | 77 +++-
- forgottenserver-1.2/src/monster.cpp | 271 ++++++------
- forgottenserver-1.2/src/monster.h | 26 +-
- forgottenserver-1.2/src/monsters.cpp | 491 ++++++---------------
- forgottenserver-1.2/src/monsters.h | 18 +-
- forgottenserver-1.2/src/player.cpp | 7 +-
- forgottenserver-1.2/src/player.h | 2 +-
- forgottenserver-1.2/src/spells.h | 21 +-
- forgottenserver-1.2/src/tools.cpp | 37 +-
- forgottenserver-1.2/src/weapons.cpp | 19 +-
- 24 files changed, 820 insertions(+), 946 deletions(-)
- create mode 100644 forgottenserver-1.2/data/actions/scripts/tools/emptyPokeball.lua
- create mode 100644 forgottenserver-1.2/data/spells/scripts/energy_beam.lua
- create mode 100644 forgottenserver-1.2/data/talkactions/scripts/summonspell.lua
- diff --git a/forgottenserver-1.2/data/actions/scripts/tools/emptyPokeball.lua b/forgottenserver-1.2/data/actions/scripts/tools/emptyPokeball.lua
- new file mode 100644
- index 0000000..d3fdd91
- --- /dev/null
- +++ b/forgottenserver-1.2/data/actions/scripts/tools/emptyPokeball.lua
- @@ -0,0 +1,14 @@
- +function onUse(player, pokeball, fromPosition, target, toPosition, isHotkey)
- + if not target:isMonster() then
- + return false
- + end
- +
- + local pokeball = player:addItem(2467, 1)
- + pokeball:setPokemonName(target:getName())
- + pokeball:setLevel(target:getLevel())
- + pokeball:setExperience(target:getExperience())
- + pokeball:setMaxHealth(target:getMaxHealth())
- + pokeball:setHealth(target:getHealth())
- +
- + target:remove()
- +end
- \ No newline at end of file
- diff --git a/forgottenserver-1.2/data/monster/Dragons/dragon.xml b/forgottenserver-1.2/data/monster/Dragons/dragon.xml
- index 5437025..ed54145 100644
- --- a/forgottenserver-1.2/data/monster/Dragons/dragon.xml
- +++ b/forgottenserver-1.2/data/monster/Dragons/dragon.xml
- @@ -2,7 +2,25 @@
- <monster name="Dragon" nameDescription="a dragon" race="blood" experience="700" speed="185" manacost="0">
- <health now="1000" max="1000" />
- <look type="34" corpse="5973" />
- - <targetchange interval="4000" chance="10" />
- +
- + <level min="10" max="20" />
- + <basestatus hp="150" attack="50" defense="20" specialattack="10" specialdefense="10" speed="25" />
- + <statusperlevel hp="2" attack="5" defense="1" specialattack="1.5" specialdefense="0.5" speed="3" />
- + <targetchange interval="4000" chance="20" />
- +
- + <attacks>
- + <spell name="Energy Beam" word="m1" level="1" cooldown="2500" chance="10"/>
- + </attacks>
- + <passives>
- + </passives>
- +
- + <elements>
- + <element icePercent="-80" />
- + <element firePercent="30" />
- + </elements>
- + <immunities>
- + </immunities>
- +
- <flags>
- <flag summonable="0" />
- <flag attackable="1" />
- @@ -16,31 +34,6 @@
- <flag staticattack="80" />
- <flag runonhealth="300" />
- </flags>
- - <attacks>
- - <attack name="melee" interval="2000" min="0" max="-120" />
- - <attack name="fire" interval="2000" chance="15" range="7" radius="4" target="1" min="-60" max="-140">
- - <attribute key="shootEffect" value="fire" />
- - <attribute key="areaEffect" value="firearea" />
- - </attack>
- - <attack name="fire" interval="2000" chance="10" length="8" spread="3" min="-100" max="-170">
- - <attribute key="areaEffect" value="firearea" />
- - </attack>
- - </attacks>
- - <defenses armor="30" defense="30">
- - <defense name="healing" interval="2000" chance="15" min="40" max="70">
- - <attribute key="areaEffect" value="blueshimmer" />
- - </defense>
- - </defenses>
- - <elements>
- - <element earthPercent="80" />
- - <element energyPercent="20" />
- - <element icePercent="-10" />
- - </elements>
- - <immunities>
- - <immunity paralyze="1" />
- - <immunity invisible="1" />
- - <immunity fire="1" />
- - </immunities>
- <voices interval="5000" chance="10">
- <voice sentence="GROOAAARRR" yell="1" />
- <voice sentence="FCHHHHH" yell="1" />
- diff --git a/forgottenserver-1.2/data/monster/monsters.xml b/forgottenserver-1.2/data/monster/monsters.xml
- index 8aa1bd3..352773e 100644
- --- a/forgottenserver-1.2/data/monster/monsters.xml
- +++ b/forgottenserver-1.2/data/monster/monsters.xml
- @@ -2,7 +2,4 @@
- <monsters>
- <!-- Dragons -->
- <monster name="Dragon Lord" file="Dragons/dragon_lord.xml" />
- - <monster name="Dragon Lord Hatchling" file="Dragons/dragon_lord_hatchling.xml" />
- - <monster name="Dragon" file="Dragons/dragon.xml" />
- - <monster name="Dragon Hatchling" file="Dragons/dragon_hatchling.xml" />
- </monsters>
- diff --git a/forgottenserver-1.2/data/spells/scripts/energy_beam.lua b/forgottenserver-1.2/data/spells/scripts/energy_beam.lua
- new file mode 100644
- index 0000000..0c21c72
- --- /dev/null
- +++ b/forgottenserver-1.2/data/spells/scripts/energy_beam.lua
- @@ -0,0 +1,20 @@
- +local combat = Combat()
- +combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE)
- +combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_WATERSPLASH)
- +combat:setArea(createCombatArea(AREA_SQUARE1X1))
- +combat:setCondition(condition)
- +
- +function onMonsterCombat(monster, hp, attack, defense, specialattack, specialdefense, speed)
- + local chance = math.random(1, 5)
- + print(hp, attack, defense, specialattack, specialdefense, speed)
- +
- + local min = (attack * 1.5)/ chance
- + local max = (attack * 2) / chance
- + return -min, -max
- +end
- +
- +combat:setCallback(CALLBACK_PARAM_MONSTER, "onMonsterCombat")
- +
- +function onCastSpell(creature, variant)
- + return combat:execute(creature, variant)
- +end
- diff --git a/forgottenserver-1.2/data/spells/spells.xml b/forgottenserver-1.2/data/spells/spells.xml
- index cc793e2..342d1fc 100644
- --- a/forgottenserver-1.2/data/spells/spells.xml
- +++ b/forgottenserver-1.2/data/spells/spells.xml
- @@ -1,3 +1,4 @@
- <?xml version="1.0" encoding="UTF-8"?>
- <spells>
- + <instant name="Energy Beam" words="m1" aggressive="1" blockwalls="1" needtarget="0" needlearn="1" script="energy_beam.lua" />
- </spells>
- diff --git a/forgottenserver-1.2/data/talkactions/scripts/summonspell.lua b/forgottenserver-1.2/data/talkactions/scripts/summonspell.lua
- new file mode 100644
- index 0000000..ace81b2
- --- /dev/null
- +++ b/forgottenserver-1.2/data/talkactions/scripts/summonspell.lua
- @@ -0,0 +1,7 @@
- +function onSay(player, words, param)
- + if (#player:getSummons() <= 0) then
- + return
- + end
- +
- + player:getSummons()[1]:castSpell(words)
- +end
- \ No newline at end of file
- diff --git a/forgottenserver-1.2/src/combat.cpp b/forgottenserver-1.2/src/combat.cpp
- index 6c48f54..1b8f820 100644
- --- a/forgottenserver-1.2/src/combat.cpp
- +++ b/forgottenserver-1.2/src/combat.cpp
- @@ -25,6 +25,7 @@
- #include "weapons.h"
- #include "configmanager.h"
- #include "events.h"
- +#include "monster.h"
- extern Game g_game;
- extern Weapons* g_weapons;
- @@ -36,50 +37,37 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const
- CombatDamage damage;
- damage.origin = params.origin;
- damage.primary.type = params.combatType;
- - if (formulaType == COMBAT_FORMULA_DAMAGE) {
- +
- + if (!creature) {
- damage.primary.value = normal_random(
- static_cast<int32_t>(mina),
- static_cast<int32_t>(maxa)
- - );
- - } else if (creature) {
- - int32_t min, max;
- - if (creature->getCombatValues(min, max)) {
- - damage.primary.value = normal_random(min, max);
- - } else if (Player* player = creature->getPlayer()) {
- - if (params.valueCallback) {
- - params.valueCallback->getMinMaxValues(player, damage, params.useCharges);
- - } else if (formulaType == COMBAT_FORMULA_LEVELMAGIC) {
- - int32_t levelFormula = player->getLevel() * 2 + player->getMagicLevel() * 3;
- - damage.primary.value = normal_random(
- - static_cast<int32_t>(levelFormula * mina + minb),
- - static_cast<int32_t>(levelFormula * maxa + maxb)
- + );
- +
- + return damage;
- + }
- +
- + int32_t min, max;
- + if (creature->getCombatValues(min, max)) {
- + damage.primary.value = normal_random(min, max);
- + } else if (Monster* monster = creature->getMonster()) {
- + if (params.monsterCallback) {
- + params.monsterCallback->onMonsterCombat(monster, damage);
- + } else if (formulaType == COMBAT_FORMULA_DAMAGE) {
- + //TODO REVISAR ATTACK FORMULAS
- + int32_t attackFormula;
- + if (params.spellType == COMBATSPELL_SPECIALATTACK)
- + attackFormula = monster->getStatus().getSpecialAttack();
- + else
- + attackFormula = monster->getStatus().getAttack();
- +
- + damage.primary.value = normal_random(
- + static_cast<int32_t>(mina - attackFormula),
- + static_cast<int32_t>(maxa - attackFormula)
- );
- - } else if (formulaType == COMBAT_FORMULA_SKILL) {
- - Item* tool = player->getWeapon();
- - const Weapon* weapon = g_weapons->getWeapon(tool);
- - if (weapon) {
- - damage.primary.value = normal_random(
- - static_cast<int32_t>(minb),
- - static_cast<int32_t>(weapon->getWeaponDamage(player, target, tool, true) * maxa + maxb)
- - );
- -
- - damage.secondary.type = weapon->getElementType();
- - damage.secondary.value = weapon->getElementDamage(player, target, tool);
- - if (params.useCharges) {
- - uint16_t charges = tool->getCharges();
- - if (charges != 0) {
- - g_game.transformItem(tool, tool->getID(), charges - 1);
- - }
- - }
- - } else {
- - damage.primary.value = normal_random(
- - static_cast<int32_t>(minb),
- - static_cast<int32_t>(maxb)
- - );
- - }
- - }
- }
- }
- +
- return damage;
- }
- @@ -104,32 +92,43 @@ void Combat::getCombatArea(const Position& centerPos, const Position& targetPos,
- CombatType_t Combat::ConditionToDamageType(ConditionType_t type)
- {
- switch (type) {
- - case CONDITION_FIRE:
- - return COMBAT_FIREDAMAGE;
- -
- - case CONDITION_ENERGY:
- - return COMBAT_ENERGYDAMAGE;
- -
- - case CONDITION_BLEEDING:
- - return COMBAT_PHYSICALDAMAGE;
- -
- - case CONDITION_DROWN:
- - return COMBAT_DROWNDAMAGE;
- -
- - case CONDITION_POISON:
- - return COMBAT_EARTHDAMAGE;
- -
- - case CONDITION_FREEZING:
- - return COMBAT_ICEDAMAGE;
- -
- - case CONDITION_DAZZLED:
- - return COMBAT_HOLYDAMAGE;
- -
- - case CONDITION_CURSED:
- - return COMBAT_DEATHDAMAGE;
- -
- - default:
- - break;
- + case CONDITION_BUG:
- + return COMBAT_BUGDAMAGE;
- + case CONDITION_DRAGON:
- + return COMBAT_DRAGONDAMAGE;
- + case CONDITION_FAIRY:
- + return COMBAT_FAIRYDAMAGE;
- + case CONDITION_FIRE:
- + return COMBAT_FIREDAMAGE;
- + case CONDITION_GHOST:
- + return COMBAT_GHOSTDAMAGE;
- + case CONDITION_GROUND:
- + return COMBAT_GROUNDDAMAGE;
- + case CONDITION_NORMAL:
- + return COMBAT_NORMALDAMAGE;
- + case CONDITION_STEEL:
- + return COMBAT_STEELDAMAGE;
- + case CONDITION_DARK:
- + return COMBAT_DARKDAMAGE;
- + case CONDITION_ELECTRIC:
- + return COMBAT_ELECTRICDAMAGE;
- + case CONDITION_FIGHTING:
- + return COMBAT_FIGHTINGDAMAGE;
- + case CONDITION_FLYING:
- + return COMBAT_FLYINGDAMAGE;
- + case CONDITION_GRASS:
- + return COMBAT_GRASSDAMAGE;
- + case CONDITION_ICE:
- + return COMBAT_ICEDAMAGE;
- + case CONDITION_POISON:
- + return COMBAT_POISONDAMAGE;
- + case CONDITION_ROCK:
- + return COMBAT_ROCKDAMAGE;
- + case CONDITION_WATER:
- + return COMBAT_WATERDAMAGE;
- +
- + default:
- + break;
- }
- return COMBAT_NONE;
- @@ -138,32 +137,42 @@ CombatType_t Combat::ConditionToDamageType(ConditionType_t type)
- ConditionType_t Combat::DamageToConditionType(CombatType_t type)
- {
- switch (type) {
- - case COMBAT_FIREDAMAGE:
- - return CONDITION_FIRE;
- -
- - case COMBAT_ENERGYDAMAGE:
- - return CONDITION_ENERGY;
- -
- - case COMBAT_DROWNDAMAGE:
- - return CONDITION_DROWN;
- -
- - case COMBAT_EARTHDAMAGE:
- - return CONDITION_POISON;
- -
- - case COMBAT_ICEDAMAGE:
- - return CONDITION_FREEZING;
- -
- - case COMBAT_HOLYDAMAGE:
- - return CONDITION_DAZZLED;
- -
- - case COMBAT_DEATHDAMAGE:
- - return CONDITION_CURSED;
- -
- - case COMBAT_PHYSICALDAMAGE:
- - return CONDITION_BLEEDING;
- -
- - default:
- - return CONDITION_NONE;
- + case COMBAT_BUGDAMAGE:
- + return CONDITION_BUG;
- + case COMBAT_DRAGONDAMAGE:
- + return CONDITION_DRAGON;
- + case COMBAT_FAIRYDAMAGE:
- + return CONDITION_FAIRY;
- + case COMBAT_FIREDAMAGE:
- + return CONDITION_FIRE;
- + case COMBAT_GHOSTDAMAGE:
- + return CONDITION_GHOST;
- + case COMBAT_GROUNDDAMAGE:
- + return CONDITION_GROUND;
- + case COMBAT_NORMALDAMAGE:
- + return CONDITION_NORMAL;
- + case COMBAT_STEELDAMAGE:
- + return CONDITION_STEEL;
- + case COMBAT_DARKDAMAGE:
- + return CONDITION_DARK;
- + case COMBAT_ELECTRICDAMAGE:
- + return CONDITION_ELECTRIC;
- + case COMBAT_FIGHTINGDAMAGE:
- + return CONDITION_FIGHTING;
- + case COMBAT_FLYINGDAMAGE:
- + return CONDITION_FLYING;
- + case COMBAT_GRASSDAMAGE:
- + return CONDITION_GRASS;
- + case COMBAT_ICEDAMAGE:
- + return CONDITION_ICE;
- + case COMBAT_POISONDAMAGE:
- + return CONDITION_POISON;
- + case COMBAT_ROCKDAMAGE:
- + return CONDITION_ROCK;
- + case COMBAT_WATERDAMAGE:
- + return CONDITION_WATER;
- + default:
- + return CONDITION_NONE;
- }
- }
- @@ -459,6 +468,11 @@ bool Combat::setCallback(CallBackParam_t key)
- params.targetCallback.reset(new TargetCallback());
- return true;
- }
- +
- + case CALLBACK_PARAM_MONSTER: {
- + params.monsterCallback.reset(new MonsterCallback());
- + return true;
- + }
- }
- return false;
- }
- @@ -478,6 +492,10 @@ CallBack* Combat::getCallback(CallBackParam_t key)
- case CALLBACK_PARAM_TARGETCREATURE: {
- return params.targetCallback.get();
- }
- +
- + case CALLBACK_PARAM_MONSTER: {
- + return params.monsterCallback.get();
- + }
- }
- return nullptr;
- }
- @@ -486,10 +504,11 @@ void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatPa
- {
- assert(data);
- CombatDamage damage = *data;
- - if (g_game.combatBlockHit(damage, caster, target, params.blockedByShield, params.blockedByArmor, params.itemId != 0)) {
- + if (g_game.combatBlockHit(damage, caster, target, params.blockedByShield, params.blockedByArmor, params.itemId != 0, params.spellType)) {
- return;
- }
- + //Todo: Rever Isso
- if ((damage.primary.value < 0 || damage.secondary.value < 0) && caster) {
- Player* targetPlayer = target->getPlayer();
- if (targetPlayer && caster->getPlayer() && targetPlayer->getSkull() != SKULL_BLACK) {
- @@ -741,12 +760,11 @@ void Combat::doCombat(Creature* caster, Creature* target) const
- //target combat callback function
- if (params.combatType != COMBAT_NONE) {
- CombatDamage damage = getCombatDamage(caster, target);
- - if (damage.primary.type != COMBAT_MANADRAIN) {
- + if (damage.primary.type) {
- doCombatHealth(caster, target, damage, params);
- - } else {
- - doCombatMana(caster, target, damage, params);
- }
- - } else {
- + }
- + else {
- doCombatDefault(caster, target, params);
- }
- }
- @@ -756,10 +774,8 @@ void Combat::doCombat(Creature* caster, const Position& position) const
- //area combat callback function
- if (params.combatType != COMBAT_NONE) {
- CombatDamage damage = getCombatDamage(caster, nullptr);
- - if (damage.primary.type != COMBAT_MANADRAIN) {
- + if (damage.primary.type) {
- doCombatHealth(caster, position, area.get(), damage, params);
- - } else {
- - doCombatMana(caster, position, area.get(), damage, params);
- }
- } else {
- CombatFunc(caster, position, area.get(), params, CombatNullFunc, nullptr);
- @@ -1054,6 +1070,58 @@ void TargetCallback::onTargetCombat(Creature* creature, Creature* target) const
- scriptInterface->resetScriptEnv();
- }
- +void MonsterCallback::onMonsterCombat(Monster* monster, CombatDamage& damage) const
- +{
- + //onMonsterCombat(monster, level, hp, attack, defense, specialattack, specialdefense, speed)
- + if (!scriptInterface->reserveScriptEnv()) {
- + std::cout << "[Error - MonsterCallback::onMonsterCombat] Call stack overflow" << std::endl;
- + return;
- + }
- +
- + ScriptEnvironment* env = scriptInterface->getScriptEnv();
- + if (!env->setCallbackId(scriptId, scriptInterface)) {
- + scriptInterface->resetScriptEnv();
- + return;
- + }
- +
- + lua_State* L = scriptInterface->getLuaState();
- +
- + scriptInterface->pushFunction(scriptId);
- +
- + if (monster) {
- + LuaScriptInterface::pushUserdata<Monster>(L, monster);
- + LuaScriptInterface::setCreatureMetatable(L, -1, monster);
- +
- + lua_pushnumber(L, monster->getStatus().getHealth());
- + lua_pushnumber(L, monster->getStatus().getAttack());
- + lua_pushnumber(L, monster->getStatus().getDefense());
- + lua_pushnumber(L, monster->getStatus().getSpecialAttack());
- + lua_pushnumber(L, monster->getStatus().getSpecialDefense());
- + lua_pushnumber(L, monster->getStatus().getSpeed());
- + }
- + else {
- + lua_pushnil(L);
- + }
- +
- + int size0 = lua_gettop(L);
- + if (lua_pcall(L, 7, 2, 0) != 0) {
- + LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L));
- + }
- + else {
- + damage.primary.value = normal_random(
- + LuaScriptInterface::getNumber<int32_t>(L, -2),
- + LuaScriptInterface::getNumber<int32_t>(L, -1)
- + );
- + lua_pop(L, 2);
- + }
- +
- + if ((lua_gettop(L) + 7 + 1) != size0) {
- + LuaScriptInterface::reportError(nullptr, "Stack size changed!");
- + }
- +
- + scriptInterface->resetScriptEnv();
- +}
- +
- //**********************************************************//
- void AreaCombat::clear()
- diff --git a/forgottenserver-1.2/src/combat.h b/forgottenserver-1.2/src/combat.h
- index 8f9b373..87cfca5 100644
- --- a/forgottenserver-1.2/src/combat.h
- +++ b/forgottenserver-1.2/src/combat.h
- @@ -60,18 +60,30 @@ class TargetCallback final : public CallBack
- formulaType_t type;
- };
- +class MonsterCallback final : public CallBack
- +{
- +public:
- + void onMonsterCombat(Monster* monster, CombatDamage& damage) const;
- +
- +protected:
- + formulaType_t type;
- +
- +};
- +
- struct CombatParams {
- std::forward_list<std::unique_ptr<const Condition>> conditionList;
- std::unique_ptr<ValueCallback> valueCallback;
- std::unique_ptr<TileCallback> tileCallback;
- std::unique_ptr<TargetCallback> targetCallback;
- + std::unique_ptr<MonsterCallback> monsterCallback;
- uint16_t itemId = 0;
- ConditionType_t dispelType = CONDITION_NONE;
- CombatType_t combatType = COMBAT_NONE;
- CombatOrigin origin = ORIGIN_SPELL;
- + CombatSpellType_t spellType = COMBATSPELL_NONE;
- uint8_t impactEffect = CONST_ME_NONE;
- uint8_t distanceEffect = CONST_ANI_NONE;
- diff --git a/forgottenserver-1.2/src/creature.cpp b/forgottenserver-1.2/src/creature.cpp
- index 318380b..44dfccb 100644
- --- a/forgottenserver-1.2/src/creature.cpp
- +++ b/forgottenserver-1.2/src/creature.cpp
- @@ -800,48 +800,13 @@ void Creature::drainMana(Creature* attacker, int32_t manaLoss)
- }
- BlockType_t Creature::blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
- - bool checkDefense /* = false */, bool checkArmor /* = false */, bool /* field = false */)
- + bool checkDefense /* = false */, bool checkArmor /* = false */, bool /* field = false */, CombatSpellType_t spellType)
- {
- BlockType_t blockType = BLOCK_NONE;
- if (isImmune(combatType)) {
- damage = 0;
- blockType = BLOCK_IMMUNITY;
- - } else if (checkDefense || checkArmor) {
- - bool hasDefense = false;
- -
- - if (blockCount > 0) {
- - --blockCount;
- - hasDefense = true;
- - }
- -
- - if (checkDefense && hasDefense) {
- - int32_t defense = getDefense();
- - damage -= uniform_random(defense / 2, defense);
- - if (damage <= 0) {
- - damage = 0;
- - blockType = BLOCK_DEFENSE;
- - checkArmor = false;
- - }
- - }
- -
- - if (checkArmor) {
- - int32_t armor = getArmor();
- - if (armor > 3) {
- - damage -= uniform_random(armor / 2, armor - (armor % 2 + 1));
- - } else if (armor > 0) {
- - --damage;
- - }
- -
- - if (damage <= 0) {
- - damage = 0;
- - blockType = BLOCK_ARMOR;
- - }
- - }
- -
- - if (hasDefense && blockType != BLOCK_NONE) {
- - onBlockHit();
- - }
- }
- if (attacker) {
- @@ -1036,32 +1001,59 @@ void Creature::onTickCondition(ConditionType_t type, bool& bRemove)
- }
- switch (type) {
- - case CONDITION_FIRE:
- - bRemove = (field->getCombatType() != COMBAT_FIREDAMAGE);
- - break;
- - case CONDITION_ENERGY:
- - bRemove = (field->getCombatType() != COMBAT_ENERGYDAMAGE);
- - break;
- - case CONDITION_POISON:
- - bRemove = (field->getCombatType() != COMBAT_EARTHDAMAGE);
- - break;
- - case CONDITION_FREEZING:
- - bRemove = (field->getCombatType() != COMBAT_ICEDAMAGE);
- - break;
- - case CONDITION_DAZZLED:
- - bRemove = (field->getCombatType() != COMBAT_HOLYDAMAGE);
- - break;
- - case CONDITION_CURSED:
- - bRemove = (field->getCombatType() != COMBAT_DEATHDAMAGE);
- - break;
- - case CONDITION_DROWN:
- - bRemove = (field->getCombatType() != COMBAT_DROWNDAMAGE);
- - break;
- - case CONDITION_BLEEDING:
- - bRemove = (field->getCombatType() != COMBAT_PHYSICALDAMAGE);
- - break;
- - default:
- - break;
- + case CONDITION_BUG:
- + bRemove = (field->getCombatType() != COMBAT_BUGDAMAGE);
- + break;
- + case CONDITION_DRAGON:
- + bRemove = (field->getCombatType() != COMBAT_DRAGONDAMAGE);
- + break;
- + case CONDITION_FAIRY:
- + bRemove = (field->getCombatType() != COMBAT_FAIRYDAMAGE);
- + break;
- + case CONDITION_FIRE:
- + bRemove = (field->getCombatType() != COMBAT_FIREDAMAGE);
- + break;
- + case CONDITION_GHOST:
- + bRemove = (field->getCombatType() != COMBAT_GHOSTDAMAGE);
- + break;
- + case CONDITION_GROUND:
- + bRemove = (field->getCombatType() != COMBAT_GROUNDDAMAGE);
- + break;
- + case CONDITION_NORMAL:
- + bRemove = (field->getCombatType() != COMBAT_NORMALDAMAGE);
- + break;
- + case CONDITION_PSYCHIC:
- + bRemove = (field->getCombatType() != COMBAT_PSYCHICDAMAGE);
- + break;
- + case CONDITION_STEEL:
- + bRemove = (field->getCombatType() != COMBAT_STEELDAMAGE);
- + break;
- + case CONDITION_ELECTRIC:
- + bRemove = (field->getCombatType() != COMBAT_ELECTRICDAMAGE);
- + break;
- + case CONDITION_FIGHTING:
- + bRemove = (field->getCombatType() != COMBAT_FIGHTINGDAMAGE);
- + break;
- + case CONDITION_FLYING:
- + bRemove = (field->getCombatType() != COMBAT_FLYINGDAMAGE);
- + break;
- + case CONDITION_GRASS:
- + bRemove = (field->getCombatType() != COMBAT_GRASSDAMAGE);
- + break;
- + case CONDITION_ICE:
- + bRemove = (field->getCombatType() != COMBAT_ICEDAMAGE);
- + break;
- + case CONDITION_POISON:
- + bRemove = (field->getCombatType() != COMBAT_POISONDAMAGE);
- + break;
- + case CONDITION_ROCK:
- + bRemove = (field->getCombatType() != COMBAT_ROCKDAMAGE);
- + break;
- + case CONDITION_WATER:
- + bRemove = (field->getCombatType() != COMBAT_WATERDAMAGE);
- + break;
- + default:
- + break;
- }
- }
- diff --git a/forgottenserver-1.2/src/creature.h b/forgottenserver-1.2/src/creature.h
- index 583fa80..3f02c99 100644
- --- a/forgottenserver-1.2/src/creature.h
- +++ b/forgottenserver-1.2/src/creature.h
- @@ -274,7 +274,7 @@ class Creature : virtual public Thing
- }
- virtual bool setAttackedCreature(Creature* creature);
- virtual BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
- - bool checkDefense = false, bool checkArmor = false, bool field = false);
- + bool checkDefense = false, bool checkArmor = false, bool field = false, CombatSpellType_t spellType = COMBATSPELL_NONE);
- void setMaster(Creature* creature) {
- master = creature;
- diff --git a/forgottenserver-1.2/src/enums.h b/forgottenserver-1.2/src/enums.h
- index 2613586..91bd00e 100644
- --- a/forgottenserver-1.2/src/enums.h
- +++ b/forgottenserver-1.2/src/enums.h
- @@ -138,23 +138,36 @@ enum RaceType_t : uint8_t {
- RACE_ENERGY,
- };
- -enum CombatType_t : uint16_t {
- +enum CombatType_t {
- COMBAT_NONE = 0,
- - COMBAT_PHYSICALDAMAGE = 1 << 0,
- - COMBAT_ENERGYDAMAGE = 1 << 1,
- - COMBAT_EARTHDAMAGE = 1 << 2,
- + COMBAT_BUGDAMAGE = 1 << 0,
- + COMBAT_DRAGONDAMAGE = 1 << 1,
- + COMBAT_FAIRYDAMAGE = 1 << 2,
- COMBAT_FIREDAMAGE = 1 << 3,
- - COMBAT_UNDEFINEDDAMAGE = 1 << 4,
- - COMBAT_LIFEDRAIN = 1 << 5,
- - COMBAT_MANADRAIN = 1 << 6,
- - COMBAT_HEALING = 1 << 7,
- - COMBAT_DROWNDAMAGE = 1 << 8,
- - COMBAT_ICEDAMAGE = 1 << 9,
- - COMBAT_HOLYDAMAGE = 1 << 10,
- - COMBAT_DEATHDAMAGE = 1 << 11,
- -
- - COMBAT_COUNT = 12
- + COMBAT_GHOSTDAMAGE = 1 << 4,
- + COMBAT_GROUNDDAMAGE = 1 << 5,
- + COMBAT_NORMALDAMAGE = 1 << 6,
- + COMBAT_PSYCHICDAMAGE = 1 << 7,
- + COMBAT_STEELDAMAGE = 1 << 8,
- + COMBAT_DARKDAMAGE = 1 << 9,
- + COMBAT_ELECTRICDAMAGE = 1 << 10,
- + COMBAT_FIGHTINGDAMAGE = 1 << 11,
- + COMBAT_FLYINGDAMAGE = 1 << 12,
- + COMBAT_GRASSDAMAGE = 1 << 13,
- + COMBAT_ICEDAMAGE = 1 << 14,
- + COMBAT_POISONDAMAGE = 1 << 15,
- + COMBAT_ROCKDAMAGE = 1 << 16,
- + COMBAT_WATERDAMAGE = 1 << 17,
- + COMBAT_HEALING = 1 << 18,
- +
- + COMBAT_COUNT = 18
- +};
- +
- +enum CombatSpellType_t {
- + COMBATSPELL_NONE = 0,
- + COMBATSPELL_ATTACK = 1 << 0,
- + COMBATSPELL_SPECIALATTACK = 2 << 0,
- };
- enum CombatParam_t {
- @@ -175,6 +188,7 @@ enum CallBackParam_t {
- CALLBACK_PARAM_SKILLVALUE,
- CALLBACK_PARAM_TARGETTILE,
- CALLBACK_PARAM_TARGETCREATURE,
- + CALLBACK_PARAM_MONSTER,
- };
- enum ConditionParam_t {
- @@ -229,7 +243,7 @@ enum ConditionParam_t {
- enum BlockType_t : uint8_t {
- BLOCK_NONE,
- BLOCK_DEFENSE,
- - BLOCK_ARMOR,
- + BLOCK_SPECIALDEFENSE,
- BLOCK_IMMUNITY
- };
- @@ -269,34 +283,51 @@ enum formulaType_t {
- enum ConditionType_t {
- CONDITION_NONE,
- - CONDITION_POISON = 1 << 0,
- - CONDITION_FIRE = 1 << 1,
- - CONDITION_ENERGY = 1 << 2,
- - CONDITION_BLEEDING = 1 << 3,
- - CONDITION_HASTE = 1 << 4,
- - CONDITION_PARALYZE = 1 << 5,
- - CONDITION_OUTFIT = 1 << 6,
- - CONDITION_INVISIBLE = 1 << 7,
- - CONDITION_LIGHT = 1 << 8,
- - CONDITION_MANASHIELD = 1 << 9,
- - CONDITION_INFIGHT = 1 << 10,
- - CONDITION_DRUNK = 1 << 11,
- - CONDITION_EXHAUST_WEAPON = 1 << 12, // unused
- - CONDITION_REGENERATION = 1 << 13,
- - CONDITION_SOUL = 1 << 14,
- - CONDITION_DROWN = 1 << 15,
- - CONDITION_MUTED = 1 << 16,
- - CONDITION_CHANNELMUTEDTICKS = 1 << 17,
- - CONDITION_YELLTICKS = 1 << 18,
- - CONDITION_ATTRIBUTES = 1 << 19,
- - CONDITION_FREEZING = 1 << 20,
- - CONDITION_DAZZLED = 1 << 21,
- - CONDITION_CURSED = 1 << 22,
- - CONDITION_EXHAUST_COMBAT = 1 << 23, // unused
- - CONDITION_EXHAUST_HEAL = 1 << 24, // unused
- - CONDITION_PACIFIED = 1 << 25,
- - CONDITION_SPELLCOOLDOWN = 1 << 26,
- - CONDITION_SPELLGROUPCOOLDOWN = 1 << 27,
- + CONDITION_POISON = 1,
- + CONDITION_FIRE = 2,
- + CONDITION_ENERGY = 3,
- + CONDITION_BLEEDING = 4,
- + CONDITION_HASTE = 5,
- + CONDITION_PARALYZE = 6,
- + CONDITION_OUTFIT = 7,
- + CONDITION_INVISIBLE = 8,
- + CONDITION_LIGHT = 9,
- + CONDITION_MANASHIELD = 10,
- + CONDITION_INFIGHT = 11,
- + CONDITION_DRUNK = 12,
- + CONDITION_EXHAUST_WEAPON = 13, // unused
- + CONDITION_REGENERATION = 14,
- + CONDITION_SOUL = 15,
- + CONDITION_DROWN = 16,
- + CONDITION_MUTED = 17,
- + CONDITION_CHANNELMUTEDTICKS = 18,
- + CONDITION_YELLTICKS = 19,
- + CONDITION_ATTRIBUTES = 20,
- + CONDITION_FREEZING = 21,
- + CONDITION_DAZZLED = 22,
- + CONDITION_CURSED = 23,
- + CONDITION_EXHAUST_COMBAT = 24, // unused
- + CONDITION_EXHAUST_HEAL = 25, // unused
- + CONDITION_PACIFIED = 26,
- + CONDITION_SPELLCOOLDOWN = 27,
- + CONDITION_SPELLGROUPCOOLDOWN = 28,
- + CONDITION_BUG = 29,
- + CONDITION_DRAGON = 30,
- + CONDITION_FAIRY = 31,
- + CONDITION_GHOST = 32,
- + CONDITION_GROUND = 33,
- + CONDITION_NORMAL = 34,
- + CONDITION_PSYCHIC = 35,
- + CONDITION_STEEL = 36,
- + CONDITION_DARK = 38,
- + CONDITION_ELECTRIC = 39,
- + CONDITION_FIGHTING = 40,
- + CONDITION_FLYING = 41,
- + CONDITION_GRASS = 42,
- + CONDITION_ICE = 43,
- + CONDITION_ROCK = 44,
- + CONDITION_WATER = 45,
- +
- };
- enum ConditionId_t : int8_t {
- @@ -564,7 +595,7 @@ public:
- attack += nStatus.getAttack();
- defense += nStatus.getDefense();
- health += nStatus.getHealth();
- - specialAttack += nStatus.getSpeciaAttack();
- + specialAttack += nStatus.getSpecialAttack();
- specialDefense += nStatus.getSpecialDefense();
- speed += nStatus.getSpeed();
- }
- @@ -600,7 +631,7 @@ public:
- {
- specialAttack = value;
- }
- - double getSpeciaAttack()
- + double getSpecialAttack()
- {
- return specialAttack;
- }
- diff --git a/forgottenserver-1.2/src/game.cpp b/forgottenserver-1.2/src/game.cpp
- index cf3014b..efc77e7 100644
- --- a/forgottenserver-1.2/src/game.cpp
- +++ b/forgottenserver-1.2/src/game.cpp
- @@ -3595,7 +3595,7 @@ void Game::changeLight(const Creature* creature)
- }
- }
- -bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field)
- +bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field, CombatSpellType_t spellType)
- {
- if (damage.primary.type == COMBAT_NONE && damage.secondary.type == COMBAT_NONE) {
- return true;
- @@ -3610,37 +3610,15 @@ bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* ta
- }
- static const auto sendBlockEffect = [this](BlockType_t blockType, CombatType_t combatType, const Position& targetPos) {
- - if (blockType == BLOCK_DEFENSE) {
- + if (blockType == BLOCK_SPECIALDEFENSE) {
- addMagicEffect(targetPos, CONST_ME_POFF);
- - } else if (blockType == BLOCK_ARMOR) {
- + }
- + else if (blockType == BLOCK_DEFENSE) {
- addMagicEffect(targetPos, CONST_ME_BLOCKHIT);
- - } else if (blockType == BLOCK_IMMUNITY) {
- + }
- + else if (blockType == BLOCK_IMMUNITY) {
- uint8_t hitEffect = 0;
- - switch (combatType) {
- - case COMBAT_UNDEFINEDDAMAGE: {
- - return;
- - }
- - case COMBAT_ENERGYDAMAGE:
- - case COMBAT_FIREDAMAGE:
- - case COMBAT_PHYSICALDAMAGE:
- - case COMBAT_ICEDAMAGE:
- - case COMBAT_DEATHDAMAGE: {
- - hitEffect = CONST_ME_BLOCKHIT;
- - break;
- - }
- - case COMBAT_EARTHDAMAGE: {
- - hitEffect = CONST_ME_GREEN_RINGS;
- - break;
- - }
- - case COMBAT_HOLYDAMAGE: {
- - hitEffect = CONST_ME_HOLYDAMAGE;
- - break;
- - }
- - default: {
- - hitEffect = CONST_ME_POFF;
- - break;
- - }
- - }
- + hitEffect = CONST_ME_POFF;
- addMagicEffect(targetPos, hitEffect);
- }
- };
- @@ -3648,116 +3626,34 @@ bool Game::combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* ta
- BlockType_t primaryBlockType, secondaryBlockType;
- if (damage.primary.type != COMBAT_NONE) {
- damage.primary.value = -damage.primary.value;
- - primaryBlockType = target->blockHit(attacker, damage.primary.type, damage.primary.value, checkDefense, checkArmor, field);
- + primaryBlockType = target->blockHit(attacker, damage.primary.type, damage.primary.value, checkDefense, checkArmor, field, spellType);
- damage.primary.value = -damage.primary.value;
- sendBlockEffect(primaryBlockType, damage.primary.type, target->getPosition());
- - } else {
- + }
- + else {
- primaryBlockType = BLOCK_NONE;
- }
- if (damage.secondary.type != COMBAT_NONE) {
- damage.secondary.value = -damage.secondary.value;
- - secondaryBlockType = target->blockHit(attacker, damage.secondary.type, damage.secondary.value, false, false, field);
- + secondaryBlockType = target->blockHit(attacker, damage.secondary.type, damage.secondary.value, false, false, field, spellType);
- damage.secondary.value = -damage.secondary.value;
- sendBlockEffect(secondaryBlockType, damage.secondary.type, target->getPosition());
- - } else {
- + }
- + else {
- secondaryBlockType = BLOCK_NONE;
- }
- +
- return (primaryBlockType != BLOCK_NONE) && (secondaryBlockType != BLOCK_NONE);
- }
- void Game::combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColor_t& color, uint8_t& effect)
- {
- - switch (combatType) {
- - case COMBAT_PHYSICALDAMAGE: {
- - Item* splash = nullptr;
- - switch (target->getRace()) {
- - case RACE_VENOM:
- - color = TEXTCOLOR_LIGHTGREEN;
- - effect = CONST_ME_HITBYPOISON;
- - splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_GREEN);
- - break;
- - case RACE_BLOOD:
- - color = TEXTCOLOR_RED;
- - effect = CONST_ME_DRAWBLOOD;
- - splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_BLOOD);
- - break;
- - case RACE_UNDEAD:
- - color = TEXTCOLOR_LIGHTGREY;
- - effect = CONST_ME_HITAREA;
- - break;
- - case RACE_FIRE:
- - color = TEXTCOLOR_ORANGE;
- - effect = CONST_ME_DRAWBLOOD;
- - break;
- - case RACE_ENERGY:
- - color = TEXTCOLOR_PURPLE;
- - effect = CONST_ME_ENERGYHIT;
- - break;
- - default:
- - color = TEXTCOLOR_NONE;
- - effect = CONST_ME_NONE;
- - break;
- - }
- -
- - if (splash) {
- - internalAddItem(target->getTile(), splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
- - startDecay(splash);
- - }
- -
- - break;
- - }
- -
- - case COMBAT_ENERGYDAMAGE: {
- - color = TEXTCOLOR_PURPLE;
- - effect = CONST_ME_ENERGYHIT;
- - break;
- - }
- -
- - case COMBAT_EARTHDAMAGE: {
- - color = TEXTCOLOR_LIGHTGREEN;
- - effect = CONST_ME_GREEN_RINGS;
- - break;
- - }
- -
- - case COMBAT_DROWNDAMAGE: {
- - color = TEXTCOLOR_LIGHTBLUE;
- - effect = CONST_ME_LOSEENERGY;
- - break;
- - }
- - case COMBAT_FIREDAMAGE: {
- - color = TEXTCOLOR_ORANGE;
- - effect = CONST_ME_HITBYFIRE;
- - break;
- - }
- - case COMBAT_ICEDAMAGE: {
- - color = TEXTCOLOR_SKYBLUE;
- - effect = CONST_ME_ICEATTACK;
- - break;
- - }
- - case COMBAT_HOLYDAMAGE: {
- - color = TEXTCOLOR_YELLOW;
- - effect = CONST_ME_HOLYDAMAGE;
- - break;
- - }
- - case COMBAT_DEATHDAMAGE: {
- - color = TEXTCOLOR_DARKRED;
- - effect = CONST_ME_SMALLCLOUDS;
- - break;
- - }
- - case COMBAT_LIFEDRAIN: {
- - color = TEXTCOLOR_RED;
- - effect = CONST_ME_MAGIC_RED;
- - break;
- - }
- - default: {
- - color = TEXTCOLOR_NONE;
- - effect = CONST_ME_NONE;
- - break;
- - }
- - }
- + //Todo: Arrumar os Combat Type
- + color = TEXTCOLOR_LIGHTGREEN;
- + effect = CONST_ME_HITBYPOISON;
- }
- bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage)
- @@ -3873,7 +3769,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage
- message.position = targetPos;
- SpectatorVec list;
- - if (target->hasCondition(CONDITION_MANASHIELD) && damage.primary.type != COMBAT_UNDEFINEDDAMAGE) {
- + if (target->hasCondition(CONDITION_MANASHIELD)) {
- int32_t manaDamage = std::min<int32_t>(target->getMana(), healthChange);
- if (manaDamage != 0) {
- if (damage.origin != ORIGIN_NONE) {
- @@ -4087,7 +3983,7 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, int32_t manaCh
- }
- int32_t manaLoss = std::min<int32_t>(target->getMana(), -manaChange);
- - BlockType_t blockType = target->blockHit(attacker, COMBAT_MANADRAIN, manaLoss);
- + BlockType_t blockType = target->blockHit(attacker, COMBAT_NONE, manaLoss);
- if (blockType != BLOCK_NONE) {
- addMagicEffect(targetPos, CONST_ME_POFF);
- return false;
- diff --git a/forgottenserver-1.2/src/game.h b/forgottenserver-1.2/src/game.h
- index 06e4f21..8050020 100644
- --- a/forgottenserver-1.2/src/game.h
- +++ b/forgottenserver-1.2/src/game.h
- @@ -435,7 +435,7 @@ class Game
- void checkCreatures(size_t index);
- void checkLight();
- - bool combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field);
- + bool combatBlockHit(CombatDamage& damage, Creature* attacker, Creature* target, bool checkDefense, bool checkArmor, bool field, CombatSpellType_t spellType = COMBATSPELL_NONE);
- void combatGetTypeInfo(CombatType_t combatType, Creature* target, TextColor_t& color, uint8_t& effect);
- diff --git a/forgottenserver-1.2/src/items.cpp b/forgottenserver-1.2/src/items.cpp
- index 37a1201..790f037 100644
- --- a/forgottenserver-1.2/src/items.cpp
- +++ b/forgottenserver-1.2/src/items.cpp
- @@ -376,6 +376,8 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
- continue;
- }
- +
- + //Todo: Arrumar fields
- std::string tmpStrValue = asLowerCaseString(keyAttribute.as_string());
- if (tmpStrValue == "type") {
- tmpStrValue = asLowerCaseString(valueAttribute.as_string());
- @@ -657,11 +659,11 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
- } else if (tmpStrValue == "magicpointspercent") {
- it.getAbilities().statsPercent[STAT_MAGICPOINTS] = pugi::cast<int32_t>(valueAttribute.value());
- } else if (tmpStrValue == "fieldabsorbpercentenergy") {
- - it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "fieldabsorbpercentfire") {
- it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "fieldabsorbpercentpoison" || tmpStrValue == "fieldabsorpercentearth") {
- - it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().fieldAbsorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentall" || tmpStrValue == "absorbpercentallelements") {
- int16_t value = pugi::cast<int16_t>(valueAttribute.value());
- Abilities& abilities = it.getAbilities();
- @@ -671,43 +673,43 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
- } else if (tmpStrValue == "absorbpercentelements") {
- int16_t value = pugi::cast<int16_t>(valueAttribute.value());
- Abilities& abilities = it.getAbilities();
- - abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
- + //abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
- abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
- - abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
- + //abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
- abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value;
- } else if (tmpStrValue == "absorbpercentmagic") {
- int16_t value = pugi::cast<int16_t>(valueAttribute.value());
- Abilities& abilities = it.getAbilities();
- - abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
- + //abilities.absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += value;
- abilities.absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += value;
- - abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
- + //abilities.absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += value;
- abilities.absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += value;
- - abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value;
- - abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value;
- + //abilities.absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += value;
- + //abilities.absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += value;
- } else if (tmpStrValue == "absorbpercentenergy") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ENERGYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentfire") {
- it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_FIREDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentpoison" || tmpStrValue == "absorbpercentearth") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_EARTHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentice") {
- it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_ICEDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentholy") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HOLYDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentdeath") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DEATHDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentlifedrain") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_LIFEDRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentmanadrain") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_MANADRAIN)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentdrown") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentphysical") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_PHYSICALDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercenthealing") {
- it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_HEALING)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "absorbpercentundefined") {
- - it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- + //it.getAbilities().absorbPercent[combatTypeToIndex(COMBAT_UNDEFINEDDAMAGE)] += pugi::cast<int16_t>(valueAttribute.value());
- } else if (tmpStrValue == "suppressdrunk") {
- if (valueAttribute.as_bool()) {
- it.getAbilities().conditionSuppressions |= CONDITION_DRUNK;
- @@ -757,16 +759,16 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
- combatType = COMBAT_FIREDAMAGE;
- } else if (tmpStrValue == "energy") {
- conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_ENERGY);
- - combatType = COMBAT_ENERGYDAMAGE;
- + combatType = COMBAT_FIREDAMAGE;
- } else if (tmpStrValue == "poison") {
- conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_POISON);
- - combatType = COMBAT_EARTHDAMAGE;
- + combatType = COMBAT_FIREDAMAGE;
- } else if (tmpStrValue == "drown") {
- conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_DROWN);
- - combatType = COMBAT_DROWNDAMAGE;
- + combatType = COMBAT_FIREDAMAGE;
- } else if (tmpStrValue == "physical") {
- conditionDamage = new ConditionDamage(CONDITIONID_COMBAT, CONDITION_BLEEDING);
- - combatType = COMBAT_PHYSICALDAMAGE;
- + combatType = COMBAT_FIREDAMAGE;
- } else {
- std::cout << "[Warning - Items::parseItemNode] Unknown field value: " << valueAttribute.as_string() << std::endl;
- }
- @@ -860,7 +862,7 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
- } else if (tmpStrValue == "elementearth") {
- Abilities& abilities = it.getAbilities();
- abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
- - abilities.elementType = COMBAT_EARTHDAMAGE;
- + abilities.elementType = COMBAT_FIREDAMAGE;
- } else if (tmpStrValue == "elementfire") {
- Abilities& abilities = it.getAbilities();
- abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
- @@ -868,7 +870,7 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id)
- } else if (tmpStrValue == "elementenergy") {
- Abilities& abilities = it.getAbilities();
- abilities.elementDamage = pugi::cast<uint16_t>(valueAttribute.value());
- - abilities.elementType = COMBAT_ENERGYDAMAGE;
- + abilities.elementType = COMBAT_FIREDAMAGE;
- } else if (tmpStrValue == "walkstack") {
- it.walkStack = valueAttribute.as_bool();
- } else if (tmpStrValue == "blocking") {
- diff --git a/forgottenserver-1.2/src/luascript.cpp b/forgottenserver-1.2/src/luascript.cpp
- index 351e19a..542dd0e 100644
- --- a/forgottenserver-1.2/src/luascript.cpp
- +++ b/forgottenserver-1.2/src/luascript.cpp
- @@ -1058,6 +1058,7 @@ void LuaScriptInterface::registerFunctions()
- registerEnum(CALLBACK_PARAM_SKILLVALUE)
- registerEnum(CALLBACK_PARAM_TARGETTILE)
- registerEnum(CALLBACK_PARAM_TARGETCREATURE)
- + registerEnum(CALLBACK_PARAM_MONSTER)
- registerEnum(COMBAT_FORMULA_UNDEFINED)
- registerEnum(COMBAT_FORMULA_LEVELMAGIC)
- @@ -1074,18 +1075,25 @@ void LuaScriptInterface::registerFunctions()
- registerEnum(DIRECTION_NORTHEAST)
- registerEnum(COMBAT_NONE)
- - registerEnum(COMBAT_PHYSICALDAMAGE)
- - registerEnum(COMBAT_ENERGYDAMAGE)
- - registerEnum(COMBAT_EARTHDAMAGE)
- + registerEnum(COMBAT_BUGDAMAGE)
- + registerEnum(COMBAT_DRAGONDAMAGE)
- + registerEnum(COMBAT_FAIRYDAMAGE)
- registerEnum(COMBAT_FIREDAMAGE)
- - registerEnum(COMBAT_UNDEFINEDDAMAGE)
- - registerEnum(COMBAT_LIFEDRAIN)
- - registerEnum(COMBAT_MANADRAIN)
- - registerEnum(COMBAT_HEALING)
- - registerEnum(COMBAT_DROWNDAMAGE)
- + registerEnum(COMBAT_GHOSTDAMAGE)
- + registerEnum(COMBAT_GROUNDDAMAGE)
- + registerEnum(COMBAT_NORMALDAMAGE)
- + registerEnum(COMBAT_PSYCHICDAMAGE)
- + registerEnum(COMBAT_STEELDAMAGE)
- + registerEnum(COMBAT_DARKDAMAGE)
- + registerEnum(COMBAT_ELECTRICDAMAGE)
- + registerEnum(COMBAT_FIGHTINGDAMAGE)
- + registerEnum(COMBAT_FLYINGDAMAGE)
- + registerEnum(COMBAT_GRASSDAMAGE)
- registerEnum(COMBAT_ICEDAMAGE)
- - registerEnum(COMBAT_HOLYDAMAGE)
- - registerEnum(COMBAT_DEATHDAMAGE)
- + registerEnum(COMBAT_POISONDAMAGE)
- + registerEnum(COMBAT_ROCKDAMAGE)
- + registerEnum(COMBAT_WATERDAMAGE)
- + registerEnum(COMBAT_HEALING)
- registerEnum(COMBAT_PARAM_TYPE)
- registerEnum(COMBAT_PARAM_EFFECT)
- @@ -1128,6 +1136,25 @@ void LuaScriptInterface::registerFunctions()
- registerEnum(CONDITION_SPELLCOOLDOWN)
- registerEnum(CONDITION_SPELLGROUPCOOLDOWN)
- + registerEnum(CONDITION_BUG)
- + registerEnum(CONDITION_DRAGON)
- + registerEnum(CONDITION_FAIRY)
- + registerEnum(CONDITION_FIRE)
- + registerEnum(CONDITION_GHOST)
- + registerEnum(CONDITION_GROUND)
- + registerEnum(CONDITION_NORMAL)
- + registerEnum(CONDITION_PSYCHIC)
- + registerEnum(CONDITION_STEEL)
- + registerEnum(CONDITION_DARK)
- + registerEnum(CONDITION_ELECTRIC)
- + registerEnum(CONDITION_FIGHTING)
- + registerEnum(CONDITION_FLYING)
- + registerEnum(CONDITION_GRASS)
- + registerEnum(CONDITION_ICE)
- + registerEnum(CONDITION_POISON)
- + registerEnum(CONDITION_ROCK)
- + registerEnum(CONDITION_WATER)
- +
- registerEnum(CONDITIONID_DEFAULT)
- registerEnum(CONDITIONID_COMBAT)
- registerEnum(CONDITIONID_HEAD)
- @@ -2280,6 +2307,7 @@ void LuaScriptInterface::registerFunctions()
- registerMetaMethod("Monster", "__eq", LuaScriptInterface::luaUserdataCompare);
- registerMethod("Monster", "isMonster", LuaScriptInterface::luaMonsterIsMonster);
- + registerMethod("Monster", "castSpell", LuaScriptInterface::luaMonsterCastSpell);
- registerMethod("Monster", "getType", LuaScriptInterface::luaMonsterGetType);
- @@ -3167,7 +3195,7 @@ int LuaScriptInterface::luaDoAreaCombatMana(lua_State* L)
- CombatDamage damage;
- damage.origin = getNumber<CombatOrigin>(L, 7, ORIGIN_SPELL);
- - damage.primary.type = COMBAT_MANADRAIN;
- + damage.primary.type = COMBAT_NONE;
- damage.primary.value = normal_random(getNumber<int32_t>(L, 4), getNumber<int32_t>(L, 5));
- Position pos = getPosition(L, 2);
- @@ -3202,7 +3230,7 @@ int LuaScriptInterface::luaDoTargetCombatMana(lua_State* L)
- CombatDamage damage;
- damage.origin = getNumber<CombatOrigin>(L, 6, ORIGIN_SPELL);
- - damage.primary.type = COMBAT_MANADRAIN;
- + damage.primary.type = COMBAT_NONE;
- damage.primary.value = normal_random(getNumber<int32_t>(L, 3), getNumber<int32_t>(L, 4));
- Combat::doCombatMana(creature, target, damage, params);
- @@ -7246,12 +7274,13 @@ int LuaScriptInterface::luaCreatureAddHealth(lua_State* L)
- if (damage.primary.value >= 0) {
- damage.primary.type = COMBAT_HEALING;
- } else {
- - damage.primary.type = COMBAT_UNDEFINEDDAMAGE;
- + damage.primary.type = COMBAT_NONE;
- }
- pushBoolean(L, g_game.combatChangeHealth(nullptr, creature, damage));
- return 1;
- }
- +
- int LuaScriptInterface::luaCreatureGetMaxHealth(lua_State* L)
- {
- // creature:getMaxHealth()
- @@ -9522,6 +9551,18 @@ int LuaScriptInterface::luaMonsterIsMonster(lua_State* L)
- return 1;
- }
- +int LuaScriptInterface::luaMonsterCastSpell(lua_State* L)
- +{
- + // monster:castSpell(word)
- + Monster* monster = getUserdata<Monster>(L, 1);
- + if (monster) {
- + std::string word = getString(L, 2);
- + monster->castSpell(word);
- + }
- +
- + return 1;
- +}
- +
- int LuaScriptInterface::luaMonsterGetType(lua_State* L)
- {
- // monster:getType()
- @@ -9902,7 +9943,7 @@ int LuaScriptInterface::luaMonsterGetSpecialAttack(lua_State* L)
- // monster:getSpecialAttack()
- Monster* monster = getUserdata<Monster>(L, 1);
- if (monster) {
- - lua_pushnumber(L, monster->getStatus().getSpeciaAttack());
- + lua_pushnumber(L, monster->getStatus().getSpecialAttack());
- }
- else {
- lua_pushnumber(L, 0);
- @@ -11939,7 +11980,7 @@ int LuaScriptInterface::luaMonsterTypeGetAttackList(lua_State* L)
- setField(L, "minCombatValue", spellBlock.minCombatValue);
- setField(L, "maxCombatValue", spellBlock.maxCombatValue);
- setField(L, "range", spellBlock.range);
- - setField(L, "speed", spellBlock.speed);
- + setField(L, "speed", spellBlock.cooldown);
- pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
- lua_setfield(L, -2, "spell");
- @@ -11957,11 +11998,11 @@ int LuaScriptInterface::luaMonsterTypeGetDefenseList(lua_State* L)
- return 1;
- }
- - lua_createtable(L, monsterType->info.defenseSpells.size(), 0);
- + lua_createtable(L, monsterType->info.passiveSpells.size(), 0);
- int index = 0;
- - for (const auto& spellBlock : monsterType->info.defenseSpells) {
- + for (const auto& spellBlock : monsterType->info.passiveSpells) {
- lua_createtable(L, 0, 8);
- setField(L, "chance", spellBlock.chance);
- @@ -11970,7 +12011,7 @@ int LuaScriptInterface::luaMonsterTypeGetDefenseList(lua_State* L)
- setField(L, "minCombatValue", spellBlock.minCombatValue);
- setField(L, "maxCombatValue", spellBlock.maxCombatValue);
- setField(L, "range", spellBlock.range);
- - setField(L, "speed", spellBlock.speed);
- + setField(L, "speed", spellBlock.cooldown);
- pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
- lua_setfield(L, -2, "spell");
- diff --git a/forgottenserver-1.2/src/monster.cpp b/forgottenserver-1.2/src/monster.cpp
- index 5272fac..c698753 100644
- --- a/forgottenserver-1.2/src/monster.cpp
- +++ b/forgottenserver-1.2/src/monster.cpp
- @@ -64,6 +64,15 @@ Monster::Monster(MonsterType* mtype) :
- // Adiciona a experiencia ao pokemon com base no level gerado
- experience = getExpForLevel(level);
- + // Adicona as magias no pokemon
- + for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
- + attackSpells.push_back(MonsterSpell(spellBlock));
- + }
- +
- + for (const spellBlock_t& spellBlock : mType->info.passiveSpells) {
- + passiveSpells.push_back(MonsterSpell(spellBlock));
- + }
- +
- defaultOutfit = mType->info.outfit;
- currentOutfit = mType->info.outfit;
- skull = mType->info.skull;
- @@ -104,6 +113,58 @@ bool Monster::canSee(const Position& pos) const
- return Creature::canSee(getPosition(), pos, 9, 9);
- }
- +//Todo: Talvez trocar os returns
- +void Monster::castSpell(std::string word)
- +{
- + for (MonsterSpell& spell : attackSpells) {
- + const spellBlock_t& spellBlock = *spell.spellBlock;
- + if (spellBlock.word != word) {
- + continue;
- + }
- +
- + int64_t castTime = OTSYS_TIME();
- +
- + Player* playerMaster = getMaster()->getPlayer();
- + if (level < spellBlock.level) {
- + if (playerMaster)
- + playerMaster->sendCancelMessage("Your Summon dont have level to cast this spell.");
- + return;
- + } else if ((castTime - spell.lastCooldown) < spellBlock.cooldown) {
- + if (playerMaster) {
- + std::stringstream msg;
- + msg << "This spell is in cooldown (" << ((spellBlock.cooldown - (castTime - spell.lastCooldown)) / 1000) << " sec).";
- + playerMaster->sendCancelMessage(msg.str());
- + }
- + return;
- + }
- +
- + bool needTarget = spellBlock.spell->getNeedTarget();
- + if (needTarget && (!attackedCreature || attackedCreature == this)) {
- + if (playerMaster)
- + playerMaster->sendCancelMessage("You need a target to cast this spell.");
- + return;
- + }
- +
- + updateLookDirection();
- +
- + if (needTarget)
- + spellBlock.spell->castSpell(this, attackedCreature);
- + else
- + spellBlock.spell->castSpell(this);
- +
- + const std::string& spellName = spellBlock.spell->getName();
- + if (spellName.size() > 0) {
- + g_game.internalCreatureSay(this, TALKTYPE_MONSTER_YELL, spellName, false);
- +
- + if (playerMaster)
- + g_game.internalCreatureSay(playerMaster, TALKTYPE_MONSTER_YELL, getName() + " use " + spellName + "!", false);
- + }
- +
- + spell.lastCooldown = castTime;
- + return;
- + }
- +}
- +
- void Monster::onAttackedCreatureDisappear(bool)
- {
- attackTicks = 0;
- @@ -588,7 +649,7 @@ void Monster::onFollowCreatureComplete(const Creature* creature)
- }
- BlockType_t Monster::blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
- - bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool /* field = false */)
- + bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool /* field = false */, CombatSpellType_t spellType)
- {
- BlockType_t blockType = Creature::blockHit(attacker, combatType, damage, checkDefense, checkArmor);
- @@ -600,11 +661,16 @@ BlockType_t Monster::blockHit(Creature* attacker, CombatType_t combatType, int32
- }
- if (elementMod != 0) {
- - damage = static_cast<int32_t>(std::round(damage * ((100 - elementMod) / 100.)));
- - if (damage <= 0) {
- - damage = 0;
- - blockType = BLOCK_ARMOR;
- - }
- + damage = static_cast<int32_t>(std::ceil(damage * ((100 - elementMod) / 100.)));
- + }
- +
- + if (spellType == COMBATSPELL_ATTACK) {
- + blockType = BLOCK_DEFENSE;
- + damage -= status.getDefense();
- + }
- + else if (spellType == COMBATSPELL_SPECIALATTACK) {
- + blockType = BLOCK_SPECIALDEFENSE;
- + damage -= status.getSpecialDefense();
- }
- }
- @@ -758,7 +824,7 @@ void Monster::onThink(uint32_t interval)
- onThinkTarget(interval);
- onThinkYell(interval);
- - onThinkDefense(interval);
- + onThinkPassive(interval);
- }
- }
- }
- @@ -769,94 +835,89 @@ void Monster::doAttacking(uint32_t interval)
- return;
- }
- - bool updateLook = true;
- - bool resetTicks = interval != 0;
- - attackTicks += interval;
- + if (!isSummon()) {
- + const Position& myPos = getPosition();
- + const Position& targetPos = attackedCreature->getPosition();
- - const Position& myPos = getPosition();
- - const Position& targetPos = attackedCreature->getPosition();
- + for (MonsterSpell& spell : attackSpells) {
- + tryToUseSpell(myPos, targetPos, spell);
- + }
- + }
- +}
- - for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
- - bool inRange = false;
- +bool Monster::tryToUseSpell(const Position& myPos, const Position& targetPos, MonsterSpell& spell) {
- - if (canUseSpell(myPos, targetPos, spellBlock, interval, inRange, resetTicks)) {
- - if (spellBlock.chance >= static_cast<uint32_t>(uniform_random(1, 100))) {
- - if (updateLook) {
- - updateLookDirection();
- - updateLook = false;
- - }
- + const spellBlock_t& spellBlock = *spell.spellBlock;
- +
- + bool inRange = true;
- + if (!canUseSpell(myPos, targetPos, spell, inRange))
- + return false;
- - minCombatValue = spellBlock.minCombatValue;
- - maxCombatValue = spellBlock.maxCombatValue;
- - spellBlock.spell->castSpell(this, attackedCreature);
- + if (!inRange)
- + return false;
- - if (spellBlock.isMelee) {
- - extraMeleeAttack = false;
- - }
- - }
- - }
- + if (spellBlock.chance < static_cast<uint32_t>(uniform_random(1, 100)))
- + return false;
- - if (!inRange && spellBlock.isMelee) {
- - //melee swing out of reach
- - extraMeleeAttack = true;
- - }
- - }
- + updateLookDirection();
- - if (updateLook) {
- - updateLookDirection();
- - }
- + if (spellBlock.spell) {
- + spellBlock.spell->castSpell(this, attackedCreature);
- +
- + const std::string& spellName = spellBlock.spell->getName();
- + if (spellName.size() > 0)
- + g_game.internalCreatureSay(this, TALKTYPE_MONSTER_YELL, spellName, false);
- - if (resetTicks) {
- - attackTicks = 0;
- + spell.lastCooldown = OTSYS_TIME();
- }
- +
- + return true;
- }
- bool Monster::canUseAttack(const Position& pos, const Creature* target) const
- {
- - if (isHostile()) {
- - const Position& targetPos = target->getPosition();
- - uint32_t distance = std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos));
- - for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
- - if (spellBlock.range != 0 && distance <= spellBlock.range) {
- - return g_game.isSightClear(pos, targetPos, true);
- - }
- + if (!isHostile())
- + return true;
- +
- + const Position& targetPos = target->getPosition();
- + uint32_t distance = std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos));
- +
- + for (const MonsterSpell& spell : attackSpells) {
- +
- + const spellBlock_t& spellBlock = *spell.spellBlock;
- + if (level < spellBlock.level) {
- + continue;
- + }
- + else if ((OTSYS_TIME() - spell.lastCooldown) < spellBlock.cooldown) {
- + continue;
- + }
- +
- + if (spellBlock.range != 0 && distance <= spellBlock.range) {
- + return g_game.isSightClear(pos, targetPos, true);
- }
- - return false;
- }
- - return true;
- +
- + return false;
- }
- -bool Monster::canUseSpell(const Position& pos, const Position& targetPos,
- - const spellBlock_t& sb, uint32_t interval, bool& inRange, bool& resetTicks)
- +bool Monster::canUseSpell(const Position& pos, const Position& targetPos, const MonsterSpell& spell, bool& inRange)
- {
- - inRange = true;
- + const spellBlock_t& sb = *spell.spellBlock;
- if (sb.isMelee && isFleeing()) {
- return false;
- }
- -
- - if (extraMeleeAttack) {
- - lastMeleeAttack = OTSYS_TIME();
- - } else if (sb.isMelee && (OTSYS_TIME() - lastMeleeAttack) < 1500) {
- + else if (level < sb.level) {
- return false;
- }
- -
- - if (!sb.isMelee || !extraMeleeAttack) {
- - if (sb.speed > attackTicks) {
- - resetTicks = false;
- - return false;
- - }
- -
- - if (attackTicks % sb.speed >= interval) {
- - //already used this spell for this round
- - return false;
- - }
- + else if ((OTSYS_TIME() - spell.lastCooldown) < sb.cooldown) {
- + return false;
- }
- -
- - if (sb.range != 0 && std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos)) > sb.range) {
- + else if (sb.range != 0 && std::max<uint32_t>(Position::getDistanceX(pos, targetPos), Position::getDistanceY(pos, targetPos)) > sb.range) {
- inRange = false;
- return false;
- }
- +
- return true;
- }
- @@ -897,78 +958,16 @@ void Monster::onThinkTarget(uint32_t interval)
- }
- }
- -void Monster::onThinkDefense(uint32_t interval)
- +void Monster::onThinkPassive(uint32_t interval)
- {
- - bool resetTicks = true;
- - defenseTicks += interval;
- -
- - for (const spellBlock_t& spellBlock : mType->info.defenseSpells) {
- - if (spellBlock.speed > defenseTicks) {
- - resetTicks = false;
- - continue;
- - }
- -
- - if (defenseTicks % spellBlock.speed >= interval) {
- - //already used this spell for this round
- - continue;
- - }
- -
- - if ((spellBlock.chance >= static_cast<uint32_t>(uniform_random(1, 100)))) {
- - minCombatValue = spellBlock.minCombatValue;
- - maxCombatValue = spellBlock.maxCombatValue;
- - spellBlock.spell->castSpell(this, this);
- - }
- - }
- -
- - if (!isSummon() && summons.size() < mType->info.maxSummons && hasFollowPath) {
- - for (const summonBlock_t& summonBlock : mType->info.summons) {
- - if (summonBlock.speed > defenseTicks) {
- - resetTicks = false;
- - continue;
- - }
- -
- - if (summons.size() >= mType->info.maxSummons) {
- - continue;
- - }
- -
- - if (defenseTicks % summonBlock.speed >= interval) {
- - //already used this spell for this round
- - continue;
- - }
- -
- - uint32_t summonCount = 0;
- - for (Creature* summon : summons) {
- - if (summon->getName() == summonBlock.name) {
- - ++summonCount;
- - }
- - }
- -
- - if (summonCount >= summonBlock.max) {
- - continue;
- - }
- -
- - if (summonBlock.chance < static_cast<uint32_t>(uniform_random(1, 100))) {
- - continue;
- - }
- -
- - Monster* summon = Monster::createMonster(summonBlock.name);
- - if (summon) {
- - const Position& summonPos = getPosition();
- -
- - addSummon(summon);
- + if ((attackedCreature && attackedCreature == this) || !attackedCreature)
- + return;
- - if (!g_game.placeCreature(summon, summonPos, false, summonBlock.force)) {
- - removeSummon(summon);
- - } else {
- - g_game.addMagicEffect(getPosition(), CONST_ME_MAGIC_BLUE);
- - g_game.addMagicEffect(summon->getPosition(), CONST_ME_TELEPORT);
- - }
- - }
- - }
- - }
- + const Position& myPos = getPosition();
- + const Position& targetPos = attackedCreature->getPosition();
- - if (resetTicks) {
- - defenseTicks = 0;
- + for (MonsterSpell& spell : passiveSpells) {
- + tryToUseSpell(myPos, targetPos, spell);
- }
- }
- diff --git a/forgottenserver-1.2/src/monster.h b/forgottenserver-1.2/src/monster.h
- index e22971b..feef705 100644
- --- a/forgottenserver-1.2/src/monster.h
- +++ b/forgottenserver-1.2/src/monster.h
- @@ -37,6 +37,17 @@ enum TargetSearchType_t {
- TARGETSEARCH_NEAREST,
- };
- +struct MonsterSpell {
- + MonsterSpell() {};
- + MonsterSpell(const spellBlock_t& spell) {
- + spellBlock = &spell;
- + }
- +
- + const spellBlock_t* spellBlock = nullptr;
- + int64_t lastCooldown = 0;
- +};
- +
- +
- class Monster final : public Creature
- {
- public:
- @@ -124,6 +135,8 @@ class Monster final : public Creature
- this->spawn = spawn;
- }
- + void castSpell(std::string word);
- +
- void onAttackedCreatureDisappear(bool isLogout) final;
- void onCreatureAppear(Creature* creature, bool isLogin) final;
- @@ -171,7 +184,7 @@ class Monster final : public Creature
- }
- BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
- - bool checkDefense = false, bool checkArmor = false, bool field = false);
- + bool checkDefense = false, bool checkArmor = false, bool field = false, CombatSpellType_t spellType = COMBATSPELL_NONE);
- uint64_t getExperience();
- void setExperience(uint64_t exp);
- @@ -217,6 +230,8 @@ class Monster final : public Creature
- PokemonStatus status;
- int64_t lastMeleeAttack = 0;
- + std::vector<MonsterSpell> attackSpells;
- + std::vector<MonsterSpell> passiveSpells;
- uint32_t attackTicks = 0;
- uint32_t targetTicks = 0;
- @@ -262,12 +277,11 @@ class Monster final : public Creature
- void onEndCondition(ConditionType_t type) final;
- void onCreatureConvinced(const Creature* convincer, const Creature* creature) final;
- + bool tryToUseSpell(const Position& myPos, const Position& targetPos, MonsterSpell& spell);
- bool canUseAttack(const Position& pos, const Creature* target) const;
- - bool canUseSpell(const Position& pos, const Position& targetPos,
- - const spellBlock_t& sb, uint32_t interval, bool& inRange, bool& resetTicks);
- + bool canUseSpell(const Position& pos, const Position& targetPos, const MonsterSpell& spell, bool& inRange);
- bool getRandomStep(const Position& creaturePos, Direction& direction) const;
- - bool getDanceStep(const Position& creaturePos, Direction& direction,
- - bool keepAttack = true, bool keepDistance = true);
- + bool getDanceStep(const Position& creaturePos, Direction& direction, bool keepAttack = true, bool keepDistance = true);
- bool isInSpawnRange(const Position& pos) const;
- bool canWalkTo(Position pos, Direction direction) const;
- @@ -278,7 +292,7 @@ class Monster final : public Creature
- void onThinkTarget(uint32_t interval);
- void onThinkYell(uint32_t interval);
- - void onThinkDefense(uint32_t interval);
- + void onThinkPassive(uint32_t interval);
- bool isFriend(const Creature* creature) const;
- bool isOpponent(const Creature* creature) const;
- diff --git a/forgottenserver-1.2/src/monsters.cpp b/forgottenserver-1.2/src/monsters.cpp
- index 960af30..206d9a8 100644
- --- a/forgottenserver-1.2/src/monsters.cpp
- +++ b/forgottenserver-1.2/src/monsters.cpp
- @@ -1,21 +1,21 @@
- /**
- - * The Forgotten Server - a free and open-source MMORPG server emulator
- - * Copyright (C) 2016 Mark Samman <mark.samman@gmail.com>
- - *
- - * This program is free software; you can redistribute it and/or modify
- - * it under the terms of the GNU General Public License as published by
- - * the Free Software Foundation; either version 2 of the License, or
- - * (at your option) any later version.
- - *
- - * This program is distributed in the hope that it will be useful,
- - * but WITHOUT ANY WARRANTY; without even the implied warranty of
- - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- - * GNU General Public License for more details.
- - *
- - * You should have received a copy of the GNU General Public License along
- - * with this program; if not, write to the Free Software Foundation, Inc.,
- - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- - */
- +* The Forgotten Server - a free and open-source MMORPG server emulator
- +* Copyright (C) 2016 Mark Samman <mark.samman@gmail.com>
- +*
- +* This program is free software; you can redistribute it and/or modify
- +* it under the terms of the GNU General Public License as published by
- +* the Free Software Foundation; either version 2 of the License, or
- +* (at your option) any later version.
- +*
- +* This program is distributed in the hope that it will be useful,
- +* but WITHOUT ANY WARRANTY; without even the implied warranty of
- +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- +* GNU General Public License for more details.
- +*
- +* You should have received a copy of the GNU General Public License along
- +* with this program; if not, write to the Free Software Foundation, Inc.,
- +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- +*/
- #include "otpch.h"
- @@ -214,7 +214,7 @@ bool Monsters::reload()
- }
- ConditionDamage* Monsters::getDamageCondition(ConditionType_t conditionType,
- - int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval)
- + int32_t maxDamage, int32_t minDamage, int32_t startDamage, uint32_t tickInterval)
- {
- ConditionDamage* condition = static_cast<ConditionDamage*>(Condition::createCondition(CONDITIONID_COMBAT, conditionType, 0, 0));
- condition->setParam(CONDITION_PARAM_TICKINTERVAL, tickInterval);
- @@ -242,8 +242,20 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
- return false;
- }
- - if ((attr = node.attribute("speed")) || (attr = node.attribute("interval"))) {
- - sb.speed = std::max<int32_t>(1, pugi::cast<int32_t>(attr.value()));
- + if (auto spell = g_spells->getSpellByName(name)) {
- + sb.spell = spell;
- + }
- +
- + if ((attr = node.attribute("cooldown"))) {
- + sb.cooldown = std::max<int32_t>(1, pugi::cast<int32_t>(attr.value()));
- + }
- +
- + if ((attr = node.attribute("word"))) {
- + sb.word = attr.as_string();
- + }
- +
- + if ((attr = node.attribute("level"))) {
- + sb.level = pugi::cast<uint32_t>(attr.value());
- }
- if ((attr = node.attribute("chance"))) {
- @@ -277,12 +289,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
- }
- }
- - if (auto spell = g_spells->getSpellByName(name)) {
- - sb.spell = spell;
- - return true;
- - }
- -
- - CombatSpell* combatSpell = nullptr;
- + /*CombatSpell* combatSpell = nullptr;
- bool needTarget = false;
- bool needDirection = false;
- @@ -307,6 +314,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
- combatSpell = combatSpellPtr.release();
- combatSpell->getCombat()->setPlayerCombatValues(COMBAT_FORMULA_DAMAGE, sb.minCombatValue, 0, sb.maxCombatValue, 0);
- } else {
- +
- Combat* combat = new Combat;
- if ((attr = node.attribute("length"))) {
- int32_t length = pugi::cast<int32_t>(attr.value());
- @@ -350,103 +358,12 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
- sb.maxCombatValue = -Weapons::getMaxMeleeDamage(pugi::cast<int32_t>(skillAttribute.value()), pugi::cast<int32_t>(attackAttribute.value()));
- }
- - ConditionType_t conditionType = CONDITION_NONE;
- - int32_t minDamage = 0;
- - int32_t maxDamage = 0;
- - uint32_t tickInterval = 2000;
- -
- - if ((attr = node.attribute("fire"))) {
- - conditionType = CONDITION_FIRE;
- -
- - minDamage = pugi::cast<int32_t>(attr.value());
- - maxDamage = minDamage;
- - tickInterval = 9000;
- - } else if ((attr = node.attribute("poison"))) {
- - conditionType = CONDITION_POISON;
- -
- - minDamage = pugi::cast<int32_t>(attr.value());
- - maxDamage = minDamage;
- - tickInterval = 5000;
- - } else if ((attr = node.attribute("energy"))) {
- - conditionType = CONDITION_ENERGY;
- -
- - minDamage = pugi::cast<int32_t>(attr.value());
- - maxDamage = minDamage;
- - tickInterval = 10000;
- - } else if ((attr = node.attribute("drown"))) {
- - conditionType = CONDITION_DROWN;
- -
- - minDamage = pugi::cast<int32_t>(attr.value());
- - maxDamage = minDamage;
- - tickInterval = 5000;
- - } else if ((attr = node.attribute("freeze"))) {
- - conditionType = CONDITION_FREEZING;
- -
- - minDamage = pugi::cast<int32_t>(attr.value());
- - maxDamage = minDamage;
- - tickInterval = 8000;
- - } else if ((attr = node.attribute("dazzle"))) {
- - conditionType = CONDITION_DAZZLED;
- -
- - minDamage = pugi::cast<int32_t>(attr.value());
- - maxDamage = minDamage;
- - tickInterval = 10000;
- - } else if ((attr = node.attribute("curse"))) {
- - conditionType = CONDITION_CURSED;
- -
- - minDamage = pugi::cast<int32_t>(attr.value());
- - maxDamage = minDamage;
- - tickInterval = 4000;
- - } else if ((attr = node.attribute("bleed")) || (attr = node.attribute("physical"))) {
- - conditionType = CONDITION_BLEEDING;
- - tickInterval = 5000;
- - }
- -
- - if ((attr = node.attribute("tick"))) {
- - int32_t value = pugi::cast<int32_t>(attr.value());
- - if (value > 0) {
- - tickInterval = value;
- - }
- - }
- -
- - if (conditionType != CONDITION_NONE) {
- - Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, 0, tickInterval);
- - combat->setCondition(condition);
- - }
- -
- sb.range = 1;
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE);
- - combat->setParam(COMBAT_PARAM_BLOCKARMOR, 1);
- - combat->setParam(COMBAT_PARAM_BLOCKSHIELD, 1);
- + //Todo: Editar o COmbat Type
- + combat->setParam(COMBAT_PARAM_TYPE, COMBAT_NONE);
- combat->setOrigin(ORIGIN_MELEE);
- - } else if (tmpName == "physical") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE);
- - combat->setParam(COMBAT_PARAM_BLOCKARMOR, 1);
- - combat->setOrigin(ORIGIN_RANGED);
- - } else if (tmpName == "bleed") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE);
- - } else if (tmpName == "poison" || tmpName == "earth") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE);
- - } else if (tmpName == "fire") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE);
- - } else if (tmpName == "energy") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE);
- - } else if (tmpName == "drown") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE);
- - } else if (tmpName == "ice") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE);
- - } else if (tmpName == "holy") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE);
- - } else if (tmpName == "death") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE);
- - } else if (tmpName == "lifedrain") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN);
- - } else if (tmpName == "manadrain") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_MANADRAIN);
- - } else if (tmpName == "healing") {
- - combat->setParam(COMBAT_PARAM_TYPE, COMBAT_HEALING);
- - combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0);
- - } else if (tmpName == "speed") {
- + }
- + else if (tmpName == "speed") {
- int32_t speedChange = 0;
- int32_t duration = 10000;
- @@ -473,115 +390,6 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
- ConditionSpeed* condition = static_cast<ConditionSpeed*>(Condition::createCondition(CONDITIONID_COMBAT, conditionType, duration, 0));
- condition->setFormulaVars(speedChange / 1000.0, 0, speedChange / 1000.0, 0);
- combat->setCondition(condition);
- - } else if (tmpName == "outfit") {
- - int32_t duration = 10000;
- -
- - if ((attr = node.attribute("duration"))) {
- - duration = pugi::cast<int32_t>(attr.value());
- - }
- -
- - if ((attr = node.attribute("monster"))) {
- - MonsterType* mType = g_monsters.getMonsterType(attr.as_string());
- - if (mType) {
- - ConditionOutfit* condition = static_cast<ConditionOutfit*>(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0));
- - condition->setOutfit(mType->info.outfit);
- - combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0);
- - combat->setCondition(condition);
- - }
- - } else if ((attr = node.attribute("item"))) {
- - Outfit_t outfit;
- - outfit.lookTypeEx = pugi::cast<uint16_t>(attr.value());
- -
- - ConditionOutfit* condition = static_cast<ConditionOutfit*>(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0));
- - condition->setOutfit(outfit);
- - combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0);
- - combat->setCondition(condition);
- - }
- - } else if (tmpName == "invisible") {
- - int32_t duration = 10000;
- -
- - if ((attr = node.attribute("duration"))) {
- - duration = pugi::cast<int32_t>(attr.value());
- - }
- -
- - Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0);
- - combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0);
- - combat->setCondition(condition);
- - } else if (tmpName == "drunk") {
- - int32_t duration = 10000;
- -
- - if ((attr = node.attribute("duration"))) {
- - duration = pugi::cast<int32_t>(attr.value());
- - }
- -
- - Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, 0);
- - combat->setCondition(condition);
- - } else if (tmpName == "firefield") {
- - combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL);
- - } else if (tmpName == "poisonfield") {
- - combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_POISONFIELD_PVP);
- - } else if (tmpName == "energyfield") {
- - combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_ENERGYFIELD_PVP);
- - } else if (tmpName == "firecondition" || tmpName == "energycondition" ||
- - tmpName == "earthcondition" || tmpName == "poisoncondition" ||
- - tmpName == "icecondition" || tmpName == "freezecondition" ||
- - tmpName == "deathcondition" || tmpName == "cursecondition" ||
- - tmpName == "holycondition" || tmpName == "dazzlecondition" ||
- - tmpName == "drowncondition" || tmpName == "bleedcondition" ||
- - tmpName == "physicalcondition") {
- - ConditionType_t conditionType = CONDITION_NONE;
- - uint32_t tickInterval = 2000;
- -
- - if (tmpName == "firecondition") {
- - conditionType = CONDITION_FIRE;
- - tickInterval = 10000;
- - } else if (tmpName == "poisoncondition" || tmpName == "earthcondition") {
- - conditionType = CONDITION_POISON;
- - tickInterval = 5000;
- - } else if (tmpName == "energycondition") {
- - conditionType = CONDITION_ENERGY;
- - tickInterval = 10000;
- - } else if (tmpName == "drowncondition") {
- - conditionType = CONDITION_DROWN;
- - tickInterval = 5000;
- - } else if (tmpName == "freezecondition" || tmpName == "icecondition") {
- - conditionType = CONDITION_FREEZING;
- - tickInterval = 10000;
- - } else if (tmpName == "cursecondition" || tmpName == "deathcondition") {
- - conditionType = CONDITION_CURSED;
- - tickInterval = 4000;
- - } else if (tmpName == "dazzlecondition" || tmpName == "holycondition") {
- - conditionType = CONDITION_DAZZLED;
- - tickInterval = 10000;
- - } else if (tmpName == "physicalcondition" || tmpName == "bleedcondition") {
- - conditionType = CONDITION_BLEEDING;
- - tickInterval = 5000;
- - }
- -
- - if ((attr = node.attribute("tick"))) {
- - int32_t value = pugi::cast<int32_t>(attr.value());
- - if (value > 0) {
- - tickInterval = value;
- - }
- - }
- -
- - int32_t minDamage = std::abs(sb.minCombatValue);
- - int32_t maxDamage = std::abs(sb.maxCombatValue);
- - int32_t startDamage = 0;
- -
- - if ((attr = node.attribute("start"))) {
- - int32_t value = std::abs(pugi::cast<int32_t>(attr.value()));
- - if (value <= minDamage) {
- - startDamage = value;
- - }
- - }
- -
- - Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval);
- - combat->setCondition(condition);
- - } else if (tmpName == "strength") {
- - //
- - } else if (tmpName == "effect") {
- - //
- } else {
- std::cout << "[Error - Monsters::deserializeSpell] - " << description << " - Unknown spell name: " << name << std::endl;
- delete combat;
- @@ -608,7 +416,8 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
- MagicEffectClasses effect = getMagicEffect(attr.as_string());
- if (effect != CONST_ME_NONE) {
- combat->setParam(COMBAT_PARAM_EFFECT, effect);
- - } else {
- + }
- + else {
- std::cout << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown areaEffect: " << attr.as_string() << std::endl;
- }
- }
- @@ -622,7 +431,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co
- sb.spell = combatSpell;
- if (combatSpell) {
- sb.combatSpell = true;
- - }
- + }*/
- return true;
- }
- @@ -824,7 +633,7 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
- mType->info.lookcorpse = pugi::cast<uint16_t>(attr.value());
- }
- }
- -
- +
- if ((node = monsterNode.child("level"))) {
- if ((attr = node.attribute("min"))) {
- mType->info.spawnLevel.min = pugi::cast<uint32_t>(attr.value());
- @@ -928,21 +737,13 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
- }
- }
- - if ((node = monsterNode.child("defenses"))) {
- - if ((attr = node.attribute("defense"))) {
- - mType->info.defense = pugi::cast<int32_t>(attr.value());
- - }
- -
- - if ((attr = node.attribute("armor"))) {
- - mType->info.armor = pugi::cast<int32_t>(attr.value());
- - }
- -
- - for (auto defenseNode : node.children()) {
- + if ((node = monsterNode.child("passives"))) {
- + for (auto passiveNode : node.children()) {
- spellBlock_t sb;
- - if (deserializeSpell(defenseNode, sb, monsterName)) {
- - mType->info.defenseSpells.emplace_back(std::move(sb));
- + if (deserializeSpell(passiveNode, sb, monsterName)) {
- + mType->info.passiveSpells.emplace_back(std::move(sb));
- } else {
- - std::cout << "[Warning - Monsters::loadMonster] Cant load spell. " << file << std::endl;
- + std::cout << "[Warning - Monsters::loadMonster] Cant load passive spell. " << file << std::endl;
- }
- }
- }
- @@ -951,116 +752,48 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
- for (auto immunityNode : node.children()) {
- if ((attr = immunityNode.attribute("name"))) {
- std::string tmpStrValue = asLowerCaseString(attr.as_string());
- - if (tmpStrValue == "physical") {
- - mType->info.damageImmunities |= COMBAT_PHYSICALDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_BLEEDING;
- + /*if (tmpStrValue == "physical") {
- + mType->info.damageImmunities |= COMBAT_PHYSICALDAMAGE;
- + mType->info.conditionImmunities |= CONDITION_BLEEDING;
- } else if (tmpStrValue == "energy") {
- - mType->info.damageImmunities |= COMBAT_ENERGYDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_ENERGY;
- + mType->info.damageImmunities |= COMBAT_ENERGYDAMAGE;
- + mType->info.conditionImmunities |= CONDITION_ENERGY;
- } else if (tmpStrValue == "fire") {
- - mType->info.damageImmunities |= COMBAT_FIREDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_FIRE;
- + mType->info.damageImmunities |= COMBAT_FIREDAMAGE;
- + mType->info.conditionImmunities |= CONDITION_FIRE;
- } else if (tmpStrValue == "poison" ||
- - tmpStrValue == "earth") {
- - mType->info.damageImmunities |= COMBAT_EARTHDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_POISON;
- + tmpStrValue == "earth") {
- + mType->info.damageImmunities |= COMBAT_EARTHDAMAGE;
- + mType->info.conditionImmunities |= CONDITION_POISON;
- } else if (tmpStrValue == "drown") {
- - mType->info.damageImmunities |= COMBAT_DROWNDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_DROWN;
- + mType->info.damageImmunities |= COMBAT_DROWNDAMAGE;
- + mType->info.conditionImmunities |= CONDITION_DROWN;
- } else if (tmpStrValue == "ice") {
- - mType->info.damageImmunities |= COMBAT_ICEDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_FREEZING;
- + mType->info.damageImmunities |= COMBAT_ICEDAMAGE;
- + mType->info.conditionImmunities |= CONDITION_FREEZING;
- } else if (tmpStrValue == "holy") {
- - mType->info.damageImmunities |= COMBAT_HOLYDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_DAZZLED;
- + mType->info.damageImmunities |= COMBAT_HOLYDAMAGE;
- + mType->info.conditionImmunities |= CONDITION_DAZZLED;
- } else if (tmpStrValue == "death") {
- - mType->info.damageImmunities |= COMBAT_DEATHDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_CURSED;
- + mType->info.damageImmunities |= COMBAT_DEATHDAMAGE;
- + mType->info.conditionImmunities |= CONDITION_CURSED;
- } else if (tmpStrValue == "lifedrain") {
- - mType->info.damageImmunities |= COMBAT_LIFEDRAIN;
- + mType->info.damageImmunities |= COMBAT_LIFEDRAIN;
- } else if (tmpStrValue == "manadrain") {
- - mType->info.damageImmunities |= COMBAT_MANADRAIN;
- + mType->info.damageImmunities |= COMBAT_MANADRAIN;
- } else if (tmpStrValue == "paralyze") {
- - mType->info.conditionImmunities |= CONDITION_PARALYZE;
- + mType->info.conditionImmunities |= CONDITION_PARALYZE;
- } else if (tmpStrValue == "outfit") {
- - mType->info.conditionImmunities |= CONDITION_OUTFIT;
- + mType->info.conditionImmunities |= CONDITION_OUTFIT;
- } else if (tmpStrValue == "drunk") {
- - mType->info.conditionImmunities |= CONDITION_DRUNK;
- + mType->info.conditionImmunities |= CONDITION_DRUNK;
- } else if (tmpStrValue == "invisible" || tmpStrValue == "invisibility") {
- - mType->info.conditionImmunities |= CONDITION_INVISIBLE;
- + mType->info.conditionImmunities |= CONDITION_INVISIBLE;
- } else if (tmpStrValue == "bleed") {
- - mType->info.conditionImmunities |= CONDITION_BLEEDING;
- + mType->info.conditionImmunities |= CONDITION_BLEEDING;
- } else {
- - std::cout << "[Warning - Monsters::loadMonster] Unknown immunity name " << attr.as_string() << ". " << file << std::endl;
- - }
- - } else if ((attr = immunityNode.attribute("physical"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_PHYSICALDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_BLEEDING;
- - }
- - } else if ((attr = immunityNode.attribute("energy"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_ENERGYDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_ENERGY;
- - }
- - } else if ((attr = immunityNode.attribute("fire"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_FIREDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_FIRE;
- - }
- - } else if ((attr = immunityNode.attribute("poison")) || (attr = immunityNode.attribute("earth"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_EARTHDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_POISON;
- - }
- - } else if ((attr = immunityNode.attribute("drown"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_DROWNDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_DROWN;
- - }
- - } else if ((attr = immunityNode.attribute("ice"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_ICEDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_FREEZING;
- - }
- - } else if ((attr = immunityNode.attribute("holy"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_HOLYDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_DAZZLED;
- - }
- - } else if ((attr = immunityNode.attribute("death"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_DEATHDAMAGE;
- - mType->info.conditionImmunities |= CONDITION_CURSED;
- - }
- - } else if ((attr = immunityNode.attribute("lifedrain"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_LIFEDRAIN;
- - }
- - } else if ((attr = immunityNode.attribute("manadrain"))) {
- - if (attr.as_bool()) {
- - mType->info.damageImmunities |= COMBAT_MANADRAIN;
- - }
- - } else if ((attr = immunityNode.attribute("paralyze"))) {
- - if (attr.as_bool()) {
- - mType->info.conditionImmunities |= CONDITION_PARALYZE;
- - }
- - } else if ((attr = immunityNode.attribute("outfit"))) {
- - if (attr.as_bool()) {
- - mType->info.conditionImmunities |= CONDITION_OUTFIT;
- - }
- - } else if ((attr = immunityNode.attribute("bleed"))) {
- - if (attr.as_bool()) {
- - mType->info.conditionImmunities |= CONDITION_BLEEDING;
- - }
- - } else if ((attr = immunityNode.attribute("drunk"))) {
- - if (attr.as_bool()) {
- - mType->info.conditionImmunities |= CONDITION_DRUNK;
- - }
- - } else if ((attr = immunityNode.attribute("invisible")) || (attr = immunityNode.attribute("invisibility"))) {
- - if (attr.as_bool()) {
- - mType->info.conditionImmunities |= CONDITION_INVISIBLE;
- - }
- + std::cout << "[Warning - Monsters::loadMonster] Unknown immunity name " << attr.as_string() << ". " << file << std::endl;
- + }*/
- } else {
- std::cout << "[Warning - Monsters::loadMonster] Unknown immunity. " << file << std::endl;
- }
- @@ -1110,27 +843,61 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
- if ((node = monsterNode.child("elements"))) {
- for (auto elementNode : node.children()) {
- - if ((attr = elementNode.attribute("physicalPercent"))) {
- - mType->info.elementMap[COMBAT_PHYSICALDAMAGE] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("icePercent"))) {
- - mType->info.elementMap[COMBAT_ICEDAMAGE] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("poisonPercent")) || (attr = elementNode.attribute("earthPercent"))) {
- - mType->info.elementMap[COMBAT_EARTHDAMAGE] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("firePercent"))) {
- + if ((attr = elementNode.attribute("bugPercent"))) {
- + mType->info.elementMap[COMBAT_BUGDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("dragonPercent"))) {
- + mType->info.elementMap[COMBAT_DRAGONDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("fairyPercent"))) {
- + mType->info.elementMap[COMBAT_FAIRYDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("firePercent"))) {
- mType->info.elementMap[COMBAT_FIREDAMAGE] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("energyPercent"))) {
- - mType->info.elementMap[COMBAT_ENERGYDAMAGE] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("holyPercent"))) {
- - mType->info.elementMap[COMBAT_HOLYDAMAGE] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("deathPercent"))) {
- - mType->info.elementMap[COMBAT_DEATHDAMAGE] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("drownPercent"))) {
- - mType->info.elementMap[COMBAT_DROWNDAMAGE] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("lifedrainPercent"))) {
- - mType->info.elementMap[COMBAT_LIFEDRAIN] = pugi::cast<int32_t>(attr.value());
- - } else if ((attr = elementNode.attribute("manadrainPercent"))) {
- - mType->info.elementMap[COMBAT_MANADRAIN] = pugi::cast<int32_t>(attr.value());
- - } else {
- + }
- + else if ((attr = elementNode.attribute("ghostPercent"))) {
- + mType->info.elementMap[COMBAT_GHOSTDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("groundPercent"))) {
- + mType->info.elementMap[COMBAT_GROUNDDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("normalPercent"))) {
- + mType->info.elementMap[COMBAT_NORMALDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("psychicPercent"))) {
- + mType->info.elementMap[COMBAT_PSYCHICDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("steelPercent"))) {
- + mType->info.elementMap[COMBAT_STEELDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("darkPercent"))) {
- + mType->info.elementMap[COMBAT_DARKDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("electricPercent"))) {
- + mType->info.elementMap[COMBAT_ELECTRICDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("fightingPercent"))) {
- + mType->info.elementMap[COMBAT_FIGHTINGDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("flyingPercent"))) {
- + mType->info.elementMap[COMBAT_FLYINGDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("grassPercent"))) {
- + mType->info.elementMap[COMBAT_GRASSDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("icePercent"))) {
- + mType->info.elementMap[COMBAT_ICEDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("poisonPercent"))) {
- + mType->info.elementMap[COMBAT_POISONDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("rockPercent"))) {
- + mType->info.elementMap[COMBAT_ROCKDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else if ((attr = elementNode.attribute("waterPercent"))) {
- + mType->info.elementMap[COMBAT_WATERDAMAGE] = pugi::cast<int32_t>(attr.value());
- + }
- + else {
- std::cout << "[Warning - Monsters::loadMonster] Unknown element percent. " << file << std::endl;
- }
- }
- @@ -1192,7 +959,7 @@ bool Monsters::loadMonster(const std::string& file, const std::string& monsterNa
- mType->info.summons.shrink_to_fit();
- mType->info.lootItems.shrink_to_fit();
- mType->info.attackSpells.shrink_to_fit();
- - mType->info.defenseSpells.shrink_to_fit();
- + mType->info.passiveSpells.shrink_to_fit();
- mType->info.voiceVector.shrink_to_fit();
- mType->info.scripts.shrink_to_fit();
- return true;
- diff --git a/forgottenserver-1.2/src/monsters.h b/forgottenserver-1.2/src/monsters.h
- index 43357cf..3e7731e 100644
- --- a/forgottenserver-1.2/src/monsters.h
- +++ b/forgottenserver-1.2/src/monsters.h
- @@ -62,9 +62,11 @@ struct spellBlock_t {
- spellBlock_t(const spellBlock_t& other) = delete;
- spellBlock_t& operator=(const spellBlock_t& other) = delete;
- spellBlock_t(spellBlock_t&& other) :
- + word(other.word),
- + level(other.level),
- spell(other.spell),
- chance(other.chance),
- - speed(other.speed),
- + cooldown(other.cooldown),
- range(other.range),
- minCombatValue(other.minCombatValue),
- maxCombatValue(other.maxCombatValue),
- @@ -73,9 +75,11 @@ struct spellBlock_t {
- other.spell = nullptr;
- }
- + std::string word = "";
- + uint32_t level = 1;
- BaseSpell* spell = nullptr;
- uint32_t chance = 100;
- - uint32_t speed = 2000;
- + uint32_t cooldown = 2000;
- uint32_t range = 0;
- int32_t minCombatValue = 0;
- int32_t maxCombatValue = 0;
- @@ -105,17 +109,17 @@ class MonsterType
- std::vector<LootBlock> lootItems;
- std::vector<std::string> scripts;
- std::vector<spellBlock_t> attackSpells;
- - std::vector<spellBlock_t> defenseSpells;
- + std::vector<spellBlock_t> passiveSpells;
- std::vector<summonBlock_t> summons;
- Skulls_t skull = SKULL_NONE;
- Outfit_t outfit = {};
- RaceType_t race = RACE_BLOOD;
- - spawnLevel_t spawnLevel;
- + spawnLevel_t spawnLevel = {};
- - PokemonStatus baseStatus;
- - PokemonStatus statusPerLevel;
- + PokemonStatus baseStatus = {};
- + PokemonStatus statusPerLevel = {};
- LightInfo light = {};
- uint16_t lookcorpse = 0;
- @@ -141,7 +145,7 @@ class MonsterType
- int32_t runAwayHealth = 0;
- int32_t health = 100;
- int32_t healthMax = 100;
- - int32_t changeTargetChance =0;
- + int32_t changeTargetChance = 0;
- int32_t defense = 0;
- int32_t armor = 0;
- diff --git a/forgottenserver-1.2/src/player.cpp b/forgottenserver-1.2/src/player.cpp
- index 04ae2d5..492b6b0 100644
- --- a/forgottenserver-1.2/src/player.cpp
- +++ b/forgottenserver-1.2/src/player.cpp
- @@ -1780,8 +1780,7 @@ void Player::onAttackedCreatureBlockHit(BlockType_t blockType)
- break;
- }
- - case BLOCK_DEFENSE:
- - case BLOCK_ARMOR: {
- + case BLOCK_DEFENSE: {
- //need to draw blood every 30 hits
- if (bloodHitCount > 0) {
- addAttackSkillPoint = true;
- @@ -1814,7 +1813,7 @@ bool Player::hasShield() const
- }
- BlockType_t Player::blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
- - bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool field /* = false*/)
- + bool checkDefense /* = false*/, bool checkArmor /* = false*/, bool field /* = false*/, CombatSpellType_t spellType)
- {
- BlockType_t blockType = Creature::blockHit(attacker, combatType, damage, checkDefense, checkArmor, field);
- @@ -1865,7 +1864,7 @@ BlockType_t Player::blockHit(Creature* attacker, CombatType_t combatType, int32_
- if (damage <= 0) {
- damage = 0;
- - blockType = BLOCK_ARMOR;
- + blockType = BLOCK_DEFENSE;
- }
- }
- return blockType;
- diff --git a/forgottenserver-1.2/src/player.h b/forgottenserver-1.2/src/player.h
- index a9f346a..395d3cb 100644
- --- a/forgottenserver-1.2/src/player.h
- +++ b/forgottenserver-1.2/src/player.h
- @@ -603,7 +603,7 @@ class Player final : public Creature, public Cylinder
- return pzLocked;
- }
- BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
- - bool checkDefense = false, bool checkArmor = false, bool field = false) final;
- + bool checkDefense = false, bool checkArmor = false, bool field = false, CombatSpellType_t spellType = COMBATSPELL_NONE) final;
- void doAttacking(uint32_t interval) final;
- bool hasExtraSwing() final {
- return lastAttack > 0 && ((OTSYS_TIME() - lastAttack) >= getAttackSpeed());
- diff --git a/forgottenserver-1.2/src/spells.h b/forgottenserver-1.2/src/spells.h
- index 2aea3b3..abb553c 100644
- --- a/forgottenserver-1.2/src/spells.h
- +++ b/forgottenserver-1.2/src/spells.h
- @@ -82,6 +82,12 @@ class BaseSpell
- virtual bool castSpell(Creature* creature) = 0;
- virtual bool castSpell(Creature* creature, Creature* target) = 0;
- +
- + virtual bool getNeedTarget() {
- + return false;
- + }
- +
- + virtual const std::string& getName() const = 0;
- };
- class CombatSpell final : public Event, public BaseSpell
- @@ -100,6 +106,14 @@ class CombatSpell final : public Event, public BaseSpell
- return true;
- }
- + bool getNeedTarget() final {
- + return needTarget;
- + }
- +
- + const std::string& getName() const final {
- + return name;
- + }
- +
- //scripting
- bool executeCastSpell(Creature* creature, const LuaVariant& var);
- @@ -117,6 +131,7 @@ class CombatSpell final : public Event, public BaseSpell
- bool needDirection;
- bool needTarget;
- + std::string name = "";
- };
- class Spell : public BaseSpell
- @@ -125,7 +140,7 @@ class Spell : public BaseSpell
- Spell() = default;
- bool configureSpell(const pugi::xml_node& node);
- - const std::string& getName() const {
- + const std::string& getName() const final {
- return name;
- }
- @@ -154,6 +169,10 @@ class Spell : public BaseSpell
- return learnable;
- }
- + bool getNeedTarget() final {
- + return needTarget;
- + }
- +
- static ReturnValue CreateIllusion(Creature* creature, const Outfit_t& outfit, int32_t time);
- static ReturnValue CreateIllusion(Creature* creature, const std::string& name, int32_t time);
- static ReturnValue CreateIllusion(Creature* creature, uint32_t itemId, int32_t time);
- diff --git a/forgottenserver-1.2/src/tools.cpp b/forgottenserver-1.2/src/tools.cpp
- index 6c86d46..80f261d 100644
- --- a/forgottenserver-1.2/src/tools.cpp
- +++ b/forgottenserver-1.2/src/tools.cpp
- @@ -665,18 +665,24 @@ ShootTypeNames shootTypeNames[] = {
- };
- CombatTypeNames combatTypeNames[] = {
- - {"physical", COMBAT_PHYSICALDAMAGE},
- - {"energy", COMBAT_ENERGYDAMAGE},
- - {"earth", COMBAT_EARTHDAMAGE},
- - {"fire", COMBAT_FIREDAMAGE},
- - {"undefined", COMBAT_UNDEFINEDDAMAGE},
- - {"lifedrain", COMBAT_LIFEDRAIN},
- - {"manadrain", COMBAT_MANADRAIN},
- - {"healing", COMBAT_HEALING},
- - {"drown", COMBAT_DROWNDAMAGE},
- - {"ice", COMBAT_ICEDAMAGE},
- - {"holy", COMBAT_HOLYDAMAGE},
- - {"death", COMBAT_DEATHDAMAGE},
- + { "bug", COMBAT_BUGDAMAGE },
- + { "dragon", COMBAT_DRAGONDAMAGE },
- + { "fairy", COMBAT_FAIRYDAMAGE },
- + { "fire", COMBAT_FIREDAMAGE },
- + { "ghost", COMBAT_GHOSTDAMAGE },
- + { "ground", COMBAT_GROUNDDAMAGE },
- + { "normal", COMBAT_NORMALDAMAGE },
- + { "psychic", COMBAT_PSYCHICDAMAGE },
- + { "steel", COMBAT_STEELDAMAGE },
- + { "dark", COMBAT_DARKDAMAGE },
- + { "electric", COMBAT_ELECTRICDAMAGE },
- + { "fighthing", COMBAT_FIGHTINGDAMAGE },
- + { "flying", COMBAT_FLYINGDAMAGE },
- + { "grass", COMBAT_GRASSDAMAGE },
- + { "ice", COMBAT_ICEDAMAGE },
- + { "poison", COMBAT_POISONDAMAGE },
- + { "rock", COMBAT_ROCKDAMAGE },
- + { "water", COMBAT_WATERDAMAGE },
- };
- AmmoTypeNames ammoTypeNames[] = {
- @@ -905,7 +911,8 @@ std::string getWeaponName(WeaponType_t weaponType)
- size_t combatTypeToIndex(CombatType_t combatType)
- {
- - switch (combatType) {
- + //Todo: Arrumar Types
- + /*switch (combatType) {
- case COMBAT_PHYSICALDAMAGE:
- return 0;
- case COMBAT_ENERGYDAMAGE:
- @@ -932,7 +939,9 @@ size_t combatTypeToIndex(CombatType_t combatType)
- return 11;
- default:
- return 0;
- - }
- + }*/
- +
- + return 0;
- }
- CombatType_t indexToCombatType(size_t v)
- diff --git a/forgottenserver-1.2/src/weapons.cpp b/forgottenserver-1.2/src/weapons.cpp
- index f401112..badff1f 100644
- --- a/forgottenserver-1.2/src/weapons.cpp
- +++ b/forgottenserver-1.2/src/weapons.cpp
- @@ -343,7 +343,7 @@ bool Weapon::useFist(Player* player, Creature* target)
- int32_t maxDamage = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
- CombatParams params;
- - params.combatType = COMBAT_PHYSICALDAMAGE;
- + params.combatType = COMBAT_NONE;
- params.blockedByArmor = true;
- params.blockedByShield = true;
- @@ -496,7 +496,7 @@ WeaponMelee::WeaponMelee(LuaScriptInterface* interface) :
- {
- params.blockedByArmor = true;
- params.blockedByShield = true;
- - params.combatType = COMBAT_PHYSICALDAMAGE;
- + params.combatType = COMBAT_NONE;
- }
- void WeaponMelee::configureWeapon(const ItemType& it)
- @@ -588,7 +588,7 @@ WeaponDistance::WeaponDistance(LuaScriptInterface* interface) :
- Weapon(interface)
- {
- params.blockedByArmor = true;
- - params.combatType = COMBAT_PHYSICALDAMAGE;
- + params.combatType = COMBAT_NONE;
- }
- void WeaponDistance::configureWeapon(const ItemType& it)
- @@ -840,8 +840,7 @@ bool WeaponDistance::getSkillType(const Player* player, const Item*, skills_t& s
- break;
- }
- - case BLOCK_DEFENSE:
- - case BLOCK_ARMOR: {
- + case BLOCK_DEFENSE: {
- skillpoint = 1;
- break;
- }
- @@ -874,17 +873,7 @@ bool WeaponWand::configureEvent(const pugi::xml_node& node)
- if ((attr = node.attribute("type"))) {
- std::string tmpStrValue = asLowerCaseString(attr.as_string());
- if (tmpStrValue == "earth") {
- - params.combatType = COMBAT_EARTHDAMAGE;
- - } else if (tmpStrValue == "ice") {
- params.combatType = COMBAT_ICEDAMAGE;
- - } else if (tmpStrValue == "energy") {
- - params.combatType = COMBAT_ENERGYDAMAGE;
- - } else if (tmpStrValue == "fire") {
- - params.combatType = COMBAT_FIREDAMAGE;
- - } else if (tmpStrValue == "death") {
- - params.combatType = COMBAT_DEATHDAMAGE;
- - } else if (tmpStrValue == "holy") {
- - params.combatType = COMBAT_HOLYDAMAGE;
- } else {
- std::cout << "[Warning - WeaponWand::configureEvent] Type \"" << attr.as_string() << "\" does not exist." << std::endl;
- }
- --
- 2.7.4.1.g5468f9e
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement