From a22f39a9c7c19d2a015ce51ed84e310672ee873a Mon Sep 17 00:00:00 2001 From: Beats Date: Tue, 26 Mar 2024 19:52:42 -0300 Subject: [PATCH] test --- data/XML/imbuements.xml | 19 ++++++ data/items/items.xml | 2 +- data/scripts/runes/paralyze_rune.lua | 6 +- src/creatures/combat/combat.cpp | 59 ++++++++++++++++--- src/creatures/combat/combat.hpp | 2 + .../players/imbuements/imbuements.cpp | 13 +++- .../players/imbuements/imbuements.hpp | 1 + src/items/functions/item/item_parse.cpp | 2 +- src/items/functions/item/item_parse.hpp | 3 +- src/items/items_definitions.hpp | 3 +- src/utils/tools.cpp | 3 +- 11 files changed, 93 insertions(+), 20 deletions(-) diff --git a/data/XML/imbuements.xml b/data/XML/imbuements.xml index 0a2fd90702f..e7093d60418 100644 --- a/data/XML/imbuements.xml +++ b/data/XML/imbuements.xml @@ -22,6 +22,7 @@ + @@ -427,4 +428,22 @@ + + + + + + + + + + + + + + + + + + diff --git a/data/items/items.xml b/data/items/items.xml index b1a1c6b003f..cf98e338ccd 100644 --- a/data/items/items.xml +++ b/data/items/items.xml @@ -8566,7 +8566,7 @@ - + diff --git a/data/scripts/runes/paralyze_rune.lua b/data/scripts/runes/paralyze_rune.lua index b0c602a159b..e055ab12421 100644 --- a/data/scripts/runes/paralyze_rune.lua +++ b/data/scripts/runes/paralyze_rune.lua @@ -3,7 +3,7 @@ combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_RED) combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_UNDEFINEDDAMAGE) local condition = Condition(CONDITION_PARALYZE) -condition:setParameter(CONDITION_PARAM_TICKS, 6000) +condition:setParameter(CONDITION_PARAM_TICKS, 60000) condition:setFormula(-1, 0, -1, 0) combat:addCondition(condition) @@ -29,8 +29,8 @@ rune:charges(1) rune:setPzLocked(true) rune:level(54) rune:magicLevel(18) -rune:cooldown(6 * 1000) -rune:groupCooldown(2 * 1000) +rune:cooldown(1 * 1000) +rune:groupCooldown(1 * 1000) rune:mana(1400) rune:needTarget(true) rune:isBlocking(true) -- True = Solid / False = Creature diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index cf98fcb6a7b..aeaeec358cd 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -749,23 +749,64 @@ void Combat::CombatConditionFunc(std::shared_ptr caster, std::shared_p if (condition->getType() == CONDITION_FEARED && !checkFearConditionAffected(player)) { return; } - } - if (caster == target || target && !target->isImmune(condition->getType())) { - auto conditionCopy = condition->clone(); - if (caster) { - conditionCopy->setParam(CONDITION_PARAM_OWNER, caster->getID()); - conditionCopy->setPositionParam(CONDITION_PARAM_CASTER_POSITION, caster->getPosition()); + if (condition->getType() == CONDITION_PARALYZE && target) { + if (player) { + if (reflectParalyzeCondition(caster, player, condition)) { + return; + } + } } - // TODO: infight condition until all aggressive conditions has ended - if (target) { - target->addCombatCondition(conditionCopy, caster && caster->getPlayer() != nullptr); + if (caster == target || (target && !target->isImmune(condition->getType()))) { + auto conditionCopy = condition->clone(); + if (caster) { + conditionCopy->setParam(CONDITION_PARAM_OWNER, caster->getID()); + conditionCopy->setPositionParam(CONDITION_PARAM_CASTER_POSITION, caster->getPosition()); + } + + // TODO: infight condition until all aggressive conditions has ended + if (target) { + target->addCombatCondition(conditionCopy, caster && caster->getPlayer() != nullptr); + } } } } } +bool Combat::reflectParalyzeCondition(const std::shared_ptr &caster, const std::shared_ptr &target, const std::shared_ptr &condition) { + if (!target->hasCondition(CONDITION_PARALYZE)) { + target->addCondition(condition->clone()); + return true; + } + + int32_t reflectionChance = 0; + for (int32_t slot = CONST_SLOT_FIRST; slot <= CONST_SLOT_LAST; ++slot) { + auto item = target->getInventoryItem(static_cast(slot)); + if (item) { + for (uint8_t slotid = 0; slotid < item->getImbuementSlot(); ++slotid) { + ImbuementInfo imbuementInfo; + if (item->getImbuementInfo(slotid, &imbuementInfo)) { + reflectionChance = std::max(reflectionChance, imbuementInfo.imbuement->paralyzeReduction); + } + } + } + } + + if (uniform_random(1, 100) <= reflectionChance) { + if (caster && !caster->isImmune(CONDITION_PARALYZE)) { + caster->addCondition(condition->clone()); + } + + if (target->hasCondition(CONDITION_PARALYZE)) { + target->removeCondition(CONDITION_PARALYZE); + } + return true; + } + + return false; +} + void Combat::CombatDispelFunc(std::shared_ptr, std::shared_ptr target, const CombatParams ¶ms, CombatDamage*) { if (target) { target->removeCombatCondition(params.dispelType); diff --git a/src/creatures/combat/combat.hpp b/src/creatures/combat/combat.hpp index 6a79455c7c4..206f90de94b 100644 --- a/src/creatures/combat/combat.hpp +++ b/src/creatures/combat/combat.hpp @@ -385,6 +385,8 @@ class Combat { static void combatTileEffects(const CreatureVector &spectators, std::shared_ptr caster, std::shared_ptr tile, const CombatParams ¶ms); + static bool reflectParalyzeCondition(const std::shared_ptr &caster, const std::shared_ptr &target, const std::shared_ptr &condition); + /** * @brief Calculate the level formula for combat. * diff --git a/src/creatures/players/imbuements/imbuements.cpp b/src/creatures/players/imbuements/imbuements.cpp index 55e3e8015a0..910d83cb551 100644 --- a/src/creatures/players/imbuements/imbuements.cpp +++ b/src/creatures/players/imbuements/imbuements.cpp @@ -151,7 +151,7 @@ bool Imbuements::processImbuementNode(const pugi::xml_node &imbuementNode) { return false; } - uint16_t category = pugi::cast(categorybase.value()); + auto category = pugi::cast(categorybase.value()); auto category_p = getCategoryByID(category); if (category_p == nullptr) { g_logger().warn("Category imbuement {} not exist", category); @@ -184,7 +184,7 @@ bool Imbuements::processImbuementChildNodes(const pugi::xml_node &imbuementNode, g_logger().warn("Missing item ID for imbuement name '{}'", imbuement->name); return false; } - uint16_t sourceId = pugi::cast(attr.value()); + auto sourceId = pugi::cast(attr.value()); uint16_t count = 1; if ((attr = childNode.attribute("count"))) { @@ -237,7 +237,7 @@ bool Imbuements::processImbuementChildNodes(const pugi::xml_node &imbuementNode, g_logger().warn("Missing skill bonus for imbuement name {}", imbuement->name); return false; } - int32_t bonus = pugi::cast(attr.value()); + auto bonus = pugi::cast(attr.value()); if (skillId == UseSkillMode::NormalSkill) { imbuement->skills[skillId] = bonus; @@ -306,6 +306,13 @@ bool Imbuements::processImbuementChildNodes(const pugi::xml_node &imbuementNode, } imbuement->capacity = pugi::cast(attr.value()); + } else if (strcasecmp(effecttype.c_str(), "vibrancy") == 0) { + if (!(attr = childNode.attribute("chance"))) { + g_logger().warn("Missing chance value for imbuement name {}", imbuement->name); + return false; + } + + imbuement->paralyzeReduction = pugi::cast(attr.value()); } } } diff --git a/src/creatures/players/imbuements/imbuements.hpp b/src/creatures/players/imbuements/imbuements.hpp index ae7a2a64e6d..222e600b3bc 100644 --- a/src/creatures/players/imbuements/imbuements.hpp +++ b/src/creatures/players/imbuements/imbuements.hpp @@ -134,6 +134,7 @@ class Imbuement { int32_t stats[STAT_LAST + 1] = {}; int32_t skills[SKILL_LAST + 1] = {}; int32_t speed = 0; + int32_t paralyzeReduction = 0; uint32_t capacity = 0; int16_t absorbPercent[COMBAT_COUNT] = {}; int16_t elementDamage = 0; diff --git a/src/items/functions/item/item_parse.cpp b/src/items/functions/item/item_parse.cpp index 2d1ba9301c5..520be1613c0 100644 --- a/src/items/functions/item/item_parse.cpp +++ b/src/items/functions/item/item_parse.cpp @@ -865,7 +865,7 @@ void ItemParse::parseImbuement(const std::string &tmpStrValue, pugi::xml_node at continue; } } else { - g_logger().warn("[ParseImbuement::initParseImbuement] - Unknown type: {}", valueAttribute.as_string()); + g_logger().warn("[ParseImbuement::initParseImbuement] - Unknown type: {}, item: {}", valueAttribute.as_string(), itemType.id); } } } diff --git a/src/items/functions/item/item_parse.hpp b/src/items/functions/item/item_parse.hpp index 7859a77fe9c..63fd09d2cc7 100644 --- a/src/items/functions/item/item_parse.hpp +++ b/src/items/functions/item/item_parse.hpp @@ -244,7 +244,8 @@ const phmap::flat_hash_map ImbuementsTypeMap = { { "skillboost shielding", IMBUEMENT_SKILLBOOST_SHIELDING }, { "skillboost distance", IMBUEMENT_SKILLBOOST_DISTANCE }, { "skillboost magic level", IMBUEMENT_SKILLBOOST_MAGIC_LEVEL }, - { "increase capacity", IMBUEMENT_INCREASE_CAPACITY } + { "increase capacity", IMBUEMENT_INCREASE_CAPACITY }, + { "vibrancy", IMBUEMENT_VIBRANCY_PARALYZE } }; class ItemParse : public Items { diff --git a/src/items/items_definitions.hpp b/src/items/items_definitions.hpp index 67e61f76f16..07b386ad701 100644 --- a/src/items/items_definitions.hpp +++ b/src/items/items_definitions.hpp @@ -267,7 +267,8 @@ enum ImbuementTypes_t : int64_t { IMBUEMENT_SKILLBOOST_SHIELDING = 14, IMBUEMENT_SKILLBOOST_DISTANCE = 15, IMBUEMENT_SKILLBOOST_MAGIC_LEVEL = 16, - IMBUEMENT_INCREASE_CAPACITY = 17 + IMBUEMENT_INCREASE_CAPACITY = 17, + IMBUEMENT_VIBRANCY_PARALYZE = 18 }; enum class ContainerCategory_t : uint8_t { diff --git a/src/utils/tools.cpp b/src/utils/tools.cpp index 0d8b39a485d..c81bad7003c 100644 --- a/src/utils/tools.cpp +++ b/src/utils/tools.cpp @@ -869,7 +869,8 @@ const ImbuementTypeNames imbuementTypeNames = { { "skillboost shielding", IMBUEMENT_SKILLBOOST_SHIELDING }, { "skillboost distance", IMBUEMENT_SKILLBOOST_DISTANCE }, { "skillboost magic level", IMBUEMENT_SKILLBOOST_MAGIC_LEVEL }, - { "increase capacity", IMBUEMENT_INCREASE_CAPACITY } + { "increase capacity", IMBUEMENT_INCREASE_CAPACITY }, + { "vibrancy", IMBUEMENT_VIBRANCY_PARALYZE } }; /**