void CEnmityContainer::UpdateEnmityFromCure(CBattleEntity* PEntity, uint16 level, uint16 CureAmount, bool isCureV) { if(isCureV){ UpdateEnmity(PEntity, 400, 700); } else{ CureAmount = (CureAmount < 1 ? 1 : CureAmount); uint16 mod = battleutils::GetEnmityMod(level, 0); uint16 CE = 40 / mod * CureAmount; uint16 VE = 240 / mod * CureAmount; UpdateEnmity(PEntity, CE, VE); } }
void CEnmityContainer::UpdateEnmityFromCure(CBattleEntity* PEntity, uint16 level, uint16 CureAmount, bool isCureV) { if (isCureV) { UpdateEnmity(PEntity, 400, 700); } else { CureAmount = (CureAmount < 1 ? 1 : CureAmount); uint16 mod = battleutils::GetEnmityModCure(level); uint16 CE = 40. / mod * CureAmount; uint16 VE = 240. / mod * CureAmount; // you're too far away so i'm ignoring you if (!IsWithinEnmityRange(PEntity)) { CE = 0; VE = 0; } // Crash fix, PEntity was in ACTION_FALL if (PEntity->PBattleAI->GetCurrentAction() == ACTION_FALL) return; EnmityList_t::iterator PEnmity = m_EnmityList.lower_bound(PEntity->id); // current highest enmity before this update CBattleEntity* OldEntity = GetHighestEnmity(); if (PEnmity != m_EnmityList.end() && !m_EnmityList.key_comp()(PEntity->id, PEnmity->first)) { float bonus = CalculateEnmityBonus(PEntity); float tranquilHeartReduction = 1.f - battleutils::HandleTranquilHeart(PEntity); int newCE = PEnmity->second->CE + (CE * bonus * tranquilHeartReduction); int newVE = PEnmity->second->VE + (VE * bonus * tranquilHeartReduction); //Check for cap limit PEnmity->second->CE = dsp_cap(newCE, 1, 10000); PEnmity->second->VE = dsp_cap(newVE, 0, 10000); } else if (CE >= 0 && VE >= 0) { EnmityObject_t* PEnmityObject = new EnmityObject_t; float bonus = CalculateEnmityBonus(PEntity); float tranquilHeartReduction = 1.f - battleutils::HandleTranquilHeart(PEntity); PEnmityObject->CE = dsp_cap(CE * bonus * tranquilHeartReduction, 1, 10000); PEnmityObject->VE = dsp_cap(VE * bonus * tranquilHeartReduction, 0, 10000); PEnmityObject->PEnmityOwner = PEntity; PEnmityObject->maxTH = 0; m_EnmityList.insert(PEnmity, EnmityList_t::value_type(PEntity->id, PEnmityObject)); } } }
void CEnmityContainer::UpdateEnmityFromAttack(CBattleEntity* PEntity, uint16 Damage) { if (m_EnmityList.lower_bound(PEntity->id) == m_EnmityList.end()) { return; } float reduction = (100.f - dsp_min(PEntity->getMod(MOD_ENMITY_LOSS_REDUCTION), 100)) / 100.0f; UpdateEnmity(PEntity, -(1800 * Damage / PEntity->GetMaxHP()) * reduction, 0); }
void CEnmityContainer::UpdateEnmityFromDamage(CBattleEntity* PEntity, uint16 Damage) { Damage = (Damage < 1 ? 1 : Damage); uint16 mod = battleutils::GetEnmityModDamage(PEntity->GetMLevel()); //default fallback if (m_EnmityHolder != nullptr) {//use the correct mod value mod = battleutils::GetEnmityModDamage(m_EnmityHolder->GetMLevel()); } uint16 CE = (80.0f / mod) * Damage; uint16 VE = (240.0f / mod) * Damage; UpdateEnmity(PEntity, CE, VE); }
void CEnmityContainer::LowerEnmityByPercent(CBattleEntity* PEntity, uint8 percent, CBattleEntity* HateReceiver) { EnmityList_t::iterator PEnmity = m_EnmityList.lower_bound(PEntity->id); // current highest enmity before this update CBattleEntity* OldEntity = GetHighestEnmity(); if (PEnmity != m_EnmityList.end() && !m_EnmityList.key_comp()(PEntity->id, PEnmity->first)) { float mod = ((float)(percent) / 100.0f); int32 CEValue = (float)(PEnmity->second->CE * mod); PEnmity->second->CE -= (CEValue < 0 ? 0 : CEValue); int32 VEValue = (float)(PEnmity->second->VE * mod); PEnmity->second->VE -= (VEValue < 0 ? 0 : VEValue); // transfer hate if HateReceiver not nullptr if (HateReceiver != nullptr) { UpdateEnmity(HateReceiver, 0, 0); EnmityList_t::iterator PEnmityReceiver = m_EnmityList.lower_bound(HateReceiver->id); PEnmityReceiver->second->CE = dsp_cap(PEnmityReceiver->second->CE + CEValue,1,10000); PEnmityReceiver->second->VE = dsp_cap(PEnmityReceiver->second->VE + VEValue,0,10000); } } // highest enmity holder after this update CBattleEntity* NewEntity = GetHighestEnmity(); // PEntity is now the target, face the target if (OldEntity != NewEntity && !m_EnmityHolder->isAsleep()) { if ((m_EnmityHolder->objtype == TYPE_MOB && !(((CMobEntity*)m_EnmityHolder)->m_Behaviour & BEHAVIOUR_NO_TURN)) || m_EnmityHolder->objtype != TYPE_MOB) { uint8 angle = getangle(m_EnmityHolder->loc.p, NewEntity->loc.p); m_EnmityHolder->loc.p.rotation = angle; m_EnmityHolder->loc.zone->PushPacket(m_EnmityHolder, CHAR_INRANGE, new CEntityUpdatePacket(m_EnmityHolder, ENTITY_UPDATE, UPDATE_POS)); } } }
void CEnmityContainer::UpdateEnmityFromDamage(CBattleEntity* PEntity, uint16 Damage) { // Crash fix, PEntity was in ACTION_FALL if (PEntity->PBattleAI->GetCurrentAction() == ACTION_FALL) return; Damage = (Damage < 1 ? 1 : Damage); uint16 mod = battleutils::GetEnmityMod(PEntity->GetMLevel(), 1); //default fallback if(m_EnmityHolder != NULL) {//use the correct mod value mod = battleutils::GetEnmityMod(m_EnmityHolder->GetMLevel(), 1); } uint16 CE = (80.0f / mod) * Damage; uint16 VE = (240.0f / mod) * Damage; UpdateEnmity(PEntity, CE, VE); }
void CEnmityContainer::LowerEnmityByPercent(CBattleEntity* PEntity, uint8 percent, CBattleEntity* HateReceiver) { EnmityList_t::iterator PEnmity = m_EnmityList.lower_bound(PEntity->id); // current highest enmity before this update CBattleEntity* OldEntity = GetHighestEnmity(); if( PEnmity != m_EnmityList.end() && !m_EnmityList.key_comp()(PEntity->id, PEnmity->first)) { float mod = ((float)(percent)/100.0f); int32 CEValue = (float)(PEnmity->second->CE * mod); PEnmity->second->CE -= (CEValue < 0 ? 0 : CEValue); int32 VEValue = (float)(PEnmity->second->VE * mod); PEnmity->second->VE -= (VEValue < 0 ? 0 : VEValue); // transfer hate if HateReceiver not null if (HateReceiver != NULL) { UpdateEnmity(HateReceiver,0,0); EnmityList_t::iterator PEnmityReceiver = m_EnmityList.lower_bound(HateReceiver->id); PEnmityReceiver->second->CE += CEValue; PEnmityReceiver->second->VE += VEValue; } } // highest enmity holder after this update CBattleEntity* NewEntity = GetHighestEnmity(); // PEntity is now the target, face the target if (OldEntity != NewEntity && !m_EnmityHolder->isAsleep()) { uint8 angle = getangle(m_EnmityHolder->loc.p, NewEntity->loc.p); m_EnmityHolder->loc.p.rotation = angle; m_EnmityHolder->loc.zone->PushPacket(m_EnmityHolder,CHAR_INRANGE, new CEntityUpdatePacket(m_EnmityHolder, ENTITY_UPDATE)); } }
void CEnmityContainer::LowerEnmityByPercent(CBattleEntity* PEntity, uint8 percent, CBattleEntity* HateReceiver) { auto enmity_obj = m_EnmityList.find(PEntity->id); if (enmity_obj != m_EnmityList.end()) { float mod = ((float)(percent) / 100.0f); int32 CEValue = (float)(enmity_obj->second.CE * mod); enmity_obj->second.CE -= (CEValue < 0 ? 0 : CEValue); int32 VEValue = (float)(enmity_obj->second.VE * mod); enmity_obj->second.VE -= (VEValue < 0 ? 0 : VEValue); // transfer hate if HateReceiver not nullptr if (HateReceiver != nullptr) { UpdateEnmity(HateReceiver, CEValue, VEValue); } } }
void CEnmityContainer::UpdateEnmity(CBattleEntity* PEntity, int16 CE, int16 VE, bool withMaster) { // you're too far away so i'm ignoring you if(!IsWithinEnmityRange(PEntity)) { CE = 0; VE = 0; } // Crash fix, PEntity was in ACTION_FALL if (PEntity->PBattleAI->GetCurrentAction() == ACTION_FALL) return; EnmityList_t::iterator PEnmity = m_EnmityList.lower_bound(PEntity->id); // current highest enmity before this update CBattleEntity* OldEntity = GetHighestEnmity(); if( PEnmity != m_EnmityList.end() && !m_EnmityList.key_comp()(PEntity->id, PEnmity->first)) { int8 enmityBonus = 0; if (PEntity->objtype & TYPE_PC) { enmityBonus = ((CCharEntity*)PEntity)->PMeritPoints->GetMeritValue(MERIT_ENMITY_INCREASE, (CCharEntity*)PEntity) - ((CCharEntity*)PEntity)->PMeritPoints->GetMeritValue(MERIT_ENMITY_DECREASE, (CCharEntity*)PEntity); } float bonus = (100.0f + dsp_cap(PEntity->getMod(MOD_ENMITY)+enmityBonus, -50, 100)) / 100.0f; PEnmity->second->CE += CE * bonus; PEnmity->second->VE += VE * bonus; //Check for cap limit PEnmity->second->CE = dsp_cap(PEnmity->second->CE, 1, 10000); PEnmity->second->VE = dsp_cap(PEnmity->second->VE, 1, 10000); } else { EnmityObject_t* PEnmityObject = new EnmityObject_t; int8 enmityBonus = 0; if (PEntity->objtype & TYPE_PC) { enmityBonus = ((CCharEntity*)PEntity)->PMeritPoints->GetMeritValue(MERIT_ENMITY_INCREASE, (CCharEntity*)PEntity) - ((CCharEntity*)PEntity)->PMeritPoints->GetMeritValue(MERIT_ENMITY_DECREASE, (CCharEntity*)PEntity); } float bonus = (100.0f + dsp_cap(PEntity->getMod(MOD_ENMITY)+enmityBonus, -50, 100)) / 100.0f; PEnmityObject->CE = CE * bonus; PEnmityObject->VE = VE * bonus; PEnmityObject->PEnmityOwner = PEntity; m_EnmityList.insert(PEnmity, EnmityList_t::value_type(PEntity->id, PEnmityObject)); if(withMaster && PEntity->PMaster != NULL) { //add master to the enmity list //add master to the enmity list (charmed mob) if(PEntity->objtype == TYPE_PET || PEntity->objtype == TYPE_MOB && PEntity->PMaster!=NULL && PEntity->PMaster->objtype == TYPE_PC) { UpdateEnmity(PEntity->PMaster, 0, 0); } } } }
void CEnmityContainer::AddBaseEnmity(CBattleEntity* PChar) { UpdateEnmity(PChar, 1, 1); }
void CEnmityContainer::UpdateEnmityFromAttack(CBattleEntity* PEntity, uint16 Damage) { UpdateEnmity(PEntity, -(1800 * Damage / PEntity->GetMaxHP()), 0); }
void CEnmityContainer::AddLinkEnmity(CBattleEntity* PEntity) { UpdateEnmity(PEntity, 1, 1, false); }
void CEnmityContainer::AddAggroEnmity(CBattleEntity* PEntity) { UpdateEnmity(PEntity, 0, 0, true, true); }
void CEnmityContainer::UpdateEnmity(CBattleEntity* PEntity, int16 CE, int16 VE, bool withMaster, bool aggroEnmity) { // you're too far away so i'm ignoring you if (!IsWithinEnmityRange(PEntity)) { CE = 0; VE = 0; } auto PMob = dynamic_cast<CMobEntity*>(m_EnmityHolder); if (PMob && PMob->m_HiPCLvl < PEntity->GetMLevel()) PMob->m_HiPCLvl = PEntity->GetMLevel(); EnmityList_t::iterator PEnmity = m_EnmityList.lower_bound(PEntity->id); // current highest enmity before this update CBattleEntity* OldEntity = GetHighestEnmity(); if (PEnmity != m_EnmityList.end() && !m_EnmityList.key_comp()(PEntity->id, PEnmity->first)) { float bonus = CalculateEnmityBonus(PEntity); if (PEnmity->second->CE == 0 && CE + VE <= 0) return; int newCE = PEnmity->second->CE + ((CE > 0) ? CE * bonus : CE); int newVE = PEnmity->second->VE + ((VE > 0) ? VE * bonus : VE); //Check for cap limit PEnmity->second->CE = dsp_cap(newCE, 1, 10000); PEnmity->second->VE = dsp_cap(newVE, 0, 10000); PEnmity->second->isAggroEnmity = aggroEnmity; if (CE + VE > 0 && PEntity->getMod(MOD_TREASURE_HUNTER) > PEnmity->second->maxTH) PEnmity->second->maxTH = (uint8)(PEntity->getMod(MOD_TREASURE_HUNTER)); } else if (CE >= 0 && VE >= 0) { EnmityObject_t* PEnmityObject = new EnmityObject_t; bool initial = true; for (auto&& enmityObject : m_EnmityList) { if (enmityObject.second->CE > 0 || enmityObject.second->VE > 0) { initial = false; break; } } if (initial) CE += 200; float bonus = CalculateEnmityBonus(PEntity); PEnmityObject->CE = dsp_cap(CE * bonus, 0, 10000); PEnmityObject->VE = dsp_cap(VE * bonus, 0, 10000); PEnmityObject->PEnmityOwner = PEntity; PEnmityObject->isAggroEnmity = aggroEnmity; if (CE + VE > 0) PEnmityObject->maxTH = (uint8)(PEntity->getMod(MOD_TREASURE_HUNTER)); else PEnmityObject->maxTH = 0; m_EnmityList.insert(PEnmity, EnmityList_t::value_type(PEntity->id, PEnmityObject)); if (withMaster && PEntity->PMaster != nullptr) { //add master to the enmity list //add master to the enmity list (charmed mob) if (PEntity->objtype == TYPE_PET || PEntity->objtype == TYPE_MOB && PEntity->PMaster != nullptr && PEntity->PMaster->objtype == TYPE_PC) { UpdateEnmity(PEntity->PMaster, 0, 0); } } } }
void CEnmityContainer::UpdateEnmity(CBattleEntity* PEntity, int16 CE, int16 VE, bool withMaster) { // you're too far away so i'm ignoring you if(!IsWithinEnmityRange(PEntity)) { CE = 0; VE = 0; } // Crash fix, PEntity was in ACTION_FALL if (PEntity->PBattleAI->GetCurrentAction() == ACTION_FALL) return; EnmityList_t::iterator PEnmity = m_EnmityList.lower_bound(PEntity->id); // current highest enmity before this update CBattleEntity* OldEntity = GetHighestEnmity(); if( PEnmity != m_EnmityList.end() && !m_EnmityList.key_comp()(PEntity->id, PEnmity->first)) { float bonus = CalculateEnmityBonus(PEntity); if (PEnmity->second->CE == 0 && CE + VE <= 0) return; PEnmity->second->CE += CE > 0 ? CE * bonus : CE; PEnmity->second->VE += VE > 0 ? VE * bonus : VE; //Check for cap limit PEnmity->second->CE = dsp_cap(PEnmity->second->CE, 1, 10000); PEnmity->second->VE = dsp_cap(PEnmity->second->VE, 0, 10000); if (CE + VE > 0 && PEntity->getMod(MOD_TREASURE_HUNTER) > PEnmity->second->maxTH) PEnmity->second->maxTH = (uint8)(PEntity->getMod(MOD_TREASURE_HUNTER)); } else if (CE >= 0 && VE >= 0) { EnmityObject_t* PEnmityObject = new EnmityObject_t; float bonus = CalculateEnmityBonus(PEntity); PEnmityObject->CE = CE * bonus; PEnmityObject->VE = VE * bonus; PEnmityObject->PEnmityOwner = PEntity; if (CE + VE > 0) PEnmityObject->maxTH = (uint8)(PEntity->getMod(MOD_TREASURE_HUNTER)); else PEnmityObject->maxTH = 0; m_EnmityList.insert(PEnmity, EnmityList_t::value_type(PEntity->id, PEnmityObject)); if(withMaster && PEntity->PMaster != NULL) { //add master to the enmity list //add master to the enmity list (charmed mob) if(PEntity->objtype == TYPE_PET || PEntity->objtype == TYPE_MOB && PEntity->PMaster!=NULL && PEntity->PMaster->objtype == TYPE_PC) { UpdateEnmity(PEntity->PMaster, 0, 0); } } } }