void CZoneEntities::ZoneServer(time_point tick) { for (EntityList_t::const_iterator it = m_mobList.begin(); it != m_mobList.end(); ++it) { CMobEntity* PMob = (CMobEntity*)it->second; PMob->StatusEffectContainer->CheckEffects(tick); PMob->PAI->Tick(tick); PMob->StatusEffectContainer->CheckRegen(tick); } for (EntityList_t::const_iterator it = m_npcList.begin(); it != m_npcList.end(); ++it) { CNpcEntity* PNpc = (CNpcEntity*)it->second; PNpc->PAI->Tick(server_clock::now()); } EntityList_t::const_iterator pit = m_petList.begin(); while (pit != m_petList.end()) { CPetEntity* PPet = (CPetEntity*)pit->second; PPet->StatusEffectContainer->CheckEffects(tick); PPet->PAI->Tick(tick); PPet->StatusEffectContainer->CheckRegen(tick); if (PPet->status == STATUS_DISAPPEAR) { for (auto PMobIt : m_mobList) { CMobEntity* PCurrentMob = (CMobEntity*)PMobIt.second; PCurrentMob->PEnmityContainer->Clear(PPet->id); } if (PPet->getPetType() != PETTYPE_AUTOMATON) { delete pit->second; } m_petList.erase(pit++); } else { ++pit; } } for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it) { CCharEntity* PChar = (CCharEntity*)it->second; if (PChar->status != STATUS_SHUTDOWN) { PChar->PRecastContainer->Check(); PChar->StatusEffectContainer->CheckEffects(tick); PChar->PAI->Tick(tick); PChar->PTreasurePool->CheckItems(tick); PChar->StatusEffectContainer->CheckRegen(tick); } } }
void CStatusEffectContainer::CheckRegen(uint32 tick) { DSP_DEBUG_BREAK_IF(m_POwner == nullptr); if (!m_POwner->isDead()) { if ((tick - m_RegenCheckTime) < 3000 ) { return; } CCharEntity* PChar = nullptr; if(m_POwner->objtype == TYPE_PC) { PChar = (CCharEntity*)m_POwner; } m_RegenCheckTime = tick; int16 regen = m_POwner->getMod(MOD_REGEN); int16 poison = m_POwner->getMod(MOD_REGEN_DOWN); int16 refresh = m_POwner->getMod(MOD_REFRESH) - m_POwner->getMod(MOD_REFRESH_DOWN); int16 regain = m_POwner->getMod(MOD_REGAIN) - m_POwner->getMod(MOD_REGAIN_DOWN); bool update = false; if (m_POwner->addHP(regen)) update = true; if(poison) { int16 damage = battleutils::HandleStoneskin(m_POwner, poison); if(damage > 0) { DelStatusEffectSilent(EFFECT_HEALING); m_POwner->addHP(-damage); WakeUp(); update = true; } } if (m_POwner->getMod(MOD_AVATAR_PERPETUATION) > 0 && (m_POwner->objtype == TYPE_PC)) { int16 perpetuation = m_POwner->getMod(MOD_AVATAR_PERPETUATION); if (m_POwner->StatusEffectContainer->HasStatusEffect(EFFECT_ASTRAL_FLOW)) perpetuation = 0; else { if (m_POwner->PPet != nullptr && PChar != nullptr) { if(m_POwner->PPet->objtype == TYPE_PET) { CPetEntity* PPet = (CPetEntity*)m_POwner->PPet; CItem* hands = PChar->getEquip(SLOT_HANDS); // carbuncle mitts only work on carbuncle if (hands && hands->getID() == 14062 && PPet->name == "Carbuncle"){ perpetuation /= 2; } } perpetuation -= charutils::AvatarPerpetuationReduction(PChar); if( perpetuation < 1 ) perpetuation = 1; } } if (m_POwner->addMP(refresh - perpetuation)) update = true; if( m_POwner->health.mp == 0 && m_POwner->PPet != nullptr && m_POwner->PPet->objtype == TYPE_PET) { CPetEntity* PPet = (CPetEntity*)m_POwner->PPet; if (PPet->getPetType() == PETTYPE_AVATAR) { petutils::DespawnPet(m_POwner); } } } else { if (m_POwner->addMP(refresh)) update = true; } if (m_POwner->addTP(regain)) update = true; if (m_POwner->PPet && ((CPetEntity*)(m_POwner->PPet))->getPetType() == PETTYPE_AUTOMATON) { ((CAutomatonEntity*)(m_POwner->PPet))->burdenTick(); } if( m_POwner->status != STATUS_DISAPPEAR && (m_POwner->objtype == TYPE_PC) && update) { charutils::UpdateHealth((CCharEntity*)m_POwner); } } }
/************************************************************************ * * * Tick regen/refresh/regain effects * * * ************************************************************************/ void CStatusEffectContainer::CheckRegen(uint32 tick) { DSP_DEBUG_BREAK_IF(m_POwner == NULL); if (!m_POwner->isDead()) { if ((tick - m_RegenCheckTime) < 3000 ) { return; } CCharEntity* PChar = NULL; if(m_POwner->objtype == TYPE_PC) { PChar = (CCharEntity*)m_POwner; } m_RegenCheckTime = tick; int8 regen = m_POwner->getMod(MOD_REGEN); int8 poison = m_POwner->getMod(MOD_REGEN_DOWN); int8 refresh = m_POwner->getMod(MOD_REFRESH) - m_POwner->getMod(MOD_REFRESH_DOWN); int16 regain = m_POwner->getMod(MOD_REGAIN) - m_POwner->getMod(MOD_REGAIN_DOWN); m_POwner->addHP(regen); if(poison) { int16 damage = battleutils::HandleStoneskin(m_POwner, poison); if(damage > 0) { DelStatusEffectSilent(EFFECT_HEALING); m_POwner->addHP(-damage); WakeUp(); } } if (m_POwner->getMod(MOD_AVATAR_PERPETUATION) > 0 && (m_POwner->objtype == TYPE_PC)) { int8 perpetuation = m_POwner->getMod(MOD_AVATAR_PERPETUATION); if (m_POwner->StatusEffectContainer->HasStatusEffect(EFFECT_ASTRAL_FLOW)) perpetuation = 0; else { if (m_POwner->PPet != NULL && PChar != NULL) { if(m_POwner->PPet->objtype == TYPE_PET) { CPetEntity* PPet = (CPetEntity*)m_POwner->PPet; CItem* hands = PChar->getEquip(SLOT_HANDS); // carbuncle mitts only work on carbuncle if (hands && hands->getID() == 14062 && PPet->name == "Carbuncle"){ perpetuation /= 2; } } perpetuation -= charutils::AvatarPerpetuationReduction(PChar); if( perpetuation < 1 ) perpetuation = 1; } } m_POwner->addMP(refresh - perpetuation); if( m_POwner->health.mp == 0 && m_POwner->PPet != NULL && m_POwner->PPet->objtype == TYPE_PET) { CPetEntity* PPet = (CPetEntity*)m_POwner->PPet; if (PPet->getPetType() == PETTYPE_AVATAR) { petutils::DespawnPet(m_POwner); } } } else { m_POwner->addMP(refresh); } if(PChar != NULL && IsAsleep()) { CItem* neck = PChar->getEquip(SLOT_NECK); // opo-opo necklace if(neck != NULL && neck->getID() == 13143) { // add tp regain += 2.5f; } } m_POwner->addTP(regain); if( m_POwner->status != STATUS_DISAPPEAR && (m_POwner->objtype == TYPE_PC)) { charutils::UpdateHealth((CCharEntity*)m_POwner); } } }
void CZoneEntities::ZoneServer(time_point tick, bool check_regions) { for (EntityList_t::const_iterator it = m_mobList.begin(); it != m_mobList.end(); ++it) { CMobEntity* PMob = (CMobEntity*)it->second; if (PMob->PBCNM && PMob->PBCNM->cleared()) { continue; } PMob->PRecastContainer->Check(); PMob->StatusEffectContainer->CheckEffectsExpiry(tick); if(tick > m_EffectCheckTime) { PMob->StatusEffectContainer->TickRegen(tick); PMob->StatusEffectContainer->TickEffects(tick); } PMob->PAI->Tick(tick); } for (EntityList_t::const_iterator it = m_npcList.begin(); it != m_npcList.end(); ++it) { CNpcEntity* PNpc = (CNpcEntity*)it->second; PNpc->PAI->Tick(tick); } EntityList_t::const_iterator pit = m_petList.begin(); while (pit != m_petList.end()) { CPetEntity* PPet = (CPetEntity*)pit->second; PPet->PRecastContainer->Check(); PPet->StatusEffectContainer->CheckEffectsExpiry(tick); if(tick > m_EffectCheckTime) { PPet->StatusEffectContainer->TickRegen(tick); PPet->StatusEffectContainer->TickEffects(tick); } PPet->PAI->Tick(tick); if (PPet->status == STATUS_DISAPPEAR) { for (auto PMobIt : m_mobList) { CMobEntity* PCurrentMob = (CMobEntity*)PMobIt.second; PCurrentMob->PEnmityContainer->Clear(PPet->id); } if (PPet->getPetType() != PETTYPE_AUTOMATON || !PPet->PMaster) { delete pit->second; } m_petList.erase(pit++); } else { ++pit; } } for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it) { CCharEntity* PChar = (CCharEntity*)it->second; if (PChar->status != STATUS_SHUTDOWN) { PChar->PRecastContainer->Check(); PChar->StatusEffectContainer->CheckEffectsExpiry(tick); if (tick > m_EffectCheckTime) { PChar->StatusEffectContainer->TickRegen(tick); PChar->StatusEffectContainer->TickEffects(tick); } PChar->PAI->Tick(tick); PChar->PTreasurePool->CheckItems(tick); if (check_regions) { m_zone->CheckRegions(PChar); } } } if (tick > m_EffectCheckTime) { m_EffectCheckTime = m_EffectCheckTime + 3s > tick ? m_EffectCheckTime + 3s : tick + 3s; } }