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
}
Example #8
0
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;
}