zxmatzx
Advanced OT User
Hi,
I need to change summon from experience map to master, then the master will receive the experience that summon would recive. I already blocked summon to recive experience, but if summon and player damage the creature, when the experience map is constructed, the experience wouldn't all to player, because some part is owned by summon.
The problem is:
When Player kill a rotworm alone, gain 40 experience points.
When Summon kill a rotworm alone, the player gain 40 experience points.
When Player(18 damage) and Summon(47 damage) kill a rotworm, player only gain 39 experience point.
I don't sure that the problem is in the experience map, just a guess.
Using TFS 1.2
In creature.cpp:
I compiled with this change, and don't is working, i don't know much about C++, maybe i forgot something or just my approach isn't right. Any help will be welcome.
Thanks.
I need to change summon from experience map to master, then the master will receive the experience that summon would recive. I already blocked summon to recive experience, but if summon and player damage the creature, when the experience map is constructed, the experience wouldn't all to player, because some part is owned by summon.
The problem is:
When Player kill a rotworm alone, gain 40 experience points.
When Summon kill a rotworm alone, the player gain 40 experience points.
When Player(18 damage) and Summon(47 damage) kill a rotworm, player only gain 39 experience point.
I don't sure that the problem is in the experience map, just a guess.
Using TFS 1.2
In creature.cpp:
C++:
void Creature::onDeath()
{
bool lastHitUnjustified = false;
bool mostDamageUnjustified = false;
Creature* lastHitCreature = g_game.getCreatureByID(lastHitCreatureId);
Creature* lastHitCreatureMaster;
if (lastHitCreature) {
lastHitUnjustified = lastHitCreature->onKilledCreature(this);
lastHitCreatureMaster = lastHitCreature->getMaster();
} else {
lastHitCreatureMaster = nullptr;
}
Creature* mostDamageCreature = nullptr;
const int64_t timeNow = OTSYS_TIME();
const uint32_t inFightTicks = g_config.getNumber(ConfigManager::PZ_LOCKED);
int32_t mostDamage = 0;
std::map<Creature*, uint64_t> experienceMap;
for (const auto& it : damageMap) {
if (Creature* attacker = g_game.getCreatureByID(it.first)) {
CountBlock_t cb = it.second;
if ((cb.total > mostDamage && (timeNow - cb.ticks <= inFightTicks))) {
mostDamage = cb.total;
mostDamageCreature = attacker;
}
if (attacker != this) {
uint64_t gainExp = getGainedExperience(attacker);
if (Player* player = attacker->getPlayer()) {
Party* party = player->getParty();
if (party && party->getLeader() && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) {
attacker = party->getLeader();
}
}
//Check if attacker is summon
if (attacker->isSummon()) {
//Check if is a player summon, then change the attacker for master
if (Player* attackerMaster = attacker->getMaster()->getPlayer()) {
attacker = attackerMaster;
}
}
auto tmpIt = experienceMap.find(attacker);
if (tmpIt == experienceMap.end()) {
experienceMap[attacker] = gainExp;
} else {
tmpIt->second += gainExp;
}
}
}
}
for (const auto& it : experienceMap) {
it.first->onGainExperience(it.second, this);
}
if (mostDamageCreature) {
if (mostDamageCreature != lastHitCreature && mostDamageCreature != lastHitCreatureMaster) {
Creature* mostDamageCreatureMaster = mostDamageCreature->getMaster();
if (lastHitCreature != mostDamageCreatureMaster && (lastHitCreatureMaster == nullptr || mostDamageCreatureMaster != lastHitCreatureMaster)) {
mostDamageUnjustified = mostDamageCreature->onKilledCreature(this, false);
}
}
}
bool droppedCorpse = dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
death(lastHitCreature);
if (master) {
master->removeSummon(this);
}
if (droppedCorpse) {
g_game.removeCreature(this, false);
}
}
Thanks.