void CStatusEffectContainer::SaveStatusEffects() { DSP_DEBUG_BREAK_IF(m_POwner->objtype != TYPE_PC); Sql_Query(SqlHandle,"DELETE FROM char_effects WHERE charid = %u", m_POwner->id); for (uint32 i = 0; i < m_StatusEffectList.size(); ++i) { CStatusEffect* PStatusEffect = m_StatusEffectList.at(i); if (PStatusEffect->GetDuration() != 0) { const int8* Query = "INSERT INTO char_effects (charid, effectid, icon, power, tick, duration, subid, subpower, tier) VALUES(%u,%u,%u,%u,%u,%u,%u,%u,%u);"; // save power of utsusemi and blink if(PStatusEffect->GetStatusID() == EFFECT_COPY_IMAGE){ PStatusEffect->SetPower(m_POwner->getMod(MOD_UTSUSEMI)); } else if(PStatusEffect->GetStatusID() == EFFECT_BLINK){ PStatusEffect->SetPower(m_POwner->getMod(MOD_BLINK)); } else if(PStatusEffect->GetStatusID() == EFFECT_STONESKIN){ PStatusEffect->SetPower(m_POwner->getMod(MOD_STONESKIN)); } Sql_Query(SqlHandle, Query, m_POwner->id, PStatusEffect->GetStatusID(), PStatusEffect->GetIcon(), PStatusEffect->GetPower(), PStatusEffect->GetTickTime() / 1000, (PStatusEffect->GetDuration() + PStatusEffect->GetStartTime() - gettick()) / 1000, PStatusEffect->GetSubID(), PStatusEffect->GetSubPower(), PStatusEffect->GetTier()); } } }
void CStatusEffectContainer::Fold(uint32 charid) { CStatusEffect* oldestRoll = nullptr; for (uint16 i = 0; i < m_StatusEffectList.size(); ++i) { if ((m_StatusEffectList.at(i)->GetStatusID() >= EFFECT_FIGHTERS_ROLL && m_StatusEffectList.at(i)->GetStatusID() <= EFFECT_SCHOLARS_ROLL) || m_StatusEffectList.at(i)->GetStatusID() == EFFECT_BUST)//is a cor effect { if (m_StatusEffectList.at(i)->GetSubID() == charid || m_StatusEffectList.at(i)->GetStatusID() == EFFECT_BUST) { if (oldestRoll == nullptr) { oldestRoll = m_StatusEffectList.at(i); } else if (oldestRoll->GetStatusID() != EFFECT_BUST && m_StatusEffectList.at(i)->GetStatusID() == EFFECT_BUST) { oldestRoll = m_StatusEffectList.at(i); } else if (m_StatusEffectList.at(i)->GetDuration() + m_StatusEffectList.at(i)->GetStartTime() < oldestRoll->GetDuration() + oldestRoll->GetStartTime()) { oldestRoll = m_StatusEffectList.at(i); } } } } if (oldestRoll != nullptr) { DelStatusEffectSilent(oldestRoll->GetStatusID()); DelStatusEffectSilent(EFFECT_DOUBLE_UP_CHANCE); } }
void CStatusEffectContainer::LoadStatusEffects() { DSP_DEBUG_BREAK_IF(m_POwner->objtype != TYPE_PC); const int8* Query = "SELECT " "effectid," "icon," "power," "tick," "duration," "subid," "subpower," "tier " "FROM char_effects " "WHERE charid = %u;"; int32 ret = Sql_Query(SqlHandle, Query, m_POwner->id); std::vector<CStatusEffect*> PEffectList; if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0) { while (Sql_NextRow(SqlHandle) == SQL_SUCCESS) { CStatusEffect* PStatusEffect = new CStatusEffect( (EFFECT)Sql_GetUIntData(SqlHandle, 0), (uint16)Sql_GetUIntData(SqlHandle, 1), (uint16)Sql_GetUIntData(SqlHandle, 2), (uint32)Sql_GetUIntData(SqlHandle, 3), (uint32)Sql_GetUIntData(SqlHandle, 4), (uint16)Sql_GetUIntData(SqlHandle, 5), (uint16)Sql_GetUIntData(SqlHandle, 6), (uint16)Sql_GetUIntData(SqlHandle, 7)); PEffectList.push_back(PStatusEffect); // load shadows left if (PStatusEffect->GetStatusID() == EFFECT_COPY_IMAGE) { m_POwner->setModifier(MOD_UTSUSEMI, PStatusEffect->GetPower()); } else if (PStatusEffect->GetStatusID() == EFFECT_BLINK) { m_POwner->setModifier(MOD_BLINK, PStatusEffect->GetPower()); } } } for (auto&& PStatusEffect : PEffectList) { AddStatusEffect(PStatusEffect); } m_POwner->UpdateHealth(); // после загрузки эффектов пересчитываем максимальное количество HP/MP }
CStatusEffect* CStatusEffectContainer::StealStatusEffect() { std::vector<uint16> dispelableList; for (uint16 i = 0; i < m_StatusEffectList.size(); ++i) { if (m_StatusEffectList.at(i)->GetFlag() & EFFECTFLAG_DISPELABLE && m_StatusEffectList.at(i)->GetDuration() > 0) { dispelableList.push_back(i); } } if (!dispelableList.empty()) { uint16 rndIdx = WELL512::GetRandomNumber(dispelableList.size()); uint16 effectIndex = dispelableList.at(rndIdx); CStatusEffect* oldEffect = m_StatusEffectList.at(effectIndex); //make a copy CStatusEffect* EffectCopy = new CStatusEffect(oldEffect->GetStatusID(), oldEffect->GetIcon(), oldEffect->GetPower(), oldEffect->GetTickTime()/1000, oldEffect->GetDuration()/1000); RemoveStatusEffect(effectIndex); return EffectCopy; } return 0; }
void CStatusEffectContainer::RemoveStatusEffect(uint32 id, bool silent) { CStatusEffect* PStatusEffect = m_StatusEffectList.at(id); if (PStatusEffect->GetStatusID() >= EFFECT_FIRE_MANEUVER && PStatusEffect->GetStatusID() <= EFFECT_DARK_MANEUVER && m_POwner->objtype == TYPE_PC) { puppetutils::CheckAttachmentsForManeuver((CCharEntity*)m_POwner, PStatusEffect->GetStatusID(), false); } m_StatusEffectList.erase(m_StatusEffectList.begin() + id); luautils::OnEffectLose(m_POwner, PStatusEffect); m_POwner->delModifiers(&PStatusEffect->modList); m_POwner->UpdateHealth(); if (m_POwner->objtype == TYPE_PC) { CCharEntity* PChar = (CCharEntity*)m_POwner; if (PStatusEffect->GetIcon() != 0) { UpdateStatusIcons(); if (silent == false) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, PStatusEffect->GetIcon(), 0, 206)); } } //check for latents PChar->PLatentEffectContainer->CheckLatentsFoodEffect(); PChar->PLatentEffectContainer->CheckLatentsStatusEffect(); PChar->PLatentEffectContainer->CheckLatentsRollSong(HasStatusEffectByFlag(EFFECTFLAG_SONG | EFFECTFLAG_ROLL)); PChar->UpdateHealth(); PChar->pushPacket(new CCharHealthPacket(PChar)); PChar->pushPacket(new CCharSyncPacket(PChar)); } else { if (silent == false && PStatusEffect->GetIcon() != 0 && ((PStatusEffect->GetFlag() & EFFECTFLAG_NO_LOSS_MESSAGE) == 0) && !m_POwner->isDead()) { m_POwner->loc.zone->PushPacket(m_POwner, CHAR_INRANGE, new CMessageBasicPacket(m_POwner, m_POwner, PStatusEffect->GetIcon(), 0, 206)); } } delete PStatusEffect; }
void CStatusEffectContainer::SaveStatusEffects(bool logout) { DSP_DEBUG_BREAK_IF(m_POwner->objtype != TYPE_PC); Sql_Query(SqlHandle, "DELETE FROM char_effects WHERE charid = %u", m_POwner->id); for (uint16 i = 0; i < m_StatusEffectList.size(); ++i) { CStatusEffect* PStatusEffect = m_StatusEffectList.at(i); if (logout && PStatusEffect->GetFlag() & EFFECTFLAG_LOGOUT) continue; auto realduration = std::chrono::milliseconds(PStatusEffect->GetDuration()) + PStatusEffect->GetStartTime() - server_clock::now(); if (realduration > 0s) { const int8* Query = "INSERT INTO char_effects (charid, effectid, icon, power, tick, duration, subid, subpower, tier) VALUES(%u,%u,%u,%u,%u,%u,%u,%u,%u);"; // save power of utsusemi and blink if (PStatusEffect->GetStatusID() == EFFECT_COPY_IMAGE) { PStatusEffect->SetPower(m_POwner->getMod(MOD_UTSUSEMI)); } else if (PStatusEffect->GetStatusID() == EFFECT_BLINK) { PStatusEffect->SetPower(m_POwner->getMod(MOD_BLINK)); } else if (PStatusEffect->GetStatusID() == EFFECT_STONESKIN) { PStatusEffect->SetPower(m_POwner->getMod(MOD_STONESKIN)); } uint32 tick = PStatusEffect->GetTickTime() == 0 ? 0 : PStatusEffect->GetTickTime() / 1000; uint32 duration = PStatusEffect->GetDuration() == 0 ? 0 : std::chrono::duration_cast<std::chrono::seconds>(realduration).count(); Sql_Query(SqlHandle, Query, m_POwner->id, PStatusEffect->GetStatusID(), PStatusEffect->GetIcon(), PStatusEffect->GetPower(), tick, duration, PStatusEffect->GetSubID(), PStatusEffect->GetSubPower(), PStatusEffect->GetTier()); } } }
/************************************************************************ * * * ????????? ??????? ????????? * * * ************************************************************************/ void CStatusEffectContainer::LoadStatusEffects() { DSP_DEBUG_BREAK_IF(m_POwner->objtype != TYPE_PC); const int8* Query = "SELECT " "effectid," "icon," "power," "tick," "duration," "subid," "subpower," "tier " "FROM char_effects " "WHERE charid = %u;"; int32 ret = Sql_Query(SqlHandle, Query, m_POwner->id); if( ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0) { while(Sql_NextRow(SqlHandle) == SQL_SUCCESS) { CStatusEffect* PStatusEffect = new CStatusEffect( (EFFECT)Sql_GetUIntData(SqlHandle,0), (uint16)Sql_GetUIntData(SqlHandle,1), (uint16)Sql_GetUIntData(SqlHandle,2), (uint32)Sql_GetUIntData(SqlHandle,3), (uint32)Sql_GetUIntData(SqlHandle,4), (uint16)Sql_GetUIntData(SqlHandle,5), (uint16)Sql_GetUIntData(SqlHandle,6), (uint16)Sql_GetUIntData(SqlHandle,7)); AddStatusEffect(PStatusEffect); // load shadows left if(PStatusEffect->GetStatusID() == EFFECT_COPY_IMAGE){ m_POwner->setModifier(MOD_UTSUSEMI, PStatusEffect->GetPower()); } else if(PStatusEffect->GetStatusID() == EFFECT_BLINK){ m_POwner->setModifier(MOD_BLINK, PStatusEffect->GetPower()); } } } m_POwner->UpdateHealth(); // ????? ???????? ???????? ????????????? ???????????? ?????????? HP/MP }
void CStatusEffectContainer::RemoveOldestManeuver() { CStatusEffect* oldest = nullptr; int index = 0; for (uint16 i = 0; i < m_StatusEffectList.size(); ++i) { CStatusEffect* PStatusEffect = m_StatusEffectList.at(i); if (PStatusEffect->GetStatusID() >= EFFECT_FIRE_MANEUVER && PStatusEffect->GetStatusID() <= EFFECT_DARK_MANEUVER) { if (!oldest || PStatusEffect->GetStartTime() < oldest->GetStartTime()) { oldest = PStatusEffect; index = i; } } } if (oldest) { RemoveStatusEffect(index, true); } }
bool CStatusEffectContainer::ApplyBardEffect(CStatusEffect* PStatusEffect, uint8 maxSongs) { //if all match tier/id/effect then overwrite //if tier/effect match then overwrite //but id doesn't, NO EFFECT //if targ has <2 of your songs on, then just apply //if targ has 2 of your songs, remove oldest one and apply this one. uint8 numOfEffects = 0; CStatusEffect* oldestSong = nullptr; for (uint16 i = 0; i < m_StatusEffectList.size(); ++i) { if (m_StatusEffectList.at(i)->GetStatusID() >= EFFECT_REQUIEM && m_StatusEffectList.at(i)->GetStatusID() <= EFFECT_NOCTURNE) //is a brd effect { if (m_StatusEffectList.at(i)->GetTier() == PStatusEffect->GetTier() && m_StatusEffectList.at(i)->GetStatusID()==PStatusEffect->GetStatusID()){//same tier/type, overwrite //OVERWRITE DelStatusEffectByTier(PStatusEffect->GetStatusID(), PStatusEffect->GetTier()); AddStatusEffect(PStatusEffect); return true; } if(m_StatusEffectList.at(i)->GetSubID() == PStatusEffect->GetSubID()){//YOUR BRD effect numOfEffects++; if(!oldestSong){ oldestSong = m_StatusEffectList.at(i); } else if(m_StatusEffectList.at(i)->GetDuration() + m_StatusEffectList.at(i)->GetStartTime() < oldestSong->GetDuration() + oldestSong->GetStartTime()){ oldestSong = m_StatusEffectList.at(i); } } } } if(numOfEffects<maxSongs){ AddStatusEffect(PStatusEffect); return true; } else if (oldestSong){ //overwrite oldest DelStatusEffectByTier(oldestSong->GetStatusID(), oldestSong->GetTier()); AddStatusEffect(PStatusEffect); return true; } return false; }
bool CStatusEffectContainer::ApplyCorsairEffect(CStatusEffect* PStatusEffect, uint8 maxRolls, uint8 bustDuration) { //break if not a COR roll. DSP_DEBUG_BREAK_IF(!(PStatusEffect->GetStatusID() >= EFFECT_FIGHTERS_ROLL && PStatusEffect->GetStatusID() <= EFFECT_SCHOLARS_ROLL)); //if all match tier/id/effect then overwrite //if tier/effect match then overwrite //but id doesn't, NO EFFECT //if targ has <2 of your rolls on, then just apply //if targ has 2 of your rolls, remove oldest one and apply this one. uint8 numOfEffects = 0; CStatusEffect* oldestRoll = nullptr; for (uint16 i = 0; i < m_StatusEffectList.size(); ++i) { if ((m_StatusEffectList.at(i)->GetStatusID() >= EFFECT_FIGHTERS_ROLL && m_StatusEffectList.at(i)->GetStatusID() <= EFFECT_SCHOLARS_ROLL) || m_StatusEffectList.at(i)->GetStatusID() == EFFECT_BUST)//is a cor effect { if(m_StatusEffectList.at(i)->GetStatusID() == PStatusEffect->GetStatusID() && m_StatusEffectList.at(i)->GetSubID() == PStatusEffect->GetSubID() && m_StatusEffectList.at(i)->GetSubPower() < PStatusEffect->GetSubPower()){//same type, double up if( PStatusEffect->GetSubPower() < 12) { PStatusEffect->SetDuration(m_StatusEffectList.at(i)->GetDuration()); DelStatusEffectSilent(PStatusEffect->GetStatusID()); AddStatusEffect(PStatusEffect, true); return true; } else { if (!CheckForElevenRoll()) { uint16 duration = 300; duration -= bustDuration; CStatusEffect* bustEffect = new CStatusEffect(EFFECT_BUST, EFFECT_BUST, PStatusEffect->GetPower(), 0, duration, PStatusEffect->GetTier(), PStatusEffect->GetStatusID()); AddStatusEffect(bustEffect, true); } DelStatusEffectSilent(PStatusEffect->GetStatusID()); return true; } } if(m_StatusEffectList.at(i)->GetSubID() == PStatusEffect->GetSubID() || m_StatusEffectList.at(i)->GetStatusID() == EFFECT_BUST){//YOUR cor effect numOfEffects++; if(oldestRoll==nullptr){ oldestRoll = m_StatusEffectList.at(i); } else if(m_StatusEffectList.at(i)->GetDuration() + m_StatusEffectList.at(i)->GetStartTime() < oldestRoll->GetDuration() + oldestRoll->GetStartTime()){ oldestRoll = m_StatusEffectList.at(i); } } } } if(numOfEffects<maxRolls){ AddStatusEffect(PStatusEffect, true); return true; } else{ //i'm a liar, can overwrite rolls DelStatusEffect(oldestRoll->GetStatusID()); AddStatusEffect(PStatusEffect); return true; } return false; }
bool CStatusEffectContainer::CanGainStatusEffect(EFFECT statusEffect, uint16 power) { // check for immunities first switch(statusEffect){ case EFFECT_SLEEP: case EFFECT_SLEEP_II: case EFFECT_LULLABY: if(m_POwner->hasImmunity(IMMUNITY_SLEEP)) return false; break; case EFFECT_WEIGHT: if(m_POwner->hasImmunity(IMMUNITY_GRAVITY)) return false; break; case EFFECT_BIND: if(m_POwner->hasImmunity(IMMUNITY_BIND)) return false; break; case EFFECT_STUN: if(m_POwner->hasImmunity(IMMUNITY_STUN)) return false; break; case EFFECT_SILENCE: if(m_POwner->hasImmunity(IMMUNITY_SILENCE)) return false; break; case EFFECT_PARALYSIS: if(m_POwner->hasImmunity(IMMUNITY_PARALYZE)) return false; break; case EFFECT_BLINDNESS: if(m_POwner->hasImmunity(IMMUNITY_BLIND)) return false; break; case EFFECT_SLOW: if(m_POwner->hasImmunity(IMMUNITY_SLOW)) return false; break; case EFFECT_POISON: if(m_POwner->hasImmunity(IMMUNITY_POISON)) return false; break; case EFFECT_ELEGY: if(m_POwner->hasImmunity(IMMUNITY_ELEGY)) return false; break; case EFFECT_REQUIEM: if(m_POwner->hasImmunity(IMMUNITY_REQUIEM)) return false; break; } // make sure pets can't be charmed if((statusEffect == EFFECT_CHARM || statusEffect == EFFECT_CHARM_II) && m_POwner->PMaster != nullptr) { return false; } CStatusEffect* PStatusEffect; // check if a status effect blocks this EFFECT blockId = effects::EffectsParams[statusEffect].BlockId; if(blockId != 0 && HasStatusEffect(blockId)){ return false; } // check if negative is strong enough to stop this EFFECT negativeId = effects::EffectsParams[statusEffect].NegativeId; if(negativeId != 0){ PStatusEffect = GetStatusEffect(negativeId); if(PStatusEffect != nullptr){ if(statusEffect == EFFECT_HASTE && PStatusEffect->GetStatusID() == EFFECT_SLOW && PStatusEffect->GetSubPower() == 1) { // slow i remote return true; } // new status effect must be stronger return power >= PStatusEffect->GetPower(); } } PStatusEffect = GetStatusEffect(statusEffect); // check overwrite if(PStatusEffect != nullptr){ uint16 currentPower = PStatusEffect->GetPower(); EFFECTOVERWRITE overwrite = effects::EffectsParams[statusEffect].Overwrite; if(overwrite == EFFECTOVERWRITE_ALWAYS || overwrite == EFFECTOVERWRITE_IGNORE){ return true; } if(overwrite == EFFECTOVERWRITE_NEVER){ return false; } if(overwrite == EFFECTOVERWRITE_EQUAL_HIGHER){ if(power >= currentPower){ return true; } } else if(overwrite == EFFECTOVERWRITE_HIGHER){ // overwrite only if higher if(power > currentPower){ return true; } } return false; } return true; }