Untitled diff

Created Diff never expires
0 removals
180 lines
8 additions
188 lines
void Player::death(Creature* lastHitCreature)
void Player::death(Creature* lastHitCreature)
{
{
loginPosition = town->getTemplePosition();
loginPosition = town->getTemplePosition();


if (skillLoss) {
if (skillLoss) {
uint8_t unfairFightReduction = 100;
uint8_t unfairFightReduction = 100;
bool lastHitPlayer = Player::lastHitIsPlayer(lastHitCreature);
bool lastHitPlayer = Player::lastHitIsPlayer(lastHitCreature);


if (lastHitPlayer) {
if (lastHitPlayer) {
uint32_t sumLevels = 0;
uint32_t sumLevels = 0;
uint32_t inFightTicks = g_config.getNumber(ConfigManager::PZ_LOCKED);
uint32_t inFightTicks = g_config.getNumber(ConfigManager::PZ_LOCKED);
for (const auto& it : damageMap) {
for (const auto& it : damageMap) {
CountBlock_t cb = it.second;
CountBlock_t cb = it.second;
if ((OTSYS_TIME() - cb.ticks) <= inFightTicks) {
if ((OTSYS_TIME() - cb.ticks) <= inFightTicks) {
Player* damageDealer = g_game.getPlayerByID(it.first);
Player* damageDealer = g_game.getPlayerByID(it.first);
if (damageDealer) {
if (damageDealer) {
sumLevels += damageDealer->getLevel();
sumLevels += damageDealer->getLevel();
}
}
}
}
}
}


if (sumLevels > level) {
if (sumLevels > level) {
double reduce = level / static_cast<double>(sumLevels);
double reduce = level / static_cast<double>(sumLevels);
unfairFightReduction = std::max<uint8_t>(20, std::floor((reduce * 100) + 0.5));
unfairFightReduction = std::max<uint8_t>(20, std::floor((reduce * 100) + 0.5));
}
}
}
}


//Magic level loss
//Magic level loss
uint64_t sumMana = 0;
uint64_t sumMana = 0;
uint64_t lostMana = 0;
uint64_t lostMana = 0;


//sum up all the mana
//sum up all the mana
for (uint32_t i = 1; i <= magLevel; ++i) {
for (uint32_t i = 1; i <= magLevel; ++i) {
sumMana += vocation->getReqMana(i);
sumMana += vocation->getReqMana(i);
}
}


sumMana += manaSpent;
sumMana += manaSpent;


double deathLossPercent = getLostPercent() * (unfairFightReduction / 100.);
double deathLossPercent = getLostPercent() * (unfairFightReduction / 100.);


lostMana = static_cast<uint64_t>(sumMana * deathLossPercent);
lostMana = static_cast<uint64_t>(sumMana * deathLossPercent);


while (lostMana > manaSpent && magLevel > 0) {
while (lostMana > manaSpent && magLevel > 0) {
lostMana -= manaSpent;
lostMana -= manaSpent;
manaSpent = vocation->getReqMana(magLevel);
manaSpent = vocation->getReqMana(magLevel);
magLevel--;
magLevel--;
}
}


manaSpent -= lostMana;
manaSpent -= lostMana;


uint64_t nextReqMana = vocation->getReqMana(magLevel + 1);
uint64_t nextReqMana = vocation->getReqMana(magLevel + 1);
if (nextReqMana > vocation->getReqMana(magLevel)) {
if (nextReqMana > vocation->getReqMana(magLevel)) {
magLevelPercent = Player::getPercentLevel(manaSpent, nextReqMana);
magLevelPercent = Player::getPercentLevel(manaSpent, nextReqMana);
} else {
} else {
magLevelPercent = 0;
magLevelPercent = 0;
}
}


//Skill loss
//Skill loss
for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { //for each skill
for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { //for each skill
uint64_t sumSkillTries = 0;
uint64_t sumSkillTries = 0;
for (uint16_t c = 11; c <= skills[i].level; ++c) { //sum up all required tries for all skill levels
for (uint16_t c = 11; c <= skills[i].level; ++c) { //sum up all required tries for all skill levels
sumSkillTries += vocation->getReqSkillTries(i, c);
sumSkillTries += vocation->getReqSkillTries(i, c);
}
}


sumSkillTries += skills[i].tries;
sumSkillTries += skills[i].tries;


uint32_t lostSkillTries = static_cast<uint32_t>(sumSkillTries * deathLossPercent);
uint32_t lostSkillTries = static_cast<uint32_t>(sumSkillTries * deathLossPercent);
while (lostSkillTries > skills[i].tries) {
while (lostSkillTries > skills[i].tries) {
lostSkillTries -= skills[i].tries;
lostSkillTries -= skills[i].tries;


if (skills[i].level <= 10) {
if (skills[i].level <= 10) {
skills[i].level = 10;
skills[i].level = 10;
skills[i].tries = 0;
skills[i].tries = 0;
lostSkillTries = 0;
lostSkillTries = 0;
break;
break;
}
}


skills[i].tries = vocation->getReqSkillTries(i, skills[i].level);
skills[i].tries = vocation->getReqSkillTries(i, skills[i].level);
skills[i].level--;
skills[i].level--;
}
}


skills[i].tries = std::max<int32_t>(0, skills[i].tries - lostSkillTries);
skills[i].tries = std::max<int32_t>(0, skills[i].tries - lostSkillTries);
skills[i].percent = Player::getPercentLevel(skills[i].tries, vocation->getReqSkillTries(i, skills[i].level));
skills[i].percent = Player::getPercentLevel(skills[i].tries, vocation->getReqSkillTries(i, skills[i].level));
}
}


//Level loss
//Level loss
uint64_t expLoss = static_cast<uint64_t>(experience * deathLossPercent);
uint64_t expLoss = static_cast<uint64_t>(experience * deathLossPercent);
g_events->eventPlayerOnLoseExperience(this, expLoss);
g_events->eventPlayerOnLoseExperience(this, expLoss);


if (expLoss != 0) {
if (expLoss != 0) {
uint32_t oldLevel = level;
uint32_t oldLevel = level;


if (vocation->getId() == VOCATION_NONE || level > 7) {
if (vocation->getId() == VOCATION_NONE || level > 7) {
experience -= expLoss;
experience -= expLoss;
}
}


while (level > 1 && experience < Player::getExpForLevel(level)) {
while (level > 1 && experience < Player::getExpForLevel(level)) {
--level;
--level;
healthMax = std::max<int32_t>(0, healthMax - vocation->getHPGain());
healthMax = std::max<int32_t>(0, healthMax - vocation->getHPGain());
manaMax = std::max<int32_t>(0, manaMax - vocation->getManaGain());
manaMax = std::max<int32_t>(0, manaMax - vocation->getManaGain());
capacity = std::max<int32_t>(0, capacity - vocation->getCapGain());
capacity = std::max<int32_t>(0, capacity - vocation->getCapGain());
}
}


if (oldLevel != level) {
if (oldLevel != level) {
std::ostringstream ss;
std::ostringstream ss;
ss << "You were downgraded from Level " << oldLevel << " to Level " << level << '.';
ss << "You were downgraded from Level " << oldLevel << " to Level " << level << '.';
sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str());
sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str());

if (passiveDamageBonus > 0)
{
passiveDamageBonus--;
std::ostringstream msgPassive;
msgPassive << "Your passive damage bonus has reduced from " << passiveDamageBonus + 1 << "% to " << passiveDamageBonus << "%.";
sendTextMessage(MESSAGE_EVENT_ADVANCE, msgPassive.str());
}
}
}


uint64_t currLevelExp = Player::getExpForLevel(level);
uint64_t currLevelExp = Player::getExpForLevel(level);
uint64_t nextLevelExp = Player::getExpForLevel(level + 1);
uint64_t nextLevelExp = Player::getExpForLevel(level + 1);
if (nextLevelExp > currLevelExp) {
if (nextLevelExp > currLevelExp) {
levelPercent = Player::getPercentLevel(experience - currLevelExp, nextLevelExp - currLevelExp);
levelPercent = Player::getPercentLevel(experience - currLevelExp, nextLevelExp - currLevelExp);
} else {
} else {
levelPercent = 0;
levelPercent = 0;
}
}
}
}


std::bitset<6> bitset(blessings);
std::bitset<6> bitset(blessings);
if (bitset[5]) {
if (bitset[5]) {
if (lastHitPlayer) {
if (lastHitPlayer) {
bitset.reset(5);
bitset.reset(5);
blessings = bitset.to_ulong();
blessings = bitset.to_ulong();
} else {
} else {
blessings = 32;
blessings = 32;
}
}
} else {
} else {
blessings = 0;
blessings = 0;
}
}


sendStats();
sendStats();
sendSkills();
sendSkills();
sendReLoginWindow(unfairFightReduction);
sendReLoginWindow(unfairFightReduction);


if (getSkull() == SKULL_BLACK) {
if (getSkull() == SKULL_BLACK) {
health = 40;
health = 40;
mana = 0;
mana = 0;
} else {
} else {
health = healthMax;
health = healthMax;
mana = manaMax;
mana = manaMax;
}
}


auto it = conditions.begin(), end = conditions.end();
auto it = conditions.begin(), end = conditions.end();
while (it != end) {
while (it != end) {
Condition* condition = *it;
Condition* condition = *it;
if (condition->isPersistent()) {
if (condition->isPersistent()) {
it = conditions.erase(it);
it = conditions.erase(it);


condition->endCondition(this);
condition->endCondition(this);
onEndCondition(condition->getType());
onEndCondition(condition->getType());
delete condition;
delete condition;
} else {
} else {
++it;
++it;
}
}
}
}
} else {
} else {
setSkillLoss(true);
setSkillLoss(true);


auto it = conditions.begin(), end = conditions.end();
auto it = conditions.begin(), end = conditions.end();
while (it != end) {
while (it != end) {
Condition* condition = *it;
Condition* condition = *it;
if (condition->isPersistent()) {
if (condition->isPersistent()) {
it = conditions.erase(it);
it = conditions.erase(it);


condition->endCondition(this);
condition->endCondition(this);
onEndCondition(condition->getType());
onEndCondition(condition->getType());
delete condition;
delete condition;
} else {
} else {
++it;
++it;
}
}
}
}


health = healthMax;
health = healthMax;
g_game.internalTeleport(this, getTemplePosition(), true);
g_game.internalTeleport(this, getTemplePosition(), true);
g_game.addCreatureHealth(this);
g_game.addCreatureHealth(this);
onThink(EVENT_CREATURE_THINK_INTERVAL);
onThink(EVENT_CREATURE_THINK_INTERVAL);
onIdleStatus();
onIdleStatus();
sendStats();
sendStats();
}
}
}
}