allanet
Member
- Joined
- Jan 20, 2012
- Messages
- 19
- Reaction score
- 9
Distribuition: TFS 0.3.7 , protocol 8.10
When a player die, he lose all items, backpack and equipments, and receive an empty bag, even with all the blessings.
This is only prevented using a amulet of loss, in that case everything works normal (no drop backpack or equipments drop, and aol is removed).
I tried to fix-it but i can't find where, but my guess is that the functions that deals with death, rook the equipment of everyone on death, because aside from dropping everything, the player receives an empty bag
PS: everything else works flawless, when a player die he loses only small amount of skill and level, only the equipment drop is wrong.
My player.cpp onDeath() function:
When a player die, he lose all items, backpack and equipments, and receive an empty bag, even with all the blessings.
This is only prevented using a amulet of loss, in that case everything works normal (no drop backpack or equipments drop, and aol is removed).
I tried to fix-it but i can't find where, but my guess is that the functions that deals with death, rook the equipment of everyone on death, because aside from dropping everything, the player receives an empty bag
PS: everything else works flawless, when a player die he loses only small amount of skill and level, only the equipment drop is wrong.
My player.cpp onDeath() function:
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 (!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]);
}
}
}
else if (!inventory[SLOT_BACKPACK]) // FIXME: you should receive the bag after you login back...
__internalAddThing(SLOT_BACKPACK, Item::CreateItem(g_config.getNumber(ConfigManager::DEATH_CONTAINER)));
sendIcons();
sendStats();
sendSkills();
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;
}
Last edited: