Hello Otland, I'm modifying my Otxserv 2 sources and I'm implementing a way for you not to close the session when you die. I've already achieved that. What I can't achieve is clearing the damage that the player does before dying, which means that after dying the player continues to gain monsters, experience, and loot if he was the one who inflicted the most damage. I want him to lose all of that when he dies. I'm sharing my OnDeath with you. I hope you can help me. Thank you for your attention.
I am using this distribution GitHub - mattyx14/otxserver at otxserv2 (https://github.com/mattyx14/otxserver/tree/otxserv2)
Any?
C++:
bool Player::onDeath()
{
Item *preventLoss = NULL, *preventDrop = NULL;
if(getZone() == ZONE_HARDCORE)
{
setDropLoot(LOOT_DROP_NONE);
setLossSkill(false);
}
else if(skull < SKULL_RED)
{
Item* item = NULL;
for(int32_t i = SLOT_FIRST; ((!preventDrop || !preventLoss) && i < SLOT_LAST); ++i)
{
if(!(item = getInventoryItem((slots_t)i)) || item->isRemoved() ||
(g_moveEvents->hasEquipEvent(item) && !isItemAbilityEnabled((slots_t)i)))
continue;
const ItemType& it = Item::items[item->getID()];
if(!it.hasAbilities())
continue;
if(lootDrop == LOOT_DROP_FULL && it.abilities->preventDrop)
{
setDropLoot(LOOT_DROP_PREVENT);
preventDrop = item;
}
if(skillLoss && !preventLoss && it.abilities->preventLoss)
{
preventLoss = item;
if(preventLoss != preventDrop && it.abilities->preventDrop)
preventDrop = item;
}
}
}
if(!Creature::onDeath())
{
if(preventDrop)
setDropLoot(LOOT_DROP_FULL);
return false;
}
uint32_t totalDamage = 0, pvpDamage = 0, opponents = 0;
for(CountMap::iterator it = damageMap.begin(); it != damageMap.end(); ++it)
{
if(((OTSYS_TIME() - it->second.ticks) / 1000) > g_config.getNumber(
ConfigManager::FAIRFIGHT_TIMERANGE))
continue;
totalDamage += it->second.total;
if(Creature* creature = g_game.getCreatureByID(it->first))
{
Player* player = creature->getPlayer();
if(!player)
player = creature->getPlayerMaster();
if(!player)
continue;
opponents += player->getLevel();
pvpDamage += it->second.total;
}
}
bool usePVPBlessing = false;
if(preventLoss)
{
setLossSkill(false);
g_game.transformItem(preventLoss, preventLoss->getID(), std::max(0, (int32_t)preventLoss->getCharges() - 1));
}
else if(pvpBlessing && (int32_t)std::floor((100. * pvpDamage) / std::max(
1U, totalDamage)) >= g_config.getNumber(ConfigManager::PVP_BLESSING_THRESHOLD))
usePVPBlessing = true;
if(preventDrop && preventDrop != preventLoss && !usePVPBlessing)
g_game.transformItem(preventDrop, preventDrop->getID(), std::max(0, (int32_t)preventDrop->getCharges() - 1));
removeConditions(CONDITIONEND_DEATH);
if(skillLoss)
{
double reduction = 1.;
if(g_config.getBool(ConfigManager::FAIRFIGHT_REDUCTION) && opponents > level)
reduction -= (double)level / opponents;
uint64_t lossExperience = (uint64_t)std::floor(reduction * getLostExperience()), currExperience = experience;
removeExperience(lossExperience, false);
double percent = 1. - ((double)(currExperience - lossExperience) / std::max((uint64_t)1, currExperience));
// magic level loss
uint64_t sumMana = 0, lostMana = 0;
for(uint32_t i = 1; i <= magLevel; ++i)
sumMana += vocation->getReqMana(i);
sumMana += manaSpent;
lostMana = (uint64_t)std::ceil((percent * lossPercent[LOSS_MANA] / 100.) * sumMana);
while(lostMana > manaSpent && magLevel > 0)
{
lostMana -= manaSpent;
manaSpent = vocation->getReqMana(magLevel);
magLevel--;
}
manaSpent -= lostMana;
uint64_t nextReqMana = vocation->getReqMana(magLevel + 1);
if(nextReqMana > vocation->getReqMana(magLevel))
magLevelPercent = Player::getPercentLevel(manaSpent, nextReqMana);
else
magLevelPercent = 0;
// skill loss
uint64_t lostSkillTries, sumSkillTries;
for(int16_t i = 0; i < 7; ++i) // for each skill
{
lostSkillTries = sumSkillTries = 0;
for(uint32_t c = 11; c <= skills[i][SKILL_LEVEL]; ++c) // sum up all required tries for all skill levels
sumSkillTries += vocation->getReqSkillTries(i, c);
sumSkillTries += skills[i][SKILL_TRIES];
lostSkillTries = (uint64_t)std::ceil((percent * lossPercent[LOSS_SKILLS] / 100.) * sumSkillTries);
while(lostSkillTries > skills[i][SKILL_TRIES] && skills[i][SKILL_LEVEL] > 10)
{
lostSkillTries -= skills[i][SKILL_TRIES];
skills[i][SKILL_TRIES] = vocation->getReqSkillTries(i, skills[i][SKILL_LEVEL]);
skills[i][SKILL_LEVEL]--;
}
skills[i][SKILL_TRIES] -= lostSkillTries;
}
if(usePVPBlessing)
pvpBlessing = false;
else
blessings = 0;
loginPosition = masterPosition;
if(vocationId > VOCATION_NONE && g_config.getBool(ConfigManager::ROOK_SYSTEM) &&
level <= (uint32_t)g_config.getNumber(ConfigManager::ROOK_LEVELTO))
{
if(Town* rook = Towns::getInstance()->getTown(g_config.getNumber(ConfigManager::ROOK_TOWN)))
{
level = 1;
soulMax = soul = 100;
capacity = 400;
stamina = STAMINA_MAX;
health = healthMax = 150;
loginPosition = masterPosition = rook->getPosition();
experience = magLevel = manaSpent = mana = manaMax = balance = marriage = 0;
promotionLevel = defaultOutfit.lookAddons = 0;
setTown(rook->getID());
setVocation(0);
leaveGuild();
storageMap.clear();
for(uint32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i)
{
skills[i][SKILL_LEVEL] = 10;
skills[i][SKILL_TRIES] = 0;
}
for(uint32_t i = SLOT_FIRST; i < SLOT_LAST; ++i)
{
if(inventory[i])
g_game.internalRemoveItem(NULL, inventory[i]);
}
}
}
health = healthMax;
mana = manaMax;
removeConditions(CONDITIONEND_DEATH);
removeCondition(CONDITION_FIRE);
removeCondition(CONDITION_POISON);
removeCondition(CONDITION_ENERGY);
removeCondition(CONDITION_BLEEDING);
removeCondition(CONDITION_DROWN);
removeCondition(CONDITION_PARALYZE);
removeCondition(CONDITION_INVISIBLE);
removeCondition(CONDITION_HASTE);
removeCondition(CONDITION_CURSED);
sendStats();
sendIcons();
sendSkills();
onIdleStatus();
// Mostrar en consola que murió
std::cout << getName() << " has died." << std::endl;
// Detener follow si lo había
setFollowCreature(nullptr);
// Cerrar tienda si estaba abierta
closeShopWindow();
// Salir de party si pertenece a una
if (getParty()) {
getParty()->leave(this);
}
clearPartyInvitations();
// Quitar target visualmente
setAttackedCreature(nullptr);
sendCancelTarget();
// Mostrar vida falsa (puedes ajustar esto si haces revive)
g_game.addCreatureHealth(this);
// Teleportar al templo
g_game.internalTeleport(this, masterPosition, true);
/* g_creatureEvents->playerLogout(this, true);
g_game.removeCreature(this, false);
sendReLoginWindow(); */
}
else
{
setLossSkill(true);
if(preventLoss)
{
loginPosition = masterPosition;
g_creatureEvents->playerLogout(this, true);
g_game.removeCreature(this, false);
sendReLoginWindow();
}
}
return true;
}
I am using this distribution GitHub - mattyx14/otxserver at otxserv2 (https://github.com/mattyx14/otxserver/tree/otxserv2)
Post automatically merged:
Any?
Last edited: