S
Shadow_
Guest
i'm trying to make the DMG/healing anything related to mana/health change to be in percent, so i did the following in game.cpp but i don't understand what im doing wrong to always get 0, more info in the screenshot
In this screenshot i went from 100% to 0% and then move to 50% HP and everything gives zeros
C++:bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage) { const Position& targetPos = target->getPosition(); if (damage.primary.value > 0) { if (target->getHealth() <= 0) { return false; } Player* attackerPlayer; if (attacker) { attackerPlayer = attacker->getPlayer(); } else { attackerPlayer = nullptr; } Player* targetPlayer = target->getPlayer(); if (attackerPlayer && targetPlayer && attackerPlayer->getSkull() == SKULL_BLACK && attackerPlayer->getSkullClient(targetPlayer) == SKULL_NONE) { return false; } double bonusRebirth = 0.0; if(attackerPlayer != nullptr){ bonusRebirth = attackerPlayer->rebirth * g_config.getNumber(ConfigManager::REBORN_DMGBONUS); bonusRebirth /= 10; bonusRebirth /= 100; bonusRebirth += 1; } else bonusRebirth = 1.0; damage.primary.value = std::abs(damage.primary.value) * bonusRebirth; damage.secondary.value = std::abs(damage.secondary.value * bonusRebirth); if (damage.origin != ORIGIN_NONE) { const auto& events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE); if (!events.empty()) { for (CreatureEvent* creatureEvent : events) { creatureEvent->executeHealthChange(target, attacker, damage); } damage.origin = ORIGIN_NONE; return combatChangeHealth(attacker, target, damage); } } int64_t realHealthChange = damage.primary.value; target->gainHealth(attacker, damage.primary.value); realHealthChange = ( realHealthChange / target->getMaxHealth() ) * 100; if (realHealthChange > 0 && !target->isInGhostMode()) { std::stringstream ss; ss << realHealthChange << (realHealthChange != 1 ? "% hitpoints." : "% hitpoint."); std::string damageString = ss.str(); std::string spectatorMessage; TextMessage message; message.position = targetPos; message.primary.value = realHealthChange; message.primary.color = TEXTCOLOR_PASTELRED; SpectatorHashSet spectators; map.getSpectators(spectators, targetPos, false, true); for (Creature* spectator : spectators) { Player* tmpPlayer = spectator->getPlayer(); if (tmpPlayer == attackerPlayer && attackerPlayer != targetPlayer) { ss.str({}); ss << "You heal " << target->getNameDescription() << " for " << damageString; message.type = MESSAGE_HEALED; message.text = ss.str(); } else if (tmpPlayer == targetPlayer) { ss.str({}); if (!attacker) { ss << "You were healed"; } else if (targetPlayer == attackerPlayer) { ss << "You healed yourself"; } else { ss << "You were healed by " << attacker->getNameDescription(); } ss << " for " << damageString; message.type = MESSAGE_HEALED; message.text = ss.str(); } else { if (spectatorMessage.empty()) { ss.str({}); if (!attacker) { ss << ucfirst(target->getNameDescription()) << " was healed"; } else { ss << ucfirst(attacker->getNameDescription()) << " healed "; if (attacker == target) { ss << (targetPlayer ? (targetPlayer->getSex() == PLAYERSEX_FEMALE ? "herself" : "himself") : "itself"); } else { ss << target->getNameDescription(); } } ss << " for " << damageString; spectatorMessage = ss.str(); } message.type = MESSAGE_HEALED_OTHERS; message.text = spectatorMessage; } tmpPlayer->sendTextMessage(message); } } } else { if (!target->isAttackable()) { if (!target->isInGhostMode()) { addMagicEffect(targetPos, CONST_ME_POFF); } return true; } Player* attackerPlayer; if (attacker) { attackerPlayer = attacker->getPlayer(); } else { attackerPlayer = nullptr; } Player* targetPlayer = target->getPlayer(); if (attackerPlayer && targetPlayer && attackerPlayer->getSkull() == SKULL_BLACK && attackerPlayer->getSkullClient(targetPlayer) == SKULL_NONE) { return false; } Monster* monster = attacker ? attacker->getMonster() : nullptr; if (monster && monster->getLevel() > 0) { float bonusDmg = g_config.getFloat(ConfigManager::MLVL_BONUSDMG) * monster->getLevel(); if (bonusDmg != 0.0) { damage.primary.value += std::round(damage.primary.value * bonusDmg); damage.secondary.value += std::round(damage.secondary.value * bonusDmg); } } damage.primary.value = std::abs(damage.primary.value); damage.secondary.value = std::abs(damage.secondary.value); if (damage.primary.value + damage.secondary.value == 0) { return true; } if (attackerPlayer) { uint16_t chance = attackerPlayer->getSkillLevel(SKILL_LIFE_LEECH_CHANCE); if (chance != 0 && uniform_random(1, 100) <= chance) { CombatDamage lifeLeech; lifeLeech.primary.value = std::round((damage.primary.value + damage.secondary.value) * (attackerPlayer->getSkillLevel(SKILL_LIFE_LEECH_AMOUNT) / 100.)); g_game.combatChangeHealth(nullptr, attackerPlayer, lifeLeech); } chance = attackerPlayer->getSkillLevel(SKILL_MANA_LEECH_CHANCE); if (chance != 0 && uniform_random(1, 100) <= chance) { CombatDamage manaLeech; manaLeech.primary.value = std::round((damage.primary.value + damage.secondary.value) * (attackerPlayer->getSkillLevel(SKILL_MANA_LEECH_AMOUNT) / 100.)); g_game.combatChangeMana(nullptr, attackerPlayer, manaLeech); } chance = attackerPlayer->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE); if (chance != 0 && uniform_random(1, 100) <= chance) { damage.primary.value += std::round(damage.primary.value * (attackerPlayer->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) / 100.)); damage.secondary.value += std::round(damage.secondary.value * (attackerPlayer->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) / 100.)); g_game.addMagicEffect(attacker->getPosition(), CONST_ME_CRITICAL_DAMAGE); } } int64_t healthChange = damage.primary.value + damage.secondary.value; TextMessage message; message.position = targetPos; SpectatorHashSet spectators; if (targetPlayer && target->hasCondition(CONDITION_MANASHIELD) && damage.primary.type != COMBAT_UNDEFINEDDAMAGE) { int64_t manaDamage = std::min<int64_t>(targetPlayer->getMana(), healthChange); if (manaDamage != 0) { if (damage.origin != ORIGIN_NONE) { const auto& events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); if (!events.empty()) { for (CreatureEvent* creatureEvent : events) { creatureEvent->executeManaChange(target, attacker, damage); } healthChange = damage.primary.value + damage.secondary.value; if (healthChange == 0) { return true; } manaDamage = std::min<int64_t>(targetPlayer->getMana(), healthChange); } } targetPlayer->drainMana(attacker, manaDamage); map.getSpectators(spectators, targetPos, true, true); addMagicEffect(spectators, targetPos, CONST_ME_LOSEENERGY); std::stringstream ss; int64_t manap = (manaDamage / targetPlayer->getMaxMana()) * 100; std::string damageString = std::to_string(manap); std::string spectatorMessage; message.primary.value = manap; message.primary.color = TEXTCOLOR_BLUE; for (Creature* spectator : spectators) { Player* tmpPlayer = spectator->getPlayer(); if (tmpPlayer->getPosition().z != targetPos.z) { continue; } if (tmpPlayer == attackerPlayer && attackerPlayer != targetPlayer) { ss.str({}); ss << ucfirst(target->getNameDescription()) << " loses " << damageString + "% mana due to your attack."; message.type = MESSAGE_DAMAGE_DEALT; message.text = ss.str(); } else if (tmpPlayer == targetPlayer) { ss.str({}); ss << "You lose " << damageString << "% mana"; if (!attacker) { ss << '.'; } else if (targetPlayer == attackerPlayer) { ss << " due to your own attack."; } else { ss << " due to an attack by " << attacker->getNameDescription() << '.'; } message.type = MESSAGE_DAMAGE_RECEIVED; message.text = ss.str(); } else { if (spectatorMessage.empty()) { ss.str({}); ss << ucfirst(target->getNameDescription()) << " loses " << damageString + "% mana"; if (attacker) { ss << " due to "; if (attacker == target) { ss << (targetPlayer->getSex() == PLAYERSEX_FEMALE ? "her own attack" : "his own attack"); } else { ss << "an attack by " << attacker->getNameDescription(); } } ss << '.'; spectatorMessage = ss.str(); } message.type = MESSAGE_DAMAGE_OTHERS; message.text = spectatorMessage; } tmpPlayer->sendTextMessage(message); } damage.primary.value -= manaDamage; if (damage.primary.value < 0) { damage.secondary.value = std::max<int64_t>(0, damage.secondary.value + damage.primary.value); damage.primary.value = 0; } } } int64_t realDamage = damage.primary.value + damage.secondary.value; if (realDamage == 0) { return true; } if (damage.origin != ORIGIN_NONE) { const auto& events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE); if (!events.empty()) { for (CreatureEvent* creatureEvent : events) { creatureEvent->executeHealthChange(target, attacker, damage); } damage.origin = ORIGIN_NONE; return combatChangeHealth(attacker, target, damage); } } int64_t targetHealth = target->getHealth(); if (damage.primary.value >= targetHealth) { damage.primary.value = targetHealth; damage.secondary.value = 0; } else if (damage.secondary.value) { damage.secondary.value = std::min<int64_t>(damage.secondary.value, targetHealth - damage.primary.value); } realDamage = damage.primary.value + damage.secondary.value; if (realDamage == 0) { return true; } int64_t prealDamage = (realDamage / target->getMaxHealth()) * 100; int64_t pridmg = (damage.primary.value / target->getMaxHealth()) * 100; int64_t secdmg = (damage.secondary.value / target->getMaxHealth()) * 100; if (spectators.empty()) { map.getSpectators(spectators, targetPos, true, true); } message.primary.value = pridmg; message.secondary.value = secdmg; uint8_t hitEffect; if (message.primary.value) { combatGetTypeInfo(damage.primary.type, target, message.primary.color, hitEffect); if (hitEffect != CONST_ME_NONE) { addMagicEffect(spectators, targetPos, hitEffect); } } if (message.secondary.value) { combatGetTypeInfo(damage.secondary.type, target, message.secondary.color, hitEffect); if (hitEffect != CONST_ME_NONE) { addMagicEffect(spectators, targetPos, hitEffect); } } if (message.primary.color != TEXTCOLOR_NONE || message.secondary.color != TEXTCOLOR_NONE) { std::stringstream ss; ss << prealDamage << (prealDamage != 1 ? "% hitpoints" : "% hitpoint"); std::string damageString = ss.str(); std::string spectatorMessage; for (Creature* spectator : spectators) { Player* tmpPlayer = spectator->getPlayer(); if (tmpPlayer->getPosition().z != targetPos.z) { continue; } if (tmpPlayer == attackerPlayer && attackerPlayer != targetPlayer) { ss.str({}); ss << ucfirst(target->getNameDescription()) << " loses " << damageString << " due to your attack."; message.type = MESSAGE_DAMAGE_DEALT; message.text = ss.str(); } else if (tmpPlayer == targetPlayer) { ss.str({}); ss << "You lose " << damageString; if (!attacker) { ss << '.'; } else if (targetPlayer == attackerPlayer) { ss << " due to your own attack."; } else { ss << " due to an attack by " << attacker->getNameDescription() << '.'; } message.type = MESSAGE_DAMAGE_RECEIVED; message.text = ss.str(); } else { message.type = MESSAGE_DAMAGE_OTHERS; if (spectatorMessage.empty()) { ss.str({}); ss << ucfirst(target->getNameDescription()) << " loses " << damageString; if (attacker) { ss << " due to "; if (attacker == target) { if (targetPlayer) { ss << (targetPlayer->getSex() == PLAYERSEX_FEMALE ? "her own attack" : "his own attack"); } else { ss << "its own attack"; } } else { ss << "an attack by " << attacker->getNameDescription(); } } ss << '.'; spectatorMessage = ss.str(); } message.text = spectatorMessage; } tmpPlayer->sendTextMessage(message); } } if (realDamage >= targetHealth) { for (CreatureEvent* creatureEvent : target->getCreatureEvents(CREATURE_EVENT_PREPAREDEATH)) { if (!creatureEvent->executeOnPrepareDeath(target, attacker)) { return false; } } } target->drainHealth(attacker, realDamage); addCreatureHealth(spectators, target); } return true; } bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage& damage) { Player* targetPlayer = target->getPlayer(); if (!targetPlayer) { return true; } Monster* monster = attacker ? attacker->getMonster() : nullptr; if (monster && monster->getLevel() > 0) { float bonusDmg = g_config.getFloat(ConfigManager::MLVL_BONUSDMG) * monster->getLevel(); if (bonusDmg != 0.0) { if (damage.primary.value < 0) { damage.primary.value += std::round(damage.primary.value * bonusDmg); } if (damage.secondary.value < 0) { damage.secondary.value += std::round(damage.secondary.value * bonusDmg); } } } int64_t manaChange = damage.primary.value + damage.secondary.value; if (manaChange > 0) { if (attacker) { const Player* attackerPlayer = attacker->getPlayer(); if (attackerPlayer && attackerPlayer->getSkull() == SKULL_BLACK && attackerPlayer->getSkullClient(target) == SKULL_NONE) { return false; } } if (damage.origin != ORIGIN_NONE) { const auto& events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); if (!events.empty()) { for (CreatureEvent* creatureEvent : events) { creatureEvent->executeManaChange(target, attacker, damage); } damage.origin = ORIGIN_NONE; return combatChangeMana(attacker, target, damage); } } int64_t realManaChange = manaChange; targetPlayer->changeMana(manaChange); realManaChange = (realManaChange / targetPlayer->getMaxMana()) * 100; if (realManaChange > 0 && !targetPlayer->isInGhostMode()) { TextMessage message(MESSAGE_HEALED, "You gained " + std::to_string(realManaChange) + "% mana."); message.position = target->getPosition(); message.primary.value = realManaChange; message.primary.color = TEXTCOLOR_MAYABLUE; targetPlayer->sendTextMessage(message); } } else { const Position& targetPos = target->getPosition(); if (!target->isAttackable()) { if (!target->isInGhostMode()) { addMagicEffect(targetPos, CONST_ME_POFF); } return false; } Player* attackerPlayer; if (attacker) { attackerPlayer = attacker->getPlayer(); } else { attackerPlayer = nullptr; } if (attackerPlayer && attackerPlayer->getSkull() == SKULL_BLACK && attackerPlayer->getSkullClient(targetPlayer) == SKULL_NONE) { return false; } int64_t manaLoss = std::min<int64_t>(targetPlayer->getMana(), -manaChange); BlockType_t blockType = target->blockHit(attacker, COMBAT_MANADRAIN, manaLoss); if (blockType != BLOCK_NONE) { addMagicEffect(targetPos, CONST_ME_POFF); return false; } if (manaLoss <= 0) { return true; } if (damage.origin != ORIGIN_NONE) { const auto& events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE); if (!events.empty()) { for (CreatureEvent* creatureEvent : events) { creatureEvent->executeManaChange(target, attacker, damage); } damage.origin = ORIGIN_NONE; return combatChangeMana(attacker, target, damage); } } targetPlayer->drainMana(attacker, manaLoss); std::stringstream ss; int64_t manalossP = (manaLoss / targetPlayer->getMaxMana()) * 100; std::string damageString = std::to_string(manalossP); std::string spectatorMessage; TextMessage message; message.position = targetPos; message.primary.value = manalossP; message.primary.color = TEXTCOLOR_BLUE; SpectatorHashSet spectators; map.getSpectators(spectators, targetPos, false, true); for (Creature* spectator : spectators) { Player* tmpPlayer = spectator->getPlayer(); if (tmpPlayer == attackerPlayer && attackerPlayer != targetPlayer) { ss.str({}); ss << ucfirst(target->getNameDescription()) << " loses " << damageString << "% mana due to your attack."; message.type = MESSAGE_DAMAGE_DEALT; message.text = ss.str(); } else if (tmpPlayer == targetPlayer) { ss.str({}); ss << "You lose " << damageString << "% mana"; if (!attacker) { ss << '.'; } else if (targetPlayer == attackerPlayer) { ss << " due to your own attack."; } else { ss << " mana due to an attack by " << attacker->getNameDescription() << '.'; } message.type = MESSAGE_DAMAGE_RECEIVED; message.text = ss.str(); } else { if (spectatorMessage.empty()) { ss.str({}); ss << ucfirst(target->getNameDescription()) << " loses " << damageString << "% mana"; if (attacker) { ss << " due to "; if (attacker == target) { ss << (targetPlayer->getSex() == PLAYERSEX_FEMALE ? "her own attack" : "his own attack"); } else { ss << "an attack by " << attacker->getNameDescription(); } } ss << '.'; spectatorMessage = ss.str(); } message.type = MESSAGE_DAMAGE_OTHERS; message.text = spectatorMessage; } tmpPlayer->sendTextMessage(message); } } return true; }
In this screenshot i went from 100% to 0% and then move to 50% HP and everything gives zeros